Skip to content
Published on

Cilium ClusterMesh:マルチクラスタネットワーキング内部実装

Authors

Cilium ClusterMesh:マルチクラスタネットワーキング内部実装

概要

Cilium ClusterMeshは複数のKubernetesクラスタを1つの統合ネットワークに接続するマルチクラスタソリューションです。各クラスタの独立性を維持しながらクラスタ間サービスディスカバリ、ロードバランシング、ネットワークポリシーを提供します。

1. ClusterMeshアーキテクチャ

1.1 核心コンポーネント

クラスタA                              クラスタB
+---------------------------+          +---------------------------+
| Cilium Agent(ノードごと) |          | Cilium Agent(ノードごと) |
|   - ローカルエンドポイント管理|          |   - ローカルエンドポイント管理|
|   - リモートクラスタ状態監視 |          |   - リモートクラスタ状態監視 |
+---------------------------+          +---------------------------+
         |                                       |
         v                                       v
+---------------------------+          +---------------------------+
| clustermesh-apiserver     |          | clustermesh-apiserver     |
|   - 内蔵etcdインスタンス   |   <--->  |   - 内蔵etcdインスタンス   |
|   - 外部アクセス可能なAPI  |          |   - 外部アクセス可能なAPI  |
+---------------------------+          +---------------------------+

1.2 clustermesh-apiserver

clustermesh-apiserverは各クラスタで実行されるコンポーネントで、他のクラスタに対して該当クラスタの状態を公開します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: clustermesh-apiserver
  namespace: kube-system
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: apiserver
          image: quay.io/cilium/clustermesh-apiserver:v1.16.0
          ports:
            - containerPort: 2379
              name: etcd
        - name: etcd
          image: quay.io/coreos/etcd:v3.5.11
          args:
            - --data-dir=/var/run/etcd
            - --listen-client-urls=https://0.0.0.0:2379

1.3 データ同期フロー

クラスタAの状態変更(例:新規Pod作成)
    |
    v
