マルチクラスタ・フェデレーション
1クラスタの限界を超え、複数Kubernetesクラスタを1つの運用単位として束ねる。配置戦略・コントロールプレーン集約・フェイルオーバーの原理を押さえれば、リージョン跨ぎ運用の事故を防げる。
- 1.フェデレーションはクラスタ内スケジューラの代替ではなく上位層。Placementポリシーで『どのクラスタに何を配るか』を決め、各クラスタの標準スケジューラが『どのノードに置くか』を担う二層構造。
- 2.コントロールプレーン集約にはpull型(メンバークラスタがHubから望ましい状態を取得しApply)とpush型(Hubが各クラスタAPIへ直接書き込む)があり、ネットワーク要件と障害分離特性が異なる。
- 3.クラスタ横断フェイルオーバーはPodの再スケジューリングでは解決できず、トラフィック側(DNS/GSLB)とデータ側(レプリケーション遅延・整合性)の両方を切り替える必要がある。
なぜ1クラスタでは足りなくなるのか
Kubernetes のスケジューラは「1つの API サーバー・1つの etcd」を前提に、ノード単位で Pod を配置します(/devops/cluster-autoscaler-binpacking/で扱ったビンパッキングも同一クラスタ内の話です)。しかしクラスタ規模が大きくなると、etcd の書き込みスループットや API サーバーの watch 負荷が上限に近づき、単一クラスタのノード数には実務上の上限が生まれます。加えてリージョン分散・テナント分離・障害ドメイン分割の要求から、複数クラスタを運用するのはほぼ必然になります。
問題は「複数クラスタを別々に運用する」と「複数クラスタを1つの運用単位として束ねる(フェデレーション)」の間には大きな溝がある点です。前者は単なる台数の複製ですが、後者は どのクラスタに何を配置し、障害時にどう振り替えるかを一元的に決める制御層 を必要とします。
マルチクラスタ・フェデレーションは「クラスタ内でノードにどう詰めるか」ではなく「複数クラスタのどれに何を配るか」を扱います。ノード単位のスケーリングは/devops/cluster-autoscaler-binpacking/、単一クラスタ内でのカスタムリソース運用は/devops/operator-pattern-crd/を参照してください。
配置の二層構造:Placementとスケジューラ
フェデレーションの中核は「配置(Placement)」の意思決定です。これは Kubernetes 標準スケジューラの上位に乗る、もう一段のスケジューリングだと理解すると整理しやすくなります。
二層スケジューリング
上位層(フェデレーション): どのクラスタ群に配るか
入力: クラスタのラベル・容量・リージョン・コンプライアンス要件
出力: 対象クラスタ集合 + レプリカ配分
下位層(各クラスタ標準スケジューラ): どのノードに置くか
入力: Podのrequests・アフィニティ・taint
出力: ノードへのbind
上位層の代表的な決定要素は次のとおりです。
- クラスタセレクタ: リージョン・クラウド・環境(本番/検証)などのラベルで対象クラスタを絞る。
- 容量ベースの重み付け: 各クラスタの空き容量に応じてレプリカ数を比例配分する(例: クラスタA:B = 60:40)。
- オーバーライド: クラスタごとに異なる値(レプリカ数、Ingressのホスト名、リソースリクエスト)を注入する差分適用。
ここで見落としやすいのは、上位層は下位層のスケジュール成否を保証しないという点です。フェデレーションが「クラスタXに3レプリカ」と決めても、クラスタX内でリソース不足があれば Pod は Pending のままです。したがって配置の健全性を見るには、フェデレーション層のダッシュボードだけでなく各クラスタの実スケジュール結果まで追う必要があります。
多くのフェデレーション実装(KubeFed 系、Argo CD ApplicationSet、Fleet など)は、Placement 決定を「その時点のクラスタ状態」に基づいて行い、以降のクラスタ内リソース枯渇までは追跡しません。配置直後にオートスケーラがノードを増やせず Pending が滞留する事故は珍しくなく、フェデレーション層のメトリクスと各クラスタのメトリクスを両方監視する運用が前提になります。
コントロールプレーン集約:push型とpull型
複数クラスタへ同じマニフェスト(あるいはクラスタ差分を持つマニフェスト)を配布する方式は、大きく push 型と pull 型に分かれます。
| 方式 | 仕組み | 利点 | 弱点 |
|---|---|---|---|
| push型 | Hubクラスタが各メンバークラスタのAPIサーバーへ直接書き込む | Hub側で状態を一元把握しやすい | HubからN個のクラスタAPIへの到達性が必要。Hub障害時に全体が止まりうる |
| pull型 | 各メンバークラスタのエージェントがHub(Gitやレジストリ)から望ましい状態を取得しApply | エージェント側からHubへの片方向到達性で済む。クラスタ間の障害が伝播しにくい | Hub側は各クラスタの現在状態を能動的に集約する必要がある |
push 型は Hub が「司令塔」として全クラスタの API へ直接コマンドを出すため直感的ですが、ネットワーク的には Hub→各クラスタの N 本の到達性が要ります。プライベートクラスタや異なるクラウド・オンプレ混在の環境では、この到達性の確保自体が運用負荷になります。
pull 型(GitOps 的な構成、例えば各クラスタに配置した Argo CD/Flux のインスタンスが共通の Git リポジトリを参照する構成)は、各エージェントが Hub 側へ アウトバウンドで取りに行く だけで済むため、ファイアウォール越しの多拠点運用に向きます。さらに Hub(Git リポジトリ)が一時的に落ちても、各クラスタのエージェントは直近取得済みの状態を適用し続けられるため、Hub障害が即座に全メンバークラスタへ波及しないという障害分離特性を持ちます。この非同期性はトレードオフでもあり、Hub の更新が全クラスタに伝播し終えるまでの遅延(伝播ラグ)は pull 型の方が構造的に大きくなりがちです。
push型・pull型のいずれでも、Hub(フェデレーションのコントロールプレーンやGitリポジトリ)は単一障害点になりやすい構成要素です。Hubを冗長化する、あるいはHubが落ちてもメンバークラスタは直近の設定で自律稼働を続けられる設計(pull型の非同期適用はこれに寄与)にしておくことが、フェデレーション全体の可用性を左右します。
クラスタ横断フェイルオーバー:トラフィックとデータの両輪
クラスタ内での Pod 障害は再スケジューリングで自己修復しますが、クラスタ自体が丸ごと不通になった場合、フェデレーション層はまったく別の対応を要求されます。ここが単一クラスタの自己修復と質的に異なる点です。
フェイルオーバーは次の2つの軸を同時に動かす必要があります。
- トラフィック側の切替: DNSベースのグローバルロードバランシング(GSLB)やAnycast、あるいはL7のグローバルロードバランサで、健全なクラスタへ新規リクエストを振り向ける。DNSのTTLが長いと切替の反映に時間がかかり、切替中は一部クライアントが不通クラスタへ向かい続ける。
- データ側の整合性: アプリケーションが状態を持つ場合、フェイルオーバー先クラスタのデータストアが最新かどうかが問題になる。非同期レプリケーションを使っていれば、フェイルオーバー時点で未反映の書き込みが失われる可能性があり、これは/devops/rpo-rto-disaster-recovery/で扱うRPO(許容できるデータ損失量)の議論そのものです。
クラスタ横断フェイルオーバーの判断フロー(概念)
1. ヘルスチェック(複数拠点からの合議、単一拠点の誤検知を避ける)
で対象クラスタの不通を確定
2. トラフィックを健全クラスタへ切替(DNS/GSLB更新、TTL経過待ち)
3. 状態を持つワークロードは
レプリケーション遅延ぶんのデータ損失を許容するか
書き込み停止して手動復旧するかを事前ポリシーで決定
4. 復旧後のフェイルバックは自動化せず
データ整合性を確認してから慎重に戻すのが定石
ヘルスチェックが単一の観測点(Hubから1回のping等)に依存すると、実際にはクラスタが生きているのにネットワーク分断だけが起きているケースを「死んだ」と誤判定し、両クラスタが同時に書き込みを受け付ける スプリットブレイン を招きます。複数リージョンからの合議(quorum)でヘルスを判定する、あるいはフェイルオーバーを自動即時実行にせず一段階の確認を挟むといった設計が要ります。これは/devops/multi-region-failover/で扱うインフラ層のフェイルオーバー設計と地続きの問題ですが、本稿の対象はKubernetesリソースのフェデレーション層であり、DNS切替やレプリケーション方式自体の詳細はそちらに譲ります。
フェイルオーバーの自動化レベルも設計判断です。データを持たないステートレスなワークロードなら自動フェイルオーバーの安全性は高い一方、状態を持つワークロードはデータ損失や整合性検証のため、**検知は自動・切替は半自動(人の承認を挟む)**にする運用が現実的です。フェイルバック(元クラスタの復旧後に戻す操作)も同様に、データの再同期を確認してからでないと二重書き込みや消失を招くため、自動フェイルオーバーほど自動フェイルバックは一般化していません。
マルチクラスタ・フェデレーションは「どのクラスタに配るか」という上位層と「どのノードに置くか」という各クラスタの標準スケジューラの二層構造であること、コントロールプレーン集約にはpush型(Hubが直接書き込み、到達性要件が重い)とpull型(エージェントが取得、Hub障害の影響が伝播しにくいが伝播ラグがある)があること、クラスタ横断フェイルオーバーはトラフィック切替とデータ整合性の両方を扱う必要があり単一クラスタの自己修復とは別問題であることを押さえておくこと。
まとめ
- フェデレーションは単一クラスタのスケジューリングを置き換えるのではなく、その 上位に「どのクラスタに配るか」を決める層 を追加する。Placement はベストエフォートであり、各クラスタ内の実スケジュール結果は別途監視が要る。
- コントロールプレーン集約には push型(Hubが各クラスタAPIへ直接書き込み、到達性要件が重いが状態把握は一元的)と pull型(エージェントがHubから取得、障害分離に優れるが伝播ラグがある)があり、ネットワーク制約と障害分離要件で選ぶ。
- クラスタ横断フェイルオーバーは トラフィック側(DNS/GSLB)とデータ側(レプリケーション遅延・RPO)の両方 を切り替える必要があり、ヘルスチェックの合議設計を誤るとスプリットブレインを招く。
- 検知は自動化しても、データを持つワークロードの切替とフェイルバックは人の確認を挟む半自動運用が現実的な落としどころになる。
DevOps/インフラ Article
マルチクラスタ・フェデレーションを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
Kubernetes
比較で見る軸
難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 6
導入後に効く点
コントロールプレーン集約にはpull型(メンバークラスタがHubから望ましい状態を取得しApply)とpush型(Hubが各クラスタAPIへ直接書き込む)があり、ネットワーク要件と障害分離特性が異なる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- DevOps/インフラ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「Kubernetes / マルチクラスタ」に近いか確認する。
- 強みである「フェデレーションはクラスタ内スケジューラの代替ではなく上位層。Placementポリシーで『どのクラスタに何を配るか』を決め、各クラスタの標準スケジューラが『どのノードに置くか』を担う二層構造。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。