698 views
2

コンテナをゲームインフラに実践投入した話(2)

コンテナをゲームインフラに実践投入した話(2)

コンテナをゲームインフラに実践投入した話(1)からの続きです。

※具体的なインフラの設定に関する内容は割愛しています。

この記事の概要

  • 大手ゲームパブリッシャー受託開発案件でのコンテナ導入の項はGCPではなく国内クラウド業者での事例の話。

トップゲート主催のイベント
酒とゲームとインフラとGCP 第3回
にて登壇した内容と同一のものです。

コンテナの設定に関する具体的な記述の仕方や技術的な深い内容は割愛しています。

受託案件のインフラにコンテナ導入

コンテナを大手パブリッシャーの受託開発案件で導入した時のお話です。

こちらはプロトタイプの開発での事例です。

内容については、NDAに触れる部分がありますので、ちょっとご紹介はできないのですが、こちらの案件では、全面的なコンテナベースのインフラを構築しました。

商用を見据えた構成

構築するにあたり、商用を意識するということで行いました。

つまり、マルチホスト構成です。

詳細はざっくりと、こんな感じに。
StructureText

LostNia(自社アプリ)のケースとは打って変わった構成です。
まずはCoreOSのクラスタをしっかり構築しています。

クラスタ全体の情報を管理するためのetcd2を、3台マスター専用として立て、他はそのproxyとして参加としました。

サーバー側のプログラムには、より実行速度とメモリ効率の良いプログラム言語、そして何よりdockerと相性が良いGo言語を採用することに。

これは以前、ブラウザゲームをRails4で組んだのですが、メモリの消費が富豪的でサーバーコストが肥大化した苦い経験から、速度的にもネイティブとして実行できるGO言語を選択しました。

また、バトルサーバーはリアルタイム通信を要求するものでしたので、WebSocketを使用し、バッファーフォーマットはJSONではなくFlatBuffers を使用しました。

HAProxyでBackendサーバーにProxy

Image

App/マッチング/バトルサーバーコンテナがいるホストにはHAProxyコンテナも同居させ、そのHAProxyを介してDBやRedisにアクセスするようになっています。

RedisClusterのマスタは落ちるとSlaveが自動的にマスタに昇格するようにしています。
この時のどのノードがマスタなのかをHAProxyで管理することにしたのですが、これを実現するためには解決しなければいけない問題がいくつかありました。

ホストをまたぐコンテナをどう繋ぐか?

前回の記事では、docker-composeではdockerのlink機能を使ってコンテナ間の接続していましたが、別ホストにいるコンテナに繋ぐことはできません。

さらに、dockerコンテナは起動されるまでIPアドレスが確定しません。
これも合わせてなんとかする必要があります

flannel

最初に、ホストをまたぐコンテナ間の通信についてですが、
これはflannelを使用しています

image

flannelを導入するとflannel0というネットワークデバイスが出現します。(ipコマンドなどで確認できます)

これによりコンテナを起動する時に、flannel0のサブネット内IPアドレスが割てられるようになり、
このIPアドレスを使用してコンテナ間で通信することができるようになります。

これで、ホストを跨いだコンテナ間の通信ができるようになります。

サービスディスカバリー

これは、consulが持つサービスディスカバリーの機能を使用しました。

これだけだと、consulへの登録/削除は自前で行わなければいけませんので、
dockerの起動/終了を検知してconsulに登録/削除を行ってくれるregistratorも合わせて起動させます。

consulに登録されたサービスは、.service.consulという名前で引けるようになり、
これで自ホスト内のconsulに問い合わせれば、目的のコンテナを発見できるようになりました。

先のホスト間の疎通はflannelで既に可能になっているので、晴れてどのホストにいようとも
目的のコンテナに対してアクセスすることができるようになりました!

RedisClusterで難儀

というのも、Redis Clusterにはクラスタリング設定をする際、
ドメイン名で設定できないという仕様があります。注)3.2.1現在。

サービスディスカバリーでせっかくドメインで管理できるようになったのにもかかわらず、RedisClusterだけはIP指定しかできません。

この解決方法は以下の通り。
つまり、頑張りました(泣)

image

etcd2でクラスタ構成を記録しておき、コンテナが再起動する度に、
クラスタ管理情報である、node.confを動的に書き換えて起動するという、かなーり泥臭いことをしています
もしRedisClusterにドメインが使えていたら、この対応がまるっと削れていた部分です。

これは非常に複雑になりました。

ちなみに、こんなことしなくてもいい方法があるよ。ってのをご存知の方がいましたら、後でこっそり私に教えてくださいw

なお、MariaDBの方は、ドメイン指定ができますので、
別段話すこともないので割愛します。

デプロイ

コンテナのデプロイですが、
これにはfleetを使用しました。

image

構築ツールはAnsibleを使用していまして、
Ansibleからfleetctlを使ってデプロイします。

各サーバーは幾つか依存するコンテナもありますので、
関連のあるコンテナごとに振り分けていきます。

振り分けは、あらかじめマシンごとにmetadataを設定しておき、
この情報を元に、デプロイしていきます。

例えば、apiサーバーをデプロイする場合は、metadata=apiに対して、と行った感じです。

コンテナのメリット、デメリット

image

やはりDBのクラスタリングが大変。
クラスタを初期化するために、期待する数のコンテナを立ち上げる必要性があるとか、そういった部分ですね。

立ち上がりさえすれば、クラスタリング構成が正常に動作するように
調整する必要がありますので。

結論

先の例ですと、RedisClusterはコンテナ化する方が大変でしたので。
コンテナである方が都合が良いものとそうでないものがあると思います。

全てをコンテナにしていくよりも、
適材適所で使っていくのがいいのかなと思っています。

ちなみに、フェイルオーバー、スケーリング、ロードバランス、サービスディスカバリー、ローリングアップデートなどはKubernetesでカバーできるので、本当に一からコンテナベースでインフラを組む場合は、頑張ってくださいって感じになりますね(笑)

なので、私は今後はKubernetesを使っていくことを考えています。
なんか、Kubernetesがどれだけ良いかみたいな記事になってしまいましたが。

まあ、1から組んだ苦労があったからこそ、Kubernetesの有り難さを実感できたのということです。

短い時間で、説明しきれなかった部分がもあり、駆け足でしたが、
以上が、登壇時の内容でした。

シェアする

プロフィール

たみ Lv 34

サーバーエンジニア的な

HP : 384 /65535

SP : 256 /32768

新技術を積極的に実戦投入していくエンジニア。
ライフワークは育児とインディープロジェクトの企画・開発・販売。

▼ おすすめ記事

  • 開発の謎

    【フォトショップでUI素材をメイキング②】

  • クリエイティブ・オブ・ゴッド

    アニメーション基礎① なんちゃってアニメーターへの道

  • クリエイティブ・オブ・ゴッド

    アニメーションとSpine制作承ります!ファイブスターズゲーム

  • クリエイティブ・オブ・ゴッド

    中文版のGUNDAM VERSUS特典が豪華!