Karmada 多 Kubernetes集群管理实战
一、技术背景
1.1 什么是 Kubernetes 多集群?
Kubernetes 多集群管理,并非简单地独立运维多个集群,而是通过专门的工具和策略,将它们作为统一的、协调的系统进行编排与控制。其核心目标是将多个 Kubernetes 集群抽象为一个逻辑上的整体,从而在可伸缩性、可靠性和灵活性等方面超越单集群的限制。
虽然多集群环境仍基于 Kubernetes 的核心组件(节点、Pod、API 服务器等),但其管理范围扩展到了多个控制平面,并常常引入跨集群协调组件(如全局负载均衡器、服务网格或像 Karmada 这样的多集群控制平面),以实现统一的应用分发、服务发现和策略执行。理解多集群的关键在于认识到其核心价值在于协调与整合,而非集群数量本身。
1.2 单集群VS多集群
尽管 Kubernetes 单集群本身具备强大的扩展能力,但无限扩展会遇到瓶颈并带来风险。主要体现在:
-
单点故障风险 (SPOF): 单个控制平面或关键基础设施的故障可能导致整个环境瘫痪。
-
扩展性上限: 单集群在节点数量、资源总量和 API 吞吐量上存在物理和逻辑限制。
-
隔离性挑战: 在单集群内实现严格的多租户、环境(开发/测试/生产)或应用隔离,往往复杂度高且效果有限。
这些限制,结合日益增长的业务需求,催生了向多集群架构演进的必要性。主要驱动因素可归纳为:
-
提升可靠性与可用性 (Reliability & Availability): 通过跨地域、跨可用区部署,分散风险,实现高可用 (HA) 和有效的灾难恢复 (DR)。单集群故障影响范围可控。
-
突破规模瓶颈 (Scalability): 通过横向增加集群数量,轻松超越单集群的资源和管理限制。
-
增强隔离性与安全性 (Isolation & Security): 为不同团队、应用或环境提供物理集群级别的强隔离,简化安全模型,满足合规要求。
-
优化地理分布与延迟 (Geo-distribution & Latency): 将应用部署在靠近用户的位置,降低访问延迟,提升用户体验,特别适用于全球化业务和边缘计算场景。
-
满足合规与数据主权 (Compliance & Data Sovereignty): 在特定地理区域部署集群,以满足 GDPR 等数据本地化法规要求。
-
灵活性与基础设施管理 (Flexibility & Lifecycle): 支持混合云/多云策略,避免厂商锁定;简化 Kubernetes 版本升级、组件变更等生命周期管理,可在隔离环境中先行验证。
1.3 多集群价值
采用 Kubernetes 多集群战略的核心目标是获得更高的可靠性、可伸缩性、灵活性、安全性,并优化资源利用率。
更重要的是,通过统一的多集群管理平台(如 Karmada),可以实现以下战略优势:
-
简化运维 (Simplified Operations): 通过单一入口点或 API 管理所有集群,实现跨集群的统一部署、配置更新、策略分发和监控,减少重复劳动和人为错误。
-
提升一致性与治理 (Consistency & Governance): 确保跨集群的配置、安全策略、访问控制保持一致,简化合规审计和成本管理。
-
改善开发者体验 (Developer Experience): 为开发者提供一致的应用部署接口,屏蔽底层集群的复杂性,加速应用交付。
1.4 集群中心 vs. 应用中心
-
集群中心 (Cluster-Centric):
-
理念: 将多个物理集群视为一个大型虚拟集群。目标是抽象底层差异,提供统一视图和管理接口(类似 Kubernetes Federation V1 的思路)。
-
优/劣: 对开发者友好,体验一致;但对跨集群网络要求高,集群间耦合度高,运维复杂性增加。
-
-
应用中心 (Application-Centric):
-
理念: 每个集群相对独立运行。应用被设计为可在集群间部署或迁移。管理层(如 Dashboard 或 Karmada)提供统一视图,但集群实体保持独立。
-
优/劣: 灵活性高,控制粒度细,易于实现强隔离和灾难恢复,适合异构环境;但可能需要应用具备一定的“集群感知”能力,跨集群通信可能需要额外组件(如服务网格)。 Karmada 更倾向于这种模式。
-
1.5 工作负载模式复制 vs. 服务拆分
-
复制模型 (Replicated):
-
模式: 将应用的相同副本部署到多个目标集群。
-
优/劣: 天然支持 HA/DR(配合全局负载均衡),部署相对简单;但资源消耗高,有状态应用需处理跨集群数据同步。
-
适用: 无状态应用高可用、灾难恢复、全局扩展。
-
-
服务拆分模型 (Split-by-Service):
-
模式: 将应用的不同服务/组件拆分部署到不同集群。
-
优/劣: 强服务隔离,满足特定合规,可独立扩展优化资源;但架构复杂,需处理跨集群服务发现、通信、数据一致性,运维开销增大。
-
适用: 微服务架构、有强隔离/合规需求、需要差异化资源管理的应用。
-
二、karmada 介绍
2.1 简介
Karmada(Kubernetes Armada)是一个 Kubernetes 管理系统,使您能够在多个 Kubernetes 集群和云中运行云原生应用程序,而无需更改应用程序。通过使用 Kubernetes 原生 API 并提供先进的调度功能,Karmada 实现了真正的开放式、多云 Kubernetes。
Karmada 旨在为多云和混合云场景下的多集群应用程序管理提供即插即用的自动化,具有集中式多云管理、高可用性、故障恢复和流量调度等关键功能。
2.2 核心组件介绍
-
karmada-apiserver
API 服务器是 Karmada 控制平面的一个组件,对外暴露 Karmada API 以及 Kubernetes 原生API,API 服务器是 Karmada 控制平面的前端。
Karmada API 服务器是直接使用 Kubernetes 的 kube-apiserver
实现的,因此 Karmada 与 Kubernetes API 自然兼容。 这也使得 Karmada 更容易实现与 Kubernetes 生态系统的集成,例如允许用户使用 kubectl
来操作 Karmada、 与 ArgoCD 集成、与 Flux 集成等等。
-
karmada-aggregated-apiserver
聚合 API 服务器是使用 Kubernetes API 聚合层技术实现的扩展 API 服务器。 它提供了集群 API 以及相应的子资源, 例如 cluster/status
和 cluster/proxy
,实现了聚合 Kubernetes API Endpoint 等可以通过 karmada-apiserver 访问成员集群的高级功能。
-
kube-controller-manager
kube-controller-manager 由一组控制器组成,Karmada 只是从 Kubernetes 的官方版本中挑选了一些控制器,以保持与原生控制器一致的用户体验和行为。
值得注意的是,并非所有的原生控制器都是 Karmada 所需要的, 推荐的控制器请参阅 推荐的控制器。
-
karmada-controller-manager
Karmada 控制器管理器运行了各种自定义控制器进程。
控制器负责监视Karmada对象,并与底层集群的API服务器通信,以创建原生的 Kubernetes 资源。
所有的控制器列举在 Karmada 控制器。
-
karmada-scheduler
karmada-scheduler 负责将 Kubernetes 原生API资源对象(以及CRD资源)调度到成员集群。
调度器依据策略约束和可用资源来确定哪些集群对调度队列中的资源是可用的,然后调度器对每个可用集群进行打分排序,并将资源绑定到最合适的集群。
-
karmada-webhook
karmada-webhook 是用于接收 karmada/Kubernetes API 请求的 HTTP 回调,并对请求进行处理。你可以定义两种类型的 karmada-webhook,即验证性质的 webhook 和修改性质的 webhook。 修改性质的准入 webhook 会先被调用。它们可以更改发送到 Karmada API 服务器的对象以执行自定义的设置默认值操作。
在完成了所有对象修改并且 Karmada API 服务器也验证了所传入的对象之后,验证性质的 webhook 会被调用,并通过拒绝请求的方式来强制实施自定义的策略。
-
etcd
一致且高可用的键值存储,用作 Karmada 的所有 Karmada/Kubernetes 资源对象数据的后台数据库。
如果你的 Karmada 使用 etcd 作为其后台数据库,请确保你针对这些数据有一份备份计划。
你可以在官方文档中找到有关 etcd 的深入知识。
-
karmada-agent
Karmada 有 Push 和 Pull 两种集群注册模式,karmada-agent 应部署在每个 Pull 模式的成员集群上。 它可以将特定集群注册到 Karmada 控制平面,并将工作负载清单从 Karmada 控制平面同步到成员集群。 此外,它也负责将成员集群及其资源的状态同步到 Karmada 控制平面。
2.3 多集群管理工具对比
三、多集群管理实战
3.1 准备节点9 台 ECS 2C 8Gi
具体 ECS 申请流程请参考:
Qwen2.5 7B 极简微调训练_qwen 2.5 7b训练-CSDN博客文章浏览阅读291次,点赞4次,收藏6次。实现 qwen 2.5 7b 模型微调实验,并打包好模型最后发布到 huggingface_qwen 2.5 7b训练https://blog.csdn.net/weixin_39403185/article/details/147115232?spm=1001.2014.3001.5501
3.2 三k8s集群部署准备
a) 网络规划准备
部署k8s-cluster-01
部署k8s-cluster-02
部署k8s-cluster-03
3.3 karmada部署
## 安装 CLI 工具
curl -s https://raw.githubusercontent.com/karmada-io/karmada/master/hack/install-cli.sh | sudo bash## 初始化karmada
karmadactl init --kubeconfig=$HOME/.kube/config \
--karmada-data=$HOME/karmada-space/data \
--karmada-pki=$HOME/karmada-space/data/pki \
--etcd-data=$HOME/karmada-space/etcd
pull 模式注册 (将所有的子成员)
## 刷新注册token
karmadactl token create --print-register-command \
--kubeconfig=/root/karmada-space/data/karmada-apiserver.configkarmadactl register 172.18.81.127:32443 --token gf0ttr.eky8q7tbqb8r1lkj \
--discovery-token-ca-cert-hash \
sha256:5787fa78a1b7974fc9f87fd2238aaf63ab5bdec07658c6435435a366b93fc620## 成员注册 --kubeconfig是将成员的配置文件需要修改的
## config 拷贝到 主k8s中然后注册
## token来源于第一条命令的输出
karmadactl register 172.18.81.127:32443 --token gf0ttr.eky8q7tbqb8r1lkj \
--discovery-token-ca-cert-hash sha256:5787fa78a1b7974fc9f87fd2238aaf63ab5bdec07658c6435435a366b93fc620 \
--kubeconfig=$HOME/.kube/config## 查看集群成员
karmadactl --kubeconfig=/root/karmada-space/data/karmada-apiserver.config get clusters
push 模式注册 (子成员主动注册)
MEMBER_CLUSTER_NAME=$(cat ~/.kube/config | grep current-context | sed 's/: /\n/g'| sed '1d'| tr -d "\"'")
karmadactl --kubeconfig /root/karmada-space/data/karmada-apiserver.config join ${MEMBER_CLUSTER_NAME} \
--cluster-kubeconfig=$HOME/.kube/config
k8s-01 为主
karmadactl register 172.18.81.127:32443 --token gf0ttr.eky8q7tbqb8r1lkj \
--discovery-token-ca-cert-hash sha256:5787fa78a1b7974fc9f87fd2238aaf63ab5bdec07658c6435435a366b93fc620 \
--kubeconfig=$HOME/.kube/k8s-cluster-01-configkarmadactl register 172.18.81.127:32443 --token gf0ttr.eky8q7tbqb8r1lkj \
--discovery-token-ca-cert-hash sha256:5787fa78a1b7974fc9f87fd2238aaf63ab5bdec07658c6435435a366b93fc620 \
--kubeconfig=$HOME/.kube/k8s-cluster-02-configkarmadactl register 172.18.81.127:32443 --token gf0ttr.eky8q7tbqb8r1lkj \
--discovery-token-ca-cert-hash sha256:5787fa78a1b7974fc9f87fd2238aaf63ab5bdec07658c6435435a366b93fc620 \
--kubeconfig=$HOME/.kube/k8s-cluster-03-config
## 安装一个k8s 上下文管理工具
wget https://github.com/sunny0826/kubecm/releases/download/v0.30.0/kubecm_v0.30.0_Linux_x86_64.tar.gz
tar -zxvf kubecm_v0.30.0_Linux_x86_64.tar.gz
sudo mv kubecm /usr/local/bin/## 添加上下文
kubecm add -f $HOME/karmada-space/data/karmada-apiserver.config
kubecm add -f $HOME/.kube/k8s-cluster-01-config
kubecm add -f $HOME/.kube/k8s-cluster-02-config
kubecm add -f $HOME/.kube/k8s-cluster-03-config
补充命令:
###
kubectl get clusters --kubeconfig $HOME/karmada-space/data/karmada-apiserver.config## 重置 集群
karmadactl deinit ## 删除集群
karmadactl delete cluster rancher-k8s-02 \--kubeconfig=$HOME/karmada-space/data/karmada-apiserver.config
3.4 karmada dashboard安装
karmada-apiserver.config路径和最开始的配置有关系
git clone https://github.com/karmada-io/dashboard.git
cd dashboard# Karmada 配置创建秘密,Karmada 仪表板将使用此配置与 Karmada API 服务器通信
kubectl create secret generic kubeconfig \
--from-file=kubeconfig=$HOME/karmada-space/data/karmada-apiserver.config \
-n karmada-system## 开始部署
kubectl apply -k artifacts/overlays/nodeport-mode
注意配置此刻上下文:
获取令牌访问:
### 注意现在已经切换上下文了
kubectl config use-context karmada-apiserver
kubectl apply -f artifacts/dashboard/karmada-dashboard-sa.yaml
kubectl -n karmada-system get secret/karmada-dashboard-secret -o go-template="{{.data.token | base64decode}}"
现在已经能顺利的查看 dashboard:
3.5 部署调度示例
a) 简单多集群调度
切换上下文到karmada-apiserver
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxlabels:app: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxannotations:karmada.io/health-check: "true"spec:containers:- name: nginximage: nginx:1.27.4imagePullPolicy: IfNotPresentresources:requests:cpu: 100mmemory: 128Milimits:cpu: 200mmemory: 256Mi
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:name: nginx-policy
spec:resourceSelectors:- apiVersion: apps/v1kind: Deploymentname: nginxschedulerName: default-schedulerplacement:clusterAffinity:clusterNames: [k8s-cluster-02, k8s-cluster-03]
EOF
k8s-cluster-01 没有 nginx 部署
k8s-cluster-02 nginx 部署3 个 pod
k8s-cluster-03 nginx 部署3 个 pod
符合预期
b) 标签选择调度
kubectl --context karmada-apiserver label cluster k8s-cluster-01 environment=dev region=cn-north
kubectl --context karmada-apiserver label cluster k8s-cluster-02 environment=staging region=cn-east
kubectl --context karmada-apiserver label cluster k8s-cluster-03 environment=dev region=cn-south
# 验证标签
kubectl --context karmada-apiserver get cluster --show-labels
watch kubectl --context kubernetes-admin@kubernetes get po -owide -A
watch kubectl --context kubernetes-admin@kubernetes-02 get po -owide -A
watch kubectl --context kubernetes-admin@kubernetes-03 get po -owide -A
k8s-cluster-01 nginx 部署3 个
k8s-cluster-01 没有 nginx 部署
k8s-cluster-03 nginx 部署3 个
c) 权重调度分配
cat <<EOF | kubectl --context karmada-apiserver apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxlabels:app: nginx
spec:replicas: 6selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxannotations:karmada.io/health-check: "true"spec:containers:- name: nginximage: nginx:1.27.4imagePullPolicy: IfNotPresentresources:requests:cpu: 100mmemory: 128Milimits:cpu: 200mmemory: 256Mi
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:name: nginx-policy
spec:resourceSelectors:- apiVersion: apps/v1kind: Deploymentname: nginxschedulerName: default-schedulerplacement:clusterAffinity:clusterNames:- k8s-cluster-01- k8s-cluster-02replicaScheduling:replicaDivisionPreference: WeightedreplicaSchedulingType: DividedweightPreference:staticWeightList:- targetCluster:clusterNames:- k8s-cluster-01weight: 2 - targetCluster:clusterNames:- k8s-cluster-02weight: 1
EOF
也可以尝试Duplicated 多个集群复制完整的副本数
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:name: nginx-policy
spec:resourceSelectors:- apiVersion: apps/v1kind: Deploymentname: nginxschedulerName: default-schedulerplacement:clusterAffinity:clusterNames:- k8s-cluster-01- k8s-cluster-02replicaScheduling:replicaSchedulingType: Duplicated
四、小结
karmada具体调度实现比较容易,并没有太多复杂逻辑。可能环境的构建比较繁琐,还需要考虑到Pod,Service 不同集群的 Kubernetes 的网络划分。需要提前规划好,实操下来基本上没有太多问题。不过这种调度策略还是偏简单了一些,很多实践生产项目,通过 helm 安装复杂的 crd 自定义资源。这些karmada兼容的不是特别好。
参考:
https://github.com/karmada-io/karmadahttps://github.com/karmada-io/karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration | karmadaOpen, Multi-Cloud, Multi-Cluster Kubernetes Orchestration
https://karmada.io/