news 2026/10/22 9:50:10

Kubernetes集群Pod CIDR与Service CIDR修改实操指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes集群Pod CIDR与Service CIDR修改实操指南

改 CIDR 这种操作,平时没人愿意碰,可真轮到要碰的时候,基本都是网段规划埋下的雷炸了:集群搭到一半发现 Pod 段和内网冲突、Service 段把公司的私有网段占了、或者两套环境要合并必须统一网段。Kubernetes 的 Pod CIDR 和 Service CIDR 一旦进入生产,修改牵扯的就不是一个配置文件,而是控制面、节点、CNI、kube-proxy、DNS、所有存量 Service 和 Pod 一整条链路。

这篇文章把我完整做过的 Pod CIDR 与 Service CIDR 修改过程整理出来,包含了每一步操作、验证手段、遇到过的坑和回滚思路。特别适合集群已经建好、业务已经跑着、但因为各种原因必须调整网段的运维同学参考。内容基于 kubeadm 部署的集群展开,二进制部署的大方向一致,细节我会单独标注。整体思路不复杂,难的是顺序和耐心。

1. 先说清楚:改 CIDR 为什么不是改个参数那么简单

很多第一次接触这个操作的人,以为改 CIDR 就是去控制平面组件里把--cluster-cidr和--service-cluster-ip-range两个参数改一下,重启完事。我在早期规划集群时也这么想过,直到真正看了一遍集群里这些网段的作用链路才明白,CIDR 其实是整个集群网络的地基,改地基必须连带改地基上的每一层建筑。

1.1 CIDR 在集群里到底串起了哪些组件

先梳理一下 Pod CIDR 的完整作用链。kube-controller-manager的--cluster-cidr参数,职责是给每个 Node 划分一个spec.podCIDR子网段。例如整个 Pod 网段是 10.244.0.0/16,那么 controller-manager 拿到一台新节点,就会从里面划一个 /24 给这台节点。这个信息写在 Node 对象上,kubectl get node -o jsonpath='{.items[*].spec.podCIDR}'可以直接看到。

CNI 插件拿到 Node 上的 podCIDR 之后,才知道该给这台机器上的 Pod 从哪个子网里分配 IP。以 flannel 为例,它会读取 Node 对象上的 PodCIDR,并以此为基准创建 VXLAN 设备、维护路由表。Calico 则是通过 IPPool 和 Node 上的 podCIDR 建立映射关系,然后下发 Felix 配置。

kubelet在启动 Pod 时,会通过 CNI 插件请求分配 IP,CNI 再基于节点 PodCIDR 从对应的子网池里分配。所以如果只改了 controller-manager 的 cluster-cidr,而没有同步调整 CNI 侧的数据和路由,新 Pod 要么分到 IP 后网络不通,要么直接分配不了 IP。

Service CIDR 的作用链相对隐蔽一些。API Server 的--service-cluster-ip-range参数维护了一个 ClusterIP 分配池,所有 Service 的 ClusterIP 都从这个池子里分配。kube-proxy 在 node 上监听 Service 和 EndpointSlice 的变化,生成 iptables 或 IPVS 规则时,需要知道 Service 的 ClusterIP 属于哪个网段,以便做地址过滤和转发判断。CoreDNS 的 ClusterIP 也是在创建时从 Service CIDR 里分的一个固定地址,DNS 解析依赖的就是这个地址。

这样一看就明白了:Pod CIDR 改的是 Node、CNI、路由、Pod 地址四层的东西,Service CIDR 改的是 API Server 分配池、kube-proxy 规则、Service 存量对象、DNS 依赖四层的东西。任何一层漏掉,整个集群就会出现局部不通或者分配异常的诡异现象。

1.2 最容易被低估的两个链路

在实际操作里,有两条链路特别容易被低估。

