Skip to content

Part 13: バージョン、インストール/アップグレード、Cluster Mesh ​

レビュー基準: Cilium 1.20.2(安定版、2026-09-16)、Cilium CLI 0.20.1、Hubble CLI 1.20.2。[1.21 プレリリース] と記した項目は v1.21.0-pre.3 に基づいており、GA までに変更される可能性があります。 最終更新日: 2026年10月15日

この章では、前のパートで概要だけ触れた3つの運用上の疑問に答えます。各機能がどのCiliumバージョンで、どの成熟度で使えるか、安全にインストールおよびアップグレードする方法(EKS固有の詳細を含む)、そしてCluster Meshの仕組みをコントロールプレーンから解説します。以前のリポジトリでは、IPAMとネットワークポリシーの中に短いCluster Meshの節があるだけでした。この章では詳しく説明します。

関連パート: はじめに、ネットワーキング、IPAM、BGP、ロードバランサー、Egress、mTLS、暗号化、ID。

目次 ​

  1. リリース系列とツールのバージョン
  2. バージョン別機能マトリクス(1.17~1.21プレリリース)
  3. 1.20.1から1.20.2への変更点
  4. 互換性と要件
  5. Helmによるインストール(OCIチャート、検証)
  6. EKSへのインストール固有の事項
  7. アップグレードとロールバックの手順
  8. Day 2の設定: ドリフト検出、CiliumNodeConfig、ID移行
  9. Cluster Meshのアーキテクチャ
  10. Cluster Meshの設定
  11. Global Service、アフィニティ、EndpointSlice同期
  12. MCS-API(マルチクラスターサービス)
  13. クラスター間ポリシー
  14. EKS上のCluster Mesh
  15. ラボ
  16. バージョン差分、トラブルシューティング、検証範囲、参照資料

1. リリース系列とツールのバージョン ​

Ciliumには、混同しやすい独立したバージョン体系の成果物が3つあります。

成果物今回のレビュー時点備考
Cilium(agent、operator、Helm chart)1.20.2(2026-09-16)v1.20.2ツリーのinstall/kubernetes/cilium/Chart.yamlでは、チャートのversionとappVersionはいずれも1.20.2です
Cilium CLI(cilium)0.20.1(2026-09-24)0.20.1の変更は依存関係とCIのみで、Cilium依存関係をv1.20.2に更新しています
Hubble CLI(hubble)1.20.2(2026-10-07)直前のタグは1.19.4で、Hubble CLIの1.20.0/1.20.1タグはありません。1.20.2では、デフォルトのフィールドマスクを使ったポリシー判定イベントに対するcompact出力が修正されています
バックポートブランチ1.19.8、1.18.14(いずれも2026-09-16)1.20.2と同じ日にリリースされました
プレリリース1.21.0-pre.3(2026-10-02)v1.21.0-pre.1は公開されていません。pre.2の変更履歴はpre.0からpre.2までを扱います

Cilium CLIはagentとは別のリリース系列です。特定のagentバージョンを指定する場合は、--versionを明示してください。

今回のレビュー前後のリリース履歴:

リリース日付備考
v1.20.02026-07-292660コミット(リリース本文による)
v1.20.12026-08-18Cluster Meshドキュメントを大幅改訂。agent再起動後のCIDRポリシー処理に関するendpointの不具合を修正
v1.20.22026-09-16最新の安定版。3節を参照
v1.21.0-pre.02026-08-03
v1.21.0-pre.22026-09-09
v1.21.0-pre.32026-10-02最新のプレリリース

1.21.0-pre.xはプレビューとして扱ってください。オプション名、デフォルト値、アップグレードに関する注意点は今後変わる可能性があります。

2. バージョン別機能マトリクス(1.17~1.21プレリリース) ​

成熟度を示す語句は、該当バージョンのリリースノートまたはソースツリー内のドキュメント(.. include:: /beta.rstのバナー)から引用しています。ダッシュは、その機能がまだ存在しないことを示します。

2.1 主な機能 ​

機能1.171.181.191.201.21 pre.3
最小カーネル5.45.10(RHEL 8.10では4.18)5.105.105.10(ネイティブビルドではLLVM >= 21.1)
テスト済みKubernetes1.17のドキュメントを参照1.33まで(Goライブラリ1.33)ライブラリ1.351.33~1.361.34~1.37
Gateway API CRDv1.2.1v1.3.0v1.4v1.6.1v1.6.1
Helm OCIチャート quay.io/cilium/charts/ciliumなしなしありあり(推奨)あり
MCS-APIベータ(導入)ベータ、EndpointSliceミラーリングベータ、CRDはv1alpha1、CRD自動インストール安定版、v1beta1(v1alpha1も引き続きサポート)v1beta1、ミラーされたEndpointSlice名を修正
Cluster Meshポリシーのデフォルトスコープ全クラスター全クラスター。policy-default-local-clusterフラグを導入(デフォルトはfalse)ローカルクラスターのみ(デフォルトtrue)ローカルクラスターのみ、cluster-meshエンティティローカルクラスターのみ
clustermesh.apiserver.tls.authModelegacy(デフォルト)legacy(デフォルト)migration(デフォルト)migration(デフォルト)cluster(新しいcluster-strictもあり)
KVStoreMesh1.16以降デフォルトで有効kvstoremesh.enabledは非推奨デフォルトで有効デフォルトで有効、値は非推奨常に有効、値は削除
Double Write ID割り当て導入(ベータ)ベータベータベータベータ。cilium-dbg preflight migrate-identityは非推奨
マルチプールIPAMベータベータ(KVStore、IPsec、トンネルにも対応)安定版安定版。cluster-poolからmulti-poolへのインプレース移行Azure IPAMがmulti-poolへ移行。CiliumPodIPPool APIはcilium.io/v2とreservedRanges
ENI IPv6 IPAM---ベータENIモードではIPv6 masqueradeがデフォルトで無効
相互認証(SPIFFE/SPIRE)ありありデフォルトで無効非推奨削除(ファイアウォール一覧からポート4250も削除)
ztunnel--ベータベータ(内部CAまたはSPIRE)ベータ(1.21ツリーのencryption-ztunnel.rstには、引き続きbeta.rstのバナーあり)
Kafka対応L7ポリシーサポート非推奨非推奨削除削除
Envoy Go拡張(proxylib)サポート非推奨非推奨削除削除
BGPv1 CiliumBGPPeeringPolicyサポート非推奨削除--
ConfigMapドリフト検出(configDriftDetection)-1.18.xのパッチリリースにバックポート1.19.xのパッチリリースにバックポート1.20.0で標準搭載同じ
データパスモードveth(デフォルト)、netkit(ベータ)、netkit-l2、lb-onlyveth、netkitトンネル内のBIG TCP、PLPMTUDbpf.datapathMode=auto(対応時はnetkit、非対応時はveth。デフォルトはvethのまま)変更なし

2.2 リリースごとの主な変更 ​

1.17(2025-02、2761コミット): QoS用Podアノテーション(Guaranteed/Burstable/BestEffortのegress優先度)、MCS-API導入、プロトコル別(TCP/UDP)サービスロードバランシング、ServiceごとのLBアルゴリズム(maglev/random)、loadBalancerSourceRangesのdeny-listモード、タグによるAWS静的IPと単一IPのマルチプール、動的MTU、CiliumCIDRGroupによるラベル選択、ポート範囲を対象とするHTTPポリシー、静的Gatewayアドレスに対応したGateway API 1.2.1、動的HubbleメトリクスConfigMap、KVStoreとCRD間の移行に使うDouble Write ID割り当てモード。

1.18(3298コミット): LBコントロールプレーンの再設計、IPsec over VXLAN、複数のegress gateway(IPv6範囲にも対応)、ingress帯域幅のレート制限、トンネルのIPv6 underlay、Hubbleのポリシー名とpolicy logフィールド、clusterエンティティをローカルクラスターに限定する機能、k8s.apiServerURLsによるAPIサーバーフェイルオーバー、BGP CRD、CiliumCIDRGroupとCiliumLoadBalancerIPPoolを安定版cilium.io/v2に昇格、ENIモードのAWS prefix delegation、CiliumGatewayClassConfigを含むGateway API 1.3.0、カーネル最小要件を5.10に引き上げ。動作変更: ENIモードでenableIPv4Masqueradeのデフォルトがtrueからfalseに変更(1.18未満のupgradeCompatibilityを使うか、明示的に設定)、ENIモードのoperatorにec2:DescribeRouteTables権限が必要、io.cilium.k8s.policy.serviceaccountがデフォルトのIDラベルに加わり、アップグレード時に一時的なIDの入れ替わりが発生。

