マルチクラスタKubernetes 3つのパターンと実運用事例
この記事はKubernetes Advent Calendarの7日目の記事です。 今回は、Kubernetesのマルチクラスタ化についての考察記事を書きます。
マルチクラスタの定義
マルチクラスタと一重にいっても色々とありますが、本記事では、「複数のKubernetesクラスタを並列に並べ、トラフィックを特定の条件でそれぞれにルーティングする」構成のことを指すとします。
また常時マルチクラスタではなく、普段はシングルでも、いつでもクラスタを並列に並べることができる構成もマルチクラスタ構成とします。
マルチクラスタが必要になるケース
運用する側としては、クラスタの数は少なければ少ないほど嬉しいはずです。
では、どのようなケースでマルチクラスタ構成を取る必要が出てくるのでしょうか?
Multi-cluster use casesにも記載されていますが、コアなものに絞って要約すると、下記のようになると解釈しています。
可用性の向上
地理分散への考慮
- リクエスト元のロケーションを考慮したルーティング
- Locationごとの固有サービスのデプロイ
セキュリティポリシーへの対応
- 特別セキュリティが厳しいワークロードとそうでないものを区別して、別々のクラスタで運用
パフォーマンス改善
- master nodeを分離することでクラスタ機能そのものの負荷を分散
私の現場のケースで採用に至った理由
私のケースでは「可用性の向上」が主たる理由になります。
Surge Upgrade + Graceful Shutdownを有効にしているものの、Master Upgradeしただけでも一瞬ダウンタイムが挟まってしまっている(原因究明中)
アップグレード起因で何か問題があったとしてもFail Over、ないしロールバックはできるようにしておきたい
BCP観点でリージョン障害に耐えうる構成を取る必要性
これらがマルチクラスタで実現したかった要件になります。
マルチクラスタの実現方法
では、この要件を満たすためにどうすればマルチクラスタ化を実現できるでしょうか?
主に一般的なのはこの3つではないでしょうか。
- DNSパターン
- HA Proxyパターン
- Global Load Balancerパターン
1. DNSパターン
これは一番シンプルで運用が楽なパターンではないでしょうか? これはクラスタを指すドメインに対して、複数のクラスタのIPを登録しておく構成になります。 クラスタのIPはNodePortもしくは、L4ないし、L7のLBを払い出すことになります。
メリット
- シンプルで管理運用コストが低い
- Route53などを使えばGeographic Routingも可能
デメリット
私のケースでは特にこのTTLの部分で、即時FailOverできない点、ロールバックなどが気軽に行えい点を踏まえてこのパターンは見送りました。
2. HA Proxy パターン
このパターンは、前段にHAProxyのクラスタを設置し、そのバックエンドとしてKubernetesクラスタを置くパターンです。 HA Proxy自体を冗長化しておくために、何台かを並列で並べて管理する必要があります。
可用性の文脈ではなく、各コンポーネントごとに配置するクラスタを分散して、そのためのトラフィック制御を行う文脈ですが、コロプラさんがこの構成をとっています。
メリット
デメリット
- Managedなものを使わない限り、HA ProxyがSPOFにならないよう管理運用コストがかかる
このパターンもメリットは大きいものの、HA Proxy自体の可用性、耐障害性への管理運用コストを鑑みて見送りました。
3. Global Load Balancerパターン
これは、クラスタの前段にグローバルなLBを配置し、その下にクラスタを置くパターンです。 私のケースでは、前述2パターンのデメリットが許容できず、消去法でこのパターンになっています。
LBそのものの機能性に左右されそうですが、 このパターン自体のメリデメは下記のようになっています。
メリット
- LBからのヘルスチェック機構により、即時でFail Overできる
- TTLなどに支配されない
- 管理運用コストが比較的低め
デメリット
- HAProxyのような細かいトラフィックルーティングができない ※1
- 各ゾーンごとに均等に分散されるだけ
- HAProxyのような細かいトラフィックルーティングができない ※1
※1 AWSでEKSを使えばできる模様
ALB Weighted Target Groups による EKS Cluster の Canary Switching
Global Load Balancerパターンでの実運用
前述した通り、最終的にはLoadBalancerパターンを用いて対応しました。 このパターンを実現するために、GCPのIngress For Anthosの機能を使って実現しており、構成の詳細について、Kubernetes MeetUp Tokyoにて私がLTした資料に記載してあります。
Ingress For Anthosを活用した安全なk8sクラスタ運用
Ingress For Anthosを使うことで、LBの設定は完全に自動化されています。 これにより、
といったことが担保できています。
この構成での惜しいところ
消去法で選んでいるので、当然完璧ではありません。 少なからず辛いところは存在しています。 例えば下記のようなポイントです。
Config ClusterというLBの設定同期用のクラスタを用意し、そこにLBの設定をデプロイしなくてはならない
マルチクラウドが実現できることにはできるが、EKSをそのまま突っ込んだりできるわけではなく、それなりに複雑な構成を取る必要がある
実際のクラスタアップグレードについて
実際のアップグレードとしては、
といったようにローリングアップデートの形をとっています。
ただ、カナリアリリースのようなことはできないので、 いきなりクラスタをサービスアウトし、アップグレードするようなことをやると、一気にトラフィックが片側に流れることになってしまいます。
現在は、ある程度minimumのPod数をある程度積んでおくことで対処していますが、これはリソース効率が悪く、本意ではありません。
よって将来的には、
といった対応をする必要が出てくる可能性があります。
(現在はコスト面でもトラフィック面でもゆとりがあるので予定はありません)
マルチクラスタとGitOps
これは余談ですがマルチクラスタ化するにあたり、GitOpsの考え方を取り入れて、ArgoCDによってデプロイパイプラインを組んでいたことにより、ここに関してはほぼノーコストで移行できました。 また、移行後も特に問題なく稼働できています。
ただ、現状各クラスタごとにArgoCDを独立してデプロイしており、各クラスタの状態を見るためには各クラスタ用のダッシュボードをみる必要があります。
一応ArgoCD側でもMultiClusterのための提案がなされていて、一つのApplicationに対して複数クラスタへのデプロイができるような、ApplicationSetというCRDおよびOperatorの開発が進んでいるようです。
まとめ
本記事ではマルチクラスタ化する理由、実運用してみた所感について紹介してきました。 Kubernetesを安全に運用するためのエコシステムはどんどん様々なソリューションが生まれてきており、今後も益々発展していくと思いますが、本記事が何かのお役に立てれば幸いです。