docker と ecs と websocket で最強のマルチプレイ・ゲームサーバを構築

Post on 16-Apr-2017

5.291 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

最強のマルチプレイ・ゲームサーバを構築2016/07/07 Gaming Tech Night

グリー株式会社 開発本部 堀口真司

Docker と ECS と WebSocket で

はじめに• 技術ブログに書いたのが元ネタです

「 Docker ECS WebSocket 」でぐぐると元ネタページ出ます

http://labs.gree.jp/blog/2016/06/16024/

• 今回だけの詳細版

開発と構築と運用ぜんぶ。

• 自己紹介

コンソール → ネトゲ → アーケード → ソシャゲ

先週から33歳

稀によくあるプロジェクト要件 (仮)• リアルタイム・マルチプレイゲームの案件が浮上

Photon エンジンとか Monobit エンジンとかもあるけど…

• ざっくり要件

そんなガチゲーじゃないけど、 20 人ぐらいでプレイ

マップギミックがある

NPC もいる

そもそも WebGL クライアントとか

• 技術選定にて

WebSocket で十分だろう。となると、 nodejs になる

ステートレスは難しいので、 RDB/KVS は使わない。オンメモリでやる

モニタリング、デプロイはありもので何とかならないか

一番最初に浮かんだ案

ロードバランサ

IP Masquerade

API サーバ群

WebSocket

Stateful なので狙ったプロセスにアクセスするため

DB を持たずオンメモリですべて処理

WebSocket とそれ以外は使い分ける。マッチング等は API サーバでやる

永続的な状態は一応 API 経由

で更新

WebSocket サーバ群

API サーバ群

WebSocket サーバ群に負担

ロードバランサ

IP Masquerade

問題なし

デプロイ

モニタリング

メモリリーク

NAT 更新マルチコア対応

ゲームに関係ない部分…

もんだいだらけの…• メモリリーク

ステートフルサーバの場合、状態を内部に持つのでどんどんオブジェクトが溜まっていく。完璧に対応することもできなくはないが、それをやるコストがかかってしまう。一般的には定期的に再起動させることで、ある程度のメモリリークを妥協し、効率よく開発する。

• NAT 更新(あるいは案内) LB 層での RR や WRR 等は利用できない。各サーバ、全ポート固定で割り振っても良かったが、安

定した内部システムに大量の NAT エントリを作るのはリスクが高かった。できればグローバル IP直結にし、個別の Firewall が好ましい。いずれにせよ管理コストがふくらむ。

• デプロイ ディレクトリスイッチや Apache のリロードのように完璧に近いふるまいができない。 nodejs の

デーモン化ツールは普通のステートレス Web 向けのものがほとんど。となると自前でそれを考慮したつくりにしなければならない。

• モニタリング プロセスの監視や負荷の監視が要るが、 Apache ではないので何か回収するための仕組みを作らな

いといけない。既存のメトリクス回収システムとのプラグインを作らないといけない。

• マルチコア対応 nodejs はシングルスレッド・イベントドリブンで安定高速動作するが、マルチコア OS に乗せると

そのサーバの性能を出し切れない。となると、 Prefork 系のアプローチを取ってマルチプロセスで運用するなど、 NAT の仕組みと競合したり、オーケストレーション層を対応しないといけない。

作るモノが多い問題• なぜならこの課題に対する世間の需要がほとんどなく OSS が発展してないため。

わずかなモノも、こちらの要件にマッチすることはほぼない

• たとえば Photon エンジンなら

ロードバランシング → SPOF だけど、独自のものが用意されてる。

モニタリング → Windows API で取れる

マルチコア対応 → どうやら、マルチスレッドで動いてる

デプロイ → 専用コンソールでボタンをポチポチするだけそれなりの規模なら作る。または、買うんだけどどうしようかな~

nodejs プロセスと TCP Port を完全にマップしたい

いつもの LAMP じゃだめなんか?

デプロイどうしよ