1.19(2934コミット): ポリシーのデフォルトをローカルクラスターに限定、相互認証をデフォルトで無効化、マルチプールIPAMを安定版に昇格、OCI Helmチャート、ztunnelをベータ化、IPsecとWireGuardの厳格な暗号化モード、Kafkaポリシーフィールドを非推奨化してFromRequires/ToRequiresを削除、BGPv1削除、MCS-API CRDの自動インストール(clustermesh.mcsapi.installCRDs)、証明書生成を再設計してCronJobをHelm hookではなくしたためArgo CDや--waitに適合、Gateway API 1.4、GAMMA GRPCRoute。

1.20(2026-07-29): Gateway API 1.6.1(ListenerSet、BackendTLSPolicy、TCPRoute/UDPRoute、ExternalAuth、CORS)、データパスプラグイン、bpf.datapathMode=auto、egress gatewayのIPv6 egress IP、cilium-dbg shell -- bgp/*経由のBGPとGoBGP 4.6.1、ENI IPv6(ベータ)、cluster-poolからmulti-poolへのインプレース移行、PreferSameZone/PreferSameNodeトラフィック分散、service.cilium.io/weightによるMaglevウェイト(0でdrain)、MCS-API安定版、cluster-meshポリシーエンティティ、Kubernetes ClusterNetworkPolicyのadmin/baseline階層、ConfigMapドリフト検出、cilium-cniバイナリを77 MBから16 MBに縮小、Kubernetes 1.36、Envoy 1.37.x。1.20で削除: Envoy Go拡張(proxylib)、Kafka対応L7ポリシー、CiliumNodeConfigのv2alpha1、clustermesh.enableMCSAPISupport(clustermesh.mcsapi.enabledを使用)、Cluster Meshの証明書を値として直接指定する方式、cilium-docker-plugin、旧encryption.strictMode.*フラグ(新しいencryption.strictMode.egress.*を使用)、--node-port-algorithm/--node-port-mode、--ces-slice-mode、encryption.ipsec.interface。動作変更: bpf.tproxy=trueはnetkitと併用不可。SocketLBを使わないPod(またはsocketLB.hostNamespaceOnly=trueのPod)からクラスター内NodePortへアクセスすると、クライアントPod側でロードバランスされるため、クライアントのegressポリシーとバックエンドのingressポリシーの両方で許可が必要。空のCiliumNetworkPolicy/CiliumClusterwideNetworkPolicy(spec/specsなし)はadmissionで拒否。Cluster Meshの自動生成証明書は有効期間がデフォルト1年で、4か月ごとにCronJobで再生成。certgenはCAの有効期間がleaf以上であることを検証(certgen.enforceCAValidityThroughoutLeavesDuration=falseで無効化)。

1.21プレリリース(v1.21.0-pre.3): delta xDS(envoy.xdsMode=delta-split)、Cilium Network Driver(DRA、SR-IOV)、Gateway API session persistence、ポリシー内のAWS managed prefix list、KVStoreMeshを常時有効化、Cluster MeshのauthModeデフォルトをclusterに変更、相互認証を削除、encryption.nodeEncryption(WireGuard)を非推奨化し1.22で削除予定、operatorの--aws-use-primary-addressフラグを削除(eni.nodeSpec.usePrimaryAddressを使用)、Gateway/GAMMAインフラメタデータのcec.cilium.io/*アノテーションを生成先のCiliumEnvoyConfigへ伝播しないよう変更、operatorが旧オブジェクトのストレージバージョンを自動移行、Kubernetesライブラリ1.37。pre.2のリリースノートにある「BPF masqueradingをデフォルトで有効化」はpre.3ツリーには反映されていません(「検証範囲」を参照)。

3. 1.20.1から1.20.2への変更点 ​

gh api repos/cilium/cilium/compare/v1.20.1...v1.20.2では204コミットと報告されます(APIはファイル一覧を300件で打ち切るため、変更ファイル数は信頼できません)。機能に影響するコミットを一覧全体で監査したわけではありません。アップグレードのリスクが低いと決めつけず、リリースノートを確認してください。特定の構成に関係する修正が複数あります。

領域修正内容
AWS ENI IPAM使用中のprefix-delegated IPをoperatorが個別IPとして解放していた問題、サブネットのprefix枯渇時に割り当てが失敗する問題、ipv4NativeRoutingCIDRがセカンダリVPC CIDRの場合にENIモードでagentが起動時にクラッシュする問題を修正。IPv6 ENIルーティング(health endpoint、ingress、IPsec)を修正。masquerade設定変更後のENI endpointルーティング規則を復元し、EC2 IMDSの負荷を軽減
Cluster Mesh削除済みのリモートクラスターが接続状態のままになるまれな競合、Cluster Meshから取り込むService backendの検証、設定変更時にclustermesh-apiserverのetcdユーザー管理が古いロールを失効しない問題を修正(Helmチャートのユーザーには影響なし)
アップグレードCilium 1.15以前で作成したクラスターは、CiliumNodeConfigのv2alpha1 CRDバージョン削除によりアップグレードに失敗。1.20へ上げる際は1.20.2以降を使用
無視されていたオプション受け付けられていたものの黙って無視されていた5つのオプションが動作するように修正: vtep-sync-interval、enable-xt-socket-fallback、カスタムCNI設定でのeni-delete-on-termination、chaining mode以外でのHelm enableIdentityMark、lb-retry-backoff-max。sinkへ届かなかったHubble設定4つも修正
データパス分割されたUDPをWireGuardと誤判定する問題、SNAT LB通信のICMPエラーチェックサム、DSR復旧とPMTU ICMP送信元、externalTrafficPolicy: LocalでのL2 announcement、LocalRedirectPolicyの回帰、egress denyメトリクスのpolicy-deny-response: icmpを修正
ポリシーNetworkPolicy変更直後に作られたPodで最大2分間古いrevisionが表示される問題、named port利用時の並行policy-mapクラッシュ、想定の2倍の時間identityが残存する問題を修正
Gateway API無効なbackendRefを指定したHTTPRoute ExternalAuthをfail-closedに変更。bpf.tproxyがfalse(デフォルト)の場合、Gateway APIにはiptablesとnetfilter TPROXYモジュールが必要だとドキュメントに明記
BGPdefaultGateway peerの自動検出が誤ったルーティングテーブルを選ぶ問題を修正

1.20.2でのイメージおよびチャートの更新: certgen v0.4.9からv0.4.11、Envoy v1.37.5からv1.37.6、hubble-ui v0.13.5からv0.13.6、SPIRE 1.15.2から1.15.3。values.yamlの差分はイメージタグとスキーマアノテーション1つだけです。また、enableIdentityMarkが設定された場合にのみenable-identity-mark ConfigMapキーが出力されるようになりました。

1.20.2のドキュメント変更: system_requirements.rstの必須カーネル設定から2項目(CONFIG_CRYPTO_USER_API_HASH、CONFIG_INET_XFRM_MODE_TUNNEL)を削除。Cluster Meshの導入に「セキュリティ」節を追加し、mesh内のクラスターは単一の信頼ドメインを形成するため、相互に信頼し、同等のセキュリティ態勢を持つクラスターのみ接続するよう説明しています。

推奨: ENI利用者、Cluster Meshのデプロイ、Cilium 1.15以前で作成したクラスターでは、--version 1.20.2を使用してください。

4. 互換性と要件 ​

4.1 バージョン互換性 ​

項目1.20.21.21.0-pre.3
Kubernetes(テスト済み)1.33、1.34、1.35、1.361.34、1.35、1.36、1.37
Linuxカーネル>= 5.10(RHEL 8.10: 4.18)>= 5.10
clang/LLVM(agentのネイティブビルドのみ)>= 18.1>= 21.1
Gateway API CRDv1.6.1が必須v1.6.1
Helm chart kubeVersion>= 1.21.0-0(テスト範囲ではなくチャート制約)同じ
Cilium CLI0.20.1該当なし
Hubble CLI1.20.2該当なし

1.20.2のシステム要件にある機能別カーネル最小要件: AMD64でのmulticastは>= 5.10、AArch64では>= 6.0、IPv6 BIG TCPは>= 5.19、IPv4 BIG TCPは>= 6.3、netkitはCONFIG_NETKIT=yを有効にした>= 6.8。1.19の注意点として、IPsecとkube-proxy replacementとBPF masqueradeを併用するとBPF host routingが自動的に有効になります。これにはCVE-2025-37959に対するカーネル修正が必要です。

Cluster Meshには別の制約があります。接続するすべてのクラスター間で、Ciliumのマイナーバージョン差を1以内にしてください(例: 1.19.xは1.18.xと1.20.xには接続できますが、1.17.xには接続できません)。

4.2 ポート ​

ノード間の通信は、セキュリティグループ参照またはプライベートCIDRに限定して許可してください(0.0.0.0/0は絶対に使わないでください)。

ポート用途
UDP 8472VXLANトンネル
UDP 6081Geneveトンネル
TCP 4240およびICMP type 8/0ヘルスチェック
TCP 4244Hubble server
TCP 4245Hubble Relay
UDP 51871WireGuard
ESP(IP protocol 50)IPsec(AWSセキュリティグループはルールで許可しない限りESPをブロック)
TCP 4250相互認証(1.20のドキュメントには記載、1.21のドキュメントでは削除)
TCP 2379クラスター間のclustermesh-apiserver

4.3 Gateway API CRD ​

Cilium 1.20にはGateway API CRD v1.6.1が必要です(Documentation/conf.pyのgateway_api_version = 'v1.6.1'、go.modのsigs.k8s.io/gateway-api v1.6.1)。Helm chartはCRDをインストールしません。必須CRD: GatewayClass、Gateway、HTTPRoute、GRPCRoute、ReferenceGrant、BackendTLSPolicy、TLSRoute。任意CRD(なければ該当機能は無効): TCPRoute、UDPRoute、ListenerSet。前提条件はkubeProxyReplacement=true、l7Proxy=true、およびiptablesとTPROXYモジュールです。ただしbpf.tproxy=true(ベータ)の場合は不要です。kubectl apply --server-sideで適用します。

TLSRouteの注意点: すでにTLSRouteを使っている場合は、v1alpha2を引き続き含むexperimental channelのTLSRoute v1.6.1をインストールしてください。standard channelのTLSRoute v1.6をインストールすると、既存のTLSRouteオブジェクトを読み取れなくなり、実質的に消失します。先にオブジェクトをバックアップしてください(kubectl get tlsroutes -A -o yaml)。

5. Helmによるインストール ​

Helm chartは次の2か所から取得できます。

配布元状態
oci://quay.io/cilium/charts/cilium1.19以降の推奨として記載。チャートはcosign署名付きで、digestを指定して固定可能
https://helm.cilium.io/(helm repo add cilium)従来のリポジトリ。引き続き完全にサポート

チャートバージョンにはvを付けません(--version 1.20.2)。イメージタグには付きます。OCIレジストリではhelm searchを使えません。バージョン一覧にはcrane ls quay.io/cilium/charts/ciliumを使用してください。チャート署名を検証します。

bash
cosign verify \
  --certificate-identity-regexp='https://github.com/cilium/cilium/.*' \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  quay.io/cilium/charts/cilium:1.20.2

値はバージョン管理下のファイルに保存し、-f values.yamlでインストールしてください。大量の--setフラグに頼らないでください。7節のとおり、マイナーバージョンを上げるたびに値を再指定する必要があります。

6. EKSへのインストール固有の事項 ​

6.1 モードの選択 ​

モードHelm設定データパス/IPAM備考
ENI(EKSでのupstreamデフォルト)eni.enabled=trueネイティブルーティング(eni.enabled時のchartデフォルト)、AWS ENI IPAM、Kubernetes CRD datastorePodにはVPCでルーティング可能なIPを割り当てます。operatorにEC2 API権限が必要です。Ciliumノードではaws-nodeを実行しないでください
Overlayeni.enabledを省略(chartデフォルトはトンネル/VXLAN)VXLAN、cluster-pool IPAMENIの上限を超えるPodを各ノードで実行可能。PodからVPCへの通信はnode IPにSNATされます。EKS API serverはoverlayのPod IPへルーティングできないため、webhookはhost networkを使うか、Service/Ingress経由で到達できる必要があります。VPC CNIが残したAWS-SNAT-CHAIN-0/1とAWS-CONNMARK-CHAIN-0/1のiptables chainをflushしてください
VPC CNIとのchainingcni.chainingMode=aws-cni、cni.exclusive=false、enableIPv4Masquerade=false、routingMode=nativeネットワーキングはVPC CNI、Ciliumはポリシーと可視性を追加VPC CNI >= 1.11.2が必要です。有効化後、既存Podを再起動してください。chainingの制約はupstreamのcni-chaining-limitations.rstに記載されています。選択前に確認してください
EKS Hybrid NodesAWSビルドのchart oci://public.ecr.aws/eks/cilium/ciliumVXLAN overlay、cluster-pool6.4を参照
EKS Auto Mode非対応該当なし6.5を参照

6.2 ENIモードのインストール ​

CiliumがENIを管理するため、Cilium管理下のノードでVPC CNIが動作しないようにします。upstreamのコマンドをそのまま使い、どのノードにも存在しないnode selectorでaws-node DaemonSetをpatchしてください。

bash
kubectl -n kube-system patch daemonset aws-node --type='strategic' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"io.cilium/aws-node-enabled":"true"}}}}}'

アプリケーションPodがCiliumの準備前に起動しないよう、managed node groupにtaintを設定します(upstreamの推奨)。

yaml
# eksctl ClusterConfig fragment
managedNodeGroups:
- name: ng-1
  taints:
  - key: "node.cilium.io/agent-not-ready"
    value: "true"
    effect: "NoExecute"

valuesファイル(すべてのキーは1.20.2 chartに存在します。eni.enabled=trueを設定するとoperatorイメージ、endpoint route、CiliumNode管理、IPv4 masqueradeのデフォルトが設定されます。また、eni.enabled=trueなしでipam.mode=eniを指定するとchart検証が失敗します)。

yaml
# values-eks-eni.yaml  (Cilium 1.20.2)
eni:
  enabled: true
kubeProxyReplacement: true
k8sServiceHost: <EKS-API-ENDPOINT-FQDN-without-scheme>
k8sServicePort: 443
cluster:
  name: eks-a
  id: 1   # keep below 128 in ENI mode (see the cluster.id note in the Helm reference)
bash
helm install cilium oci://quay.io/cilium/charts/cilium --version 1.20.2 \
  -n kube-system -f values-eks-eni.yaml

注意点:

  • kube-proxy replacementを使う場合、kube-proxyを削除する前にk8sServiceHostとk8sServicePortを設定してください。そうしないとagentがAPI serverに接続できません。
  • operatorにはEC2権限(upstreamのec2privileges節を参照)が必要です。1.18以降はec2:DescribeRouteTablesも必要です。
  • 1.18でENIモードのenableIPv4Masqueradeデフォルトがfalseに変わりました。1.18より前のENIクラスターをアップグレードし、masqueradeに依存している場合は、明示的に設定するかupgradeCompatibilityを使ってください。
  • ENI IPv6は1.20ではベータです(eni.rst)。upstreamのrequirements-eks.rstにはENIはIPv4のみとする記述がまだありますが、リリースノートとeni.rstに従ってください。
  • ENIでは1.20.2を使用してください。prefix delegationの解放、サブネットのprefix不足時の割り当て、セカンダリVPC CIDRを使うネイティブルーティングのクラッシュが修正されています。
  • Pod IPはdefault poolから割り当てられます。ENIモードではCiliumPodIPPoolとipam.cilium.io/ip-poolアノテーションは使われません(eni.rst)。IPAMも参照してください。

6.3 AMI ​

1.20.2のシステム要件では、Amazon Linux 2とBottlerocket(全バージョン)、Ubuntu >= 20.04、RHEL >= 8.6、Talos >= 1.5.0、Flatcar(ENIではDHCPに注意)をサポート対象としています。Amazon Linux 2023は名前が明記されていません。カーネルは5.10の最小要件より新しいものの、これは推論でありupstreamによる明示ではありません。AWSのHybrid Nodesドキュメントでは、Ubuntu 20.04とRHEL 8はCilium 1.18.3のカーネル要件を満たさないとしています。

6.4 EKS Hybrid Nodes ​

AWSがHybrid NodesでCiliumをサポートするのは、公開ECRリポジトリoci://public.ecr.aws/eks/cilium/ciliumにあるAWS保守ビルドのみです(AWSのドキュメントには1.17.9-0や1.18.3-0などのバージョンが掲載されています。これより新しいAWSビルドの一覧は今回のレビューでは確認していません)。Hybrid NodesではVPC CNIを使えません。AWSのデフォルト構成はVXLAN overlayとcluster-pool IPAMです。pool CIDRはEKSのremote Pod networkと一致させ、node、VPC、Service CIDRと重複させず、デプロイ後に変更しないでください。eks.amazonaws.com/compute-type In hybrid affinityでagentとoperatorをHybrid Nodesに固定し、BGP Control Planeを使ってPod CIDRをルーティング可能にします。AWSのサポート表ではCilium IngressとCilium GatewayをHybrid Nodesでサポートしています(デフォルト構成。CNIとIngressのページを参照)。envoy.enabled: falseはAWSのベースライン例のvaluesにのみ記載されています。Cilium Ingress/GatewayとL7 network policyにはEnvoyが必要なので、利用する場合はAWSのIngressページに従い有効にしてください。この構成ではAWSクラウド側ノード上のCiliumはサポートされません。

6.5 EKS Auto Mode ​

EKS Auto ModeはCiliumと連携しません。AWSのドキュメントでは、Auto Modeは代替CNIプラグインやネットワークポリシープラグインをサポートしないとしています(EKS User Guideの「alternate CNI plugins」と「auto networking」ページ)。upstream CiliumドキュメントにもAuto Modeのページはありません。Ciliumには通常のmanaged node groupまたはself-managed nodeを使ってください。

6.6 このリポジトリの公開範囲のルール ​

この章の構成にpublic listenerは必要ありません。VPC外のクライアントからアプリケーションへ到達させる場合は、CloudFrontのVPC originからinternal ALB/NLBへ接続してください。clustermesh-apiserver Serviceもinternalにします(14節)。

7. アップグレードとロールバックの手順 ​

7.1 ルール ​

  1. テスト対象は連続したマイナーバージョン間のアップグレードとロールバックのみです(1.19から1.20への移行とその逆)。マイナーを飛ばさないでください。
  2. まず、現在のマイナー系列の最新パッチへ上げ、すべての修正を含むロールバック先を確保してください。
  3. agent、operator、Hubble Relay、clustermesh-apiserverをすべて同じバージョンにアップグレードしてください。agentだけを更新してはいけません。
  4. L3/L4トラフィックへの影響はほぼないか、わずかです。ユーザー空間proxy(L7 policy、Ingress、Gateway API、Envoy)を経由する接続は中断され、クライアント側で再接続が必要です。各ノードではagentが戻るまで新しいポリシールールの適用が遅れます。
  5. マイナーバージョンをまたいでhelm upgrade --reuse-valuesを使わないでください。新しいchartのデフォルト値が反映されず、壊れたmanifestが生成される場合があります。chartバージョンが変わらない場合(この章後半のCluster Mesh設定更新など)に限り、--reuse-valuesを使えます。
  6. upgradeCompatibilityにはアップグレード元ではなく、最初にインストールしたマイナーを設定します。出力されるConfigMapのデフォルト値を古いものに固定します。例えば1.18より前のENI masqueradeデフォルトを復元します。
  7. Cilium 1.15以前で作成したクラスターは1.20.0/1.20.1ではなく、1.20.2以降へアップグレードしてください。

7.2 手順 ​

bash
# 0. Save and review current values for renamed/removed keys
helm get values cilium -n kube-system -o yaml > old-values.yaml

# 1. Pre-flight: pre-pulls the new image on every node and validates existing CNPs
helm install cilium-preflight oci://quay.io/cilium/charts/cilium --version 1.20.2 \
  -n kube-system \
  --set preflight.enabled=true --set agent=false --set operator.enabled=false
#   (add k8sServiceHost/k8sServicePort when kube-proxy replacement is on)
kubectl -n kube-system get ds cilium-pre-flight-check   # READY must equal the node count
kubectl -n kube-system get deploy cilium-pre-flight-check   # must be 1/1
kubectl -n kube-system logs deployment/cilium-pre-flight-check -c cnp-validator --previous
helm delete cilium-preflight -n kube-system

# 2. Upgrade (NO --reuse-values); 1.19 is the minor you installed originally in this example
helm upgrade cilium oci://quay.io/cilium/charts/cilium --version 1.20.2 \
  -n kube-system -f old-values.yaml --set upgradeCompatibility=1.19

# 3. Watch
kubectl -n kube-system rollout status ds/cilium
kubectl -n kube-system rollout status deploy/cilium-operator
cilium status --wait

事前チェック用DeploymentがREADY 0/1のままの場合、新バージョンで検証に失敗する既存のCiliumNetworkPolicyが少なくとも1つあります。アップグレード前にポリシーを修正してください。

7.3 ロールバック ​

bash
helm history cilium -n kube-system
helm rollback cilium <REVISION> -n kube-system
# or, for the DaemonSet only:
kubectl -n kube-system rollout undo daemonset/cilium

新しいマイナーの機能(新しいCRやConfigMapのopt-in設定など)をすでに使った場合は、ロールバック前にそのバージョンのアップグレードノートを確認してください。ロールバックで古いmanifestは復元されますが、新バージョンが作成したオブジェクトは戻りません。

7.4 CRDの扱い ​

CRDファミリーインストール/更新担当対応
Cilium CRD(cilium.io)operator/agentが起動時に登録・更新特になし。ただしアップグレード後にkubectl get crd | grep cilium.ioで確認。1.20ではCiliumNodeConfigのv2alpha1を削除したため、cilium.io/v2を使用
Gateway API手動で実施(kubectl apply --server-side)4.3節にあるバージョンを使用。先にTLSRouteをバックアップ
MCS-API(multicluster.x-k8s.io)clustermesh.mcsapi.enabled=trueならchartが担当。ただし1.19以降、clustermesh.mcsapi.installCRDs=falseならインストールしない別のcontrollerが管理する場合はinstallCRDs=falseを設定
廃止されたストレージバージョン[1.21 プレリリース] operatorが自動移行CiliumPodIPPoolのv2がストレージバージョンになります

7.5 マイナーごとに確認するアップグレード作業 ​

移行先マイナーの「Upgrade Notes」を必ず確認してください。前述のうち問題になりやすい項目: ENI masqueradeのデフォルトとec2:DescribeRouteTables(1.18)、service-accountラベル追加によるidentityラベルの入れ替わり(1.18)、policy-default-local-clusterがtrueに変更(1.19、13節参照)、相互認証がデフォルトで無効(1.19)、オプションおよびKafka/proxylibの削除(1.20)、bpf.tproxyとnetkitの併用、NodePortのクライアント側ロードバランシング(1.20)、authMode=clusterのデフォルト化とkvstoremesh.enabled値の削除(1.21プレリリース)。

8. Day 2の設定 ​

8.1 ConfigMapドリフト検出 ​

多くのオプションはagentの再起動後にのみ有効になります。helm upgradeまたはcilium config setでcilium-config ConfigMapを編集すると、実行中のagentとConfigMapの設定が異なる場合があります。ドリフト検出を使うと、その状態を確認できます。1.20.0で標準搭載され、1.18.xと1.19.xのパッチリリースにもバックポートされました(v1.18.14とv1.19.8のchartにはありますが、v1.18.0とv1.19.0のchartにはありません)。

yaml
configDriftDetection:
  enabled: true        # enable-dynamic-config: watch the ConfigMap
  driftChecker: true   # enable-drift-checker: compare desired vs active
  ignoredKeys: []      # for example ["devices"] for keys that are intentionally different

キーごとに不一致を示す警告をagentログへ出力し、ゲージcilium_drift_checker_config_deltaを公開します。値が0なら同期済み、0より大きければagentは現在のConfigMapを適用しておらず、再起動が必要です。ロールアウト時間を超えてcilium_drift_checker_config_delta > 0が続く場合にアラートを出してください。

cilium config set <key> <value>はConfigMapを編集し、デフォルトでagentを再起動します。再起動を保留してドリフトゲージに変更待ちを表示するには、--restart=falseを指定してください。

8.2 CiliumNodeConfig(ノード単位の上書き) ​

CiliumNodeConfig(apiVersion: cilium.io/v2、namespace kube-system)は、spec.nodeSelectorに一致するノードのConfigMap/agentキーを上書きします(空のselector {}は全ノードに一致)。変更を反映するにはagent Podを再作成するか、ノードを再起動する必要があります。v2alpha1は1.20で削除されました。

yaml
apiVersion: cilium.io/v2
kind: CiliumNodeConfig
metadata:
  namespace: kube-system
  name: enable-xdp
spec:
  nodeSelector:
    matchLabels:
      io.cilium.xdp-offload: "true"
  defaults:
    bpf-lb-acceleration: native

典型的な用途は、対応ハードウェアを持つノードだけでXDPやIPv6 BIG TCPを有効にすること、kube-proxy replacementを段階的に展開することです。後者では、移行対象ノードにio.cilium.migration/kube-proxy-replacement=trueラベルを付け、kube-proxy DaemonSetをそのラベルのNotIn affinityでpatchし、CiliumNodeConfigにkube-proxy-replacement: "true"を設定したうえで、ノードごとにagent Podを削除します。kube-proxyを停止する前にk8sServiceHostとk8sServicePortを設定してください。

8.3 KVStoreからCRDへのidentity移行(Double Write、ベータ) ​

1.17で導入され、1.20.2と1.21 pre.3でもベータです。割り当てモードはagentオプション--identity-allocation-modeで、Helm値identityAllocationModeを使って設定します(chartではConfigMapキーidentity-allocation-modeとして出力)。

手順モードロールアウト順序正とするデータ
0kvstoreKVStore
1doublewrite-readkvstoreoperator、次にagentKVStore(identityもCRDへ書き込むが、CRDは参照しない)
2doublewrite-readcrdoperator、次にagentCRD(迅速なロールバック用にKVStoreにも書き込む)
3crdagent、次にoperatorCRDのみ。KVStoreを廃止可能

各段階の間でデータが収束するのを待ちます。operatorはcilium_operator namespaceにゲージを公開します。upstreamのupgradeページには古い名前cilium_operator_identity_*_countがまだ載っていますが、v1.20.2のoperator/doublewrite/metrics.goではdoublewrite_crd_identities、doublewrite_kvstore_identities、doublewrite_crd_only_identities、doublewrite_kvstore_only_identitiesを登録しており、cilium_operator_doublewrite_*として表示されます。使用バージョンでの正確な名前は、operatorのmetrics portへcurlして確認してください。KVStoreとCRDのガベージコレクションは実行時刻が異なるため、一時的な差は正常です(--identity-gc-interval、--identity-heartbeat-timeout)。逆方向(CRDからKVStore)への移行は手順を逆に繰り返します。初期状態からの復旧: agentがcrdモードで動いていない状態でkubectl delete ciliumid --allを実行します。

単発のcilium-dbg preflight migrate-identityツールは1.20.2で制約付き(identity churnが許されず、簡単にロールバックできない)として記載され、1.21プレリリースでは非推奨です。Double Writeを使ってください。

9. Cluster Meshのアーキテクチャ ​

Cluster Meshは複数のKubernetesクラスターのコントロールプレーンを接続し、identity、endpoint、node、Serviceを共有します。一方、Podトラフィックはgatewayやproxyを介さず、ノード間を直接流れます。

 Cluster 1                                         Cluster 2
 ┌──────────────────────────────┐                  ┌──────────────────────────────┐
 │ clustermesh-apiserver (Deploy)│                 │ clustermesh-apiserver (Deploy)│
 │  ┌────────┐ ┌──────────────┐ │  mTLS etcd 2379  │  ┌────────┐ ┌──────────────┐ │
 │  │ etcd   │◄┤ apiserver    │ │◄────────────────►│  │ etcd   │◄┤ apiserver    │ │
 │  │(local  │ │ (sync local  │ │  (via internal LB│  │        │ │              │ │
 │  │ state) │ │  state -> etcd)│ │   / NodePort)   │  │        │ │              │ │
 │  └───▲────┘ └──────────────┘ │                  │  └───▲────┘ └──────────────┘ │
 │      │      ┌──────────────┐ │                  │      │      ┌──────────────┐ │
 │      └──────┤ kvstoremesh  │─┼─ pulls remote ──►│      └──────┤ kvstoremesh  │ │
 │             └──────▲───────┘ │   cluster state  │             └──────▲───────┘ │
 │   agents read ONLY │ local   │                  │   agents read ONLY │ local   │
 │   ┌────────────────┴─┐       │                  │   ┌────────────────┴─┐       │
 │   │ cilium-agent (DS)│       │                  │   │ cilium-agent (DS)│       │
 │   └─────────┬────────┘       │                  │   └─────────┬────────┘       │
 └─────────────┼────────────────┘                  └─────────────┼────────────────┘
               └──────── Pod -> Pod, node to node (VXLAN/Geneve or native) ───────┘

構成要素(v1.20.2のintro.rst、values.yaml):

  • clustermesh-apiserverは3つのコンテナを含むDeploymentです。etcdは永続ストレージを使わない単一の組み込みインスタンスです。起動時にKubernetes API serverから状態を再構築し、mTLSで公開されます。apiserverはローカルのCiliumとKubernetesの状態(node、endpoint、identity、Service)をそのetcdに同期します(etcdQPS: 50)。kvstoremeshは各リモートクラスターの状態をローカルetcdキャッシュに取り込みます(etcdQPS: 100)。
  • KVStoreMesh: agentはローカルキャッシュからのみリモート状態を読み取るため、それぞれのagentがすべてのリモートetcdへ個別に接続する必要はありません。1.16からデフォルトで有効です。clustermesh.apiserver.kvstoremesh.enabled値は1.18で非推奨になり、[1.21プレリリース]では無条件に有効となり、値も削除されます。
  • レプリカ: clustermesh.apiserver.replicasのデフォルトは1です。各レプリカはそれぞれetcdクラスターを実行し、リモートクライアントはService経由で接続先を選びます。service.enableSessionAffinity(デフォルトHAOnly、ほかにAlways、Never)は、再接続時に全状態を再同期する頻度を減らします。podDisruptionBudgetはデフォルトで無効です。
  • KVStoreモード: Ciliumがすでに外部etcdをidentity/状態ストアとして利用している場合、Cluster Meshでも再利用できます(clustermesh.apiserver.kvstoremesh.kvstoreMode: external)。externalとcrd identity割り当てモードは併用できません。
  • 単一の信頼ドメイン(v1.20.2 intro.rst): 侵害されたクラスターから他のクラスターへ不正な状態を伝播されるおそれがあります。相互に信頼し、同等のセキュリティ態勢を持つクラスターだけを接続してください。

9.1 データパス ​

リモートPodはローカルipcacheに登録され、トンネルendpointとしてリモートノードが指定されます(overlayの場合)。ネイティブルーティングではunderlayによってルーティングされます。identityにはcluster IDが含まれるため、クラスター1でクラスター2のPodからのトラフィックを判定するポリシーは、リモートPodの数値identityを使い、gatewayなしで機能します。このためPod CIDRの重複を避け、node IP間の接続性を確保することが必須です。

10. Cluster Meshの設定 ​

10.1 前提条件 ​

要件詳細
データパスモードを統一すべてのクラスターをoverlay、またはすべてをネイティブルーティングにする
Ciliumのマイナーバージョン差最大1つ
一意で重複しないPod CIDR全クラスターの全ノードで重複を避ける
ノード間の到達性各ノードのInternalIPを利用(peering、TGW、VPN)
ファイアウォールTCP 2379(clustermesh-apiserver)、TCP 4240とICMP(health)、UDP 8472/6081(トンネル)、UDP 51871(WireGuard)
ネイティブルーティングのみipv4NativeRoutingCIDRに全クラスターのPod CIDRが含まれること(例: 10.0.0.0/8)。Podが全ポートでクラスター間ルーティング可能なこと

10.2 クラスター名とID ​

設定ルール
cluster.name最大32文字。正規表現は^([a-z0-9][-a-z0-9]*)?[a-z0-9]$(pkg/clustermesh/types/types.go)。クラスターごとに一意にする。IDが0以外の場合、defaultは使えません
cluster.idデフォルトでは1~255。0は未設定を表し、予約済みです。maxConnectedClusters: 511の場合は511まで拡張。ENIモードとaws-cni chaining: extraConfig.allow-unsafe-policy-skb-usage=trueを設定しない限り、chartは128~255(maxConnectedClusters: 511の場合は384~511)のIDを拒否します(templates/validate.yaml:160-168、cilium/cilium#21330)。EKSのENIモードでは128未満を使用してください
clustermesh.maxConnectedClusters255(デフォルト)または511。すべてのクラスターで同じ値にし、インストール時に設定

トレードオフ: cluster IDは数値identityのビットを使用します。255クラスターの場合、クラスター内identityの最大数は65535です。511クラスターでは32767に減ります。稼働中のクラスターでmaxConnectedClustersを変更すると、接続が中断したりポリシー判定を誤ったりする可能性があります。values.yamlのcluster.idコメントは現在も1~255と記載されており、511の場合には古い情報です。稼働中にクラスター名やIDを変える場合、identityにcluster IDが埋め込まれているため、すべてのワークロードを再起動する必要があります。

10.3 TLSとauthMode ​

値意味
clustermesh.apiserver.tls.auto.methodhelm(証明書はhelm upgrade時のみ更新されるため、少なくとも年1回アップグレード)、cronJob(デフォルトスケジュール0 0 1 */4 *、4か月ごと)、certmanager
tls.auto.certValidityDuration365日
共有CAすべてのクラスターで同じCAを使う。Cluster Mesh有効化前にcilium-ca Secretを他クラスターへコピーするか、tls.caBundleを設定
ユーザー指定証明書Secretはclustermesh-apiserver-{server,admin,remote,local}-cert。CN: serverはclustermesh-apiserver.<ns>.svc(SANは*.mesh.cilium.io、127.0.0.1、::1、追加DNS名)、adminはadmin-<cluster>、localはlocal-<cluster>、remoteはremote(1.20)またはremote-<cluster-name>(clusterモード)

