本文主要记录在 kubeadm 搭建的 Kubernetes 集群中批量调整节点主机名时的操作:先统一 /etc/hosts,再对 Worker 做 drain → delete node → kubeadm reset → 重新 join;Control-Plane 侧补充证书 SAN 与配置中的 API 地址调整要点。

需要注意的是:kubeadm reset 会清理本机 Kubernetes 相关状态,等同于节点离队;生产环境必须在维护窗口操作,并确认业务已迁移或可中断。下文 IP、域名与 token 均为占位或已脱敏示意,禁止把真实 bootstrap token / certificate-key 写进仓库

背景说明

常见诉求:集群内节点仍使用旧命名(例如带 CNI 或网段前缀的主机名),希望改成统一规范,同时让 kubectl get nodes 中的 NAME 与系统 hostname 一致。

角色推荐思路
Workerdrain → 删 Node 对象 → 改 hostname → reset → 重新 join
Control-Plane风险更高;涉及 etcd 成员名、证书 SAN、kubeadm-config 等,需分步验证

本文环境示例(历史记录,数值请按现场替换):

项目取值(示例)
发行方式kubeadm
版本v1.26.0
运行时containerd 1.6.x
节点规模3× control-plane + 3× worker
API 入口<apiserver-host>:8443 或 VIP <api-vip>:8443

准备工作

更新全集群 /etc/hosts

在所有节点写入新主机名与 IP 的映射,旧映射可暂时保留,避免切换窗口 DNS/解析中断:

127.0.0.1   localhost localhost.localdomain
::1         localhost localhost.localdomain

<api-vip>    <apiserver-host>
<master-1-ip>  <master-1-old-name>  <master-1-new-name>
<master-2-ip>  <master-2-old-name>  <master-2-new-name>
<master-3-ip>  <master-3-old-name>  <master-3-new-name>
<worker-1-ip>  <worker-1-old-name>  <worker-1-new-name>
...

确认节点间可用新主机名互通(ping/getent hosts)。若依赖外部 DNS,还应同步 DNS 记录。

确认当前节点列表

kubectl get nodes -o wide

记录待改名节点的当前 NAME、角色与是否 Ready。

修改 Worker 节点

对每个 Worker 按下列顺序执行(一次一台更稳妥)。

驱逐并删除 Node 对象

在可操作 apiserver 的控制面或管理机上:

kubectl drain <worker-old-name> --ignore-daemonsets --delete-emptydir-data
kubectl delete node <worker-old-name>

drain 参数按业务调整;有 local PV / 特殊 DaemonSet 时需额外评估。删除后 kubectl get nodes 中不应再出现该旧名。

节点本机改名并 reset

在目标 Worker 上:

hostnamectl set-hostname <worker-new-name>

