Kitsu ホスティング基盤のディープダイブ

Kitsu ホスティング基盤のディープダイブ

Webサーバーの導入は、かなり簡単に行えます。特に、すべてがオンラインでドキュメント化されている Kitsu のようなWebアプリケーションならなおさらです。ですが、数日を費やす意志のあるIT担当なら、確実に実現できるでしょう。とはいえ問題は、クラウドアプリケーションの運用はWebサービスを設定することではなく、想定外の事態を管理することだという点です。

最初のスタートアップ(Cozy Cloud)を立ち上げたとき、当初は私自身がサーバーを管理していたので、そう言い切れます。  多数の仮想マシンを用意し、DNSを設定し、登録してくれたユーザーに対して製品を提供できるようにしました。すべてがうまくいきそうに見えたのは、ユーザーが本当に製品を使い始めるまではの話です。

美しいインフラが整ったら、今度は大量の面倒な状況に対処しなければなりませんでした。ソフトウェア障害、ホスティング事業者の障害、遅延、バックアップ戦略、復旧……。それは昼夜を問わず、いつでも起こりました。私は共同創業者兼CTOだったので、対応すべき仕事がさらに山ほどありました。学ぶことはたくさんありましたが、正直に言うと、その負荷をさばくには足りませんでした。幸い、資金調達ができ、私たちの代わりに運用を管理できる経験者を雇うことができました。ほかにも多くの解決策を探すことはできました。でも結局、「これはフルタイムの仕事なのだ」と認めて、その状況に対処するための最善の判断をすることができました。

だからこそCGWireでは、スタジオがそうしたつらい瞬間を避けられるようにしたいのです。私たちのソフトウェアは無料だとしても、その上でホスティングサービスを提供せずに Kitsu を開発するのは賢明ではありません。あなたの主な仕事は映画を作ること。IT担当は、あなたのアーティストに専念してもらう必要があります。スタジオのために管理しているハードウェアやサービスそのものに加えて、Webホスティングの複雑さや危険な挙動に対処する必要はありません。

Kitsu はパイプラインの重要な構成要素です。それが失敗すると、生産が危機にさらされます。これは、あなた自身やチームにとって不要な追加ストレスです。

この問題を多くの人が認識しています。だからこそ、無料かつオープンソースのプロジェクトにおいて、ソフトウェアのクラウド提供が定番のビジネスモデルになるのは、私たちに限った話ではありません。

このソフトウェアを適切にホストするために必要な仕事を具体化するために、私たちのインフラで実際に行っているセットアップをすべてお見せしたいと思いました。現在、私たちは約3,000人の利用者を持つ60社のお客様向けに、Kitsuの導入・運用を管理しています。

このブログ記事では、Kitsu を利用する上で可能な限り最高のサービスをお届けするために、私たちのオペレーションチームが整備してきたすべてを紹介します。

Context

The base Stack

念のため、Kitsu は次の要素で構成されるWebアプリケーションです:

  • Python Flask の2つのサービス(REST API と WebSocket の pub/sub システム)
  • RQ デーモン
  • Redis インスタンス
  • Postgres データベース。
  • ファイルはディスク上、またはオブジェクトストレージインスタンスに保存されます。
  • フロントエンドは Vue.js フレームワークのツール(Webpackベース)でビルドされた静的Javascriptファイルで構成されます。
  • 静的ファイルを配信し、単一のドメイン名から API とフロントエンドへアクセスできるようにするためのリバースプロキシとして Nginx インスタンスを使用します。

要するに、常に稼働している必要がある7つのサービスで構成されています。そのうちのどれかが停止すると、アプリケーションは適切に動作できません。

The offer

私たちはクライアントに2つのオファーを用意しています:

  • クラウドホスティング:専用VMをクライアントに提供します。すべてのサービスは私たちのクラウド上で動作します。
  • オンプレミス導入:私たちのクライアントがハードウェアを用意します。セットアップ、メンテナンス、アップデートは私たちが行います。ご要望に応じて LDAP 統合も対応します。
    より大規模なお客様には、Kitsu のインスタンスをローカルで起動・停止できるツールも提案します。