authModeは、各クラスターがリモートclustermesh-apiserverに接続する際に使うetcdユーザーを制御します。

authMode動作デフォルトのバージョン
legacyすべてのクラスターがユーザーremoteを使う1.17、1.18(values.yaml: v1.17.18の3416行、v1.18.14の3634行)
migrationクラスターごとのユーザーを作成するが、認証には引き続きremoteを使う。停止せずlegacyからclusterへ移行するために必要1.19、1.20
cluster各クラスターがremote-<cluster-name>として認証。同じCAを共有する場合に意味がある[1.21プレリリース]
cluster-strict[1.21プレリリース] 共有remoteユーザーなしでclusterと同様に動作。すべてのクラスターがclusterを使ってから有効化-

1.21での対応: clustermesh.useAPIServer=trueかつtls.auto.enabled=falseの場合、remote証明書をCN remote-<cluster-name>で再発行するか、authModeをmigrationまたはlegacyに戻します。自動証明書を使っていれば移行は透過的に行われる見込みです。clustermesh.config.enabled=falseの場合は、clustermesh-remote-users ConfigMapを自分で作成する必要があります(1.19の注意点)。証明書の有効期間の変更: 1.19で生成方式を改訂し、CronJobをHelm hookではなくしました。1.20ではデフォルトの有効期間は1年で、4か月ごとに再生成され、CAの有効期間がleaf以上であることを検証します。また1.20でclustermesh.apiserver.tls.server.{extraDnsNames,extraIpAddresses}キーはclustermesh.apiserver.tls.auto.server.*へ移動しました。

