K8s节点IP变更实战:从规划到验证的完整操作手册
1. 为什么需要变更K8s节点IP?
在实际生产环境中,Kubernetes节点IP变更的需求并不少见。最常见的情况是公司网络架构调整,比如从192.168.0.0/24网段迁移到10.0.0.0/16网段。也可能是服务器硬件升级,需要将虚拟机迁移到新的宿主机上。还有可能是安全合规要求,需要定期更换IP地址。
我遇到过最棘手的情况是某金融客户因为机房搬迁,需要将200多个K8s节点全部更换IP。当时我们团队花了整整三天时间才完成所有节点的平滑迁移。这个过程中积累的经验告诉我,IP变更绝不是简单的改个网络配置那么简单,它涉及到系统层、K8s组件层、证书层、存储层等多个维度的联动调整。
2. 变更前的准备工作
2.1 风险评估与影响分析
在动手之前,我建议你先做个全面的影响评估。列出所有依赖该节点IP的服务和组件。通常包括:
- K8s控制平面组件(apiserver、controller-manager、scheduler)
- etcd集群成员
- kubelet和kube-proxy
- CoreDNS配置
- 存储服务端点(如Ceph、NFS)
- 监控系统(Prometheus、Grafana)
- 日志收集系统(EFK)
我曾经在一个生产环境变更IP时,就因为漏掉了监控系统的配置更新,导致告警系统失效了整整一天。这个教训让我养成了做变更前先列检查清单的习惯。
2.2 备份关键数据
备份是变更操作的安全绳。我建议至少备份以下内容:
# 备份K8s配置和证书 cp -rf /etc/kubernetes /etc/kubernetes-bak cp -rf /var/lib/kubelet/pki /var/lib/kubelet/pki-bak # 备份etcd数据(如果是控制平面节点) ETCDCTL_API=3 etcdctl snapshot save /var/lib/etcd/etcd-snapshot.db \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key记得验证备份的完整性。我有次恢复时发现备份文件损坏,差点酿成事故。现在我都会用md5sum记录备份文件的校验值。
3. 分步操作指南
3.1 修改系统网络配置
首先修改网络配置文件,不同Linux发行版位置可能不同:
# Ubuntu/Debian vi /etc/netplan/00-installer-config.yaml # CentOS/RHEL vi /etc/sysconfig/network-scripts/ifcfg-eth0更新IP后别忘了修改/etc/hosts文件:
vi /etc/hosts # 将旧IP替换为新IP应用网络变更:
# Ubuntu netplan apply # CentOS systemctl restart network这里有个坑要注意:如果你是通过SSH连接的,IP变更后连接会断开。建议提前准备带外管理通道,或者在本机准备好新IP的连接配置。
3.2 更新K8s组件配置
接下来是最关键的部分——更新K8s内部配置。我推荐使用变量来操作:
oldip=192.168.0.41 newip=10.98.99.140 # 批量替换配置文件中的IP cd /etc/kubernetes find . -type f | xargs sed -i "s/$oldip/$newip/"证书处理要格外小心:
cd /etc/kubernetes/pki # 检查哪些证书包含旧IP for f in $(find -name "*.crt"); do openssl x509 -in $f -text -noout > $f.txt done grep -Rl $oldip . # 删除旧证书 rm apiserver.crt apiserver.key etcd/peer.key etcd/peer.crt etcd/server.crt etcd/server.key # 重新生成证书 kubeadm init phase certs all3.3 更新Kubeconfig文件
cd /etc/kubernetes rm -f admin.conf kubelet.conf controller-manager.conf scheduler.conf kubeadm init phase kubeconfig all cp /etc/kubernetes/admin.conf /root/.kube/config这一步经常被忽略,但非常重要。我有次就因为没更新kubelet.conf,导致节点虽然在线但无法调度Pod。
4. 配置验证与测试
4.1 检查节点状态
kubectl get nodes kubectl describe node <node-name>健康的节点应该显示Ready状态,且所有系统组件都正常运行。
4.2 更新核心配置映射
需要手动更新几个关键ConfigMap:
kubectl -n kube-system edit cm kubeadm-config # 修改3处IP kubectl -n kube-system edit cm kube-proxy # 修改1处IP kubectl -n kube-system edit cm coredns # 修改2处IP kubectl edit cm cluster-info -n kube-public # 修改1处IP这些配置如果不更新,虽然节点可能看起来正常,但某些功能会出问题。比如CoreDNS更新不及时会导致服务发现异常。
4.3 重启关键服务
systemctl daemon-reload systemctl restart docker systemctl restart kubelet重启后务必检查服务状态:
systemctl status kubelet -l journalctl -u kubelet -n 100 --no-pager5. 存储和网络特殊处理
5.1 更新存储端点
如果你的集群使用了外部存储(如NFS、Ceph),需要检查并更新所有相关的Endpoint:
kubectl get endpoints -A kubectl edit endpoints <endpoint-name> -n <namespace>我曾经遇到过一个生产事故,就是因为StorageClass的provisioner配置中写死了旧IP,导致PVC无法自动创建。
5.2 网络插件调整
不同的CNI插件处理方式不同:
- Calico:需要更新node配置
- Flannel:检查subnet.env文件
- Cilium:可能需要重启agent
以Calico为例:
kubectl -n kube-system edit ds calico-node6. 回滚方案设计
即使准备再充分,也要做好回滚准备。我的回滚checklist包括:
- 网络配置回退到旧IP
- 恢复备份的K8s证书和配置
- 回滚所有修改过的ConfigMap
- 重启相关服务
关键是要记录每个变更步骤,这样回滚时才能有的放矢。我习惯用如下命令记录操作历史:
script -a /var/log/k8s-ip-change-$(date +%Y%m%d).log7. 生产环境实战技巧
经过多次实战,我总结了几个提高成功率的关键点:
- 变更窗口选择:避开业务高峰,最好在维护窗口期操作
- 分批处理:如果是多节点集群,逐个节点变更
- 监控观察:变更后至少观察30分钟,确认监控指标正常
- 文档记录:详细记录每个步骤和结果,方便复盘
有个特别有用的调试技巧:在变更前先给节点打上taint,避免新Pod调度上来:
kubectl taint nodes <node-name> ip-change=:NoSchedule等验证通过后再移除taint。这个简单的操作帮我避免了很多次服务中断。
8. 常见问题排查
节点状态NotReady
- 检查kubelet日志:
journalctl -u kubelet -n 100 - 验证证书有效性:
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
Pod网络不通
- 检查CNI插件日志
- 验证节点路由表:
ip route list
API Server无法连接
- 检查证书SAN是否包含新IP
- 验证防火墙规则
我整理了一份完整的检查清单,包含20多个关键检查项,可以帮助你快速定位问题。
