← 返回上一頁
Kubernetes

Cilium Cluster Mesh 實戰:打造跨叢集 Kubernetes 網路互聯與全域負載均衡

本頁目錄

前言

隨著業務規模的增長,單一 Kubernetes 叢集往往無法滿足高可用、跨地域部署或資源隔離的需求。Cilium 的 Cluster Mesh 功能提供了一種優雅的多叢集解決方案,讓多個 K8s 叢集之間能夠實現 Pod IP 直接路由、全域服務發現與跨叢集網路策略。本篇將從概念、架構到實作完整介紹 Cilium Cluster Mesh。

Cluster Mesh 核心能力

  • 跨叢集 Pod IP 路由:透過隧道或直接路由方式,在多個叢集間進行 Pod 互聯,不需要額外的閘道器或代理
  • 標準 Kubernetes 服務發現:使用 K8s 原生機制實現跨叢集服務發現
  • 跨叢集網路策略:支援 Kubernetes NetworkPolicy 和 CiliumNetworkPolicy CRD
  • 透明加密:自動加密叢集內及跨叢集的所有通訊流量

典型使用場景

高可用

在不同區域(regions)或可用區(availability zones)各跑一組叢集,部署相同服務副本。當某個叢集發生故障時,請求自動故障轉移到其他叢集,確保服務不中斷。

共享服務

密鑰管理、日誌收集、監控、DNS 等公共基礎服務可以集中在一個叢集,讓其他叢集共享存取,避免重複部署造成的資源浪費。

有狀態與無狀態服務分離

將無狀態服務(API Server、Web 前端等)和有狀態服務(MySQL、Elasticsearch、etcd 等)分別部署在不同叢集。無狀態叢集可以靈活擴縮、快速升級;有狀態叢集的複雜依賴和儲存遷移被隔離在少數叢集中。

架構解析

Cluster Mesh 的架構設計有幾個關鍵原則:

  • 每個 K8s 叢集維護自己的 etcd,叢集狀態不會混在一起
  • 每個叢集透過 clustermesh-apiserver Pod 對外暴露自己的配置資訊,其中包含一個 apiserver 容器(負責寫入資料)和一個 etcd 容器(作為 etcd 代理)
  • 其他叢集的 Cilium Agent 連接到這個 etcd 代理來監聽變化
  • 跨叢集存取永遠是唯讀的——這確保故障域不會跨叢集傳播

前置需求

  • 所有工作節點的 IP 位址必須唯一,且節點間 IP 可路由
  • 每個叢集必須分配唯一的 Pod CIDR
  • Cilium 必須使用 etcd 作為 KV 儲存
  • 叢集之間網路必須互通

所需工具:kubectl、Kind(用於實驗環境)、Helm、Cilium CLI

實驗環境搭建

建立兩個 Kind 叢集

c1 叢集設定:

# kind-config1.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  disableDefaultCNI: true
  podSubnet: "10.10.0.0/16"
  serviceSubnet: "10.11.0.0/16"

c2 叢集設定(注意 CIDR 不能重疊):

# kind-config2.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
networking:
  disableDefaultCNI: true
  podSubnet: "10.20.0.0/16"
  serviceSubnet: "10.21.0.0/16"
kind create cluster --config kind-config1.yaml --name c1
kind create cluster --config kind-config2.yaml --name c2

安裝 Cilium

每個叢集必須分配唯一的 cluster.id(範圍 1-255)和 cluster.name:

helm repo add cilium https://helm.cilium.io/

# c1 叢集
helm install --kube-context kind-c1 cilium cilium/cilium --version 1.11.4 \
  --namespace kube-system \
  --set ipam.mode=kubernetes \
  --set cluster.id=1 \
  --set cluster.name=cluster1

# c2 叢集
helm install --kube-context kind-c2 cilium cilium/cilium --version 1.11.4 \
  --namespace kube-system \
  --set ipam.mode=kubernetes \
  --set cluster.id=2 \
  --set cluster.name=cluster2