10.4 Helmの設定 ​

クラスターごとのvalues(upstream設定ガイドと同じ形式。internal LBのannotationはAWS Load Balancer Controller標準のscheme annotationです。chartのコメントにも記載があるかは確認していません):

yaml
# cluster1.yaml
cluster:
  name: cluster1
  id: 1
clustermesh:
  useAPIServer: true
  config:
    enabled: true
  apiserver:
    service:
      type: LoadBalancer
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-scheme: internal
    tls:
      auto:
        enabled: true
        method: cronJob
        server:
          extraDnsNames:
            - cluster1.example.com
yaml
# clusters.yaml  (shared; the local cluster entry is ignored by each cluster)
clustermesh:
  config:
    clusters:
      cluster1:
        address: cluster1.example.com
        port: 2379
      cluster2:
        address: cluster2.example.com
        port: 2379

先にCAをコピーし、インストール済みと同じchartバージョンで適用してください(upstreamガイドと同様に、この場合は--reuse-valuesを使えます)。

bash
helm upgrade cilium oci://quay.io/cilium/charts/cilium --version 1.20.2 -n kube-system \
  --kube-context $CLUSTER1 --reuse-values -f clusters.yaml -f cluster1.yaml

kubectl --context $CLUSTER1 get secret -n kube-system cilium-ca -o yaml | \
  kubectl --context $CLUSTER2 create -f -

