Kubernetes集群子网迁移实战:RKE2/K3s安全迁移方案

发布时间:2026/11/3 23:57:14
Kubernetes集群子网迁移实战:RKE2/K3s安全迁移方案

1. 项目概述

最近在帮客户做Kubernetes集群网络改造时,遇到一个典型场景:原先部署在AWS VPC子网A中的RKE2集群,由于网络规划调整需要整体迁移到子网B。这个看似简单的需求背后其实暗藏玄机,今天就来详细聊聊如何安全地将RKE2/K3s下游集群迁移到新子网。

作为Rancher的老用户,我深知直接修改现有节点的网络配置会导致各种诡异问题。去年就有一个惨痛教训:某生产环境因为IP变更导致etcd集群脑裂,最后不得不重建整个集群。经过多次实践,我总结出一套稳妥的迁移方案,核心思路是"新旧子网并行,节点逐步替换"。

2. 迁移方案设计原理

2.1 为什么不能直接修改现有节点网络?

RKE2/K3s集群的网络配置是深度耦合的,主要体现在三个层面:

  1. 节点注册层面:通过Rancher节点驱动创建的实例,其网络配置(安全组、子网、IP分配方式等)是固化在Cloud-Init模板中的。我曾在测试环境尝试直接修改EC2实例的子网,结果kubelet启动后无法加入原有集群。

  2. Kubernetes网络层面:每个Node对象的status.addresses字段会记录节点的InternalIP和ExternalIP。当底层网络变更时,这些IP信息不会自动更新,导致kube-proxy、CNI插件等组件无法正常工作。

  3. 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 关键备份操作
  1. etcd快照(RKE2特有命令):
sudo rke2 etcd-snapshot \ --name pre-migration \ --s3 \ --s3-bucket=<your-bucket> \ --s3-region=us-west-1
  1. 集群状态备份:
kubectl get nodes -o wide > node-status.txt kubectl get pods -A -o wide > pod-status.txt

3.2 创建新机器池

在Rancher UI中操作时,有几个关键配置项需要注意:

  1. 角色分配策略:

    • 先迁移worker节点,再迁移control-plane
    • 每个etcd节点迁移前确保新etcd节点已加入quorum
  2. 高级网络配置:

# 在cloud-config中显式指定新子网配置 network: interfaces: eth0: addresses: - 10.1.2.100/24 gateway: 10.1.2.1

重要提示:建议开启"节点自动替换"功能,这样当排空旧节点时,Rancher会自动补充新节点

3.3 节点迁移实战技巧

3.3.1 Worker节点迁移

采用"增-删"循环策略:

  1. 新worker节点就绪后:
kubectl cordon <old-node> kubectl drain <old-node> --ignore-daemonsets --delete-emptydir-data
  1. 观察工作负载迁移状态:
watch kubectl get pods -o wide | grep <old-node>
3.3.2 Control Plane节点迁移

特殊处理步骤:

  1. 先添加新control-plane节点:
# 检查新节点加入情况 sudo journalctl -u rke2-server -f | grep "successfully established"
  1. 确认etcd成员状态:
sudo ETCDCTL_API=3 etcdctl \ --endpoints=https://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
  1. 移除旧节点前确保:
# 检查quorum健康状态 sudo ETCDCTL_API=3 etcdctl endpoint health

3.4 迁移后验证

3.4.1 网络连通性测试
# 跨节点Pod通信测试 kubectl run test-pod --image=busybox -- sleep 3600 kubectl exec test-pod -- ping <其他节点PodIP> # 服务发现测试 nslookup kubernetes.default.svc.cluster.local
3.4.2 存储卷验证

特别关注使用Local PV或节点绑定的存储:

kubectl get pv -o yaml | grep -A 3 nodeAffinity

4. 常见问题排查

4.1 新节点无法加入集群

典型表现:kubelet日志中出现"x509 certificate signed by unknown authority"

解决方案:

  1. 检查新节点是否使用与原集群相同的RKE2版本
  2. 验证/etc/rancher/rke2/config.yaml中的server URL配置
  3. 确保新子网可以访问Rancher的TCP/443端口

4.2 etcd成员列表不一致

错误现象:etcdctl member list显示旧节点仍存在

修复步骤:

# 强制移除故障成员 sudo ETCDCTL_API=3 etcdctl member remove <旧成员ID> # 清理旧数据(在新节点上) sudo rm -rf /var/lib/rancher/rke2/server/db/etcd

4.3 CNI网络异常

典型症状:Pod间网络不通,但节点间网络正常

处理方案:

  1. 检查CNI插件Pod状态:
kubectl get pods -n kube-system -l app=cni-plugin
  1. 必要时重置CNI配置:
sudo rm /etc/cni/net.d/* sudo systemctl restart kubelet

5. 经验总结

经过多次迁移实践,我总结了几个关键要点:

  1. 迁移顺序很重要:先worker后control-plane,且etcd节点要逐个替换。有次同时迁移两个etcd节点导致quorum丢失,不得不从快照恢复。

  2. 监控关键指标:迁移过程中要密切观察:

    • etcd leader变更次数(prometheus指标etcd_server_leader_changes_seen_total)
    • API Server响应延迟(apiserver_request_duration_seconds)
  3. DNS缓存问题:迁移完成后曾遇到CoreDNS继续解析旧节点IP的情况,通过重启coredns Pod解决:

kubectl rollout restart deployment coredns -n kube-system
  1. 客户端配置更新:别忘了更新以下客户端的kubeconfig:
    • CI/CD系统的集群配置
    • 开发者的本地kubectl配置
    • 监控系统的抓取配置