kubernetes pending pod 优先级
kubernetes pending pod priority
我的 kubernetes (1.18.3) 集群上有以下 pods:
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 14m
pod2 1/1 Running 0 14m
pod3 0/1 Pending 0 14m
pod4 0/1 Pending 0 14m
pod3 和 pod4 无法启动,因为节点只有 2 pods 的容量。当 pod1 完成并退出时,调度程序会选择 pod3 或 pod4 并启动它。到目前为止一切顺利。
但是,我还有一个高优先级 pod (hpod),我想在 运行 pods 完成并退出时在 pod3 或 pod4 之前启动。
所以我创建了一个优先级类,可以在 kubernetes 文档中找到:
kind: PriorityClass
metadata:
name: high-priority-no-preemption
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
我创建了以下 pod yaml:
apiVersion: v1
kind: Pod
metadata:
name: hpod
labels:
app: hpod
spec:
containers:
- name: hpod
image: ...
resources:
requests:
cpu: "500m"
memory: "500Mi"
limits:
cpu: "500m"
memory: "500Mi"
priorityClassName: high-priority-no-preemption
现在的问题是,当我使用 kubectl apply -f hpod.yaml 启动高优先级 pod 时,调度程序会终止 运行 pod 以允许高优先级 pod 启动,尽管我'已设置 'preemptionPolicy: Never'.
预期的行为是推迟启动 hpod,直到当前 运行 pod 完成。当它启动时,让 hpod 在 pod3 或 pod4 之前启动。
我做错了什么?
先决条件:
此解决方案已在 Kubernetes v1.18.3
、docker 19.03 和 Ubuntu 18 上进行测试。
还需要文本编辑器(即 sudo apt-get install vim
)。
在 How to disable preemption 下的 Kubernetes 文档中,您可以找到 注意:
Note: In Kubernetes 1.15
and later, if the feature NonPreemptingPriority
is enabled
, PriorityClasses
have the option to set preemptionPolicy: Never
. This will prevent pods of that PriorityClass
from preempting other pods.
也在Non-preempting PriorityClass下你有信息:
The use of the PreemptionPolicy field requires the NonPreemptingPriority
feature gate to be enabled
.
稍后如果您查看这些 Feature Gates 信息,您会发现 NonPreemptingPriority
是 false
,因此默认情况下它是禁用的。
使用您当前的配置输出:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 32s
nginx-normal-2 1/1 Running 0 32s
$ kubectl apply -f prio.yaml
pod/nginx-priority created$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-normal-2 1/1 Running 0 48s
nginx-priority 1/1 Running 0 8s
要启用 preemptionPolicy: Never
,您需要将 --feature-gates=NonPreemptingPriority=true
应用到 3 个文件:
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
要检查此 feature-gate
是否已启用,您可以使用命令进行检查:
ps aux | grep apiserver | grep feature-gates
ps aux | grep scheduler | grep feature-gates
ps aux | grep controller-manager | grep feature-gates
有关非常详细的信息,为什么您必须编辑这些文件,请查看 this Github thread。
$ sudo su
# cd /etc/kubernetes/manifests/
# ls
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
使用文本编辑器向这些文件添加功能门控
# vi kube-apiserver.yaml
并在 spec.containers.command
下添加 - --feature-gates=NonPreemptingPriority=true
如下例所示:
spec:
containers:
- command:
- kube-apiserver
- --feature-gates=NonPreemptingPriority=true
- --advertise-address=10.154.0.31
并对其他 2 个文件执行相同的操作。之后你可以检查是否应用了这个标志。
$ ps aux | grep apiserver | grep feature-gates
root 26713 10.4 5.2 565416 402252 ? Ssl 14:50 0:17 kube-apiserver --feature-gates=NonPreemptingPriority=true --advertise-address=10.154.0.31
现在您已经重新部署了 PriorityClass
。
$ kubectl get priorityclass
NAME VALUE GLOBAL-DEFAULT AGE
high-priority-no-preemption 1000000 false 12m
system-cluster-critical 2000000000 false 23m
system-node-critical 2000001000 false 23m
$ kubectl delete priorityclass high-priority-no-preemption
priorityclass.scheduling.k8s.io "high-priority-no-preemption" deleted
$ kubectl apply -f class.yaml
priorityclass.scheduling.k8s.io/high-priority-no-preemption created
最后一步是使用此 PriorityClass
部署 pod。
测试
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 4m4s
nginx-normal-2 1/1 Running 0 18m
$ kubectl apply -f prio.yaml
pod/nginx-priority created
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 5m17s
nginx-normal-2 1/1 Running 0 20m
nginx-priority 0/1 Pending 0 67s
$ kubectl delete po nginx-normal-2
pod "nginx-normal-2" deleted
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 5m55s
nginx-priority 1/1 Running 0 105s
我的 kubernetes (1.18.3) 集群上有以下 pods:
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 14m
pod2 1/1 Running 0 14m
pod3 0/1 Pending 0 14m
pod4 0/1 Pending 0 14m
pod3 和 pod4 无法启动,因为节点只有 2 pods 的容量。当 pod1 完成并退出时,调度程序会选择 pod3 或 pod4 并启动它。到目前为止一切顺利。
但是,我还有一个高优先级 pod (hpod),我想在 运行 pods 完成并退出时在 pod3 或 pod4 之前启动。
所以我创建了一个优先级类,可以在 kubernetes 文档中找到:
kind: PriorityClass
metadata:
name: high-priority-no-preemption
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
我创建了以下 pod yaml:
apiVersion: v1
kind: Pod
metadata:
name: hpod
labels:
app: hpod
spec:
containers:
- name: hpod
image: ...
resources:
requests:
cpu: "500m"
memory: "500Mi"
limits:
cpu: "500m"
memory: "500Mi"
priorityClassName: high-priority-no-preemption
现在的问题是,当我使用 kubectl apply -f hpod.yaml 启动高优先级 pod 时,调度程序会终止 运行 pod 以允许高优先级 pod 启动,尽管我'已设置 'preemptionPolicy: Never'.
预期的行为是推迟启动 hpod,直到当前 运行 pod 完成。当它启动时,让 hpod 在 pod3 或 pod4 之前启动。
我做错了什么?
先决条件:
此解决方案已在 Kubernetes v1.18.3
、docker 19.03 和 Ubuntu 18 上进行测试。
还需要文本编辑器(即 sudo apt-get install vim
)。
在 How to disable preemption 下的 Kubernetes 文档中,您可以找到 注意:
Note: In Kubernetes
1.15
and later, if the featureNonPreemptingPriority
isenabled
,PriorityClasses
have the option to setpreemptionPolicy: Never
. This will prevent pods of thatPriorityClass
from preempting other pods.
也在Non-preempting PriorityClass下你有信息:
The use of the PreemptionPolicy field requires the
NonPreemptingPriority
feature gate to beenabled
.
稍后如果您查看这些 Feature Gates 信息,您会发现 NonPreemptingPriority
是 false
,因此默认情况下它是禁用的。
使用您当前的配置输出:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 32s
nginx-normal-2 1/1 Running 0 32s
$ kubectl apply -f prio.yaml
pod/nginx-priority created$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-normal-2 1/1 Running 0 48s
nginx-priority 1/1 Running 0 8s
要启用 preemptionPolicy: Never
,您需要将 --feature-gates=NonPreemptingPriority=true
应用到 3 个文件:
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
要检查此 feature-gate
是否已启用,您可以使用命令进行检查:
ps aux | grep apiserver | grep feature-gates
ps aux | grep scheduler | grep feature-gates
ps aux | grep controller-manager | grep feature-gates
有关非常详细的信息,为什么您必须编辑这些文件,请查看 this Github thread。
$ sudo su
# cd /etc/kubernetes/manifests/
# ls
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
使用文本编辑器向这些文件添加功能门控
# vi kube-apiserver.yaml
并在 spec.containers.command
下添加 - --feature-gates=NonPreemptingPriority=true
如下例所示:
spec:
containers:
- command:
- kube-apiserver
- --feature-gates=NonPreemptingPriority=true
- --advertise-address=10.154.0.31
并对其他 2 个文件执行相同的操作。之后你可以检查是否应用了这个标志。
$ ps aux | grep apiserver | grep feature-gates
root 26713 10.4 5.2 565416 402252 ? Ssl 14:50 0:17 kube-apiserver --feature-gates=NonPreemptingPriority=true --advertise-address=10.154.0.31
现在您已经重新部署了 PriorityClass
。
$ kubectl get priorityclass
NAME VALUE GLOBAL-DEFAULT AGE
high-priority-no-preemption 1000000 false 12m
system-cluster-critical 2000000000 false 23m
system-node-critical 2000001000 false 23m
$ kubectl delete priorityclass high-priority-no-preemption
priorityclass.scheduling.k8s.io "high-priority-no-preemption" deleted
$ kubectl apply -f class.yaml
priorityclass.scheduling.k8s.io/high-priority-no-preemption created
最后一步是使用此 PriorityClass
部署 pod。
测试
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 4m4s
nginx-normal-2 1/1 Running 0 18m
$ kubectl apply -f prio.yaml
pod/nginx-priority created
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 5m17s
nginx-normal-2 1/1 Running 0 20m
nginx-priority 0/1 Pending 0 67s
$ kubectl delete po nginx-normal-2
pod "nginx-normal-2" deleted
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 5m55s
nginx-priority 1/1 Running 0 105s