helm upgrade cilium oci://quay.io/cilium/charts/cilium --version 1.20.2 -n kube-system \
  --kube-context $CLUSTER2 --reuse-values -f clusters.yaml -f cluster2.yaml

Service公開: clustermesh.apiserver.service.typeのデフォルトはNodePort(nodePort: 32379)です。upstreamは安定したアドレスを得るためLoadBalancerを推奨しています。NodePortでは安定したnode IPが必要です。ClusterIPの場合はClusterIP間をクラスター間でルーティング可能にします。AWSではservice.beta.kubernetes.io/aws-load-balancer-scheme: internal(およびpeer VPC CIDRに限定したloadBalancerSourceRanges)を必ず使うか、peering/TGW経由でNodePort/ClusterIPを使います。このコントロールプレーンをinternet-facing LBで公開すると、このリポジトリのポリシーに違反し、meshの信頼ドメインを露出します。peerクラスターのnode security groupまたはプライベートCIDRからのみTCP 2379を許可するsecurity groupも併用してください。

部分的なmeshを構成する場合は、各クラスターのclusters mapに接続対象のクラスターだけを指定します。クラスターごとの静的なipsにも対応しています。[1.21プレリリース]では、静的IPを変更してもPodは再起動しなくなり、clustermesh.apiserver.service.portも設定可能です。

