公众号关注 「奇妙的 Linux 世界」
设为「星标」,每天带你玩转 Linux !
需求场景
同一应用的不同 Pod 可能其利用率是不同的。
在对应用执行缩容操作时, 可能希望移除利用率较低的 Pod。
为了避免频繁更新 Pod,应用应该在执行缩容操作之前更新一次 controller.kubernetes.io/pod-deletion-cost
注解值 (将注解值设置为一个与其 Pod 利用率对应的值)。如果应用自身控制器缩容操作时(例如 Spark 部署的驱动 Pod),这种机制是可以起作用的。
controller.kubernetes.io/pod-deletion-cost
通过使用 controller.kubernetes.io/pod-deletion-cost
注解,用户可以对 ReplicaSet 缩容时要先删除哪些 Pod 设置偏好。
• 类别:注解
• 特性状态:
Kubernetes v1.22 [beta]
• 例子:
controller.kubernetes.io/pod-deletion-cost: "10"
• 用于:Pod
• 该注解用于设置 Pod 删除成本允许用户影响 ReplicaSet 缩减顺序。注解解析为
int32
类型。
此注解要设置到 Pod 上,取值范围为 [-2147483647, 2147483647]。所代表的是删除同一 ReplicaSet 中其他 Pod 相比较而言的开销。删除开销较小的 Pod 比删除开销较高的 Pod 更容易被删除。
Pod 如果未设置此注解,则隐含的设置值为 0。负值也是可接受的。如果注解值非法,API 服务器会拒绝对应的 Pod。
此功能特性处于 Beta 阶段,默认被启用。你可以通过为 kube-apiserver 和 kube-controller-manager 设置特性门控 PodDeletionCost
来禁用此功能。
说明:
• 此机制实施时仅是尽力而为,并不能对 Pod 的删除顺序作出任何保证;
• 用户应避免频繁更新注解值,例如根据某观测度量值来更新此注解值是应该避免的。这样做会在 API 服务器上产生大量的 Pod 更新操作。
实操演练
编写一个副本数为3的nginx-deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
# tells deployment to run 3 pods matching the template
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
部署后,效果如下:
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
$ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-66b6c48dd5-97rjj 1/1 Running 0 11s 10.244.219.78 master <none> <none>
nginx-deployment-66b6c48dd5-fcckz 1/1 Running 0 11s 10.244.219.77 master <none> <none>
nginx-deployment-66b6c48dd5-rsq8j 1/1 Running 0 11s 10.244.219.79 master <none> <none>
修改pod注解,使用 controller.kubernetes.io/pod-deletion-cost
注解
nginx-deployment-66b6c48dd5-97rjj
删除成本设置为100
nginx-deployment-66b6c48dd5-fcckz
删除成本设置为60
nginx-deployment-66b6c48dd5-rsq8j
删除成本设置为20
# `nginx-deployment-66b6c48dd5-97rjj `删除成本设置为100
kubectl annotate pod nginx-deployment-66b6c48dd5-97rjj controller.kubernetes.io/pod-deletion-cost=100 --overwrite
# `nginx-deployment-66b6c48dd5-fcckz`删除成本设置为60
kubectl annotate pod nginx-deployment-66b6c48dd5-fcckz controller.kubernetes.io/pod-deletion-cost=60 --overwrite
# `nginx-deployment-66b6c48dd5-rsq8j`删除成本设置为20
kubectl annotate pod nginx-deployment-66b6c48dd5-rsq8j controller.kubernetes.io/pod-deletion-cost=20 --overwrite
查看所有pod的controller.kubernetes.io/pod-deletion-cost
注解,发现 controller.kubernetes.io/pod-deletion-cost
注解已经被添加
$ kubectl get pods -l app=nginx -o custom-columns=POD_NAME:.metadata.name,POD_DELETION_COST:.metadata.annotations.'controller\.kubernetes\.io/pod-deletion-cost'
POD_NAME POD_DELETION_COST
nginx-deployment-66b6c48dd5-97rjj 100
nginx-deployment-66b6c48dd5-fcckz 60
nginx-deployment-66b6c48dd5-rsq8j 20
使用kubectl scale
命令缩容nginx-deployment
,发现controller.kubernetes.io/pod-deletion-cost
数值低的pod优先被删除
$ kubectl scale deployment nginx-deployment --replicas=2
deployment.apps/nginx-deployment scaled
# 发现`controller.kubernetes.io/pod-deletion-cost`数值低的pod优先被删除
$ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-66b6c48dd5-97rjj 1/1 Running 0 12m 10.244.219.78 master <none> <none>
nginx-deployment-66b6c48dd5-fcckz 1/1 Running 0 12m 10.244.219.77 master <none> <none>
上面我们的nginx-deployment-66b6c48dd5-rsq8j
删除成本设置为20,数值最低,所以优先被删除。
拓展:kubectl scale缩容时删除pod的规则
缩容时默认删除pod的逻辑代码如下,有兴趣的同学可以看一下:
https://github.com/kubernetes/kubernetes/blob/release-1.11/pkg/controller/controller_utils.go#L737
func (s ActivePods) Less(i, j int) bool {
// 1. Unassigned < assigned
// If only one of the pods is unassigned, the unassigned one is smaller
if s[i].Spec.NodeName != s[j].Spec.NodeName && (len(s[i].Spec.NodeName) == 0 || len(s[j].Spec.NodeName) == 0) {
return len(s[i].Spec.NodeName) == 0
}
// 2. PodPending < PodUnknown < PodRunning
m := map[v1.PodPhase]int{v1.PodPending: 0, v1.PodUnknown: 1, v1.PodRunning: 2}
if m[s[i].Status.Phase] != m[s[j].Status.Phase] {
return m[s[i].Status.Phase] < m[s[j].Status.Phase]
}
// 3. Not ready < ready
// If only one of the pods is not ready, the not ready one is smaller
if podutil.IsPodReady(s[i]) != podutil.IsPodReady(s[j]) {
return !podutil.IsPodReady(s[i])
}
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
// see https://github.com/kubernetes/kubernetes/issues/22065
// 4. Been ready for empty time < less time < more time
// If both pods are ready, the latest ready one is smaller
if podutil.IsPodReady(s[i]) && podutil.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
return afterOrZero(podReadyTime(s[i]), podReadyTime(s[j]))
}
// 5. Pods with containers with higher restart counts < lower restart counts
if maxContainerRestarts(s[i]) != maxContainerRestarts(s[j]) {
return maxContainerRestarts(s[i]) > maxContainerRestarts(s[j])
}
// 6. Empty creation time pods < newer pods < older pods
if !s[i].CreationTimestamp.Equal(&s[j].CreationTimestamp) {
return afterOrZero(&s[i].CreationTimestamp, &s[j].CreationTimestamp)
}
return false
}
总结一下:
1. 如果pod没分配到节点,先被删除
2. 如果pod的状态是 Pending>PodUnknown>PodRunning,则Pending优先被删除,PodUnknown次之,PodRunning最后被删除。
3. 不是Ready状态的Pod先被删除。
4. 如果Pod都是Ready状态,则最后一个变成Ready状态的Pod先被删除(Ready时间最短的)。
5. 重启次数大的Pod先被删除。
6. 创建时间最新的Pod先被删除。
总结
controller.kubernetes.io/pod-deletion-cost
是一个用于 Kubernetes Pod 的注解(Annotation)。这个注解通常用于管理控制器(Controller)对于 Pod 删除的优先级和策略。以下是有关如何使用 controller.kubernetes.io/pod-deletion-cost
注解的一些信息:
1. 控制器中的 Pod 删除顺序:Kubernetes 控制器(如 Deployment、StatefulSet 等)通常会维护一组 Pod,它们共同形成一个应用程序或服务的一部分。在某些情况下,你可能希望定义哪些 Pod 比其他 Pod 更容易删除。这可以通过
controller.kubernetes.io/pod-deletion-cost
注解来实现。2. 定义 Pod 删除的相对优先级:通过为 Pod 添加
controller.kubernetes.io/pod-deletion-cost
注解,你可以为每个 Pod 指定一个数字值,表示其删除的成本。较低成本的 Pod 将被控制器优先删除,以便在需要缩容时释放资源。这可以有助于控制器在缩容时选择删除哪些 Pod。例如,你可以设置:controller.kubernetes.io/pod-deletion-cost: "50"
对于一个 Pod,而对于另一个 Pod,你可以设置:controller.kubernetes.io/pod-deletion-cost: "100"
在这种情况下,具有成本为 50 的 Pod 会在成本为 100 的 Pod 之前被删除,以便控制器更倾向于删除成本较低的 Pod。3. 控制器的自定义删除策略:一些自定义控制器可能会使用这个注解来实现自定义的 Pod 删除策略。这取决于控制器的设计和需求。
请注意,controller.kubernetes.io/pod-deletion-cost
注解的实际效果取决于控制器的实现和支持。并非所有控制器都支持这个注解,而且它的行为可能因控制器而异。如果你使用的是自定义控制器,可能需要查看相关文档或代码以了解如何正确配置和使用这个注解。
本文转载自:「云原生百宝箱」,原文:https://url.hi-linux.com/vpCoh,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。
最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。
你可能还喜欢
点击下方图片即可阅读
图解几种常见 Kubernetes Pod 驱逐场景
点击上方图片,『美团|饿了么』外卖红包天天免费领
更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!