
kubernetesの無停止運用を意識した検証
こんにちは、ゲーム事業のCTOをやってます白井です。
てっくぼっとに出張してきました。
今回は、現在検討している kubernetes でのゲーム運用についてお話します。
ゲームの運用で必要となる要件として「無停止」があります。
この「無停止」をkubernetesを使ってどのように実現するのか、実現方法を検証した結果をまとめます。
kubernetes自体、耐障害性を持っています。
例えば、kubernetesの最小管理単位としてPodという概念があります。
また、Deploymentという概念によって状態が定義されています。

Pod,Deployment
たとえば、Pod数が3、みたいな形です。

Deploymentのyamlのサンプル replicaに3が設定されている
Deploymentで定義されたPod数をkubernetesは維持するように動きます。
何かしらの理由で一部のPodに障害が起きたときには、すぐに新しいPodを起動します(コンテナをデプロイする)。
そんな便利なkubernetesですが開発が活発なこともあり、ちょっと困ったことがあります。
それは、kubernetes自体のバージョンアップです。
この記事を書いている時点では、1.4.6です。
しかし、マイナーバージョンは、約3ヶ月に1回あがります。
kubernetes自体はクラスタ内にマスターのデーモンとノードのデーモン2つのデーモンで構成されています。
マスターのバージョンは無停止でアップグレードできるのですが、
ノードのバージョンは、バージョンアップ時にダウンタイムが発生する可能性があります。

ダウンタイムが発生する旨の警告がでる
これでは、ゲーム運用の要件の無停止が満たせなくなってしまいます。
そこで次のような方法(A)で回避することにしました。
(1)新規NodePoolを作成する
gcloud container node-pools create node-pool-v1.4-nodes --num-nodes=2
NodePoolはNodeのグループです(NodeはPodのホスト、つまりVMインスタンスと思ってください)
※node-pool-v1.4-nodesはNodePool名です
新規NodePoolは最新のkubernetesのバージョンで作成されます
(2)いままでつかっていたNodePoolでは新規Podが作成されないようにする(cordon)
kubectl cordon node-pool-v1.3-node1
kubectl cordon node-pool-v1.3-node2
※ node-pool-v1.3-node1、node-pool-v1.3-node2はNode名
(3)Node上のPodを新しいNodePoolへ移動させる(drain)
kubectl drain node-pool-v1.3-node1
kubectl drain node-pool-v1.3-node2
(4)すべてPodを移動させたら、いままでつかっていたNodePoolを削除する
gcloud container node-pools delete node-pool-v1.3-nodes
以上でバージョンアップ完了です。
では、運用を想定してアプリのデプロイ時の動作を考えてみましょう。
コンテナを使うからといって、マシンリソースを余らせるのはもったいないです。
そのため、通常の運用時では、Node数は必要なPodを立てるのに最低限必要な数しかないと思われます。
デプロイ時のみNode数を増やす運用にします。
現状のkubernetesでは、Node数を減らすときにどのNodeを減らすか指定できません。
(どのNodeにどのPodがのっているのか、管理する必要がない、という思想かもしれません)
そのため、デプロイ時にNodeを増やして、デプロイ後にNodeを減らす、といった操作を行うと、次のようなことが起こる可能性があります。
↓
!!あたらしくデプロイしたPodがのっているNodeが減ってしまう!!
↓
Podが再作成されるまで、サービス停止!
無停止の運用ができなくなってしまいます。
そこで(A)でやったことをデプロイ時にも実行します。
つまり、デプロイ毎にNodePoolを作成するというルールです。
デプロイする前に、Node数を増やすのではなく、新規のNodePoolを作成します。
その後デプロイします。
デプロイがおわったら、いままでつかっていた古い方のNodePoolを削除します。
NodePoolをコンテナのバージョンと結びつけることで、意図しないPodをが再作成されることを防ぐことが出来ます。
これで、運用要件の「無停止」が達成できそうです。
kubernetesは様々な機能、管理する概念が提供されています。
自分たちの運用要件によって、kubernetesの機能を組み合わせた検証結果となります。
今回の検証した内容が、みなさんの参考になれば幸いです。
この記事へのコメントはありません。