Orchestration

ホスティング事業者として OVH を、IaaS(Infrastructure as a Service)として OpenStack を使用しています。私たちのインフラは仮想マシンに基づいています。 Terraform により必要なハードウェア要件を記述します。これにより、新しい Kitsu インスタンスを素早くセットアップできます。

ここでは、新しい Kitsu を起動するために使用する Terraform ファイルの例を示します:

module "customer_cgwire" {
  source         = "./modules/customer"
  shortname      = "cgwire"
  fqdn           = "cgwire"
  customer_class = "bronze"
  flavor         = "${var.flavor_bronze}"
  net_public     = "${var.net_public}"
  net_priv       = "${var.net_priv}"
  region         = "${var.region}"
  image_name     = "${var.image_name}"
  key_pair       = "${openstack_compute_keypair_v2.keypair.name}"
}

Terraform はシンプルなコマンド(terraform apply)で、設定ファイルを実運用のインフラに反映できます。

Kitsu のVMが起動したら、次のステップはインスタンスの設定です。データベースを作成し、オペレーティングシステムを設定し、データを初期化します。そのために、構成管理システムを使用します。しばらくは Ansible を使っていましたが、最近は Saltstack に移行しました。多くのアップデートを並列で実行するほうが、より便利だと感じたからです。

使うには、構成ファイルを記述し、正しい Kitsu インスタンスとして必要な状態をすべて定義します。続いて salt state.highstate コマンドを実行します。完了すれば、Kitsu インスタンスは使用可能になります!

Saltstack のファイル例(ここでは Redis サービスのセットアップ):

====== redis.sls
redis_packages:
  pkg.latest:
    - pkgs:
      - redis-server

/etc/redis/redis.conf: file.managed: - user: redis - group: redis - mode: '0640' - template: jinja - source: salt:///files/redis.conf.j2 - context: bind_addrs: - require: - pkg: redis_packages

redis: service.running: - name: redis-server - enable: True - require: - pkg: redis_packages - watch: - file: /etc/redis/redis.conf

====== redis.j2 daemonize yes pidfile /var/run/redis/redis-server.pid port 6379 bind

Storage

Kitsu は大量のプレビュー用ファイルを保存します。主に動画ファイルです。ユーザーが動画をアップロードするたびに正規化され、いくつかのサムネイルが抽出されます。スタジオは高解像度版の動画にアクセスしたいので、保存されるファイルはかなり大きくなります。
画像もサムネイルが生成され、その他のファイルタイプはそのまま保存されます。

では、私たちはこれらのファイルをどう保存しているのでしょうか?状況に応じて、2つのケースがあります:

  • オンプレミス導入:私たちは主にプレビューをシンプルなファイルシステム(Kitsu インスタンスをホストしているホスト上で利用可能なフォルダ)に保存します。Kitsu はプレビュー用ファイル UUID(Postgres によって生成されます)にもとづいてフォルダを整理し、同じリポジトリ内のファイル数を増やしすぎないようにするとともに、衝突が起きないようにします。あるいは、エンタープライズのお客様にはローカルのオブジェクトストレージも提案しています。
  • クラウドホスティング:オブジェクトストレージとして OVH の OpenStack Swift を使用します。クラウドインフラでは、仮想マシンを簡単に失う可能性があります。それは、ファイルデータをすべて失うことにつながります。専用ストレージをVMから切り離して使うことで、バックアップが容易になります(2つの別ロケーションにそれぞれ3回複製します)。そのため、Kitsu VMの削除と復元を簡単に行えます。

Compute

もう1つ管理が必要なのが、動画の計算(コンピューティング)です。アップロードされたすべての動画を正規化して、再生時のスムーズな体験を保証することが重要です。そのために FFmpeg を使用します。入力としてあり得るすべてのコーデックとコンテナを処理します。一方、出力としては、私たちのシステムに合わせて標準化され最適化された動画を生成します。

