Skip to content

RKE2 集群检查与修复报告(192.168.122.20)

  • 日期:2026-07-30
  • 节点sza122020.local(192.168.122.20,Rocky Linux 9.8,kernel 5.14.0-687.10.1.el9_8)
  • 集群:单节点 RKE2 v1.35.6+rke2r1(control-plane + etcd),CNI = Calico,kube-proxy = IPVS 模式

1. 问题现象

  • 节点 Ready,但 kube-system 下多个 helm-install-rke2-* Pod 处于 CrashLoopBackOff,导致 ingress-nginx、metrics-server、snapshot-controller 等系统组件无法部署。

  • calico-kube-controllers 持续重启,CoreDNS 就绪探针失败(0/1)。

  • 相关 Pod 日志统一报错:

    kubernetes cluster unreachable: Get "https://10.13.0.1:443/version": dial tcp 10.13.0.1:443: connect: no route to host

    Pod 无法访问 Kubernetes API 的 ClusterIP(10.13.0.1),但直接访问宿主机 IP(192.168.122.20:6443)正常。

2. 根因分析

排查发现两个叠加问题:

2.1 kube-ipvs0 接口处于 DOWN 状态(主因)

集群配置 kube-proxy-arg: proxy-mode=ipvs,所有 ClusterIP 以 /32 形式绑定在 dummy 接口 kube-ipvs0 上。该接口当时为 DOWN:

3: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN ...
    inet 10.13.0.1/32 scope global kube-ipvs0

接口 DOWN 时内核移除了对应 local 路由,Pod 发来的报文路由查找失败,宿主机回 ICMP host unreachable,客户端表现为 "no route to host"

2.2 系统 iptables.service 默认 REJECT 规则冲突(次因)

Rocky Linux 自带的 iptables.service 处于 enabled 状态,开机加载 /etc/sysconfig/iptables 中的默认规则,在 INPUT / FORWARD 链末尾追加了兜底 REJECT:

-A INPUT   -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

该规则会 REJECT 掉未被 kube-proxy/Calico 显式放行的流量(icmp-host-prohibited 在客户端同样表现为 "No route to host"),且 FORWARD 链的 REJECT 会阻断 Pod 出网流量。firewalld 未安装/未运行,此问题由 iptables.service 引起。

3. 修复步骤

bash
# 1) 启用 IPVS dummy 接口(立即生效)
ip link set kube-ipvs0 up

# 2) 禁止 iptables.service 开机恢复默认 REJECT 规则(持久化)
systemctl disable iptables
# 注意:不要 systemctl stop iptables,stop 会清空全部 iptables 规则,
# 包括 kube-proxy/Calico 的规则。

# 3) 删除兜底 REJECT 规则(立即生效)
iptables -D INPUT   -j REJECT --reject-with icmp-host-prohibited
iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited

# 4) 删除失败的 Pod 强制立即重试(CrashLoopBackOff 退避最长达 5 分钟)
kubectl -n kube-system delete pod \
  helm-install-rke2-ingress-nginx-qqf4x \
  helm-install-rke2-metrics-server-t4gcb \
  helm-install-rke2-runtimeclasses-97468 \
  helm-install-rke2-snapshot-controller-crd-wkdhz \
  helm-install-rke2-snapshot-controller-vdzpr
kubectl -n calico-system delete pod calico-kube-controllers-649b8f56f9-85fk9

修复后 5 个 helm-install Job 全部 Completed,ingress-nginx、metrics-server、snapshot-controller、calico-kube-controllers 自动部署并就绪,CoreDNS 转为 1/1 Ready。

4. 修复后验证结果

检查项结果
节点状态sza122020.local Ready(control-plane,etcd),v1.35.6+rke2r1
全部 Pod所有命名空间 Pod 均为 Running / Completed
Deployment / DaemonSetcalico、coredns、metrics-server、snapshot-controller、ingress-nginx、tigera-operator 全部 AVAILABLE
HelmChart(helm.cattle.io)8 个 chart 全部 FAILED=False
Pod → ClusterIP从 coredns Pod 内访问 https://10.13.0.1:443/version 返回 401(连通正常)
集群 DNS测试 Pod 通过 10.13.0.10 成功解析 kubernetes.default.svc.cluster.local → 10.13.0.1
iptables / ip6tables 服务均已 disabled
kube-ipvs0UP,LOWER_UP,ClusterIP 地址正常绑定

