こんにちは!SRE部のcw-ozakiです。
creators-note.chatwork.com creators-note.chatwork.com
今回はその2の続きで、EC2からKubernetesに移行するのは良いとして、そもそもChatworkのKubernetesクラスタの構成と更新戦略をどうしているのかというベース部分の話をしたいと思います。 このあたりの話ってあまり表に出てこないので、これを機会に他社様ではどうしているのかという話がもう少し出てくるといいなと思います。
ChatworkにおけるKubernetesクラスタの構成と更新戦略
2020/11現在、ChatworkではEKSを使用してKubernetesクラスタを構築しています。
このKubernetesクラスタはマルチテナントのシングルクラスター構成を取っており、テスト、ステージ、プロダクションの3環境を管理しています。 このクラスタに対してアプリケーションとそれを管理するチームは下記のようになっています。
- クラスタ管理用のアプリケーション: SREチーム
- Scalaで作られたアプリケーション(6アプリケーション): Scalaチーム
- PHPで作られたアプリケーション(6アプリケーション): SREチーム(PHPチームに委譲予定)
Kubernetesクラスタ自体はだいたい3ヶ月に1度更新する方針で、Blue/Greenという形で新しいクラスタを立ち上げて、アプリケーションを個別に新しいクラスタに移行作業をする形です。
つまり、取り敢えずガッと新しいクラスタを作って、ガッとアプリケーションを移動して、問題起きたら戻そうぜ!!!というスタイルですね。
Kubernetesクラスタの更新間隔
EKSではだいたい3ヶ月ごとに新しいバージョンが配布され、1年経つ前ぐらいでEnd of Supportを迎えます。 これはKubernetesとほぼ同じサイクルで回っていて、仮にEKSを使っていなくてもこのサイクルに乗って行く必要があります。
そのため、Kubernetesを採用するさいには3ヶ月ごとに最新に追従するか、1年経つ前に更新していくか選択する必要があります。
ここはもう趣味の世界かと思いますが、Chatworkでは下記を考えて3ヶ月ごとに更新するようにしています。
- 新機能を早い段階で導入fできる
- 数バージョン空けて更新すると変更箇所が大きくなりすぎて追いにくい
- EOS間際で更新した場合に、変更箇所によって更新スケジュールが変わるのでEOSを越えてしまう可能性が出てくる
ここで3ヶ月ごとに更新するということは、年に4回も作業するということであり、ちょっと手間取ると次のバージョンが出てしまうということになります。 そのためには、このとき行う作業を自動化して、仮に手作業をするにしてもそれを最小限にする。ということを考えて行く必要があります。
つまりは、ChatworkはこのKubernetesの運用に力を入れて行くという意思表明みたいなものですね。 とはいえまだまだカオスな状態ではあるので、ここに自信のある方は弊社にぜひご応募ください。
シングルテナント vs マルチテナント
シングルテナントにするのか、マルチテナントのどちらを選択するのかは開発体制やポリシーによって変わってきます。
シングルテナント
pros
- Blast Radiusを最小化できる
- 1クラスタ、1アプリケーションのため他アプリケーションの影響を考えなくて良い
- 仮にクラスタ障害が発生しても影響範囲が1アプリケーションに閉じれる
- クラスタサイズが小さくなるので、単一クラスタで見た場合に管理コストが下がる
cons
- 複数のアプリケーションがあると複数のクラスタができるので全体の管理コストは上がる
- 特に横断的にクラスタを管理するチームを作る場合にうまく自動化しないと維持する運用コストが高くなる
- コスト最適が効きにくい
マルチテナント
pros
- クラスタが1つで済むため管理が楽になる
- 複数のサイズのアプリケーションが複数乗るのでNode上のPod数を最適化して、ノード台数のコスト最適がしやすい
- Control Planeも一つになるのでその分コストが最適化できる
cons
- 他アプリケーションから影響が起きる可能性がある
- Kubernetesクラスタが死亡したときに影響範囲が広くなる
それぞれのpros/consは集約すると、影響範囲と管理コストというワードに集約できるかと思います。 影響範囲は極小化されるべきではあるので、管理コストが支払えるならシングルテナントを選択するのが良いですね。
それではシングルテナントにおいて管理コストを支払える状態というのは、どういった状態でしょうか?
- 高度に自動化されていて1クラスタも複数クラスタも変わらない状態まで作り込まれている
- KaaS
- GitOpsを使った全クラスタへのインストール
- ログ、メトリクスの収集基盤
- Gatekeeperを使った監査などなど
- アプリケーションごとにKubernetesクラスタを支える人材がいる
- 例えばSREやインフラエンジニア
- もしくはアプリケーション開発者自身がKubernetesに精通している
- 管理を放棄してアプリケーション開発者にぶん投げる
Chatworkでは1は絶賛頑張っている最中ですし、2はSREのKubernetesバリバリできるエンジニアの人数が3人に対して12アプリケーションという状況で全然手が回りません。アプリケーション開発者もKubernetesをバリバリできて、問題発生時に調査・対応までいけるのは数人しかいない状態です。 3もぶん投げる側としては心ときめくのですが、将来に禍根を残すことが目に見えるため選択肢としては取りたくありません。(とはいえ、サービス初期のアジリティ重視でこの選択肢も悪くはないと思うけど、それならKubernetesを選択するのが間違っているとも思います)
という訳で、ChatworkとしてはKubernetesクラスタはマルチテナントのシングルクラスターという選択肢しかない状態です。 将来的にSREの数が増えて、開発体制などが変わって管理コストがペイできる状態になったらシングルクラスター構成にしていきたいですね。
インプレース vs Blue/Greenデプロイ
EKSの場合はControl Planeがマネージドになっており、Kubernetesクラスタをインプレースでアップグレードをすると切り戻せません。 そのため、インプレースでクラスタを更新する場合は、事前にManifestが問題ないか、挙動が変わるところはないか、パフォーマンスに変化はないかなど検証する必要があります。
シングルテナントの場合は一つのアプリケーションを検証するだけなので難しくはないのですが、これがマルチテナントの場合は複数のアプリケーション全てを検証し終わらないクラスタを更新できません。 そうなるとアプリケーションを管理しているチームの状況に合わせる必要があり、クラスタの更新の完了に時間がかかることが想定されます。
対して、Blue/Greenデプロイでクラスタを更新する場合、一時的に複数のクラスタを立ててアプリケーションへのリクエストのルーティングを制御する必要が出てきますが、その代わりに切り戻せるという大きなメリットがあります。 また、アプリケーション単位で切り替えるので、SRE的にはクラスタの準備さえ済ませればあとはアプリケーションチームに任せられるというのも大きいです。
ただし、注意点としてBlue/Greenデプロイでは状態を持つようなアプリケーションの管理難易度は高くなります。 例えばPostfixやFluentdのような吐き出せば終わるようなバッファの場合は問題ありませんが、MySQLのデータや、Akka Cluster全体で1Actorしか起動しないといった制約などがある場合、どのように移行するのか考える必要があります。 最悪、メンテナンスにしてサービス停止を行なって移行するという選択肢もありますが、メンテナンスに気楽に切り替えられる環境でないなら出来る限りオンラインで切り替えなアプリケーションのみをKubernetesに載せるのが幸せかと思います。
Chatworkではマルチテナントのシングルクラスタを選択しており、3ヶ月に1度クラスタを更新するという方針のため、取れる選択肢はBlue/Greenだけになります。
まとめ
- Chatworkは3ヶ月に1度Kubernetesクラスタを更新するよ!
- マルチテナント、シングルクラスタ構成で運用しているよ!!
- クラスタの更新はBlue/Greenでやってるよ!!!
という訳で、今回はChatworkでのKubernetesクラスタの構成と更新戦略の話でした。 次回はこの上で、PHPのレジェンドアプリケーションを、この構成と更新戦略にどのように載せるのかという話をしたいと思います。
www.wantedly.com ChatworkではSREメンバーを絶賛募集中です! このKubernetes化の話やChatworkの各種インフラや体制など興味があればカジュアルに話を聞きにきちゃってください。