天天看点

Kubernets 调度 常用的命令迁移Pod

节点添加删除标签

 添加标签

[[email protected] ~]# kubectl label node master node-role.kubernetes.io/etcd=
node/master labeled

[[email protected] ~]# kubectl get node
NAME     STATUS   ROLES         AGE   VERSION
master   Ready    etcd,master   79d   v1.19.8
node1    Ready    pg,worker     79d   v1.19.8
node2    Ready    worker        79d   v1.19.8
           

删除标签

[[email protected] ~]# kubectl label node master node-role.kubernetes.io/etcd-
node/master labeled
[[email protected] ~]# kubectl get node
NAME     STATUS   ROLES       AGE   VERSION
master   Ready    master      79d   v1.19.8
node1    Ready    pg,worker   79d   v1.19.8
node2    Ready    worker      79d   v1.19.8
           

 污点的设置、查看和去除

taints 内容包括 key、value、effect:

  • key 就是配置的键值
  • value 就是内容
  • effect 是标记了这个 taints 行为是什么

目前 Kubernetes 里面有三个 taints 行为:

  1. NoSchedule 禁止新的 Pod 调度上来
  2. PreferNoSchedul 尽量不调度到这台
  3. NoExecute 会 evict 没有对应 toleration 的 Pods,并且也不会调度新的上来。这个策略是非常严格的,大家在使用的时候要小心一点

k8s的master节点本身就带有effect类型为NoSchedule的污点,这也是为什么k8s在调度Pod时,不会调度到master节点的原因,具体查看如下:(Kubeadm在安装初始化init的时候给master打上了污点,其余节点是没有该污点的。Master节点主要任务是管理集群的,不应该跑具体的业务应用。所以不允许pod落在master节点)

如果不让pod调度到某个节点,那么可以对该节点打污点

[[email protected] ~]# kubectl describe node k8s-master 
Taints:             node-role.kubernetes.io/master:NoSchedule         


kubectl taint nodes k8s-master node-role.kubernetes.io/master=:NoSchedule   
           

注意⚠️ : 为master设置的这个taint中, 

node-role.kubernetes.io/master

key

value

为空, 

effect

NoSchedule,

如果输入命令时, 你丢掉了

=

符号, 写成了

node-role.kubernetes.io/master:NoSchedule

, 会报

error: at least one taint update is required

错误

 过程介绍:

# 设置污点
kubectl taint nodes [node name] key1=value:NoSchedule

# 节点说明中,查看Taint字段
kubectl describe node [node name]

# 去除污点
kubectl taint nodes [node name] key1:NoSchedule-
           

迁移Pod

驱逐节点是一种有损操作,驱逐的原理 :

  1. 封锁节点 (设为不可调度,避免新的 Pod 调度上来)。
  2. 将该节点上的 Pod 删除。
  3. ReplicaSet 控制器检测到 Pod 减少,会重新创建一个 Pod,调度到新的节点上。

这个过程是先删除,再创建,并非是滚动更新,因此更新过程中,如果一个服务的所有副本都在被驱逐的节点上,则可能导致该服务不可用。

1. 设置节点是否可调度

确定需要迁移和被迁移的节点,将不允许被迁移的节点设置为不可调度。

在 node 节点上有一个 NodeUnschedulable 的标记,我们可以通过 kube-controller 对这个节点直接标记为不可调度,那这个节点就不会被调度了。在 1.16 的版本里,这个 Unschedulable 已经变成了一个 Taints。也就是说需要校验一下 Pod 上打上的 Tolerates 是不是可以容忍这个 Taints; 

[[email protected] ~]# kubectl cordon k8s-node1

[[email protected] ~]# kubectl describe node k8s-node1
node.kubernetes.io/unschedulable:NoSchedule
           
# 查看节点
kubectl get nodes

# 设置节点为不可调度
kubectl cordon <NodeName>

# 设置节点为可调度
kubectl uncordon <NodeName>
           

2. 执行kubectl drain命令

kubectl drain <NodeName> --force --ignore-daemonsets


[[email protected] ~]# kubectl drain node2 --force --ignore-daemonsets
node/node2 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-vwtrf, kube-system/kube-proxy-fpjpd, kube-system/nodelocaldns-v6fsq
node/node2 drained

[[email protected] ~]# kubectl get pod -A -o wide | grep node2
kube-system   calico-node-vwtrf                         1/1     Running   0          8d    192.168.179.104   node2    <none>           <none>
kube-system   kube-proxy-fpjpd                          1/1     Running   0          8d    192.168.179.104   node2    <none>           <none>
kube-system   nodelocaldns-v6fsq                        1/1     Running   0          8d    192.168.179.104   node2    <none>           <none>
           

示例:

$ kubectl drain bjzw-prek8sredis-99-40 --force --ignore-daemonsets
node "bjzw-prek8sredis-99-40" already cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: kube-proxy-bjzw-prek8sredis-99-40; Ignoring DaemonSet-managed pods: calicoopsmonitor-mfpqs, arachnia-agent-j56n8
pod "pre-test-pro2-r-0-redis-2-8-19-1" evicted
pod "pre-test-hwh1-r-8-redis-2-8-19-2" evicted
pod "pre-eos-hdfs-vector-eos-hdfs-redis-2-8-19-0" evicted
           

3. 特别说明

对于statefulset创建的Pod,kubectl drain的说明如下:

kubectl drain操作会将相应节点上的旧Pod删除,并在可调度节点上面起一个对应的Pod。当旧Pod没有被正常删除的情况下,新Pod不会起来。例如:旧Pod一直处于

Terminating

状态。

对应的解决方式是通过重启相应节点的kubelet,或者强制删除该Pod。

示例:

# 重启发生`Terminating`节点的kubelet
systemctl restart kubelet

# 强制删除`Terminating`状态的Pod
kubectl delete pod <PodName> --namespace=<Namespace> --force --grace-period=0
           

4. kubectl drain 流程图

Kubernets 调度 常用的命令迁移Pod

5. TroubleShooting

1、存在不是通过

ReplicationController

ReplicaSet

Job

DaemonSet

 或者

StatefulSet

创建的Pod(即静态pod,通过文件方式创建的),所以需要设置强制执行的参数

--force

$ kubectl drain bjzw-prek8sredis-99-40
node "bjzw-prek8sredis-99-40" already cordoned
error: unable to drain node "bjzw-prek8sredis-99-40", aborting command...

There are pending nodes to be drained:
 bjzw-prek8sredis-99-40
error: DaemonSet-managed pods (use --ignore-daemonsets to ignore): calicoopsmonitor-mfpqs, arachnia-agent-j56n8; pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override): kube-proxy-bjzw-prek8sredis-99-40
           

2、存在DaemonSet方式管理的Pod,需要设置

--ignore-daemonsets

参数忽略报错。

$ kubectl drain bjzw-prek8sredis-99-40 --force
node "bjzw-prek8sredis-99-40" already cordoned
error: unable to drain node "bjzw-prek8sredis-99-40", aborting command...

There are pending nodes to be drained:
 bjzw-prek8sredis-99-40
error: DaemonSet-managed pods (use --ignore-daemonsets to ignore): calicoopsmonitor-mfpqs, arachnia-agent-j56n8
           

继续阅读