欠点は、非常にリソース集約的な消費につながることです。そこでVMに過負荷がかからないように、Hashicorp社の Nomad クラスタを構築しています。Kitsu インスタンスから計算負荷の高い非同期ジョブをすべて投入します。Kitsu は Nomad のジョブを作成し、Docker コンテナを起動して動画を受け取り、計算を行い、すべてのファイルをオブジェクトストレージへアップロードします。そして次の動画を処理できるように、ローカルではすべてをクリアします。

Nomad は複数のVMからなるクラスタを管理でき、クラスタを利用する必要があるものすべてのための単一の入口を提供します。これにより、動画の正規化を大幅に効率化できます。さらに、プレイリストの作成にも Nomad を使っています。ユーザーは複数のショット版をつなぎ合わせて、1本の映画を作ります。この作業が、リソース消費の点では群を抜いて最も重い処理です。

Logs

すべてのインスタンスにおいて、標準ログは各ホストに書き込まれます。バグを見つけたり状況を分析したりするために、それらをすべて参照するのは複雑です。そこで、ログ集約システムとして Grafana Loki を使用します。

すべてのログ情報を取得し、インスタンス全体でエラーの発生を検索できるようにします。そこから、パフォーマンスのボトルネックも監視できます。最後に、リクエストがどこから来ているかの見当もつきます。これはサイバー攻撃が起きた場合にも役立ちます。

Monitoring

システム管理者にとって非常に重要なのが監視です。インフラ上で問題が発生したときに通知してくれます。重要な理由は次のとおりです:

  • お客様から「壊れてる!」と言われる前に、私たちは問題を把握できます。
  • 問題の根本原因を素早く特定するのに役立ちます。

より具体的に言うと、主に定期的に以下の条件を収集しています:

  • 主要なサービスが稼働しているか、していないか。
  • Kitsu インスタンスがインターネット経由で到達可能かどうか。
  • CPU負荷がしきい値を超えているか。
  • メモリ消費がしきい値を超えているか。
  • 空きディスク容量がしきい値を下回っているか。

いずれかの条件が満たされない場合、アラートが発報されます。アラートが発生したら、状況を今すぐ修正するために何か対応しなければならないことが分かります。

クラウドスタックでは、Grafana 製品で監視を設定しています: PrometheusAlertmanager。アラートメッセージは専用のSlackチャンネルに送信し、重要度の高いものはメールでも送ります。

Alertmanager のダッシュボードには、進行中のすべてのアラートがリアルタイムで表示されます:

システムホストのメトリクスを収集し、HTTPポートに対して疎通確認を行うことで、情報を幅広く把握します。

オンプレミス導入の場合は、レガシーとシンプルさの理由から、 MonitM/Monit を組み合わせて、導入状態の中央集約ビューを持つようにしています。

Metrology

これは監視のもう一つの側面です。ここではデータを視覚的に分析します。インスタンスが稼働しているかどうかを調べるだけではなく、時間の経過とともに起きる不自然な挙動(予期しない変化)を探します。たとえば CPU の長時間使用です(この場合、システム自体は稼働しているものの、サービスは劣化しています)。

メトリクスを収集するためにも同じツールを使います。中心となるのはデータを保存するための Prometheus です。表示には Grafana が連携します。時間の経過に沿ってメトリクスがどう変化しているかを、強力に可視化できます。ファイルシステムに問題が起きたとき、それが「秒」なのか「日」なのか「分」なのかを見分けられます。繰り返し現れるパターンも特定できます。問題の根本原因を見つけるのにとても役立ちます。

いくつかの例です:

インスタンスの「HTTP health」を確認:

リソース消費がどのように変化するかを見る:

Security

