Skip to content

192.168.122.31 集群 Master 打污点 / Worker 恢复普通副本调度手册

  • 日期:2026-08-01
  • 目标集群:API Server 192.168.122.31(Rancher/RKE 系集群)
  • 目标:
    1. 给所有 master(control-plane)节点打污点,普通业务副本(Pod)不再调度到 master;
    2. 移除 worker 节点上驱逐/排斥普通副本的污点,普通副本只落在 worker 上。

1. 背景与原理

  • 污点(Taint)与容忍(Toleration):节点打了 NoSchedule 污点后,只有带对应 toleration 的 Pod 才能调度上来;NoExecute 污点会同时驱逐已运行的不容忍 Pod。
  • master 节点默认应只跑系统组件(apiserver、etcd、controller-manager 等,这些组件自带 toleration),普通副本不应占用 master 资源。
  • 若 worker 之前被打过污点(如维护时打的 node.kubernetes.io/unschedulable、自定义 dedicated 等),需要移除,否则普通副本无处可去。

2. 前置条件

bash
# 在有 kubectl 的机器上配置好该集群的 kubeconfig
export KUBECONFIG=~/.kube/192.168.122.31.yaml
kubectl get nodes -o wide

确认能列出节点后再继续。

3. 查看现状

bash
# 查看所有节点角色
kubectl get nodes -o wide --show-labels | grep -E 'control-plane|master|worker'

# 查看所有节点现有污点(重点!)
kubectl get nodes -o json | \
  jq -r '.items[] | "\(.metadata.name)\t\( [.spec.taints[]? | "\(.key)=\(.value // ""):\(.effect)"] | join(", ") )"'

记录输出,后面操作完逐项对比。

4. Master 节点打污点

每个 master 节点执行:

bash
MASTER_NODES=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o name)
# 老版本集群标签可能是 node-role.kubernetes.io/master=true,按实际调整

for n in $MASTER_NODES; do
  kubectl taint nodes $n node-role.kubernetes.io/control-plane=true:NoSchedule --overwrite
done

说明:

  • NoSchedule 而不是 NoExecute:只阻止新副本调度上来,不会立即驱逐 master 上已运行的普通 Pod,避免业务闪断。
  • 如需把 master 上已存在的普通副本赶走,见第 6 节。
  • --overwrite 避免 key 已存在时报错。

5. 移除 Worker 节点的驱逐污点

5.1 移除指定污点(推荐,精准)

根据第 3 节查到的 worker 污点逐个移除,污点 key 后加 - 表示删除:

bash
# 示例:去掉维护期打的污点
kubectl taint nodes <worker-name> dedicated-

# 示例:去掉不可调度污点
kubectl taint nodes <worker-name> node.kubernetes.io/unschedulable-

去掉污点时可带 effect 精确匹配,如 dedicated=true:NoSchedule-;不带 effect 则删除该 key 的所有 effect。

5.2 批量移除 worker 上所有自定义污点(谨慎)

bash
for n in $(kubectl get nodes -l '!node-role.kubernetes.io/control-plane' -o name); do
  echo "== $n =="
  kubectl get $n -o jsonpath='{.spec.taints}' ; echo
done
# 确认无误后再执行删除,切勿误删 longhorn/存储类专用污点

注意:如果 worker 上有故意保留的污点(如存储节点专用 storage=true:NoSchedule),不要删,只删驱逐普通副本的那条。

6. (可选)驱逐 master 上已存在的普通副本

NoSchedule 不影响存量 Pod。若要把 master 上已运行的普通副本迁走:

bash
# 方式一:温和重启,由 Deployment 控制器把副本重新调度到 worker
kubectl get pods -A -o wide --field-selector spec.nodeName=<master-name> | grep -v -E 'kube-system|cattle-system'

# 对查出的普通业务 Pod 逐个 delete(确保是多副本!)
kubectl -n <ns> delete pod <pod-name>

# 方式二:临时加 NoExecute 污点强制驱逐,完成后改回 NoSchedule
kubectl taint nodes <master-name> node-role.kubernetes.io/control-plane=true:NoExecute --overwrite
# 确认普通副本全部迁走后:
kubectl taint nodes <master-name> node-role.kubernetes.io/control-plane=true:NoSchedule --overwrite

DaemonSet 类型的系统组件一般自带 toleration,不受影响,无需处理。

7. 验证

bash
# ① 污点终态检查:master 有 NoSchedule 污点,worker 无驱逐污点
kubectl get nodes -o json | \
  jq -r '.items[] | "\(.metadata.name)\t\( [.spec.taints[]? | "\(.key)=\(.value // ""):\(.effect)"] | join(", ") )"'

# ② 调度测试:起一个 3 副本测试 Deployment,应全部落在 worker
kubectl create deploy taint-test --image=nginx --replicas=3
kubectl get pods -o wide -l app=taint-test

# ③ 清理
kubectl delete deploy taint-test

8. 回滚

bash
# 撤销 master 污点
kubectl taint nodes <master-name> node-role.kubernetes.io/control-plane:NoSchedule-

# 恢复 worker 污点(按需补回)
kubectl taint nodes <worker-name> <key>=<value>:<effect>