深色模式
Karmada 多集群编排
面向需要在多套集群间统一下发应用、做跨集群调度与容灾的平台工程师。覆盖 Karmada 架构、下发策略、调度与排障。
适用版本与前提
- Karmada:1.x(本文以 1.9+ 常见形态描述,
[版本相关]) - Kubernetes:v1.28+(成员集群)
- 前提:已有一个 Karmada 控制面 + ≥2 个成员集群注册
背景与问题
单集群事故域过大、地域合规、容量天花板,都会逼你走向多集群。但"多集群"之后立刻出现新问题:
- 同一个 Deployment 要在 N 个集群里各发一份,如何保证一致?
- 不同集群需要不同的副本数、镜像、资源限制,如何差异化?
- 集群故障时,如何把流量与负载迁走?
Karmada 的定位是不侵入成员集群 API 的编排层:它复用 K8s 原生 API(Deployment/Service/ConfigMap 原样下发),在控制面做"Propagation(传播)+ Scheduling(调度)+ Override(差异化)",成员集群仍由各自的 kube-controller-manager 驱动 Pod。
核心概念
| 概念 | 作用 |
|---|---|
ResourceTemplate | 你提交的原生 K8s 资源(Deployment 等),Karmada 不改写其 schema |
PropagationPolicy | 声明"这个资源要去哪些集群 / 按什么规则分发" |
OverridePolicy | 声明"到某个集群后要改哪些字段"(副本、镜像、资源限制) |
Cluster 对象 | 成员集群的注册抽象,含同步模式(Push/Pull)、状态、taint |
ResourceBinding | 内部产物,记录资源与集群的绑定关系(排障常用) |
Work | 下发到成员集群执行命名空间的实际资源载体 |
两种同步模式:
- Push:Karmada 控制面直连成员集群 kube-apiserver(集群需可达)。
- Pull:成员集群跑
karmada-agent主动拉(适合成员集群在 NAT 后 / 边缘)。[版本相关]
架构与原理
关键点:Karmada 不参与成员集群内的 Pod 调度,它只决定"副本数如何分到各集群"。集群内调度仍由该集群 kube-scheduler 负责。这个分层让成员集群在断连后仍能独立运行——这是容错上的重要设计。
生产实践
注册成员集群(Push 模式)
bash
# 注册集群(需提供成员集群 kubeconfig)
karmadactl join member-cluster-a --cluster-kubeconfig=/path/to/a.kubeconfig
# 查看注册结果与同步模式
kubectl get clusters
kubectl get cluster member-cluster-a -o yaml | grep -A3 syncMode1
2
3
4
5
6
2
3
4
5
6
按标签分发 + 差异化副本
yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: web-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: web
placement:
clusterAffinity:
labelSelector:
matchLabels:
region: cn-hangzhou
spreadConstraints:
- spreadByField: cluster
maxGroups: 3
minGroups: 2
replicaScheduling:
replicaSchedulingType: Divided
replicaDivisionPreference: Weighted
weightPreference:
staticWeightList:
- targetCluster:
clusterNames: [member-cluster-a]
weight: 3
- targetCluster:
clusterNames: [member-cluster-b]
weight: 11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
yaml
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
name: web-override
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: web
overrideRules:
- targetCluster:
clusterNames: [member-cluster-b]
overriders:
plaintext:
- path: /spec/template/spec/containers/0/image
operator: replace
value: registry.example.com/web:v1.2.3-canary
- path: /spec/replicas
operator: replace
value: 21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
建议
灰度场景优先用
OverridePolicy改镜像 tag,而不是复制多份 Deployment。这样"基线版本"只有一份,回滚时只改 Override 即可。
用 Cluster Taint 做故障隔离
成员集群异常时,给 Cluster 打 taint 阻止新调度,避免继续往故障集群下发:
bash
kubectl taint clusters member-cluster-b not-ready=:NoSchedule
kubectl describe cluster member-cluster-b | grep -A5 Taints1
2
2
验证
bash
# 1) 资源是否被正确传播
kubectl get resourcebindings -A
kubectl get works -A
# 2) 各集群副本分配是否符合预期
kubectl get rb <name> -o jsonpath='{.spec.clusters[*].name}{"\n"}'
kubectl get rb <name> -o jsonpath='{.spec.clusters[*].replicas}{"\n"}'
# 3) 成员集群实际是否落盘(一定要回成员集群确认)
kubectl --context=member-cluster-a get deploy web -n default1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
回滚与清理
bash
# 撤销分发:删除 PropagationPolicy,资源仍在 karmada-apiserver,但不再下发
kubectl delete propagationpolicy web-propagation
# 彻底清理:删除资源模板
kubectl delete deployment web
# 摘除集群(会移除该集群上的 Work)[危险]
kubectl delete cluster member-cluster-b1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
生产危险
kubectl delete cluster会触发该成员集群上由 Karmada 下发的所有 Work 被清理。执行前确认该集群已不再承载关键流量,并先kubectl get works -A核对影响面。
故障排查
| 现象 | 定位 |
|---|---|
| 资源没下发到任何集群 | kubectl get rb 看 spec.clusters 是否为空;检查 PropagationPolicy 的 resourceSelectors 是否匹配 |
| 部分集群没收到 | 检查 clusterAffinity 标签、集群 taint、集群 Ready 状态 |
| 副本分配不均 | 检查 replicaScheduling 类型(Divided/Aggregated)与权重 |
| 差异化没生效 | 检查 OverridePolicy 的 targetCluster 与 path 是否命中;JSON Patch 路径越界会静默失败 |
| 状态回传缺失 | Pull 模式检查 karmada-agent 日志与网络连通性 |
bash
kubectl logs -n karmada-system deployment/karmada-controller-manager
kubectl logs -n karmada-system deployment/karmada-scheduler
kubectl describe rb <name>1
2
3
2
3
安全与合规
karmada-apiserver 持有所有成员集群的凭证(Push 模式),是高价值目标:
- 控制面 RBAC 严格收敛,
Cluster对象的写权限等同"接管集群"。 - 成员集群凭证用最小权限 ServiceAccount,不要复用
cluster-admin。 - 审计
OverridePolicy变更:它能改镜像与资源限制,是供应链攻击面。
替代方案与权衡
| 方案 | 特点 | 适用 |
|---|---|---|
| Karmada | 不侵入成员集群、原生 API、跨集群调度强 | 需要统一分发 + 差异化 + 容灾 |
| OCM(open-cluster-management) | 更强的插件/Addon 体系,偏管理与策略 | 偏集群生命周期与治理 |
| KubeFed | 已归档/不再活跃 | 不建议新项目 |
| Cluster API | 管"集群创建",不管"应用分发" | 与 Karmada 互补而非替代 |
版本相关
Karmada 的 API 组为
policy.karmada.io/v1alpha1,字段随版本演进较快(如spreadConstraints、replicaScheduling细节)。落地前用kubectl explain核对目标版本字段。
参考资料
- Karmada 官方文档,访问日期:2026-10-09。
- Karmada GitHub 仓库,访问日期:2026-10-09。
- Karmada 核心概念,访问日期:2026-10-09。
- CNCF 多集群相关项目,访问日期:2026-10-09。