CLIでの代替方法(Helmのラッパー。ラボで便利):

bash
cilium install --set cluster.name=$CLUSTER1 --set cluster.id=1 --context $CLUSTER1
cilium install --set cluster.name=$CLUSTER2 --set cluster.id=2 --context $CLUSTER2
cilium clustermesh enable --context $CLUSTER1
cilium clustermesh enable --context $CLUSTER2
cilium clustermesh connect --context $CLUSTER1 --destination-context $CLUSTER2   # one direction is enough
cilium clustermesh status --context $CLUSTER1 --wait
cilium connectivity test --context $CLUSTER1 --multi-cluster $CLUSTER2

10.5 namespace: defaultGlobalNamespace ​

clustermesh.defaultGlobalNamespace(デフォルトtrue。1.20.2 chartにはありますが、1.19.8 chartにはありません)は、namespace内のCiliumEndpoints、CiliumIdentities、Serviceをエクスポートするか制御します。clustermesh.cilium.io/global: "true"または"false"をnamespaceにannotation付与して上書きできます。クラスター間接続とポリシーには、送信元と送信先の両namespaceをglobalにする必要があります。Global Serviceはglobal namespace内に置き、Service annotationも付与してください。デフォルトをfalseにすると、クラスター間で同期する状態を減らし、スケーラビリティを高められます。

10.6 データの古さ: cacheTTL ​

clustermesh.cacheTTLのデフォルトは"0s"です。接続が切れたリモートクラスターのキャッシュデータは失効しません。接続が指定した時間内(例: "15m")に復旧しなければ古いリモートデータを破棄するよう、期間を設定してください。

11. Global Service、アフィニティ、EndpointSlice同期 ​

Global Serviceは、各クラスターで同じService名とnamespaceを使い、service.cilium.io/global: "true" annotationを付与します。すべてのクラスターのbackendが統合されます。

Annotation効果
service.cilium.io/global: "true"Serviceをglobalにする。いずれかのクラスターで省略またはfalseにすると、そのクラスターのServiceはローカルにとどまる
service.cilium.io/shared: "false"このクラスターのbackendをエクスポートしないが、リモートbackendは利用。両側でglobalかつsharedが有効なら各クラスターからローカルとリモートの両方が見える。shared: "false"のクラスターは何もエクスポートしない
service.cilium.io/affinity: none|local|remotelocal: 正常なローカルbackendを使い、すべて利用不可の場合のみリモートへ切り替え。remoteは逆。none(デフォルト)は優先設定なし
service.cilium.io/global-sync-endpoint-slices: "true"ベータ。他のcontrollerからも見えるようにリモートbackendのEndpointSliceも作成。Helmのclustermesh.enableEndpointSliceSynchronization=trueとoperator再起動が必要。headless Global Serviceではデフォルトで有効
yaml
apiVersion: v1
kind: Service
metadata:
  name: rebel-base
  annotations:
    service.cilium.io/global: "true"
    service.cilium.io/affinity: "local"
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    name: rebel-base