第一条是 CNI 的“网段边界”校验。flannel 在kube-flannel-cfgConfigMap 里有一项Network,默认配置的是整个大网段,比如10.244.0.0/16。flannel 的 backend 在校验 Pod IP 时,会检查这个 IP 是否落在大网段范围内,一旦 Pod 的 IP 不在范围内,flannel 会直接报错拒绝启动。所以只改节点子网范围、不改大网段配置,flannel 阶段就会直接失败。Calico 则相对灵活,IPPool 是独立的 CRD 资源,只要改动 IPPool 和节点分配策略即可,不必像 flannel 那样强绑定一个全局 Network 字段。

第二条是 controller-manager 划分 Node 子网的“格式”逻辑。--cluster-cidr=10.244.0.0/16只是一个大范围,具体给每个 Node 分配多大的子网,取决于 controller-manager 的--node-cidr-mask-size参数。在 IPv4 集群里默认是 /24,也就是说一个 /16 的大网段最多容纳 256 个节点。如果你的集群节点数超过这个大网段的按 mask 计算出的上限,新节点会一直处于无 podCIDR 的状态,调度上去的 Pod 全部无法创建。这个知识点在规划新网段时很重要,改 CIDR 时最好连node-cidr-mask-size一并重新核对。

所以改 CIDR 前,脑子里必须画清楚这张链路图:网段参数 → Controller-manager 划段 → Node 对象 → CNI 分配 → Pod 地址 → 路由/iptables 规则 → 应用访问。改的是参数,实际动的是整条链路。

2. 动手之前:先摸清现状并确定迁移策略

盲目改参数是最危险的,改之前必须把集群当前的全部网段状态、安装方式、CNI 类型和业务依赖摸清楚。我一般按下面几条线去收集信息。

2.1 收集当前网段全景信息

先把正在使用的 Pod CIDR 和 Service CIDR 完整列出来,这一步是后面所有判断的基础。

# 查看当前 Node 上的 PodCIDR kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.spec.podCIDR}{"\n"}{end}' # 查看所有 Service 的 ClusterIP 分布 kubectl get svc -A -o wide # 查看集群配置中声明的网段(kubeadm 方式) kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' | grep -A5 networking

还需要确认 CNI 类型和配置:

# flannel 查看 ConfigMap kubectl -n kube-flannel get cm kube-flannel-cfg -o yaml # calico 查看 IPPool kubectl get ippool -A

收集这些信息有一个额外目的:判断当前集群到底是 kubeadm 初始化时一次性写好的网段,还是后来手工改过的。如果集群初始化之后从未动过网络配置,那么控制面组件的启动参数文件和 kubeadm-config ConfigMap 里的内容应该是一致的,改起来相对好对应;如果两处对不上,说明有人手工改过参数,必须以控制面真实生效的参数为准,而不是以 ConfigMap 里的为准。

2.2 明确停机窗口与风险边界

改 Pod CIDR 和 Service CIDR 不是滚动操作,它会打断集群内所有业务流量。以下是我实际做这类操作时确认过的影响边界:

  • 改 Pod CIDR 后,存量 Pod 的 IP 会全部变化。如果业务之间通过 Pod IP 直连(很多微服务调用链没走 Service,直接用了 Pod IP),必须让业务方提前知道并配合切换。
  • 改 Service CIDR 后,所有 Service 的 ClusterIP 都会变。ClusterIP 被写死在配置文件或注册中心里的服务,需要同时改配置。这个影响面往往比 Pod IP 变化更广,因为外部系统对接集群内服务时,用的基本都是 Service 的 ClusterIP。
  • 改网段期间集群网络会处于不可用或半可用状态,必须规划一个明确的窗口期,并且预备好回滚路径。
  • 有状态应用、StatefulSet、数据库相关的服务,宁可先停掉也不要强行迁,因为 IP 变化对它们的数据面和会话保持影响很大。

我的建议是,一个测试集群或者说能容忍长时间停机的环境,优先做一次完整演练,把时间开销和意外情况都跑一遍。生产环境迁移时,按照“先加新网段、再迁数据面、最后删除旧网段”的原则操作,不要想着一刀切直接替换。

