Kubernetes 集群节点生命周期管理实战:从扩容、调度管控到证书续期

Kubernetes 集群节点生命周期管理实战:从扩容、调度管控到证书续期

适用场景:基于 kubeadm 部署的生产级 K8s 集群(尤其适用于大规模 GPU / AI 计算集群)

操作风险:节点摘除涉及 Pod 驱逐,证书续期涉及控制面重启,务必在维护窗口执行

核心经验:多轮扩容必有 token 管理痕迹;证书续期必须所有 Master 节点都执行


一、背景与典型运维场景

在 AI/GPU 集群的日常运维中,节点的生命周期操作远比普通业务集群频繁:

  • 多轮扩容:业务增长导致需要分批加入大量 GPU 节点,每批使用不同 token
  • 节点维护:硬件故障、内核升级、驱动更新需要安全驱逐 Pod 并禁调度
  • 资源标记:不同批次、不同型号(如 A100-SXM4-80GB)的 GPU 需要精细化打标
  • 证书过期:kubeadm 集群运行一年后 API Server 证书过期,导致节点 NotReady

下面把实际用过的命令和手法按场景拆解。


二、节点加入:多轮扩容的正确姿势

2.1 标准 join 命令

bash 复制代码
kubeadm join api.k8s.local:8443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

2.2 多轮扩容的 token 管理

生产环境中经历过多次扩容,每轮都会生成新的 token。当 token 过期(默认 24 小时)或丢失时,需要在 Master 上重新生成:

bash 复制代码
生成新 token

kubeadm token create

获取 discovery-token-ca-cert-hash(如果没有现成的)

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
  openssl rsa -pubin -outform der 2>/dev/null | \
  openssl dgst -sha256 -hex

💡 经验:大规模扩容时建议将 join 命令、token、hash 值按批次记录到运维文档中,方便回溯。


三、节点调度管控:cordon / drain / uncordon

3.1 禁止调度(Cordon)

维护前先让节点不再接收新 Pod:

bash 复制代码
#单节点
kubectl cordon <node-name>

#批量禁调度所有节点
kubectl cordon $(kubectl get nodes -o name)

#按 label 选择器批量禁调度
kubectl cordon -l gpu_type=nvidia_a100-80gb

3.2 安全驱逐(Drain)

bash 复制代码
节点下线或重启前的标准操作,驱逐现有 Pod 并确保服务不中断:

kubectl drain <node-name> \
  --delete-local-data \
  --force \
  --ignore-daemonsets

参数说明:

参数 作用
--delete-local-data 删除依赖本地存储的 Pod(如 emptyDir)
--force 强制驱逐不属于 RC/RS/DaemonSet 的裸 Pod
--ignore-daemonsets 忽略 DaemonSet 管理的 Pod(如 kube-proxy、日志采集)

3.3 恢复调度(Uncordon)

维护完成后重新开放节点:

bash 复制代码
kubectl uncordon <node-name>

四、节点标签管理:精细化资源标记

在 GPU/AI 集群中,标签是调度器识别硬件能力的关键依据。以下是实际环境中按批次、按硬件型号打标的完整示例:

#GPU 驱动与型号标记

bash 复制代码
kubectl label node <node-name> gpu_type=nvidia_a100-80gb

#网络加速能力标记

bash 复制代码
kubectl label node <node-name> accelerator/rdma=true

集群角色标记(多租户/多集群场景)

bash 复制代码
kubectl label node <node-name> ggg/role=eflops-gpu
kubectl label node <node-name> ggg/role=ai-cluster-gpu
kubectl label node <node-name> vgpu=true

扩容批次标记(用于按批次运维)

bash 复制代码
kubectl label node <node-name> kuorong=20240319

标签命名规范建议:

维度 示例 用途
硬件型号 gpu_type=nvidia_a100-sxm4-80gb 调度器按卡型分配任务
网络能力 accelerator/rdma=true 识别是否支持 RDMA 高速网络
业务角色 role=eflops-gpu 区分不同业务线的节点池
运维批次 kuorong=20240319 按扩容批次做批量操作