5. 集群关键配置(/etc/rancher/rke2/config.yaml

yaml
cni: calico
tls-san: [192.168.122.20, 192.168.122.21, 192.168.122.22]
node-ip: 192.168.122.20
cluster-cidr: 10.12.0.0/16
service-cidr: 10.13.0.0/16
kube-proxy-arg: ["proxy-mode=ipvs"]
system-default-registry: 192.168.122.156:30000   # 私有镜像仓库
etcd-snapshot-retention: 5
etcd-snapshot-schedule-cron: "0 */6 * * *"
service-node-port-range: "30000-60000"

kubectl 使用方式:

bash
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
export PATH=$PATH:/var/lib/rancher/rke2/bin
kubectl get nodes

6. 后续建议

  1. 确认防火墙策略:本机 firewalld 未安装、iptables.service 已禁用。若后续启用 firewalld 或 iptables-services,必须按 RKE2 官方要求放行相关端口/网段,切勿保留兜底 REJECT 规则。

  2. 关注 kube-ipvs0 状态:NetworkManager 将该接口识别为 connected (externally),目前不会干预。若重启后再现接口 DOWN,可在 NetworkManager 中将其标记为 unmanaged:

    bash
    nmcli device set kube-ipvs0 managed no
  3. tls-san 规划:配置中已预留 192.168.122.21/22,后续扩展为多 server 节点时可直接加入。

  4. etcd 快照:已配置每 6 小时自动快照、保留 5 份,位于 /var/lib/rancher/rke2/server/db/snapshots/,建议定期异地备份。


附录:worker/server 节点 192.168.122.21 / 192.168.122.22 加入失败修复(2026-07-30)

现象

  • sza122021.local(.21)和 sza122022.local(.22)两台 server 节点 rke2-server 服务卡在 activating 超过 10 分钟,节点未出现在集群中。
  • .21 日志循环报:Waiting for other members to finish joining etcd cluster: etcdserver: too many learner members in cluster
  • .22 日志循环报:Failed to test etcd connection ... dial tcp 127.0.0.1:2379: authentication handshake failed: context deadline exceeded

根因(etcd learner 死锁 + 防火墙叠加)

  1. 两台节点同时启动加入集群。etcd 只允许集群中同时存在 1 个 learner 成员:.22 先注册为 learner,.21 的 member add 因此被拒("too many learner members")。
  2. .21/.22 上存在与 .20 相同的 iptables.service 默认 REJECT 规则INPUT/FORWARD 末尾 REJECT --reject-with icmp-host-prohibited),阻断了 etcd 对等端口 2380 的入站流量,导致 learner(.22)无法从 leader 同步数据、永远无法被提升为正式成员——形成死锁。

修复步骤

bash
# 1) 两台新节点:停止服务、禁用 iptables.service、删除 REJECT 规则(同主节点修复)
systemctl stop rke2-server
systemctl disable iptables
iptables -D INPUT   -j REJECT --reject-with icmp-host-prohibited
iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited

# 2) 在 .20 上确认 etcd 成员状态(通过 etcd 容器执行 etcdctl)
export CONTAINER_RUNTIME_ENDPOINT=unix:///run/k3s/containerd/containerd.sock
ETCD_CTR=$(crictl ps --name "^etcd" -q | head -1)
crictl exec $ETCD_CTR etcdctl \
  --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 -w table
# 结果:.22 已被提升为正式成员(IS LEARNER=false),.21 未注册 → 无需 member remove

# 3) .21 从未成功加入,清理其残留 etcd 数据
ssh root@192.168.122.21 'rm -rf /var/lib/rancher/rke2/server/db'

# 4) 关键:逐个启动,避免再次出现多 learner 并发
systemctl start rke2-server   # 先在 .22(已是正式成员)
kubectl get nodes             # 等待 sza122022 Ready
systemctl start rke2-server   # 再在 .21(作为唯一 learner 加入)
kubectl get nodes             # 等待 sza122021 Ready

验证结果

  • 3 个节点全部 Ready(control-plane,etcd,v1.35.6+rke2r1)。
  • etcd:3 个成员全部 startedIS LEARNER=falseendpoint health --cluster 全部 true
  • 在 .21、.22 上分别运行测试 Pod,集群 DNS(10.13.0.10)解析正常 → 跨节点 CNI 网络正常。

附带发现与加固(三个节点统一处理)

  • kube-ipvs0(IPVS dummy 接口)在 .21/.22 上同样出现创建后 DOWN 的问题,已执行 ip link set kube-ipvs0 up 修复。

  • 为杜绝 NetworkManager 干扰 CNI 接口,三个节点均已部署 /etc/NetworkManager/conf.d/99-rke2-unmanaged.confsystemctl reload NetworkManager

    ini
    [keyfile]
    unmanaged-devices=interface-name:kube-ipvs0;interface-name:cali*;interface-name:vxlan.calico;interface-name:tunl*

    已验证:重启 kube-proxy Pod 后 kube-ipvs0 保持 UP。

  • 三个节点的 iptables / ip6tables 服务均已 disabledrke2-serverenabled(开机自启)。

经验教训

  1. RKE2 多 server 节点扩容必须逐个进行:启动一个,等其 Ready 且 etcd learner 提升完成后,再启动下一个。

  2. Rocky/RHEL 9 部署 RKE2 前必须处理防火墙:未安装 firewalld 时,iptables.service 的默认 REJECT 规则同样会阻断集群端口(etcd 2379/2380、API 6443、supervisor 9345、CNI 等),应禁用:

    bash
    systemctl disable --now iptables ip6tables
  3. 节点加入失败需重试时,若该节点从未成功加入,应先清理 /var/lib/rancher/rke2/server/db 再启动。