2.3 确定本次迁移的类型

不是所有情况都需要同时改动两个 CIDR。常见的组合和场景如下:

场景改动范围操作复杂度
仅 Pod 网段冲突只改 Pod CIDR,Service CIDR 不变中等
仅 Service 网段冲突只改 Service CIDR,Pod CIDR 不变中等
两网段都需要调整同时改两个 CIDR高
只是缩容或扩容,CIDR 不变不需要改 CIDR,改 node-cidr-mask-size 或 IPPool低

评估完类型之后,再决定采用“一次性替换”还是“双网段并行迁移”。多数生产环境我推荐双网段并行:先把新网段配置进去,让集群开始支持新网段的 IP,然后把工作负载一批批迁移过去,最后再剥掉旧网段。虽然这个方案的时间周期更长,但它能在每一步都保留回退空间,不至于一步错全部崩盘。

3. 修改 Pod CIDR 的完整操作链路

在 kubeadm 部署的集群里,Pod CIDR 的修改,核心落在四个地方:controller-manager 启动参数、Node 对象上的 podCIDR、CNI 插件配置、节点上的路由与接口状态。下面按执行顺序拆开讲。

3.1 修改 controller-manager 层面

在控制平面节点上,编辑 kube-controller-manager 的静态 Pod 清单:

vim /etc/kubernetes/manifests/kube-controller-manager.yaml

找到--cluster-cidr参数,改为新规划的 Pod 网段:

- --cluster-cidr=10.250.0.0/16 - --node-cidr-mask-size=24

静态 Pod 的清单文件一旦发生变化,kubelet 会自动检测并重启对应的容器,不需要手动操作。重启后验证一下容器是否正常:

kubectl -n kube-system get pod | grep controller-manager

从这以后,新加入集群的 Node 会开始从新网段分配spec.podCIDR。但对于已经存在的 Node,它们原来拿到的 podCIDR 不会自动更新,需要手工处理。

注意,kubeadm-configConfigMap 里也保存了一份网段信息。如果集群后续会复用kubeadm upgrade apply这类工具,建议同步更新 ConfigMap,否则升级时可能重新把旧网段带回来过一次:

kubectl -n kube-system edit configmap kubeadm-config

在data.ClusterConfiguration.networking下,把podSubnet改成新网段。

3.2 逐台处理节点上的 podCIDR 和 CNI 数据

处理存量节点最稳妥的方式是逐台操作,而不是一次性全部改动。下面以其中一台节点 worker-01 为例。

第一步,驱逐节点上的全部工作负载:

kubectl drain worker-01 --ignore-daemonsets --delete-emptydir-data

执行 drain 后,节点上的 Pod 会被调度到其他节点,但节点本身仍是 Ready 状态。此时如果改掉了它的 podCIDR,原有 Pod 已经不在节点上了,不会产生并发干扰。

第二步,删除节点上现有的 CNI 配置和虚拟网络数据。这一步是很多人体会不到“只是改配置但网络不动”的直接原因。以 flannel 为例,节点上残留的cni0、flannel.1接口和/var/lib/cni/下的旧缓存,必须清理,否则新 Pod 启动时,CNI 会拿着旧接口状态和旧路由继续干活:

