【Karmada使用教程】通过 Workload Rebalancer 触发重调度
Karmada 是开放的多云多集群容器编排引擎,旨在帮助用户在多云环境下部署和运维业务应用。凭借兼容 Kubernetes 原生 API 的能力,Karmada 可以平滑迁移单集群工作负载,并且仍可保持与 Kubernetes 周边生态工具链协同。本系列文章将介绍Karmada的使用教程,本文介绍如何通过 Workload Rebalancer 触发重调度。

目标
一般情况下,工作负载类资源被调度后,会保持调度结果不变,其副本分布不会轻易发生变化。 现在,假设某些特殊情况下,您想主动触发一次重调度,可以通过使用 WorkloadRebalancer 来实现。
因此,本节将指导您如何使用 WorkloadRebalancer 来触发重调度。
前提条件
▍Karmada 及多个子集群已安装
运行安装命令:
git clone https://github.com/karmada-io/karmada
cd karmada
hack/local-up-karmada.sh
export KUBECONFIG=~/.kube/karmada.config:~/.kube/members.config
说明:在开始之前,我们应该至少安装三个 kubernetes 集群,一个用于安装 Karmada 控制平面,另外两个作为成员集群。 为了方便,我们直接使用 hack/local-up-karmada.sh 脚本快速准备上述集群。
执行上述命令后,您将看到 Karmada 控制平面和多个成员集群已安装完成。
教程
▍第一步:创建一个 Deployment
首先准备一个名为 foo 的 Deployment,您可以创建一个新文件 deployment.yaml,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo
labels:
app: test
spec:
replicas: 3
selector:
matchLabels:
app: foo
template:
metadata:
labels:
app: foo
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
name: foo
resources:
limits:
cpu: 10m
memory: 10Mi
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: default-pp
spec:
placement:
clusterTolerations:
- effect: NoExecute
key: workload-rebalancer-test
operator: Exists
tolerationSeconds: 0
clusterAffinity:
clusterNames:
- member1
- member2
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
dynamicWeight: AvailableReplicas
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: foo
namespace: default
然后,运行下述命令来创建这些资源:
kubectl --context karmada-apiserver apply -f deployment.yaml
您可以通过下述方式来检查该步骤是否成功:
$ karmadactl --karmada-context karmada-apiserver get deploy foo
NAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTION
foo member1 2/2 2 2 20s Y
foo member2 1/1 1 1 20s Y
可以看到,2 个副本分发到 member1 集群,1 个副本分发到 member2 集群。
▍第二步:在 member1 集群添加 NoExecute 污点以模拟集群故障
1)运行以下命令将 NoExecute 污点添加到 member1 集群:
$ karmadactl --karmada-context=karmada-apiserver taint clusters member1 workload-rebalancer-test:NoExecute
cluster/member1 tainted
然后,由于集群故障转移,将触发重调度,并且所有副本将被分发到 member2 集群,您可以看到:
$ karmadactl --karmada-context karmada-apiserver get deploy foo
NAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTION
foo member2 3/3 3 3 57s Y
2)运行以下命令从 member1 集群中移除上述 NoExecute 污点:
$ karmadactl --karmada-context=karmada-apiserver taint clusters member1 workload-rebalancer-test:NoExecute-
cluster/member1 untainted
移除污点不会导致副本传播变化,因为调度结果是惰性的,所有副本将保持在 member2 集群中不变。
▍第三步:创建一个 WorkloadRebalancer 来触发重调度
为了触发上述资源的重调度,您可以创建一个新文件 workload-rebalancer.yaml,内容如下:
apiVersion: apps.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
name: demo
spec:
workloads:
- apiVersion: apps/v1
kind: Deployment
name: foo
namespace: default
然后运行以下命令来创建该资源:
kubectl --context karmada-apiserver apply -f workload-rebalancer.yaml
您将得到 workloadrebalancer.apps.karmada.io/demo created 的结果,这意味着该资源创建成功。
▍第四步:检查 WorkloadRebalancer 的状态
运行以下命令:
$ kubectl --context karmada-apiserver get workloadrebalancer demo -o yaml
apiVersion: apps.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
creationTimestamp: "2024-05-25T09:49:51Z"
generation: 1
name: demo
spec:
workloads:
- apiVersion: apps/v1
kind: Deployment
name: foo
namespace: default
status:
finishTime: "2024-05-25T09:49:51Z"
observedGeneration: 1
observedWorkloads:
- result: Successful
workload:
apiVersion: apps/v1
kind: Deployment
name: foo
namespace: default
因此,您可以在 workloadrebalancer/demo 的 status.observedWorkloads 字段中观察重调度的结果。 如上述结果所示,deployment/foo 已成功重新调度。
▍第五步:观察 WorkloadRebalancer 的实际效果
您可以观察 deployment/foo 的副本实际分发状态:
$ karmadactl --karmada-context karmada-apiserver get deploy foo
NAME CLUSTER READY UP-TO-DATE AVAILABLE AGE ADOPTION
foo member1 2/2 2 2 3m14s Y
foo member2 1/1 1 1 4m37s Y
您可以看到重调度已完成,有2个副本迁移回到 member1 集群,而 member2 集群中原有的1个副本保持不变。
此外,您可以观察到由 default-scheduler 发出的调度事件,例如:
$ kubectl --context karmada-apiserver describe deployment foo
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Normal ScheduleBindingSucceed 3m34s (x2 over 4m57s) default-scheduler Binding has been scheduled successfully. Result: {member1:2, member2:1}
Normal AggregateStatusSucceed 3m20s (x20 over 4m57s) resource-binding-status-controller Update resourceBinding(default/foo-deployment) with AggregatedStatus successfully.
...
▍第六步:更新并自动清理 WorkloadRebalancer
假设您希望 WorkloadRebalancer 能在将来自动清理,您只需编辑资源声明并将 spec.ttlSecondsAfterFinished 字段设置为 300,例如:
apiVersion: apps.karmada.io/v1alpha1
kind: WorkloadRebalancer
metadata:
name: demo
spec:
ttlSecondsAfterFinished: 300
workloads:
- apiVersion: apps/v1
kind: Deployment
name: foo
namespace: default
在您应用了这个修改后,这个 WorkloadRebalancer 资源将在 300 秒后自动删除。
更多Karmada云原生多云容器引擎使用教程与技术交流,欢迎关注Karmada社区公众号或添加社区小助手k8s2222,回复Karmada进群。

Karmada 公众号
Karmada 是CNCF 首个多云多集群容器编排项目(孵化级),旨在帮助用户像使用单个集群一样轻松管理跨云多集群,让基于 Karmada 的多云方案无缝融入云原生技术生态。社区吸引了来自华为、道客、浙江大学、滴滴、腾讯、中国电子云等60多家公司的全球贡献者,广泛分布于22个国家和地区。Karmada 现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。
Karmada官网:https://karmada.io/
项目地址:https://github.com/karmada-io/karmada
Slack地址:https://slack.cncf.io/(#karmada)
- 点赞
- 收藏
- 关注作者
评论(0)