オーケストレーションもコンテナどう?

デプロイツール幾つかあるし、中身は root でどんなプロセスでも動くし、TCP Port に直結できる

せや! Amazon ECS にしたろ

コンテナとは• VM より小さく、プロセスより大きい

ホスト OS とは違うものが使える。 AmazonLinux 内に Ubuntu とか。

ミドルウェア類も全部別のバイナリで動作する

CPU はエミュレートされない。なので高速動作する

GPU もエミュレートされない。そもそもハードウェア仮想化ではない

コンテナ毎にリソースの上限が設定できるのもある

IP アドレス(ネットワーク)はホストと共有される コンテナ内のファイルディスクリプタは独立するので、一見すると NAT っぽいふるまい

コンテナ間で同じものは共有される

ストレージは設定しないと書き込めない 設定すればホスト側のボリュームも読み書きできる

コンテナのエントリポイント(=プロセス)が終了するとコンテナも消える

コンテナ内は root ユーザで動作する

“本物のオブジェクト指向”でいう、オブジェクトっぽい立ち位置。

• Google では、あらゆるアプリがコンテナ運用らしい。

ここから構築と設定

じぶんの PC

ECS Host

Amazon

ECR

Amazon ECS

fetch

build

push

AWS

Lambda

API

Auto Scaling group

ECS Host

Post

room-status

deploy

Container-status

log

pull

社内ネット

Amazon API

Gateway

じぶんの PC

shinji.horiguchi@G-PC-00366540 MINGW64 ~$ docker run -P -d websocket75ff4f9b1eee9933d867b628f75dde046467ae7f426a67344ebe6806f407f6d3

shinji.horiguchi@G-PC-00366540 MINGW64 ~$ docker run -P -d websocket38bb67d2895d4d3ac03732ce0f5631780118737c70b79c652ba293bb862cf702

shinji.horiguchi@G-PC-00366540 MINGW64 ~$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES38bb67d2895d websocket "node /home/app/serve" 4 seconds ago Up 3 seconds 0.0.0.0:32769->3000/tcp nauseous_engelbart75ff4f9b1eee websocket "node /home/app/serve" 37 seconds ago Up 36 seconds 0.0.0.0:32768->3000/tcp berserk_golick

Windows でも docker tools

入れるだけでオッケー。開発環境のセットアップに

一時間もかからない

コンテナ操作や管理はGUI なので、非エンジニア

でも安心の Kitematic

Amazon

ECR

fetch

build

push

docker が使える slave を追加しておく。古いやつは

ECR 未対応でダメ。

Jenkins ジョブに必要なので作る。超簡単。US 系リージョン。作った後に案内されるページの内容にログイン方法やアドレスが書いてあ

るので必ずメモっておく。でもデフォの latest タグのままはダメ。

ADD app /var/appWORKDIR /var/appRUN npm installRUN npm install -g bowerRUN bower install --allow-root

• WORKDIR – 使える• ENV – 使える• ENTRYPOINT – 使える• EXPOSE – 使えない• CMD – 使える• 他 – わからん

Registory API v2

に対応したクライアントが必要

Dockerfile に全部書く。docker build するまえに、ゲーム本体も fetch してくる

Dockerfile は別リポジトリ。どうせ冪等性ないのでビルド後のハッシュやタグで管理

ECS 側で設定必須

Amazon

ECR

Amazon ECS

ECS Host

deploy

pull

ECR で案内された URL をそのまま Task 定義に設定すればオッケー。 Docker Hub のも同じく使えるので、

cAdvisor はそのままデプロイ

cAdvisor はコンテナホスト単位でデプロイする。Portmap でホスト側のポートを指定すると一台に一つのコンテナしかデプロイされないので、この

仕組みを活用する。 Prometheus と組み合わせると間違いなく最強。時系列データを行列のまま扱えて関数と式でグラフを描ける

fluentd はホストで動作させ、コンテナ内から

localhost:port に流す