五、节点摘除与删除

节点彻底下线时的标准流程:

bash 复制代码
1. 先 drain 驱逐(如果节点还在线)
kubectl drain <node-name> --delete-local-data --force --ignore-daemonsets

2. 删除节点对象
kubectl delete node <node-name>

3. 在节点本机执行 kubeadm reset(如果节点还能登录)
kubeadm reset -f

六、kubeadm 证书续期(最容易翻车的维护项)

6.1 检查证书过期时间

bash 复制代码
kubeadm alpha certs check-expiration

输出会显示所有证书的过期时间,重点关注:

  • apiserver 证书(默认 1 年)
  • apiserver-kubelet-client
  • front-proxy-client
  • etcd-server / etcd-peer / etcd-healthcheck-client

6.2 执行续期

bash 复制代码
kubeadm alpha certs renew all

6.3 关键提醒:所有 Master 节点都要执行

这是生产环境最常见的坑:只在其中一台 Master 上续期证书,其他 Master 的 API Server 仍然使用旧证书,导致集群出现间歇性 NotReady。

正确流程:

bash 复制代码
1. 在每台 Master 上分别执行续期
kubeadm alpha certs renew all

2. 重启控制面组件(每台 Master 上)

如果是 static pod 方式(大多数 kubeadm 集群)
直接删除旧 pod 让 kubelet 重建
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/ && sleep 5 && mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
mv /etc/kubernetes/manifests/kube-controller-manager.yaml /tmp/ && sleep 5 && mv /tmp/kube-controller-manager.yaml /etc/kubernetes/manifests/
mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/ && sleep 5 && mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/
  1. 验证
bash 复制代码
kubectl get nodes

七、踩坑清单

现象 排查方向
kubeadm join 报 token expired token 默认 24h 过期,重新 kubeadm token create
drain 卡住不动 有 Pod 没有 PodDisruptionBudget 或 PDB 限制太严,加 --pod-selector 缩小范围
uncordon 后 Pod 不回来 检查是否有其他 taint/toleration 限制,或资源不足
证书续期后 API Server 起不来 检查 /etc/kubernetes/pki 下证书是否真的更新了,确认所有 Master 都执行了
节点 join 后一直 NotReady 检查 CNI 插件是否正常、kubelet 是否运行、防火墙是否放行 10250
label 打了不生效 确认 label key 格式合规(DNS 子域名格式),检查调度器日志

八、小结

K8s 节点生命周期管理的核心经验:

  1. 扩容有痕:每轮 join 的 token 和节点清单做好记录,方便回溯和排错
  2. 摘节点先 cordon 再 drain:顺序不能反,参数不能省
  3. 标签是调度的基石:GPU 型号、RDMA 能力、批次信息全部通过 label 表达
  4. 证书续期要全量:所有 Master 节点都要执行,且要重启控制面组件

相关推荐
weixin_416667961 小时前
linux ping命令详解
linux·运维·php
润滑卫士1 小时前
NAS 1638 油液清洁度等级:检测方法、影响因素与控制策略
运维
硅基手札1 小时前
【Linux 内核专栏 17】进程间通信 IPC(上)— 管道·信号·System V IPC·mmap·文件锁
linux·运维·服务器·stm32·单片机·mcu
seuzhouchenglong1 小时前
服务器通过本地电脑连接本地开发板
运维·服务器
AR-26710-1 小时前
Linux Day21——systemctl操作
linux·运维
闲云自留地2 小时前
Kubernetes 安装保姆级:关 swap、装 containerd、init 集群、calico 一篇通
容器·贪心算法·kubernetes
木雷坞2 小时前
Docker Compose部署Metabase:应用库隔离与日期筛选看板
运维·docker·容器
讯捷蓝达2 小时前
台山曙光I620-G20服务器RAID5离线数据恢复全过程
运维·服务器
怒放的生命19912 小时前
前端项目 Docker 打包实操指南
前端·docker·容器