セキュリティは、セットアップにおける最も重要な部分です。機器を強化するために、基本原則を適用しました:

  • ホストへの接続方法は、パスフレーズで保護されたSSHキー経由のSSHのみとしています。これにより、パスワードの総当たり攻撃による不要な接続のリスクが減ります。
  • いくつかの仮想マシンは、インターネットからのアクセスを必要としません。そのため、それらを管理するためにSSHリレーを使用します。攻撃対象領域を縮小できます。
  • インターネットからアクセスされる必要がある重要なマシンについては、IPアドレスをホワイトリスト化します。
  • オンプレミスの場合は、重要なセキュリティ対策を備えたスタジオと接続するためにVPNを使用します。
  • セキュリティグループでは、お客様が使用する必要のあるTCPポートのみを許可します。
  • すべてのマシンでファイアウォールとIP禁止の仕組みを設定しています。
  • すべてのKitsuインスタンスは、ユーザー接続を管理するための強力なSSL設定を使用しています。
  • インスタンスのOSは常に最新の状態です。
  • ログは SIEM の保護を通じて収集・分析しています。

次のステップとして、オブジェクトストレージが侵害された場合の問題を制限するため、オブジェクトストレージ内のファイルを暗号化する予定です。

Recovery

もう1つ非常に重要なのがバックアップと復旧です。オブジェクトストレージ上のプレビュー、重複(複製)されたPostgresデータベース、そしてオブジェクトストレージ上のデータベースバックアップがあるため、Kitsuインスタンスを素早く再起動するための手段がすべて揃っています。

もしお客様のインスタンスが燃えてしまった(障害・ダウンした)場合は、Terraform から作り直し、Saltstack で設定します。そして voilà、起動します!インスタンスはオブジェクトストレージに引き続きアクセスでき、データベースを再設定し、通常どおりファイルを提供できます。

オブジェクトストレージが失敗しても、複製されたオブジェクトストレージに接続して、以前と同じようにソフトウェアを使い始められます。必要なのは、Saltstack を通じて設定ファイルを更新するだけです。

Miscellaneous

メールは自社ドメイン名からユーザーに送信しています。配信可能性を高めるために、すべてのシステムを SPF と DKIM で設定しました。これらのプロトコルにより、cg-wire.com をドメイン名として送信されるすべてのメールを追跡できます。

それを監視するために DMARC プロトコルを設定します。これにより、@cg-wire.com のメールを中継(リレー)する各サーバーは毎日レポートを送信します。これにより、メールの送信元を特定できます。さらに、SPF と DKIM が適切に使われているか、また私たちのメールがスパムとして扱われているのかも分かります。加えて、メールの分析用ダッシュボードを作成し、なぜ不適切にラベル付けされたのかを突き止めることもできます。結果として、メールドメインの評判を良好に保てます。

Final Words

以上がツアーです!氷山の一角だけをお見せしました。細かなニュアンスや詳細は、そこではすべてお伝えできません(本を書く必要があるかもしれません)。それでも、Kitsu のようなWebアプリケーションを動かすために必要な作業の全体像は掴めるはずです。CGWireで私たちが作っているのは、美しく効率的なソフトウェアだけではありません。導入環境とデータにも同じくらいの注意を払っています。私たちは常に、「見せることに誇りを持てる」「あなたにとってシームレスに動く」ものとして、それを作り、改善し続けています。

スタジオのコラボレーションには、適切に動作し、安全で、大きな負荷にも耐えられるソフトウェアが必要です。人々は、そのツールを使うために信頼する必要があります。それを、堅牢で効率的かつ安全なものにすることが私たちの仕事です。

次の課題は、クラウドインフラのリージョン管理です。フランスから遠い場所にいるお客様がますます増えています。スタジオの近くに Kitsu インスタンスを提供することで、可能な限り最高のパフォーマンスをお届けしたいと考えています。この問題を解決できたら、私たちのレシピを共有します。だから、私たちがどうやって実現したのか、続報をお待ちください!

このブログはアニメーション制作のマネジメント、アニメーションパイプライン、そして私たちの製品のために捧げました。しかし、最新情報はLinkedInでフォローできます。私たちはアニメーション業界のニュースも共有しています。ぜひ覗いて、一緒に参加してください!

この記事はいかがでしたか?

ニュースレターを購読して、さらなる考察、チュートリアル、業界ニュースをお受け取りください。