ECS でのインスタンス概念• Task Definition

コンテナの URL や起動パラメータ、ヴォリュームやポート設定を行う

コンテナタグをつけかえて、バージョンアップとかできる

• Service

デプロイ設定。一部を変えると差分を埋めるようにトポロジが維持される

どの Task definition を、どれだけ

• Cluster

Service のデプロイ先で、 EC2 によるコンテナホストが複数含まれる

複数の Service が一つの Cluster に同居できる

• Task

稼働中のコンテナ。いわゆる docker ps コマンド

ECS Host

Amazon ECS

Auto Scaling group

ECS Host

deploy

Desired:10

Minimum healthy: 100%

Maximum: 120%

新デプロイを設定するとMax まですぐに増加する

デプロイ時にローリングリスタートされる容量=Max-Min となり、この設定の場合 20%

分ずつコンテナが入れ替わっていく。Min 設定を 100% 未満にするとデプロイ時にいきなり殺されてしまうのでサービスの場合

は 100% 以外に選択肢は無い。初期値の 50% では半数で障害となる

コンテナホストは AutoScaling とUserdata のみで運用できる。

ssh すら不要で、 AMI も標準のECS Optimized で良い。

Cluster 画面 Task Definition で競合が無ければ Desired

だけ Task が起動する

テスト用などはそもそも一つしか起動させていない

ホスト内で競合する場合は、一台に一つのコンテナしか

起動できない

Rolling 時

類似サービス• Kubernetes

クゥーバーネイテス。

Google 系

ECS とだいたい同じ機能

• Nomad

ノマド。

Hashicorp 系

だいたい同じ

• Docker 1.12

だいたい同じ

オーケストレーション強化

AWS

Lambda

API

Post

room-status

Container-status

いわゆる Tasks で取れるような情報を管理 API に伝える

ホスト名+ポート番号は必須

コンテナはブラックボックス化の原則に則って、

必要な情報は外から与える。AWS 依存の情報や docker

依存の情報など。それらの情報に加えて、コンテナのみが保持している状態を管理 API に伝える

コンテナへの案内やゲームのマッチングを行う。案内には NAT64/DNS64

対応のため FQDN で行う。

Amazon API

Gateway

最強ポイントまとめ4つのポイント

書くものが少ない• タスク一覧を取得し、管理 API に POST する

• コンテナ内に観測情報を set する

• 管理 API に WebSocket サーバの状態をいろいろ POST する

• Dockerfile 書く

• Jenkins ジョブ書く

• 監視やロギングの設定

落ちない• すべてが分散配置され、 SPOF が無い

ホストは AZ バランス、コンテナは分散、 Lambda も分散、 API は ELB 配下で完璧

• Rolling または Blue-Green どちらでも対応できて、メンテ停止も不要

• Service 設定を一つ変えるだけで、ロールバックも超簡単

• テスト、一部公開も同じく容易

• モニタリングツールがたくさんある

これがこの分野で意外と厄介である。

依存が少ない• 環境依存が少なく、コンテナを手元の PC で建てることもできる

チョイ確認したいときとか

• nodejs なら、そのまま Windows/Mac で建てても良い

gulp 等と相性が良く、開発しやすい

• WebSocket で SSL 対応もできる

将来 HTTPS しか通らなくなっても大丈夫

socket.io で WebSocket すら通らなくても大丈夫

シンプルなルーティングなので IPv6 も大丈夫

ロックインしない• Amazon ECS を利用しているものの、類似サービスが他にもある

コンテナ関連は情報量も多くなった

それ以外の部分もだいたい検索すればすぐに解決方法が見つかる

• コンテナやめて、従来型の運用ツール一式に戻っても良い

当手法にかかるコストが極端に少ないので、手戻りがそもそも少ない

nodejs 単体で動作するものがあるとして、ビルドからデプロイまで一通りやっても一週間(40h)もやれば、運用に乗る

ご清聴ありがとうございました

top related