手动迁移
当需要下线维护某一台node时,可通过如下操作相关命令处理
cordon
标记节点不可调度,后续新的pod不会被调度到此节点,但是该节点上的pod可以正常对外服务;
drain
驱逐节点上的pod至其他可调度节点
uncordon
取消不可调度
# 标记节点不可调度
kubectl cordon node1
# 查看节点状态
kubectl get node
NAME STATUS ROLES AGE VERSION
node1 Ready,SchedulingDisabled master 1d v1.22.0
# 驱逐pod
kubectl drain node1 --delete-local-data --ignore-daemonsets --force
# 参数如下:
# --delete-local-data 删除本地数据,即使emptyDir也将删除;
# --ignore-daemonsets 忽略DeamonSet,否则DeamonSet被删除后,仍会自动重建;
# --force 不加force参数只会删除该node节点上的ReplicationController, ReplicaSet, DaemonSet,StatefulSet or Job,加上后所有pod都将删除;
pod会先重建再终止,服务中断时间=重建时间+服务启动时间+readiness探针检测正常时间,必须等到1/1 Running服务才会正常。因此在单副本时迁移时,服务终端是不可避免的。
平滑迁移
要做到平滑迁移就需要用的pdb(PodDisruptionBudget),即主动驱逐保护。无论是默认迁移和手动迁移,都会导致服务中断,而pdb能可以实现节点维护期间不低于一定数量的pod正常运行,从而保证服务的可用性。
在仍以helloworld为例,由于只有一个副本,因此需要保证维护期间这个副本在迁移完成后,才会终止。
# 从node1 驱逐到node2 标记节点不可调度
kubectl cordon node1
新建pdb vim pdb-test.yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: pdb-test
namespace: test
spec:
minAvailable: 1
selector:
matchLabels:
app: helloworld
# kubectl apply -f pdb-test.yaml
# kubectl get pdb -n test
驱逐
kubectl drain node1 --delete-local-data --ignore-daemonsets --force
# 此时由于只有一个副本,最小可用为1,则ALLOWED就为0,因此在一个副本通过pdb是不会发生驱逐的。我们需要先扩容,将副本数调整为大于1。
# 调整副本数,将replicas为2
kubectl -n test scale deploy helloworld --replicas=2
# 再次查看pdb
# kubectl get pdb -n test
# NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
# pdb-test 1 N/A 1 13m
# 此时最小可用为1 ,ALLOWED为1,此时是数量会自动计算。
# 再次驱逐
kubectl drain node1 --delete-local-data --ignore-daemonsets --force
# 维护完毕,将node1调整为可调度
kubectl uncordon node1
本次驱逐,由于helloworld始终保持有一个pod在提供服务,因此服务是不中断的。
最后将副本数可以调节为1并将node节点调整为可调度,维护完毕。