安裝 MetalLB(選用)

在非雲端環境中,需要 MetalLB 來提供 LoadBalancer IP。注意分配的 IP 範圍要和節點 IP 在同一網段:

helm repo add bitnami https://charts.bitnami.com/bitnami

# c1 叢集 - metallb-config1.yaml
helm install --kube-context kind-c1 metallb bitnami/metallb \
  --namespace kube-system -f metallb-config1.yaml

# c2 叢集 - metallb-config2.yaml
helm install --kube-context kind-c2 metallb bitnami/metallb \
  --namespace kube-system -f metallb-config2.yaml

啟用 Cluster Mesh

在 c1 叢集啟用並建立 CA 憑證

cilium clustermesh enable --create-ca --context kind-c1 --service-type LoadBalancer

將 CA 憑證同步到 c2 叢集

這一步很關鍵,兩個叢集必須共用同一組 CA 憑證才能建立 mTLS 連線:

# 匯出 c1 的 CA
kubectl get secret --context kind-c1 -n kube-system cilium-ca -o yaml > cilium-ca.yaml

# 匯入 c2
kubectl apply -f cilium-ca.yaml --context kind-c2

在 c2 叢集啟用 Cluster Mesh

cilium clustermesh enable --context kind-c2 --service-type LoadBalancer

連接兩個叢集

cilium clustermesh connect --context kind-c1 --destination-context kind-c2

驗證連線狀態:

cilium clustermesh status --context kind-c1
cilium clustermesh status --context kind-c2

全域負載均衡

要實現跨叢集的負載均衡,只需在 Service 上加入 annotation 宣告為全域服務:

apiVersion: v1
kind: Service
metadata:
  name: rebel-base
  annotations:
    io.cilium/global-service: "true"
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    name: rebel-base

條件是兩個叢集中的 Service 名稱和命名空間必須相同。部署後,從任一叢集存取該 Service,流量會自動分發到兩個叢集的後端 Pod。

停用全域共享

如果某個叢集的服務不想被其他叢集共享,可以設定:

kubectl annotate service rebel-base \
  io.cilium/shared-service="false" --overwrite --context kind-c1

這樣 c2 叢集就只能存取自己本地的 rebel-base Pod,而 c1 叢集仍然可以存取兩邊的 Pod。

跨叢集網路策略

Cilium 支援在 CiliumNetworkPolicy 中使用叢集標籤,實現精確的跨叢集存取控制。例如只允許 cluster1 中帶有 x-wing 標籤的 Pod 存取 cluster2 中帶有 rebel-base 標籤的 Pod:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "allow-cross-cluster"
spec:
  endpointSelector:
    matchLabels:
      name: x-wing
      io.cilium.k8s.policy.cluster: cluster1
  egress:
  - toEndpoints:
    - matchLabels:
        name: rebel-base
        io.cilium.k8s.policy.cluster: cluster2

注意:K8s 的網路策略不會自動同步到所有叢集,你需要在每個叢集都部署相同的策略。另外,別忘了放行 DNS 流量,否則透過 Service 名稱的存取會失敗。

踩坑紀錄

在啟用 Cluster Mesh 時可能遇到 clustermesh-apiserver 映像檔拉取失敗的問題,原因是映像檔名稱後面的 sha256 值對不上。解決方式是編輯 Deployment,移除映像檔版本後面的 sha256 值:

kubectl edit --context kind-c1 deployment -n kube-system clustermesh-apiserver

總結

Cilium Cluster Mesh 提供了一套完整的多叢集網路方案,核心優勢在於:

  • 基於 eBPF 的高效能資料平面
  • 叢集間故障域隔離(唯讀存取設計)
  • 全域負載均衡與服務共享的靈活控制
  • 跨叢集網路策略的精細管控

如果你的組織正在考慮多叢集架構,Cilium Cluster Mesh 是目前 CNI 層面最成熟的選擇之一。相較於 Istio 的多叢集方案,Cilium 的優勢在於它工作在更底層的網路層,效能開銷更低。

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料