概述
当你的业务规模增长到单集群无法承载时,多集群就成为必然选择。可能的原因包括:单集群节点上限(5000 节点)、多地域部署、混合云策略、故障隔离、合规要求。但多集群带来的管理复杂度是指数级增长——应用如何跨集群部署、服务如何跨集群发现、配置如何同步、故障如何切换。
本文逐步梳理多集群的架构模式、主流管理工具对比,以及跨集群服务发现、CI/CD、容灾切换的实践方案。
本文基于 Kubernetes v1.30。多集群管理领域仍在快速演进,部分工具的成熟度需持续关注。
为什么需要多集群
单集群的瓶颈
| 瓶颈 | 说明 |
|---|---|
| 规模上限 | K8s 单集群推荐上限 5000 节点、15 万 Pod、30 万容器 |
| 故障域 | 单集群 etcd 故障影响所有业务 |
| 升级风险 | 集群升级可能影响所有业务 |
| 多租户隔离 | 软隔离不如硬隔离 |
| 地域延迟 | 跨地域不能用一个集群 |
| 合规要求 | 数据不能跨地域/跨境 |
多集群的典型场景
| 场景 | 架构 | 目标 |
|---|---|---|
| 多地域容灾 | 每地域一个集群,DNS 全局负载均衡 | RTO < 5min |
| 混合云 | 云上 + 自建机房 | 弹性 + 合规 |
| 开发/测试/生产隔离 | 每环境一个集群 | 安全隔离 |
| 多租户硬隔离 | 每租户独立集群 | 安全合规 |
| 边缘计算 | 中心集群 + 边缘集群 | 低延迟 |
多集群架构模式
模式一:Hub-Spoke(中心辐射)
┌─────────┐
│ Hub │ ← 管理集群
│ Cluster │
└────┬────┘
┌────────┼────────┐
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│Spoke1│ │Spoke2│ │Spoke3│ ← 工作集群
└──────┘ └──────┘ └──────┘
中心集群负责管理配置、分发应用、收集状态。工作集群只运行业务负载。这是最常见的多集群管理模式。
优势:管理集中、配置一致、操作简便。 劣势:Hub 是单点;Hub 故障不影响已有工作负载,但影响新部署。
模式二:联邦(Federation)
┌─────────────────────────────────────┐
│ Federation Control Plane │
│ (统一 API,跨集群资源调度) │
└───┬──────────┬──────────┬──────────┘
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│Clstr1│ │Clstr2│ │Clstr3│
└──────┘ └──────┘ └──────┘
联邦控制平面提供统一 API,用户在联邦层创建资源,自动分发到各集群。
优势:统一 API、自动调度、跨集群服务发现。 劣势:架构复杂、控制平面自身需要高可用。
模式三:网格(Mesh)
┌──────┐ ┌──────┐
│Clstr1│◄───────►│Clstr2│
└──┬───┘ └───┬──┘
│ │
▼ ▼
┌──────┐ ┌──────┐
│Clstr3│◄───────►│Clstr4│
└──────┘ └──────┘
各集群对等,通过服务网格互联。适合对等的多地域部署。
优势:无中心节点、故障隔离好。 劣势:管理复杂、一致性难保证。
主流多集群管理工具对比
工具总览
| 工具 | 项目状态 | 核心能力 | 成熟度 | CNCF 状态 |
|---|---|---|---|---|
| KubeFed | 已停止维护 | 联邦 API | 停滞 | 已归档 |
| Cluster API | 活跃 | 集群生命周期 | 高 | 孵化 |
| Karmada | 活跃 | 多集群编排 | 高 | 孵化 |
| OCM (Open Cluster Management) | 活跃 | 集群管理 | 中 | 孵化 |
| Argo CD + ApplicationSet | 活跃 | GitOps 多集群部署 | 高 | 毕业 |
| Submariner | 活跃 | 跨集群网络 | 中 | 孵化 |
KubeFed(已停止维护)
KubeFed 是最早的 K8s 多集群联邦项目,但已于 2023 年正式归档停止维护。
不推荐新项目使用 KubeFed。参考 KubeFed 归档公告
Cluster API
Cluster API(CAPI)专注于集群生命周期管理——创建、升级、销毁集群,不涉及跨集群应用部署。
核心概念:
| 概念 | 说明 |
|---|---|
Cluster | 一个 K8s 集群的声明式定义 |
Machine | 一个节点(Control Plane 或 Worker) |
MachineDeployment | 类似 Deployment,管理一组 Machine |
MachineSet | 类似 ReplicaSet |
MachineHealthCheck | 节点健康检查和自动修复 |
InfrastructureProvider | 基础设施提供者(AWS/GCP/Azure/vSphere) |
示例:声明式创建集群:
# cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: my-cluster
namespace: default
spec:
clusterNetwork:
pods:
cidrBlocks: ["10.244.0.0/16"]
services:
cidrBlocks: ["10.96.0.0/12"]
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
name: my-cluster-control-plane
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSCluster
name: my-cluster
---
# control-plane.yaml
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
name: my-cluster-control-plane
spec:
replicas: 3
version: v1.30.0
machineTemplate:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: my-cluster-control-plane
kubeadmConfigSpec:
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: aws
clusterConfiguration:
apiServer:
extraArgs:
cloud-provider: aws
---
# worker-nodes.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: my-cluster-md-0
spec:
clusterName: my-cluster
replicas: 3
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: my-cluster
template:
spec:
clusterName: my-cluster
version: v1.30.0
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: my-cluster-md-0
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: my-cluster-md-0
优势:声明式集群生命周期管理、支持多基础设施、自动节点修复。 劣势:只管集群创建不管应用部署、学习曲线陡峭。
Karmada
Karmada(Kubernetes Management Daemon)是华为开源的多集群编排引擎,CNCF 孵化项目。
核心能力:
- 跨集群应用分发(PropagationPolicy)
- 跨集群服务发现
- 故障转移
- 资源重调度
架构:
Karmada Control Plane
├── karmada-apiserver (统一 API 入口)
├── karmada-controller-manager
├── karmada-scheduler (跨集群调度)
└── karmada-webhook
Member Clusters
├── cluster-1 (push mode)
├── cluster-2 (push mode)
└── cluster-3 (pull mode)
应用分发示例:
# 定义应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 10
selector:
matchLabels:
app: myapp
template:
spec:
containers:
- name: app
image: myapp:v1
---
# 定义分发策略
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: myapp-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: myapp
placement:
clusterAffinity:
clusterNames:
- cluster-beijing
- cluster-shanghai
replicaScheduling:
replicaSchedulingType: Divided
replicaDivisionPreference: Weighted
weightPreference:
staticWeightList:
- targetCluster:
clusterNames: [cluster-beijing]
weight: 7
- targetCluster:
clusterNames: [cluster-shanghai]
weight: 3
故障转移:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: myapp-failover
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: myapp
placement:
clusterAffinity:
clusterNames:
- cluster-beijing
- cluster-shanghai
spreadConstraints:
- spreadByLabel: failure-domain.beta.kubernetes.io/region
maxGroups: 2
minGroups: 1
failover:
application:
decisionConditions:
maxUnavailable: 50%
gracePeriodSeconds: 300
purgeMode: Graceful
优势:功能完善、支持故障转移、中文文档好。 劣势:社区相对较小、控制平面自身需高可用。
OCM(Open Cluster Management)
OCM 是红帽开源的多集群管理框架。
核心概念:
| 概念 | 说明 |
|---|---|
ManagedCluster | 被管理的集群 |
ManagedClusterSet | 集群集合 |
Placement | 集群选择策略 |
ManifestWork | 分发到集群的工作负载 |
Subscription | GitOps 订阅 |
Channel | 订阅源 |
优势:与 OpenShift 集成好、模块化设计。 劣势:社区较小、文档以英文为主。
Argo CD ApplicationSet
Argo CD 本身是 GitOps 工具,通过 ApplicationSet 实现多集群部署:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-multi-cluster
spec:
generators:
- list:
elements:
- cluster: cluster-beijing
url: https://cluster-beijing-api:6443
- cluster: cluster-shanghai
url: https://cluster-shanghai-api:6443
template:
metadata:
name: '{{cluster}}-myapp'
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp-deploy
targetRevision: HEAD
path: overlays/{{cluster}}
destination:
server: '{{url}}'
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
优势:与 Argo CD 无缝集成、GitOps 模式、成熟稳定。 劣势:只管应用部署不管集群生命周期、无跨集群服务发现。
工具选型建议
| 需求 | 推荐工具 |
|---|---|
| 集群创建/升级/销毁 | Cluster API |
| 跨集群应用分发 + 故障转移 | Karmada |
| GitOps 多集群部署 | Argo CD + ApplicationSet |
| 跨集群网络连通 | Submariner |
| 红帽/OpenShift 生态 | OCM |
| 简单多集群部署(<10集群) | Argo CD + ApplicationSet |
| 复杂多集群编排(>10集群) | Karmada + Cluster API |
跨集群服务发现
方案一:全局 DNS
最简单的跨集群服务发现方式,利用 CoreDNS 的多集群插件:
# 集群 A 中的服务
svc-a.namespace-a.svc.cluster-beijing.cluster.local
# 集群 B 中的服务
svc-b.namespace-b.svc.cluster-shanghai.cluster.local
通过全局 DNS 解析,各集群可以互相访问 Service。
方案二:Service Mesh 多集群
Istio 支持多集群 Service Mesh,提供跨集群的负载均衡和故障转移:
# ServiceExport:导出 Service 到网格
apiVersion: networking.istio.io/v1beta1
kind: ServiceExport
metadata:
name: myapp
namespace: production
spec:
hosts:
- "myapp.production.svc.cluster.local"
ports:
- number: 8080
name: http
protocol: HTTP
# ServiceEntry:在其他集群导入
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: remote-myapp
spec:
hosts:
- "myapp.production.svc.cluster.local"
location: MESH_INTERNAL
ports:
- number: 8080
name: http
protocol: HTTP
resolution: DNS
endpoints:
- address: cluster-beijing-api.internal
ports:
http: 15443
方案三:Submariner
Submariner 通过 IP 隧道连接各集群 Pod 网络:
# 安装 Submariner
subctl deploy-broker --kubeconfig cluster-a.kubeconfig
# 加入集群
subctl join broker-info.subm --clusterid cluster-a --kubeconfig cluster-a.kubeconfig
subctl join broker-info.subm --clusterid cluster-b --kubeconfig cluster-b.kubeconfig
# 验证连通性
subctl show all --kubeconfig cluster-a.kubeconfig
方案对比
| 方案 | 复杂度 | 功能 | 延迟 | 适用场景 |
|---|---|---|---|---|
| 全局 DNS | 低 | 服务发现 | 高(跨集群) | 简单场景 |
| Service Mesh | 高 | 发现 + 负载均衡 + 策略 | 中 | 高级流量管理 |
| Submariner | 中 | Pod 网络直连 | 低 | 需要 Pod 直连 |
统一 CI/CD
GitOps 多集群部署
# 目录结构
# ├── base/ # 基础配置
# │ ├── deployment.yaml
# │ ├── service.yaml
# │ └── kustomization.yaml
# ├── overlays/ # 各集群覆盖配置
# │ ├── cluster-beijing/
# │ │ ├── deployment-patch.yaml
# │ │ └── kustomization.yaml
# │ └── cluster-shanghai/
# │ ├── deployment-patch.yaml
# │ └── kustomization.yaml
# └── argocd-apps/ # Argo CD Application
# └── appset.yaml
# Argo CD ApplicationSet
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp
spec:
generators:
- git:
repoURL: https://github.com/myorg/myapp-deploy
revision: HEAD
directories:
- path: overlays/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp-deploy
targetRevision: HEAD
path: '{{path}}'
destination:
server: '{{cluster.url}}'
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
配置差异管理
各集群的配置差异通过 Kustomize patches 管理:
# overlays/cluster-beijing/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: deployment-patch.yaml
configMapGenerator:
- name: app-config
behavior: merge
literals:
- REGION=beijing
- DB_HOST=pg-beijing.internal
# overlays/cluster-beijing/deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 5 # 北京集群5副本
template:
spec:
nodeSelector:
topology.kubernetes.io/region: cn-north-1
容灾切换
多地域容灾架构
┌─────────────────────┐
│ Global DNS / GSLB │
│ (Route53 / CloudDNS)│
└──────┬────────┬──────┘
│ │
┌─────────┘ └─────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 北京集群 │ │ 上海集群 │
│ (Active) │ │ (Standby) │
│ 权重: 100 │ │ 权重: 0 │
└──────────────┘ └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 北京 DB │ ──同步──→ │ 上海 DB │
│ (Primary) │ │ (Replica) │
└──────────────┘ └──────────────┘
RTO/RPO 设计
| 指标 | 含义 | 目标 |
|---|---|---|
| RTO | Recovery Time Objective,恢复时间目标 | < 5min |
| RPO | Recovery Point Objective,数据丢失目标 | < 1min |
故障切换流程
# 1. 检测故障(Prometheus/Blackbox Exporter)
# 北京集群连续3次健康检查失败
# 2. DNS 切换(Route53 Health Check 自动切换)
aws route53 change-resource-record-sets \
--hosted-zone-id Z123ABC \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "CNAME",
"TTL": 60,
"ResourceRecords": [{"Value": "shanghai-lb.example.com"}]
}
}]
}'
# 3. 提升备集群数据库为主
# 在上海集群执行 DB failover
# 4. 在备集群扩容
kubectl scale deployment myapp -n production --replicas=10 --kubeconfig=shanghai.kubeconfig
# 5. 验证服务
curl -f https://api.example.com/health || echo "FAIL"
自动故障切换
使用 Karmada 的故障转移功能实现自动切换:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: myapp-failover-policy
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: myapp
placement:
clusterAffinity:
clusterNames:
- cluster-beijing
- cluster-shanghai
failover:
application:
decisionConditions:
maxUnavailable: 50%
gracePeriodSeconds: 180
purgeMode: Graceful
数据同步策略
| 数据类型 | 同步方案 | RPO |
|---|---|---|
| 数据库 | 主从复制 / CDC | 秒级 |
| 对象存储 | 跨区域复制 | 秒级 |
| 配置 | GitOps 同步 | 分钟级 |
| 缓存 | 各集群独立 | 不同步(可丢失) |
恢复演练
演练流程
1. 在非生产环境模拟主集群故障
2. 验证 DNS 切换时间
3. 验证备集群数据库提升时间
4. 验证应用启动时间
5. 验证服务恢复时间
6. 验证数据一致性
7. 验证回切流程
混沌工程
# 使用 Chaos Mesh 模拟集群故障
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: kill-api-pods
namespace: production
spec:
action: pod-kill
mode: all
selector:
namespaces:
- production
labelSelectors:
app: api-server
scheduler:
cron: "@every 1h"
演练检查清单
- DNS 切换在 60 秒内完成
- 备集群应用在 3 分钟内启动
- 数据库故障转移在 1 分钟内完成
- RTO < 5 分钟
- RPO < 1 分钟
- 无数据丢失
- 回切流程正常
- 监控告警正常触发
多集群可观测性
统一监控架构
各集群 Prometheus → Thanos / VictoriaMetrics → Grafana
# Thanos Receive 配置
apiVersion: monitoring.thanos.io/v1alpha1
kind: ThanosReceive
metadata:
name: thanos-receive
spec:
replicas: 3
tsdbVolume:
storageClass: fast-ssd
size: 100Gi
tsdbRetention: 15d
configReloader:
enabled: true
跨集群日志
各集群 Fluentbit → 中央 Loki / Elasticsearch
多集群监控面板
# Grafana 数据源配置
apiVersion: 1
datasources:
- name: Thanos
type: prometheus
url: http://thanos-query.monitoring:9090
isDefault: true
jsonData:
timeInterval: "30s"
关键多集群监控指标:
| 指标 | 含义 |
|---|---|
| 各集群 Pod 总数 | 集群规模 |
| 各集群节点资源利用率 | 容量规划 |
| 跨集群服务延迟 | 容灾切换判断 |
| 各集群 Pending Pod | 扩容信号 |
| Argo CD 同步状态 | 部署健康度 |
总结
多集群管理是 K8s 生态中最复杂的领域之一,核心要点:
- 不要过早引入多集群:单集群能承载就别上多集群。多集群的管理成本是单集群的 3-5 倍。
- 选型看需求:需要集群生命周期管理用 Cluster API,需要跨集群编排用 Karmada,需要 GitOps 部商用 Argo CD。
- GitOps 是部署标配:多集群环境下,手动部署不可持续。Argo CD + Kustomize 是经过验证的组合。
- 容灾需要演练:没有演练过的容灾方案等于没有容灾。每季度至少做一次完整的故障切换演练。
- 统一可观测性:多集群监控数据必须汇聚到一个平面,否则排障时在各集群间切换会浪费大量时间。
- 数据同步是关键:应用切换容易,数据同步难。数据库主从复制、对象存储跨区域复制需要提前规划。
- DNS 是第一道防线:全局 DNS 负载均衡是最简单的流量切换手段,TTL 设短一点(60 秒),切换更快。
多集群不是银弹,它用更高的复杂度换取更好的故障隔离和扩展性。在决定上多集群之前,先确认单集群真的已经不够用了。
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- KubeFed 归档公告 — GitHub 开源社区,参考了KubeFed 归档公告相关内容