cilium-dbg service list --clustermesh-affinityでアフィニティを確認できます(優先backendには(preferred)が付きます)。制約: Global NodePortとhost-networkクライアントがリモートbackendへロードバランスするには、kube-proxy replacement(またはsocketLB.enabled=trueかつsocketLB.hostNamespaceOnly=true)が必要です。Cilium ingress controllerはEndpointSlice同期なしでmesh内で動作しますが、他のingress controllerでは同期が必要な場合があります。1.19で追加されたメトリクスはcilium_agent_clustermesh_remote_cluster_endpointsです。

12. MCS-API(マルチクラスターサービス) ​

MCS-APIはKubernetes SIG-MulticlusterのAPIです。ServiceExportでServiceを公開し、各クラスターにDNS名<svc>.<ns>.svc.clusterset.localを持つServiceImportが作成されます。CiliumはGlobal Serviceの仕組みを再利用するderived-<hash>という派生Serviceとしてimportを実装しているため、2つの方式は併用できます。

項目値
成熟度1.19ではベータ(CRDはmulticluster.x-k8s.io/v1alpha1)。1.20で安定版(v1beta1。v1alpha1も引き続きサポート)
有効化clustermesh.mcsapi.enabled=true(削除されたclustermesh.enableMCSAPISupportを置き換え)
CRDchartがインストール(clustermesh.mcsapi.installCRDs、デフォルトtrue)
CoreDNSclustermesh.mcsapi.corednsAutoConfigure.enabledを使用(CoreDNS >= 1.12.2が必要。Kubernetes >= 1.35のデフォルト)。手動設定: serviceimportsのlist/watch権限を持つClusterRole coredns-mcsapiと、CoreDNSのmulticluster clusterset.local plugin
NamespaceServiceのnamespaceがすべてのクラスターに存在すること
yaml
apiVersion: multicluster.x-k8s.io/v1beta1
kind: ServiceExport
metadata:
  name: rebel-base
spec:
  exportedLabels:
    app.kubernetes.io/name: rebel-base
  exportedAnnotations:
    service.cilium.io/affinity: local

export間で調整されるプロパティ: SessionAffinity、Ports(union)、Type(ClusterSetIPまたはHeadless)、InternalTrafficPolicy、TrafficDistribution、label/annotation。競合時、CiliumはServiceExportのstatusに競合conditionを設定し、作成日時の古い順に解決します。この解決に頼らず、競合を修正してください。クラスターごとに別のDNS名を使う方法には対応していません。mysvc-euとmysvc-usを個別にexportしてください。StatefulSet Podのhostnameは<hostname>.<cluster>.<svc>.<ns>.svc.clusterset.localとして解決されます。Gateway APIではServiceImportをbackendRefとして使用できます。[1.21プレリリース]では、prefix削除後の名前が40文字を超えるミラーEndpointSliceは、アップグレード中に再作成され短時間の中断が起きる場合があります。

13. クラスター間ポリシー ​

  • デフォルトのスコープ(1.19以降): selectorはローカルクラスターのendpointのみに一致します(policy-default-local-cluster、Helmのclustermesh.policyDefaultLocalCluster: true)。1.18以前のデフォルトは全クラスターでした。1.18からアップグレードする前にcilium clustermesh inspect-policy-default-local-cluster --all-namespaces(または-p <namespace>)で監査してください。以前の注記ではこのコマンドのCLI不具合が1.21 pre.3ツリーで修正されたとしていましたが、未検証です。使用するCLIバージョンで出力を確認してください。
  • リモートクラスターを選択するには、ラベルio.cilium.k8s.policy.clusterを使います。
yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-cross-cluster
spec:
  endpointSelector:
    matchLabels:
      name: x-wing
  egress:
  - toEndpoints:
    - matchLabels:
        name: rebel-base
        io.cilium.k8s.policy.cluster: cluster2

任意のクラスターを選ぶには、代わりにmatchExpressions: [{key: io.cilium.k8s.policy.cluster, operator: Exists}]を使います。

  • エンティティ: clusterは、ローカルクラスター限定の設定(1.18のオプション)がない限り、mesh内のリモートノードを含みます。1.20ではcluster-meshが追加され、mesh内のすべてのクラスターのendpointに加えてclusterの対象も含みます。
  • ポリシーは複製されません。各クラスターで個別に適用してください。
  • 相互認証(SPIRE)はCluster Meshと併用できず、1.21プレリリースでは完全に削除されます。このリポジトリのservice-meshノートによると、ztunnelもCluster Meshと併用できません。mTLS、暗号化、IDを参照してください。
  • Cluster Meshと併用する場合、host firewallには制約があります(host.rst)。データプレーン暗号化はコントロールプレーンで使うmTLSとは別です。WireGuardまたはIPsecをすべてのクラスターで同じように設定し、UDP 51871をクラスター間で許可してください。Cluster Meshと暗号化を組み合わせた場合の正確な注意点は、今回再確認していません。

14. EKS上のCluster Mesh ​

upstreamのeks-clustermesh-prep.rstでは、eksctl、CIDRが重複しない2つのVPC(例: 10.0.0.0/16と10.1.0.0/16。172.17.0.0/16は避ける)、VPC peering、同一VPCおよびpeerからの通信を許可するsecurity groupを使います。そのガイドはinternet gatewayを備えたpublic subnetも作成します。このリポジトリでは、次のように適用してください。

  • ノードにはprivate subnetのみを使用し、public IPやEIPを割り当てないでください。
  • VPCをpeeringする(またはTransit Gatewayを使う)とともに、private route tableにpeer CIDRへのrouteを追加します。
  • security group ruleでは両クラスターのnode security group(またはprivate CIDR)を参照します。0.0.0.0/0や::/0は使わないでください。
  • clustermesh-apiserverはinternal NLB(aws-load-balancer-scheme: internal)で公開するか、peering経由のNodePortを使います。loadBalancerSourceRangesはpeer VPC CIDRに制限します。
  • ENIモードではPod IPをVPC内でルーティングできるため、ネイティブルーティングで必要なのはipv4NativeRoutingCIDRに両VPCのPod rangeを含めることだけです。overlayモードではノード間(UDP 8472)の到達性だけが必要です。
  • 各EKSクラスターに別々のcluster.name/cluster.idを設定し、maxConnectedClustersは同じ値にします。ENIモードではcluster.idを128未満にしてください。extraConfig.allow-unsafe-policy-skb-usage=trueを設定しない限り、chartは128~255(maxConnectedClusters: 511では384~511)を拒否します(validate.yaml:160-168)。

15. ラボ ​

このレビューでは実クラスターでラボを実行していません。upstreamのソースとドキュメントに照らして確認しました。使い捨てクラスターでのみ実行してください。

ラボ1: 2クラスターのCluster Mesh ​

前提条件: ノード間通信可能な使い捨てクラスターが2つ(同じDocker host上でnetworking.podSubnet/serviceSubnetを変え、disableDefaultCNI: trueにしたkindクラスター2つ、またはpeeringしたVPC内のEKSクラスター2つ)、Helm 3、Cilium CLI 0.20.1、$CLUSTER1/$CLUSTER2 context。

  1. 各クラスターにCilium 1.20.2をインストールします。cluster.name、cluster.idをそれぞれ異なる値にし、Pod CIDRが重複しないようにします(cluster-poolのリストも異なる値にします)。
  2. CAをコピーします: kubectl --context $CLUSTER1 get secret -n kube-system cilium-ca -o yaml | kubectl --context $CLUSTER2 create -f -。
  3. 10.4節のvaluesファイルを適用します。ロードバランサーがないkindではservice.type: NodePortを使い、clustermesh.config.clusters.<name>.ipsにnode IPをport 32379とともに指定します。
  4. cilium clustermesh status --context $CLUSTER1 --waitを実行し、続けてcilium connectivity test --context $CLUSTER1 --multi-cluster $CLUSTER2を実行します。

確認: cilium clustermesh statusでclustermesh-apiserverがready、リモートクラスターが接続済みと表示されること。kubectl exec -n kube-system ds/cilium -c cilium-agent -- cilium-dbg status --all-clustersで、リモートクラスターがcluster IDとともにreadyと表示され、synchronization statusがすべてtrueであること。cilium-dbg node listにリモートノードが含まれること。

後片付け: 両クラスターでhelm uninstall cilium -n kube-systemを実行するか、使い捨てクラスターを削除します。接続に失敗した場合のロールバック: clusters.yamlから該当entryを削除し、同じchartバージョンで再度helm upgradeします。

ラボ2: Global Service、shared、アフィニティ ​