rm -rf /var/lib/cni/networks/* rm -rf /var/lib/cni/state ip link delete cni0 ip link delete flannel.1

如果是 Calico 集群,则不需要删除这些接口,但需要确认该节点的felix配置和 IPPool 分配情况,必要时删除旧 binding 记录,让 Calico 重新为该节点分配新网段的 IP。Calico 的清理动作我更倾向于在 IPPool 层面做:

# 先确认旧的 IPPool 和新网段的 IPPool 同时存在 calicoctl get ippool

第三步,修改节点对象上的spec.podCIDR:

kubectl patch node worker-01 --type='json' -p='[{"op":"replace","path":"/spec/podCIDR","value":"10.250.1.0/24"}]'

也可以直接kubectl edit node worker-01修改spec.podCIDR。这里有一个细节:controller-manager 的--cluster-cidr改完之后,新 Node 会自动拿到新网段,但旧 Node 的spec.podCIDR是历史分配结果,不会自动重算,所以手动 patch 是必须的。

第四步,uncordon 节点并让工作负载重新调度回来:

kubectl uncordon worker-01

新调度到该节点的 Pod,其 IP 会从新的 podCIDR 子网分配。

3.3 修改 flannel 或 Calico 的全局网段边界

这一步漏掉的话,最常见的现象就是:Pod 创建成功但一直 ContainerCreating,kubectl describe pod里报 CNI 插件分配地址失败。

flannel 集群需要通过 ConfigMap 修改它的全局 Network 字段:

kubectl -n kube-flannel edit cm kube-flannel-cfg

把 net-conf.json 里的Network改为和新的 Pod CIDR 一致:

{ "Network": "10.250.0.0/16", "Backend": { "Type": "vxlan" } }

改完 ConfigMap 之后,需要重启每一台节点上的 flannel DaemonSet Pod,让新的网络配置生效:

kubectl -n kube-flannel rollout restart daemonset kube-flannel-ds

Calico 集群则需要创建新的 IPPool,并且把节点分配策略切到新 IPPool 上:

cat <<EOF | kubectl apply -f - apiVersion: crd.projectcalico.org/v1 kind: IPPool metadata: name: new-pod-cidr spec: cidr: 10.250.0.0/16 ipipMode: Never natOutgoing: true disabled: false nodeSelector: all() EOF

老 IPPool 先不要删除,保证存量 Pod 还在跑;等所有 Pod 迁出旧网段后,再禁用并删除旧 IPPool。

3.4 验证 Pod 网段切换是否真的生效

改完全链路之后,不能只看 Pod 在 Running 就认为成功了,我习惯用下面四条命令做完整验证:

# 1. 确认节点上的 podCIDR 已经切到新网段 kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.spec.podCIDR}{"\n"}{end}' # 2. 在集群内起一个测试 Pod,看它的实际 IP kubectl run nettest --image=registry.local/busybox:1.36 -- sleep 3600 kubectl get pod nettest -o wide # 3. 新增 Pod 的 IP 必须在新的子网范围内 # 4. 从任意一个 Pod 去 ping 不同节点上的其他 Pod,验证跨节点通信 kubectl exec nettest -- ping -c 2 <另一个节点的 Pod IP>

这一步最容易出现的故障是 Pod 能起来、IP 也是新网段,但跨节点通信不通。原因是 CNI 数据面清理不彻底,旧路由残留。如果遇到这个问题,回到对应节点,再执行一次ip route和ip -d link,对比新旧网段的路由和接口是否同时存在,清理干净后重启该节点的 flannel Pod 一般能解决。

4. 修改 Service CIDR 的完整操作链路

Service CIDR 的修改比 Pod CIDR 更“伤筋动骨”,因为 ClusterIP 一旦重新分配,所有存量 Service 对象都必须重建。下面说清楚我怎么安全地做这一步。

4.1 修改 API Server 的 service-cluster-ip-range

kubeadm 部署的集群,API Server 同样是静态 Pod 清单。编辑/etc/kubernetes/manifests/kube-apiserver.yaml,修改--service-cluster-ip-range参数:

- --service-cluster-ip-range=10.252.0.0/16

同时更新 kubeadm-config ConfigMap 里的serviceSubnet字段,避免后续升级工具覆盖回来。保持其他参数不动,保存文件,等待 kubelet 自动重建 API Server Pod。

API Server 本身是一个集群的命脉,重启时要注意两点。第一,不要手动删除 API Server Pod,等待静态 Pod 自动滚动重建即可;第二,重启完成后立刻查看日志,确认 API Server 启动正常。如果新网段不合法或者格式有问题,API Server 会直接启动失败,这时候必须快速回滚清单文件。

此前的 Service 对象仍然在使用旧 ClusterIP,API Server 不会自动给它们重新分配。所以接下来的工作就是“重建所有 Service”。

4.2 重建 CoreDNS 等系统级 Service

系统级 Service 里,最核心的是 CoreDNS。它自身的 ClusterIP 是从 Service CIDR 里分配的,旧地址在新 CIDR 下已经失效,必须删除重建。

kubectl -n kube-system get svc kube-dns -o yaml > coredns-svc-backup.yaml kubectl -n kube-system delete svc kube-dns kubectl -n kube-system apply -f coredns-svc-backup.yaml

删除重建后,CoreDNS 会拿到一个新的 ClusterIP。这里有个连锁反应:所有节点上的 kubelet 配置里,clusterDNS字段指向的是旧 CoreDNS ClusterIP。如果 kubelet 的配置是集群初始化时通过 kubeadm 写入的,那么这个配置也需要一起更新,否则节点上所有 Pod 的 DNS 解析都会失败。

查看和更新 kubelet 配置:

# 在每台节点上查看 cat /var/lib/kubelet/config.yaml | grep clusterDNS # 改为新 CoreDNS 的 ClusterIP # 例如 clusterDNS: ["10.252.0.10"]

改完之后重启 kubelet:

systemctl restart kubelet

这一步最容易踩坑的地方在于,原本 CoreDNS 的 ClusterIP 可能不是标准配置里的10.96.0.10,而是某个自定义地址。有些集群管理员会以为改完 API Server 参数后 CoreDNS 的 ClusterIP 会自动改变,实际上 Service 是创建在旧地址上的,如果不删除重建,永远拿到的是旧 IP。

对于 metrics-server、ingress-nginx 这类同样运行在 kube-system 下的服务,检查方式一致:所有ClusterIP落在旧 Service CIDR 里的 Service,都需要按“导出清单-删除-重新应用”的流程处理。

4.3 重建业务命名空间下的存量 Service

业务侧 Service 的重建思路和系统级一致,但更需要小心。因为业务 Service 可能带有复杂的 selector、externalIPs、nodePort 等配置,个别 Service 可能还手动指定过 ClusterIP。对于手动指定过 ClusterIP 的 Service,如果指定的 IP 不在新 CIDR 范围内,重建时会直接报错,必须在 YAML 里把spec.clusterIP字段删掉,让 API Server 自动分配。

我来给一个通用的批量重建思路:

# 1. 导出所有命名空间下的 Service 清单 kubectl get svc -A -o yaml > all-services-backup.yaml # 2. 批量删除业务命名空间下的 Service(建议按命名空间分批) kubectl -n <namespace> delete svc --all # 3. 重新应用原清单(需过滤掉 clusterIP 字段中旧网段的地址) kubectl -n <namespace> apply -f all-services-backup.yaml --namespace=<namespace>

实际上,kubectl apply直接使用导出的 YAML 会有问题,因为导出内容里包含了status和clusterIP等字段。我一般建议用kubectl get svc <name> -o jsonpath='{.spec}'提取核心 spec,再手工组装一个干净的 Service YAML 重新应用。如果 Service 数量很大,可以写一个脚本对全部 Service 做“提取 spec、删除 clusterIP、重新创建”的流程化处理。

重建 Service 后,所有工作负载与 Service 通信时使用的 ClusterIP 都会变。外部依赖如果写死了 ClusterIP,必须同步更新;如果是通过 DNS 名称访问,只要 CoreDNS 正常,业务侧不需要额外变更。

4.4 kube-proxy 的配置和规则清理

kube-proxy 在每台节点上有一个 ConfigMapkube-proxy,里面也有clusterCIDR字段。这个配置用于 kube-proxy 判断 Service 所属网段,虽然 kube-proxy 本身更多依赖动态监听 Service 对象,但配置里保留旧网段会带来潜在隐患。

kubectl -n kube-system edit cm kube-proxy

更新clusterCIDR字段为新网段,然后滚动重启 kube-proxy DaemonSet:

kubectl -n kube-system rollout restart daemonset kube-proxy

如果之前使用的是 iptables 模式,节点上会残留大量旧 ClusterIP 对应的 iptables 规则。虽然 kube-proxy 重启后会自动清理与现有 Service 不对应的规则,但我见过一些残留规则导致访问异常的情况。稳妥起见,在所有 Service 重建完成、业务验证正常情况下,可以清理一次 iptables 中的 kube-proxy 自定义链:

iptables -t nat -F KUBE-SERVICES iptables -t nat -F KUBE-NODEPORTS

注意,这个清理只能在 kube-proxy 正常运行且 Service 已全部重建后进行,否则会把当前有效规则也清掉,立刻引发大规模网络故障。如果你觉得这一步风险过高,可以直接跳过,重建所有 Service 后 kube-proxy 自己会生成一套新规则,残留旧规则一般不影响新 Service 的转发。

5. 踩坑清单:那些反复出现的问题

这类迁移的坑有很强的共性,我把实际操作中反复踩到的几个单独拉出来说,每个都是血泪教训。

5.1 新网段直接冲突但没提前测

最常见的场景是规划了一个新网段,觉得没问题就直接改,改完发现宿主机所在内网网段正好命中了新 Pod 网段或者 Service 网段。比如新 Pod 网段选 10.250.0.0/16,宿主机自己的管理网也是 10.250.0.0/16 的一部分,CNI 的 VXLAN 流量和宿主机的管理流量立刻打架。

预防方法很简单,改之前在所有节点上跑一遍:

ip addr ip route

确认新网段和所有节点的物理网卡、路由表没有交集。这条我放在第一,因为它是唯一一个能从根源上避免的坑,后面其他坑都只能补救。

5.2 CoreDNS 重建后 Pod 还是解析失败

这个坑我已经见过三次了。现象是 CoreDNS Pod 一直在 Running,但所有 Pod 解析集群内 Service 都失败,报错信息是server misbehaving或者直接超时。排查到最后,原因基本都指向同一个点:kubelet 的clusterDNS没有更新,还在用旧 CoreDNS ClusterIP。

这个坑之所以阴险,是因为 DNS 访问超时或 failfast 的报错五花八门,不会直接提示“kubelet config 指向的 DNS 失效”。所以我的建议是把 CoreDNS 重建和 kubelet clusterDNS 更新绑在一起做,重建完 CoreDNS 立刻检查所有节点上的 kubelet config,确认集群里每一台节点(包括控制面节点)的clusterDNS都指向新的 ClusterIP。

for node in $(kubectl get nodes -o name | cut -d/ -f2); do echo "=== $node ===" ssh $node "grep clusterDNS /var/lib/kubelet/config.yaml" done

5.3 手动指定 clusterIP 的 Service 重建时报错

有些老项目在创建 Service 时习惯手动指定 clusterIP,比如写成了clusterIP: 10.96.0.50。新 CIDR 范围是 10.252.0.0/16,这个 IP 不在范围内,重建时 API Server 会直接拒绝。更隐蔽的是,有些 YAML 是从kubectl get svc -o yaml导出的,里面老 clusterIP 被原样带出来,重新 apply 也会报错。

我的做法是写脚本把每个 Service 的spec.clusterIP字段清掉再 apply。如果你不想写脚本,也可以手动编辑每个 Service 的 YAML,删掉clusterIP行,再重新应用。

5.4 只改 Pod CIDR 但忘记清理 CNI 缓存

只改 Pod CIDR 的场景下,很多人会把各个参数都改好,但忘了 CNI 在节点上留下的缓存。结果新 Pod 调度到节点上后,CNI 插件拿着旧缓存继续工作,分配出来的 IP 还是旧网段。这个现象和 flannel 配置没改很像,排查起来比较费时间。

解决方案我在前文写过:drain 节点后,删除/var/lib/cni/下的内容,删除旧的虚拟网卡接口,再重新调度 Pod。这是“逐节点处理”环节里最关键的一步,不要跳。

5.5 回滚预案要预演到命令级别

CIDR 修改这种操作,回滚不是简单改回参数就完事。我建议在动手之前,把下面这些信息整理成文件存档:

  • 所有节点当前的 podCIDR 列表
  • kube-controller-manager.yaml、kube-apiserver.yaml 的原始内容
  • kubeadm-config ConfigMap 的原始内容
  • 所有 Service 的完整 YAML 备份
  • CoreDNS 的 Service YAML 备份
  • kube-flannel 或 Calico 的配置备份

一旦发现新网段问题无法短期内解决,就按备份逐项回滚。回滚的执行顺序是从控制面参数回滚开始,再回滚节点 podCIDR,再回滚 CNI 配置,最后恢复 Service。整个回滚过程同样需要停机窗口。

6. 验证工作的最后一公里

这部分单独说一下验证细节。前面几章已经穿插了一些验证命令,但完整的验收逻辑值得串一遍。

6.1 静态验证

检查集群层面所有网段是否统一:

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.spec.podCIDR}{"\n"}{end}' kubectl get svc -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,CLUSTERIP:.spec.clusterIP

新 Pod 网段范围内不应再有旧 IP 的 Service ClusterIP,新 Service 网段范围内不应再有旧 Pod 网段地址。

6.2 动态验证

动态验证要覆盖三类访问路径:Pod 到 Pod,Pod 到 Service,外部到 Service。

Pod 到 Pod 的验证方法,起两个分布在节点 A 和节点 B 的测试 Pod,互相 ping 和 curl。Pod 到 Service 的验证方法,在 Pod 里访问新 CoreDNS 的 ClusterIP 做 DNS 解析,再访问业务 Service 的名称解析。外部到 Service 的验证则要看 Service 类型,如果是 NodePort,对外访问地址不变(宿主机 IP+端口),只需要验证新规则是否生效;如果是 LoadBalancer,则需要配合云平台侧确认后端实例抓取是否正常。

6.3 持续观察

网段切换后的一段时间内,建议盯着这几个指标:CoreDNS 解析成功率、kube-proxy sync 是否有异常日志、CNI 插件是否持续报分配失败、节点上是否有大量容器反复重启。任何一项出现异常,都要立即对应该项涉及的链路去排查,不要等业务方报障。

我在一次实际迁移中,就是在切换后的几小时里发现有个节点上的 flannel Pod 反复 CrashLoopBackOff,排查下来发现是该节点没有正确清理旧路由,和新的 VXLAN 接口冲突,手动清理后重启恢复。如果当时直接下班,第二天必然是一堆应用报网络异常。

7. 最后分享几组实用的命令

不同安装方式和网络方案之下,命令会有差异。以下命令组合基本覆盖了 kubeadm 集群的常见场景,推荐收藏备用。

7.1 一键导出所有关键网络配置备份

# 一次性备份控制面和网络组件配置 mkdir -p /backup/k8s-net-$(date +%Y%m%d%H%M%S) cd /backup/k8s-net-$(date +%Y%m%d%H%M%S) cp /etc/kubernetes/manifests/kube-controller-manager.yaml . cp /etc/kubernetes/manifests/kube-apiserver.yaml . kubectl -n kube-system get cm kubeadm-config -o yaml > kubeadm-config.yaml kubectl -n kube-system get cm kube-flannel-cfg -o yaml > kube-flannel-cfg.yaml kubectl -n kube-system get cm kube-proxy -o yaml > kube-proxy.yaml kubectl get svc -A -o yaml > all-services.yaml

7.2 批量重建除系统级之外的 Service

# 备份并重建指定命名空间的 Service(去掉 .status 和 .metadata.uid/resourceVersion) kubectl get svc -n my-ns -o json | jq '.items[] | {metadata: {name: .metadata.name, namespace: .metadata.namespace}, spec: .spec} | .spec.clusterIP = null' > svc-clean.json kubectl delete svc -n my-ns --all # 手工拆分 json 后逐一 apply,或使用 kubectl apply -f svc-clean.json

7.3 快速检查 DNS 是否全局可用

kubectl run dnstest --image=registry.local/busybox:1.36 --rm -it --restart=Never -- nslookup kubernetes.default.svc.cluster.local

如果这条命令返回正常解析结果,说明 CoreDNS 和 kubelet 的 clusterDNS 配置已经对齐,系统级 DNS 链路基本可用了。

7.4 快速检查全集群节点路由一致性

# 在每台节点上执行 ip route | grep -E "10\.250\.|10\.252\."

检查新网段的路由是否在每台节点上都存在,且没有旧网段的残留路由。

以我的经验来说,这类网络调整方案很难第一次就100%顺畅,但只要把链路理解清楚、备份做全、逐步推进,每次都能在预定的窗口内恢复稳定。改完网段之后的那段时间,人会不自觉地反复看监控和数据面日志,这种“心里没底”的感觉恰恰说明你在意的是什么。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 9:47:44

C++手写BP神经网络移动推荐算法竞赛源码实战解析

简介&#xff1a;阿里移动推荐算法竞赛.zip 是一份面向人工智能、计算机科学与技术等相关专业学生与算法爱好者的完整竞赛项目源码&#xff0c;适合用作毕业设计课题、课程作业或推荐系统入门实战参考。压缩包共118个文件&#xff0c;约636KB&#xff0c;以33个csv数据文件、25…

作者头像 李华
网站建设 2026/10/22 9:47:26

恶意URL检测改进版:特征工程与对抗增强实战

简介&#xff1a;这份资源是机器学习检测恶意URL的改进版源码项目&#xff0c;面向计算机、人工智能、大数据、数学、电子信息等专业正在做课程设计、期末大作业或毕业设计的学生&#xff0c;以及希望上手安全检测算法的技术学习者。项目围绕恶意URL识别这一典型安全场景&#…

作者头像 李华
网站建设 2026/10/22 9:45:36

Spring Boot机票预订系统实战:从数据库设计到分布式锁

1. 项目缘起与技术选型&#xff1a;为什么要做这个机票预定系统今年年初我接手了一个模拟项目X——基于Spring Boot的航空机票预定管理系统。说实话&#xff0c;这类业务系统在Java后端开发里算是个很经典的练手项目&#xff0c;因为它的业务链路足够完整&#xff1a;从用户注册…

作者头像 李华
网站建设 2026/10/22 9:43:39

微信小程序Wi-Fi诊断源码解析:12项指标量化网络健康

简介&#xff1a;新版WIFI大师v4.47小程序源码是一套功能完备的WiFi分销系统开源实现&#xff0c;面向小程序开发者、流量主运营者及轻量级SaaS系统学习者&#xff0c;适用于快速搭建带广告变现能力的WiFi管理与分发平台。资源包含1832个文件&#xff0c;主体为1487个PHP后端逻…

作者头像 李华
网站建设 2026/10/22 9:43:35

告别热榜焦虑:三层漏斗筛选GitHub优质开源项目的工作流

清晨的闹钟刚响过一轮&#xff0c;我照例点开当天的GitHub热门项目榜单。2026年2月5日&#xff0c;原本应该是个平淡的工作日早晨&#xff0c;结果榜首的几个仓库却让我有点意外&#xff1a;有的项目一周前刚发布&#xff0c;star数已经冲到相当夸张的位置&#xff0c;但点进is…

作者头像 李华