1.pdb介绍

当我们对某工作节点执行drain操作的时候,会立即把该worker上运行的pod立即删除,然后在其他节点上创建对应的pod。

比如有一个名字为web1的deploy,有6个副本,worker1和worker2上各运行了3个副本。现在如果对worker1执行drain操作的话,会立即删除worker1上的3个pod,然后在worker2上创建。但是如果pod的创建速度比较慢的话,那么此时整个环境里只有3个pod对外提供工作了。

那么如何确保在对worker执行drain操作的时候,保证pod必须以一个指定的数目的副本数运行呢?比如至少要有4个以上副本运行,此时可以利用pdb (PodDisruptionBudget)实现。

2.实验环境

pdb基于命名空间,只对指定的pod生效。
本实验环境如下:

kubernetes版本:1.24.2
master:vms71.rhce.cc
worker1:vms72.rhce.cc
worker2:vms73.rhce.cc

先创建一个名字为web1的deploy,共有2个副本,pod名及所在节点如下显示。

[root@vms71 ~]# kubectl get pods -l app=web1 -owide
NAME                 READY   STATUS  RESTARTS      AGE     IP       NODE  
web1-55bcbb879f-lk8qd   1/1     Running   0     21s   10.244.5.222   vms72.rhce.cc  
web1-55bcbb879f-sx8qz   1/1     Running   0     21s   10.244.88.31   vms73.rhce.cc 
[root@vms71 ~]#

这两个pod的标签为app=web1。

3.创建pdb

确保当前命名空间不存在pdb。

[root@vms71 ~]# kubectl get pdb
No resources found in chap3-pod namespace.
[root@vms71 ~]#

创建pdb的yaml文件,内容如下。

[root@vms71 ~]# cat mypdb.yaml 
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mypdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web1
[root@vms71 ~]#

这里创建一个的pdb名字为mypdb,应用在app=web1的那些pod上。
这里minAvailable的意思是,在驱逐pod时,最低要保证有2个pod在运行,这里除了可以写具体数值,也可以写一个百分比。
除了minAvailable参数之外,还有maxUnavailable可用。

创建这个pdb。

[root@vms71 ~]# kubectl apply -f mypdb.yaml 
poddisruptionbudget.policy/mypdb created
[root@vms71 ~]# 
[root@vms71 ~]# kubectl get pdb
NAME    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
mypdb   0               N/A               2                     4s
[root@vms71 ~]#

4.测试

对vms72执行drain操作,驱逐运行在vms72上的pod。

[root@vms71 ~]# kubectl drain vms72.rhce.cc --ignore-daemonsets  --delete-emptydir-data 
node/vms72.rhce.cc cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-np499, kube-system/kube-proxy-hb8tg
evicting pod kube-system/metrics-server-9d5bbf85c-jvs85
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
evicting pod kube-system/calico-kube-controllers-56cdb7c587-6t7pl
error when evicting pods/"web1-55bcbb879f-lk8qd" -n "chap3-pod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
pod/calico-kube-controllers-56cdb7c587-6t7pl evicted
pod/metrics-server-9d5bbf85c-jvs85 evicted
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
error when evicting pods/"web1-55bcbb879f-lk8qd" -n "chap3-pod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
error when evicting pods/"web1-55bcbb879f-lk8qd" -n "chap3-pod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
error when evicting pods/"web1-55bcbb879f-lk8qd" -n "chap3-pod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
error when evicting pods/"web1-55bcbb879f-lk8qd" -n "chap3-pod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
^C
[root@vms71 ~]#

这里会不停的显示报错,意思是没法驱逐pod web1-55bcbb879f-lk8qd(运行在vms72上)。为什么呢?因为所谓evicting,就是先删除pod web1-55bcbb879f-lk8qd,然后再在其他节点上重新创建一个pod。但是一旦删除了此pod的话,那么就达不到pdb里规定的至少同时有2个pod状态为running。

现在查看pod的情况。

[root@vms71 ~]# kubectl get pods -owide
NAME            READY   STATUS    RESTARTS   AGE   IP       NODE   
web1-55bcbb879f-lk8qd   1/1   Running   0   93s   10.244.5.222   vms72.rhce.cc
web1-55bcbb879f-sx8qz   1/1   Running   0   93s   10.244.88.31   vms73.rhce.cc
[root@vms71 ~]#

可以看到web1-55bcbb879f-lk8qd仍然是在vms72上运行的。

修改mypdb.yaml的内容。

[root@vms71 ~]# cat mypdb.yaml 
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mypdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: web1
[root@vms71 ~]#

这里把minAvailable的值改为了1,让修改生效。

[root@vms71 ~]# kubectl apply -f mypdb.yaml
poddisruptionbudget.policy/mypdb configured
[root@vms71 ~]#
再次对vms72执行drain操作。

[root@vms71 ~]# kubectl drain vms72.rhce.cc --ignore-daemonsets  --delete-emptydir-data 
node/vms72.rhce.cc cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-np499, kube-system/kube-proxy-hb8tg
evicting pod chap3-pod/web1-55bcbb879f-lk8qd
pod/web1-55bcbb879f-lk8qd evicted
node/vms72.rhce.cc drained
[root@vms71 ~]#

可以看到现在没有任何报错信息了,因为删除web1-55bcbb879f-lk8qd之后,还有web1-55bcbb879f-sx8qz在运行,满足了pdb的要求,至少有一个pod为running。

查看pod状态。

[root@vms71 ~]# kubectl get pods -owide
NAME          READY   STATUS    RESTARTS   AGE     IP            NODE  
web1-55bcbb879f-4qlgq   1/1     Running   0   5s      10.244.88.34   vms73.rhce.cc
web1-55bcbb879f-sx8qz   1/1     Running   0   2m49s   10.244.88.31   vms73.rhce.cc
[root@vms71 ~]#

此时pod已经去切换到了vms73上了。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