前提条件: ラボ1を完了していること。

  1. 両クラスターで同じnamespaceを作成し、DeploymentとService rebel-baseを配置します。service.cilium.io/global: "true"を設定し、Podは自身のクラスター名を応答として返すようにします。
  2. クラスター1のclient Podからcurlを繰り返し、両クラスターから応答が返ることを確認します。
  3. クラスター1のServiceにservice.cilium.io/affinity=localを付けて再試行します。クラスター1からのみ応答されることを確認します。ローカルbackendを0にスケールし、クラスター2へfailoverすることを確認します。
  4. クラスター2でservice.cilium.io/shared: "false"を設定し、クラスター1からクラスター2のbackendが見えなくなる一方、クラスター2からクラスター1には引き続き到達できることを確認します。

確認: agent内のcilium-dbg service list --clustermesh-affinityに優先backendが表示されること。cilium-dbg bpf lb listにリモートbackendアドレスが表示されること。

後片付け: 両クラスターでnamespaceを削除します。

ラボ3: MCS-API ​

前提条件: ラボ1を完了し、clustermesh.mcsapi.enabled=trueおよびcorednsAutoConfigure.enabled=trueを設定していること(手動設定の場合はCoreDNSを再起動)。

  1. 両クラスターでnamespaceとServiceを作成し、両方で同名のServiceExportを作成します。
  2. Podからrebel-base.<namespace>.svc.clusterset.localを名前解決し、curlします。
  3. exportするportをクラスター間で変え、kubectl get serviceexport -o yamlで競合conditionを確認します。

確認: 両クラスターにServiceImportがあり、derived-<hash>という派生Serviceが作成されること。DNS名が解決されること。

後片付け: ServiceExport、Service、namespaceを削除します。

ラボ4: ドリフト検出を使ったアップグレード訓練 ​

前提条件: valuesファイルからインストールした1.19.8の使い捨てクラスターと、Prometheus metrics endpoint(またはcilium-dbg metrics list)へ到達できること。

  1. valuesを保存します: helm get values cilium -n kube-system -o yaml > old-values.yaml。
  2. 1.20.2向けpre-flight chartを実行してチェックの成功を確認し、その後削除します。
  3. --version 1.20.2 -f old-values.yaml --set upgradeCompatibility=1.19を指定してupgradeします。
  4. agent再起動が必要なConfigMapキーをcilium config set --restart=false <key> <value>で変更し、ドリフトメトリクスを読み取ります: kubectl -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg metrics list | grep drift_checker_config_delta。
  5. ロールバックします: helm history cilium -n kube-systemでrevisionを確認してから、helm rollback cilium <REVISION> -n kube-systemを実行します。

確認: 手順4の後にcilium_drift_checker_config_deltaが0以外となり、agent再起動後に0へ戻ること。アップグレード後とロールバック後の両方でcilium statusが正常であること。

後片付け: 使い捨てクラスターを削除します。注意: このラボはロールバック手順を試します。1.20固有の機能を使ったクラスターでは実行しないでください。

ラボ5: ノードごとのCiliumNodeConfig上書き ​

前提条件: 2ノード以上がある任意のCilium 1.20.2クラスター。

  1. 1つのノードにラベルを付けます: kubectl label node <node> io.cilium.test-override=true。
  2. kube-systemに、そのラベルをselectorに指定したCiliumNodeConfigを適用します。debug: "true"など影響の小さいdefaultsキーを使います。
  3. ラベル付きノードとラベルなしノードの両方でagent Podを削除します。

確認: 再作成されたラベル付きノードのagentでは有効設定(cilium-dbg config)にoverrideが現れ、ラベルなしノードでは現れないこと。

後片付け: CiliumNodeConfigを削除し、ラベルを外してagent Podをもう一度再作成します。

バージョン差分 ​

領域1.181.191.201.21 pre.3
最小カーネル5.105.105.105.10(LLVM 21.1)
Gateway API CRD1.3.01.41.6.11.6.1
Helm OCI chartなしありあり(推奨)あり
MCS-APIベータベータ(v1alpha1、CRD自動インストール)安定版(v1beta1)v1beta1
Cluster Meshポリシーのデフォルト全クラスターローカルのみローカルのみ、cluster-mesh entityローカルのみ
authModeデフォルトlegacymigrationmigrationcluster(およびcluster-strict)
KVStoreMeshenabledが非推奨デフォルトで有効デフォルトで有効常時有効
相互認証ありデフォルトで無効非推奨削除
Kafka L7/proxylib非推奨Kafka非推奨削除削除
BGPv1非推奨削除--
マルチプールIPAMベータ安定版cluster-poolから移行可能Azure IPAMがmulti-poolへ移行
Double Writeベータベータベータベータ、migrate-identityは非推奨
configDriftDetectionバックポートバックポート標準搭載同じ
ENI masqueradeのデフォルトIPv4をfalseに変更falsefalseIPv6 masqueradeは無効

トラブルシューティング ​

症状確認項目
リモートクラスターが接続しないcilium clustermesh status --wait。kubectl exec -n kube-system ds/cilium -c cilium-agent -- cilium-dbg troubleshoot clustermesh [cluster...]でDNS、接続性、TLS、etcd認可などを確認。KVStoreMesh使用時はkubectl exec -n kube-system deploy/clustermesh-apiserver -c kvstoremesh -- clustermesh-apiserver kvstoremesh-dbg troubleshootも確認
リモートごとの状態cilium-dbg status --all-clustersでnode、endpoint、identity、Service、MCS-API export、再接続、has-quorum、cluster-id、kvstoremesh、同期状態を確認。... kvstoremesh-dbg status --verboseも確認
ログagent: New remote cluster configuration、Connection to remote cluster established、Unable to establish etcd connection to remote cluster。kubectl logs -n kube-system deployment/clustermesh-apiserver -c apiserverも確認
TLSエラーCAの違い(cilium-caをコピー)、証明書期限切れ(helm方式では1年後)、authModeに合わないCNを確認。Secret cilium-clustermeshとcilium-kvstoremeshも確認
*.mesh.cilium.ioの名前解決hostAliasesでcluster1.mesh.cilium.ioをLB IPに対応付け。KVStoreMeshなしではDaemonSet、KVStoreMeshありではclustermesh-apiserver Deploymentに設定
ポートsecurity groupでTCP 2379を参照またはprivate CIDRによって許可する必要があります
クラスター間通信が拒否されるcilium-dbg identity list(ラベルio.cilium.k8s.policy.cluster)、cilium-dbg bpf ipcache list、cilium-dbg service list、cilium-health statusを確認。1.19以降のローカルクラスター限定ポリシーと、両namespaceがglobalであることにも注意
CIDR重複またはID重複cilium-dbg node listに重複したnode rangeが表示されます。修正するにはIPの再割り当てとワークロード再起動が必要
古いクラスターから1.20へのアップグレードが止まるCiliumNodeConfig v2alpha1 CRDの不具合を避けるため1.20.2以降を使用
設定変更が反映されないcilium_drift_checker_config_delta > 0ならagentを再起動

検証範囲と参照資料 ​

今回のレビューでは実クラスター上でラボを実行していません。以下のタグのupstreamソースとドキュメントで確認しました。確認できなかった事項は、断定せずにここへ記載しています。

  • Cilium 1.21でBPF masqueradingがデフォルト有効になるか。pre.2のリリースノートには有効化するとありますが、pre.3ツリーのdaemonデフォルトはfalse、chartのbpf.masqueradeデフォルトもfalseで、upgrade-next.incの「Changed Options」節は空です。
  • WireGuard/IPsecとCluster Meshの正確な注意点は再確認していません。
  • EKSのchaining modeの制約、EKS管理下のkube-proxy add-onを削除する正確なコマンド、Amazon Linux 2023が名前付きでサポート対象かどうか。
  • 1.17.9-0と1.18.3-0より新しいAWS保守Ciliumビルドのバージョン。
  • bpf.tproxyとENI IPv6の成熟度。引用した「ベータ」以上の確認はしていません。
  • 1.19.0のリリース日、1.17の正確なKubernetesテストマトリクス。
  • MCS-APIの「安定版」という表記はv1.20.0のリリース本文に基づきます。ソースで確認したのはベータバナーの削除とv1beta1 CRDです。
  • Double Writeのメトリクス名はupstreamのupgradeページとコードが異なります(8.3節)。v1.20.2のコードに従いました。
  • chartのkubeVersionデフォルトはチャート制約であり、テスト済みKubernetesバージョン範囲ではありません。

参照資料:

クイズ ​

Part 13のクイズで理解度を確認してください。

ドキュメントに質問する

Enter で送信、Shift+Enter で改行します。