
1. 项目概述最近在帮客户做Kubernetes集群网络改造时遇到一个典型场景原先部署在AWS VPC子网A中的RKE2集群由于网络规划调整需要整体迁移到子网B。这个看似简单的需求背后其实暗藏玄机今天就来详细聊聊如何安全地将RKE2/K3s下游集群迁移到新子网。作为Rancher的老用户我深知直接修改现有节点的网络配置会导致各种诡异问题。去年就有一个惨痛教训某生产环境因为IP变更导致etcd集群脑裂最后不得不重建整个集群。经过多次实践我总结出一套稳妥的迁移方案核心思路是新旧子网并行节点逐步替换。2. 迁移方案设计原理2.1 为什么不能直接修改现有节点网络RKE2/K3s集群的网络配置是深度耦合的主要体现在三个层面节点注册层面通过Rancher节点驱动创建的实例其网络配置安全组、子网、IP分配方式等是固化在Cloud-Init模板中的。我曾在测试环境尝试直接修改EC2实例的子网结果kubelet启动后无法加入原有集群。Kubernetes网络层面每个Node对象的status.addresses字段会记录节点的InternalIP和ExternalIP。当底层网络变更时这些IP信息不会自动更新导致kube-proxy、CNI插件等组件无法正常工作。etcd集群层面etcd成员列表中使用的是节点的固定IP。通过抓包分析发现当某节点IP变更后其他etcd节点仍会向旧IP发送心跳检测最终导致quorum丢失。2.2 新旧子网并行迁移的优势基于上述问题我们采用的迁移方案具有以下特点无单点故障始终保持etcd quorum和control-plane可用性可回滚旧节点保留至最终验证阶段最小影响工作负载逐步迁移避免批量重启3. 详细迁移步骤3.1 迁移前准备3.1.1 网络连通性检查在新子网创建测试实例验证与以下组件的连通性# 测试控制平面通信 telnet 原API Server IP 6443 # 测试节点间通信以Canal CNI为例 nc -zv 原节点IP 8472 # VXLAN端口 nc -zv 原节点IP 9099 # Canal健康检查端口3.1.2 关键备份操作etcd快照RKE2特有命令sudo rke2 etcd-snapshot \ --name pre-migration \ --s3 \ --s3-bucketyour-bucket \ --s3-regionus-west-1集群状态备份kubectl get nodes -o wide node-status.txt kubectl get pods -A -o wide pod-status.txt3.2 创建新机器池在Rancher UI中操作时有几个关键配置项需要注意角色分配策略先迁移worker节点再迁移control-plane每个etcd节点迁移前确保新etcd节点已加入quorum高级网络配置# 在cloud-config中显式指定新子网配置 network: interfaces: eth0: addresses: - 10.1.2.100/24 gateway: 10.1.2.1重要提示建议开启节点自动替换功能这样当排空旧节点时Rancher会自动补充新节点3.3 节点迁移实战技巧3.3.1 Worker节点迁移采用增-删循环策略新worker节点就绪后kubectl cordon old-node kubectl drain old-node --ignore-daemonsets --delete-emptydir-data观察工作负载迁移状态watch kubectl get pods -o wide | grep old-node3.3.2 Control Plane节点迁移特殊处理步骤先添加新control-plane节点# 检查新节点加入情况 sudo journalctl -u rke2-server -f | grep successfully established确认etcd成员状态sudo ETCDCTL_API3 etcdctl \ --endpointshttps://127.0.0.1:2379 \ --cacert/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \ --cert/var/lib/rancher/rke2/server/tls/etcd/server-client.crt \ --key/var/lib/rancher/rke2/server/tls/etcd/server-client.key \ member list移除旧节点前确保# 检查quorum健康状态 sudo ETCDCTL_API3 etcdctl endpoint health3.4 迁移后验证3.4.1 网络连通性测试# 跨节点Pod通信测试 kubectl run test-pod --imagebusybox -- sleep 3600 kubectl exec test-pod -- ping 其他节点PodIP # 服务发现测试 nslookup kubernetes.default.svc.cluster.local3.4.2 存储卷验证特别关注使用Local PV或节点绑定的存储kubectl get pv -o yaml | grep -A 3 nodeAffinity4. 常见问题排查4.1 新节点无法加入集群典型表现kubelet日志中出现x509 certificate signed by unknown authority解决方案检查新节点是否使用与原集群相同的RKE2版本验证/etc/rancher/rke2/config.yaml中的server URL配置确保新子网可以访问Rancher的TCP/443端口4.2 etcd成员列表不一致错误现象etcdctl member list显示旧节点仍存在修复步骤# 强制移除故障成员 sudo ETCDCTL_API3 etcdctl member remove 旧成员ID # 清理旧数据在新节点上 sudo rm -rf /var/lib/rancher/rke2/server/db/etcd4.3 CNI网络异常典型症状Pod间网络不通但节点间网络正常处理方案检查CNI插件Pod状态kubectl get pods -n kube-system -l appcni-plugin必要时重置CNI配置sudo rm /etc/cni/net.d/* sudo systemctl restart kubelet5. 经验总结经过多次迁移实践我总结了几个关键要点迁移顺序很重要先worker后control-plane且etcd节点要逐个替换。有次同时迁移两个etcd节点导致quorum丢失不得不从快照恢复。监控关键指标迁移过程中要密切观察etcd leader变更次数prometheus指标etcd_server_leader_changes_seen_totalAPI Server响应延迟apiserver_request_duration_secondsDNS缓存问题迁移完成后曾遇到CoreDNS继续解析旧节点IP的情况通过重启coredns Pod解决kubectl rollout restart deployment coredns -n kube-system客户端配置更新别忘了更新以下客户端的kubeconfigCI/CD系统的集群配置开发者的本地kubectl配置监控系统的抓取配置