Cilium Agent(クラスタA-> CiliumEndpoint CRD更新
    |
    v
clustermesh-apiserver(クラスタA-> 内蔵etcdに状態を保存
    |
    v
Cilium Agent(クラスタB-> クラスタAのetcdを監視
    |
    v
クラスタBのipcache、サービスマップを更新

2. クロスクラスタサービスディスカバリ

2.1 グローバルサービス

グローバルサービスは複数のクラスタで同じ名前と名前空間を持つサービスです。

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
  annotations:
    io.cilium/global-service: 'true'
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8080

2.2 グローバルサービスの動作原理

グローバルサービス "api-service"(production名前空間)

クラスタAバックエンド:Pod-A110.244.1.5)、Pod-A210.244.1.6クラスタBバックエンド:Pod-B110.245.1.5)、Pod-B210.245.1.6
クラスタABPFサービスマップ:
  api-service:80 -> [Pod-A1, Pod-A2, Pod-B1, Pod-B2]

クラスタBBPFサービスマップ:
  api-service:80 -> [Pod-A1, Pod-A2, Pod-B1, Pod-B2]

すべてのクラスタから同じバックエンドプールでロードバランシング

2.3 サービスアフィニティ

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: production
  annotations:
    io.cilium/global-service: 'true'
    io.cilium/service-affinity: 'local'
spec:
  selector:
    app: api
  ports:
    - port: 80

サービスアフィニティオプション:

動作
defaultすべてのクラスタのバックエンドに均等分配
localローカルクラスタ優先、ローカルがなければリモート
remoteリモートクラスタ優先、リモートがなければローカル
noneアフィニティなし(defaultと同一)

3. クロスクラスタネットワークポリシー

3.1 Identity同期

ClusterMeshでは各クラスタのIdentityが同期されます。

Identity同期フロー:

クラスタA:Pod作成(app=frontend)
  -> Identity割り当て:48291(クラスタAスコープ)
  -> CiliumIdentity CRD作成
  -> clustermesh-apiserverを通じて共有

クラスタB:リモートIdentity受信
  -> リモートIdentityをローカルipcacheに追加
  -> ポリシーマップでリモートIdentityを参照可能

3.2 クロスクラスタポリシー例

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-cross-cluster
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
            io.cilium.k8s.policy.cluster: cluster-a

3.3 クラスタ識別

クラスタ識別ラベル:
  io.cilium.k8s.policy.cluster: <cluster-name>

各クラスタのIdentityにクラスタ名が含まれる:
  k8s:app=frontend
  k8s:io.kubernetes.pod.namespace=production
  k8s:io.cilium.k8s.policy.cluster=cluster-a

これによりポリシーで特定クラスタのワークロードを選択可能

4. ClusterMesh接続設定

4.1 必須要件

1. 一意のクラスタID1-255   - 各クラスタに異なるcluster-idを設定

2. 一意のクラスタ名

3. Pod CIDRの非重複
   - クラスタA10.244.0.0/16
   - クラスタB10.245.0.0/16

4. ネットワーク接続
   - クラスタ間のPodネットワークが相互到達可能
   - トンネルまたはダイレクトルーティングが必要

4.2 設定手順

# ステップ1:各クラスタでClusterMeshを有効化
cilium clustermesh enable --service-type LoadBalancer

# ステップ2:クラスタ間接続
cilium clustermesh connect --destination-context ctx-cluster-b

# ステップ3:状態確認
cilium clustermesh status

# 出力例:
# Cluster Connections:
#   cluster-b:
#     connected: true
#     endpoints: 24
#     identities: 42
#     services: 8

5. KVStoreMesh:スケーラビリティ改善

5.1 KVStoreMeshアーキテクチャ

大規模ClusterMesh環境で各AgentがリモートクラスタのetcdI直接接続すると負荷が増加します。KVStoreMeshはこれを解決します。

KVStoreMeshなし:
  クラスタAのすべてのAgent -> クラスタBのetcd(直接接続)
  Nノード x Mクラスタ = N*M接続

KVStoreMeshあり:
  クラスタAのKVStoreMesh -> クラスタBのetcd(単一接続)
  クラスタAのすべてのAgent -> ローカルKVStoreMeshキャッシュ
  接続数が大幅に削減

5.2 KVStoreMeshの動作

リモートクラスタBのデータフロー:

クラスタB:clustermesh-apiserver(etcd)
    |
    v(単一接続)
クラスタA:KVStoreMesh
    |
    v(ローカルキャッシュにデータを複製)
クラスタA:ローカルetcdまたはCRD
    |
    v
クラスタA:Cilium Agent(各ノード)
    - ローカルデータソースから読み取り
    - リモートetcdへの直接接続不要

6. 外部ワークロード(External Workloads)

6.1 概要

外部ワークロード機能によりVMやベアメタルサーバーにCilium Agentをインストールし、Kubernetesクラスタに参加させることができます。

Kubernetesクラスタ
+---------------------------+
| Pod A10.244.1.5|
| Pod B10.244.1.6|
| Cilium Agent(各ノード)    |
+---------------------------+
         |
         v(ClusterMesh接続)
+---------------------------+
| 外部VM192.168.1.100|
| Cilium Agentインストール   |
| - 同一ポリシー適用          |
| - 同一Identity割り当て     |
| - サービスアクセス可能      |
+---------------------------+

6.2 外部ワークロードの設定

# ステップ1:クラスタで外部ワークロードサポートを有効化
cilium clustermesh vm create my-vm --ipv4-alloc-cidr 10.192.1.0/24

# ステップ2:VM用インストールスクリプトを生成
cilium clustermesh vm install install-external-workload.sh

# ステップ3:VMでスクリプトを実行
# このスクリプトは:
# - Cilium Agentをインストール
# - クラスタ接続を設定
# - 証明書を設定
# - Agentを起動

6.3 外部ワークロードのIdentity

外部VMにもKubernetes Podと同じIdentityメカニズムを適用:

VMラベル:
  app: legacy-app
  env: production

Identity割り当て:59102

ポリシー適用:
  - クラスタ内PodからVMへの通信制御
  - VMからクラスタ内Podへの通信制御
  - Identityベースで同一のポリシーモデル

7. 障害処理と高可用性

7.1 クラスタ障害時の動作

シナリオ:クラスタBが完全にダウン

クラスタAの動作:
1. clustermesh-apiserver接続切断を検知
2. クラスタBのバックエンドをサービスマップから削除
3. 新しい接続はクラスタAバックエンドのみにルーティング
4. 既存接続はタイムアウト後に自動クリーンアップ

サービスアフィニティが「local」の場合:
  - クラスタB障害がクラスタAに影響なし
  - クラスタAバックエンドのみ使用中だったため

7.2 ネットワーク分断への対応

ネットワーク分断時:
1. リモートクラスタ接続タイムアウト
2. リモートバックエンドを「unreachable」としてマーク
3. ローカルバックエンドを優先使用
4. ネットワーク復旧時に自動再接続と状態同期

8. モニタリングとトラブルシューティング

8.1 ClusterMesh状態確認

# ClusterMesh接続状態
cilium clustermesh status

# リモートクラスタから同期されたエンドポイント数
cilium endpoint list --selector "reserved:remote-node"

# グローバルサービス確認
cilium service list

# リモートIdentity確認
cilium identity list | grep "cluster-b"

8.2 デバッグコマンド

# ClusterMesh関連ログ
cilium-agent --debug

# リモートクラスタ接続状態
cilium status --verbose | grep -A 10 "ClusterMesh"

# クロスクラスタサービスバックエンド確認
cilium bpf lb list | grep "global"

# リモートipcacheエントリ
cilium bpf ipcache list | grep "cluster-b"

8.3 一般的な問題と解決策

問題:クラスタ間接続ができない
確認事項:
1. cluster-idが一意であるか確認
2. Pod CIDRが重複していないか確認
3. clustermesh-apiserverが外部からアクセス可能か確認
4. TLS証明書が正しいか確認

問題:グローバルサービスにリモートバックエンドが含まれない
確認事項:
1. 両方のクラスタに同じサービス名/名前空間
2. io.cilium/global-serviceアノテーションを確認
3. cilium service listでバックエンドリストを確認

問題:クロスクラスタポリシーが適用されない
確認事項:
1. Identityが正しく同期されているか確認
2. クラスタ名ラベルがポリシーで正しく使用されているか確認
3. cilium identity listでリモートIdentityを確認

まとめ

Cilium ClusterMeshは以下の核心原則でマルチクラスタネットワーキングを提供します。

  • 分散アーキテクチャ:中央コントロールプレーンなしで各クラスタが独立的に動作
  • Identity同期:クラスタ間でセキュリティIdentityを共有し一貫したポリシー適用
  • グローバルサービス:複数クラスタにまたがるサービスディスカバリとロードバランシング
  • KVStoreMesh:大規模環境でのスケーラビリティ最適化
  • 外部ワークロード:VM/ベアメタルサーバーもKubernetesネットワークに統合
  • 障害分離:クラスタ間の障害が分離されシステム全体の安定性を維持