systemctl stop kubelet
# 视环境清理配置目录(破坏性,确认无误再执行)
rm -rf /etc/kubernetes/*

kubeadm reset
# reset 交互确认后,按提示清理网络规则(示意)
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
ipvsadm -C   # 若使用 IPVS;未安装则跳过

kubeadm reset 具体是否删除 CNI 配置、是否保留某些目录,以当前版本提示为准。

重新加入集群

在控制面生成 join 命令:

kubeadm token create --print-join-command

输出形如(token 与 hash 已脱敏):

kubeadm join <apiserver-host>:8443 \
  --token <bootstrap-token> \
  --discovery-token-ca-cert-hash sha256:<ca-cert-hash>

在 Worker 上执行上述 kubeadm join。回到控制面检查:

kubectl get nodes -o wide

期望新主机名以 Ready 出现,INTERNAL-IP 正确,版本与 runtime 符合预期。

历史环境示意(字段已脱敏):

NAME                 STATUS   ROLES    AGE    VERSION   INTERNAL-IP
<worker-new-a>       Ready    <none>   2m     v1.26.0   <worker-ip-a>
<worker-new-b>       Ready    <none>   38s    v1.26.0   <worker-ip-b>
...
<master-...>         Ready    control-plane   ...

对剩余 Worker 重复本节。

修改 Control-Plane 节点

Control-Plane 改名比 Worker 复杂,本文仅记录当时用到的若干步骤,不是完整 HA 滚动改名手册。生产前请对照当前 kubeadm 版本文档,并在测试集群演练。

导出并备份配置与证书

kubectl get cm kubeadm-config -n kube-system -o yaml > kubeadm-config.yaml
cp -a /etc/kubernetes/pki/ /etc/kubernetes/pki.bak

调整 ClusterConfiguration 中的名称与 SAN

从 ConfigMap / 初始化配置中整理出 InitConfiguration + ClusterConfiguration(字段以 v1beta3 为例),重点检查:

  • nodeRegistration.name:节点注册名
  • controlPlaneEndpoint:API 入口(VIP 或负载均衡)
  • apiServer.certSANs:所有会被客户端访问的 IP/DNS
  • networking.*:勿随意改已有集群的 Service/Pod CIDR

示意(地址均为占位):

apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: <master-1-ip>
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  name: <master-1-new-name>
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: 1.26.0
controlPlaneEndpoint: "<api-vip>:8443"
certificatesDir: /etc/kubernetes/pki
apiServer:
  certSANs:
  - "<api-vip>"
  - "<master-1-ip>"
  - "<master-2-ip>"
  - "<master-3-ip>"
  - "<apiserver-dns>"
networking:
  dnsDomain: <cluster-dns-domain>
  serviceSubnet: <service-cidr>
  podSubnet: <pod-cidr>

按需重签 apiserver 证书

若 SAN 变更导致证书不含新名字,可在备份 pki 后删除 apiserver 证书并按配置重生成(高风险,先备份):

rm -f /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key
kubeadm init phase certs apiserver --config <your-kubeadm-config.yaml>

成功时日志会列出证书覆盖的 DNS 与 IP(以实际输出为准)。若控制面组件仍指向旧 API 主机名,可能需要同步修改 /etc/kubernetes/*.conf 中的 server 地址,例如将旧 DNS 名替换为 VIP(改前备份 conf):

# 示例:按现场旧/新字符串替换,勿照抄
sed -i 's/<old-apiserver-dns>/<api-vip>/g' /etc/kubernetes/*conf

然后重启或确认 kubelet、静态 Pod 已加载新证书与 kubeconfig(crictl/docker 视运行时检查)。

控制面重新 join(备忘)

若某 control-plane 节点被 reset,需要带 --control-plane 与 certificate-key 再加入:

kubeadm init phase upload-certs --upload-certs
# 输出 certificate key,短时有效,勿泄露

kubeadm join <apiserver-host>:8443 \
  --token <bootstrap-token> \
  --discovery-token-ca-cert-hash sha256:<ca-cert-hash> \
  --control-plane \
  --certificate-key <certificate-key>

etcd 成员列表、旧成员清理是否成功,应用 kubectl get nodes 与 etcd 成员命令交叉验证(具体命令随 etcd 部署方式变化,待确认现场拓扑)。

验证结果

检查项期望
kubectl get nodes -o wide主机名为新规范;均为 Ready
业务 Poddrain 过的工作负载已调度到其它节点或迁回
API 访问使用 VIP/域名访问 apiserver 正常,证书 SAN 匹配(浏览器/curl 无名称不匹配错误)
解析节点间 /etc/hosts 或 DNS 与 Node 名一致

注意事项

  • bootstrap token、certificate-key、CA hash 均为敏感临时凭据,用后可作废 token。
  • iptables -F 影响本机所有链,确认无其它关键防火墙规则依赖;更稳妥可仅清理 kube-proxy/CNI 相关规则(视发行版工具)。
  • 改 control-plane 主机名若处理不当会导致 etcd/apiserver 互相找不到对端,务必逐台、可回滚。
  • 原稿后半关于 master 改名的步骤不完整;若需完整 HA 改名流程,应对照官方 Reconfiguring a kubeadm cluster / 证书管理文档补全演练后再上生产。
  • 内网 IP、真实集群域名已用占位符;公开文档不要贴未脱敏 hosts 全文。

参考资料