人気のワークプレイス・コミュニケーション・プラットフォームであるSlack、StatefulSetデプロイメントを管理する際の制限に対処するために、カスタムKubernetes operatorを開発した。Slackのエンジニアリング・ブログの記事で、Clément Labbe氏(クラウド担当シニア・ソフトウェア・エンジニア)は、Kubernetesクラスタにステートフルなアプリケーションをデプロイするためのコントロールと機能を改善するために書かれたBedrock Rollout Operatorを紹介している。
エンジニアは一般的に、永続的なストレージと一意のポッドIDを必要とするアプリケーションを実行するためにStatefulSetを使用している。しかし、Slackのエンジニアリングチームは、StatefulSetの既存のアップデート戦略が不足していることに気づいた。デフォルトのRollingUpdate戦略は自動化されているが、一度に1つのポッドしか更新しないため、多数のポッドを持つアプリケーションのデプロイに時間がかかる。OnDelete戦略は手動でコントロールできるが、パーセントベースのロールアウトのような高度な機能がない。
Slackは、社内チームのニーズを満たすために、Kubebuilderを使ってBedrock Rollout Operatorを開発した。このoperatorはStatefulsetRolloutと呼ばれるカスタムリソースを管理し、StatefulSet仕様を機能強化のための追加パラメーターとともにカプセル化する。
Bedrock Rollout Operatorは、いくつかの基本的な問題を解決する。
**デプロイが遅い:**デフォルトのRollingUpdate戦略の限界に対処するもので、一度に1つのポッドしか更新しないため、多数のポッドを持つアプリケーションでは非常に時間がかかる。
**制御の欠如:**Kubernetesネイティブのオプションよりも制御されたロールアウトを提供し、パーセントベースのロールアウトを高速化し、ロールアウトを一時停止できる。
ロールバック機能に制限がある: 必要なときに素早くロールバックできる。
統合のギャップ: Slackの内部サービス・ディスカバリー(Consul)と統合し、ロールアウト・ステータスに関するSlack通知を提供することで、既存のワークフローにおけるギャップを埋めることができる。
**カスタマイズの必要性:**標準的なKubernetesの機能では満たされなかった、特定の要件に合ったカスタムロールアウトロジックをSlackに実装できる。
**可視性:**リアルタイムのSlack通知や、内部のリリース管理UIとの統合により、ロールアウトプロセスの可視性が向上した。
**大規模管理:**多少の調整は必要だったが、このソリューションは最大1,000ポッドの大規模なStatefulSetの管理に役立っている。
このオペレーターは、200以上のクラスタで構成され、100近くのステートフルサービスを管理する、Slackの広範なKubernetesインフラに展開されている。
ロールアウトのプロセスは、Slackのエンジニアがbedrock.yamlファイルでアプリケーション構成を定義することから始まる。開発者がSlackの内部リリースプラットフォームを通じてデプロイを開始すると、Bedrock APIがこの設定をStatefulsetRolloutリソースに変換する。
Bedrock Rollout OperatorはStatefulsetRolloutリソースを継続的に監視し、希望する状態とクラスタの実際の状態を照合する。ロールアウトを容易にするために、StatefulSetの作成や更新、ポッドの終了などのアクションを実行する。イベント駆動型で動作するのではなく、オペレータは自己キューイング型の照合ループを使用する。このアプローチにより、カスタムリソースの逐次処理が可能になり、競合状態のリスクが低減され、全体的な調整プロセスが簡素化される。
オペレーターは、リッチテキストのSlack通知を通じてユーザーにリアルタイムのアップデートを提供する。この通知には、バージョン番号やロールアウトされるポッドのリストなどの詳細が含まれる。さらに、Bedrock APIと通信してロールアウトの成否を報告し、Slackのリリース管理UIにステータスが反映されるようにしている。
カスタムオペレーターはSlackのニーズに効果的であることが証明されているが、いくつかの制限がある。最大1,000ポッドを含む非常に大きなStatefulSetを扱う際に、1つの課題が生じた。そのため、レート制限の問題を回避するために、通知システムを修正する必要があった。もう1つの制限は、StatefulSetに OnDelete戦略を使用する場合に固有の「バージョンリーク」の問題である。ロールアウトが一時停止されたり、部分的にしか完了しなかったりするシナリオでは、ロールアウト以外の理由で終了した旧バージョンを実行しているポッドが、新バージョンを実行しているポッドに置き換わる可能性がある。これは、時間の経過とともに、完全なロールアウトに向けて徐々に、意図しない収束を招く可能性がある。Slackは、チームにロールアウトを速やかに完了するよう促すことで、この問題を軽減している。
Slackは、既存の社内システムやコミュニケーションチャネルとシームレスに統合するカスタムソリューションを作成することで、StatefulSetのデプロイメントをよりコントロールできるようになった。Kubernetesが進化するにつれて、そのメンテナーはこの機能の一部をKubernetesのコア機能に組み込むかもしれない。しかし、それまでの間は、オペレータモデルが提供する柔軟性と統合機能は、複雑なデプロイニーズとカスタムインフラストラクチャを持つ組織にとって貴重なものとなるだろう。
Slackは、Kubernetesのデプロイを管理するオペレーターモデルの利用を拡大する計画だ。同社は、Argo RolloutsやOpenKruiseといった既存のCNCFプロジェクトを、非ステートフルなデプロイメントリソース向けに模索している。他の組織もロールアウト オペレーターを開発している。例えばGrafana Labsは、ロールアウトをよりきめ細かく制御するオペレータを提供している。
Argo Rolloutsのような他の製品も同様の機能を提供し、さらにブルーグリーン、カナリア、カナリア分析、実験、プログレッシブデリバリーの機能を提供するが、デプロイメントにフォーカスしている。一方、Flaggerは、同様のニーズに対して、セッションアフィニティ、ブルーグリーン、A/Bテストの有無にかかわらず、カナリアリリースを提供している。jstobigdataのBikram Kundu氏は、KubernetesにおけるStatefulSetsの複雑さと限界について語り、この分野におけるベストプラクティスの要約も提供している。