Karmada(Kubernetes Armada)是一个云原生多集群管理系统,旨在提供跨多个 Kubernetes 集群的统一资源管理、应用分发和调度能力。它允许用户将分散在不同云平台、不同地域的集群作为一个统一的资源池进行管理,极大地简化了多云或混合云环境下的运维复杂度。
本文将通过一个实操示例,指导你如何快速搭建 Karmada 控制平面,并利用其核心的 PropagationPolicy 实现跨集群的应用统一调度。
1. 环境准备
你需要安装以下工具:
- Go 语言环境: 用于安装 Karmada CLI。
- kubectl: 用于与 Kubernetes 集群交互。
- kind/k3d/minikube: 用于本地快速创建 Kubernetes 集群,模拟不同的云环境。
安装 Karmada CLI (karmactl):
git clone https://github.com/karmada-io/karmada
cd karmada
make karmactl
sudo cp bin/karmactl /usr/local/bin/
2. 搭建 Karmada 控制平面与成员集群
我们将使用 karmactl init 快速搭建 Karmada 控制平面,并创建两个 kind 集群作为模拟的“跨云”成员集群。
步骤 2.1:初始化 Karmada
执行以下命令,Karmada 将在本地创建一个名为 karmada-host 的集群作为控制平面。
karmactl init
# 确认 Karmada API Server 已启动
kubectl get all -n karmada-system --context=karmada-apiserver
步骤 2.2:创建并加入成员集群
模拟两个不同云厂商的集群,例如 cluster-aws 和 cluster-gcp。
# 创建模拟成员集群
kind create cluster --name cluster-aws
kind create cluster --name cluster-gcp
# 将集群注册到 Karmada 控制平面
karmactl join cluster-aws --cluster-kubeconfig=$HOME/.kube/config --cluster-context=kind-cluster-aws
karmactl join cluster-gcp --cluster-kubeconfig=$HOME/.kube/config --cluster-context=kind-cluster-gcp
# 检查成员集群状态
kubectl get clusters --context=karmada-apiserver
输出应显示两个集群都处于 Ready 状态。
3. 实现跨集群统一调度
Karmada 的核心在于资源分发(Propagation)和调度策略(Policy)。我们将部署一个 Nginx 应用,并使用 PropagationPolicy 策略,将其均匀调度到 cluster-aws 和 cluster-gcp 上。
步骤 3.1:定义应用和调度策略
创建一个名为 nginx-app.yaml 的文件,包含一个 Deployment 定义和对应的 PropagationPolicy。
注意: 资源必须被应用到 Karmada 控制平面,而非任何成员集群。
---
# 1. 基础应用定义 (Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-federated
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
# 2. 资源分发策略 (PropagationPolicy)
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-policy
spec:
# 目标资源选择器:将策略应用于名为 'nginx-federated' 的 Deployment
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx-federated
placement:
# 目标集群:调度到 cluster-aws 和 cluster-gcp
clusterAffinity:
clusterNames:
- cluster-aws
- cluster-gcp
# 副本调度策略:采用权重调度,平均分配 4 个副本
replicaScheduling:
replicaDivisionPreference: Weighted
weightPreference:
staticWeightList:
- targetCluster:
clusterName: cluster-aws
weight: 1
- targetCluster:
clusterName: cluster-gcp
weight: 1
步骤 3.2:应用资源
使用 Karmada 的 kubeconfig(即 karmada-apiserver context)应用该文件。
kubectl apply -f nginx-app.yaml --context=karmada-apiserver
步骤 3.3:验证调度结果
检查 Karmada 控制平面和两个成员集群的部署状态。
在 Karmada 控制平面验证:
# 确认资源已被 Karmada 接收
kubectl get deployment nginx-federated --context=karmada-apiserver
# 检查 Karmada 如何决定分发
kubectl get resourcebinding -l app=nginx --context=karmada-apiserver -o yaml | grep replicas
# 预期输出将显示每个集群被分配了 2 个副本
在成员集群验证:
分别检查 cluster-aws 和 cluster-gcp 的 Deployment。
# 验证 cluster-aws (云 A)
kubectl get deployment nginx-federated --context=kind-cluster-aws
# 验证 cluster-gcp (云 B)
kubectl get deployment nginx-federated --context=kind-cluster-gcp
你会发现,尽管只在 Karmada 上提交了一次 Deployment,但 K8s 资源已经根据 PropagationPolicy 的定义,被均匀地调度并部署到了两个模拟的跨云集群中,每个集群拥有 2 个副本。
总结
通过 Karmada,我们可以实现应用的集中式定义和声明式的跨集群分发。利用 PropagationPolicy,不仅可以指定资源部署到哪些集群,还可以精确控制副本数分配(例如按权重、按可用资源等),完美解决了多云环境下容器应用统一调度和运维的挑战。
汤不热吧