选错CNI插件不会导致集群启动失败,但会引发CoreDNS Pending、Pod跨节点不通或节点NotReady;根本原因是kubelet等待CNI就绪,若/etc/cni/net.d为空、配置错误或插件缺失,将持续报NetworkPluginNotReady。

选错 CNI 插件不会直接导致集群起不来,但会卡在 kubeadm init 后的 CoreDNS Pending、Pod 无法跨节点通信、或 kubectl get nodes 显示 NotReady —— 这些都是网络插件没生效的明确信号。
为什么 kubeadm init 后节点长期 NotReady
根本原因不是 kubelet 没启动,而是 kubelet 等待 CNI 就绪:它读取 /etc/cni/net.d/ 下的配置文件,调用对应插件二进制,再等待返回 IP 分配结果。如果该目录为空、配置格式错误、或插件二进制缺失/权限不对,kubelet 就会持续报 NetworkPluginNotReady。
-
kubectl get nodes -o wide查看INTERNAL-IP是否有值;若为空,说明节点网络未初始化 -
journalctl -u kubelet -n 100 --no-pager | grep -i cni通常会暴露具体失败点,比如failed to load network config: no valid networks found in /etc/cni/net.d - Flannel 默认写配置到
/etc/cni/net.d/10-flannel.conflist,Calico 是10-calico.conflist,名称不匹配会导致忽略
Flannel、Calico、Cilium 的实际差异在哪
不是“谁更好”,而是“谁更适配当前环境”。关键分水岭在三点:是否需要策略控制、是否要求高性能、是否接受内核依赖。
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
- Flannel:只解决“通不通”,不提供 NetworkPolicy。VXLAN 后端兼容性最好,但 Overlay 带来约 5–10% 的吞吐损耗;Host-GW 模式零损耗,但强制所有节点二层互通(不能跨 VPC 或不同交换机)
- Calico:默认启用 BGP 直接路由,性能接近 Host-GW;
ipipMode: Always会退化为隧道模式,仅在跨子网时必要;它的NetworkPolicy实现成熟,但对 iptables 链深度有要求,某些精简版 OS(如 Alpine 容器)可能缺模块 - Cilium:依赖 eBPF,需 Linux kernel ≥ 4.19;策略执行和可观测性最强,但调试门槛高;
cilium status报KubeProxyReplacement: Partial表示部分功能降级,常见于未关闭kube-proxy或内核配置缺失
配置前必须确认的三个硬性前提
跳过这三步,90% 的“安装失败”问题都会复现。
- 所有节点的
--pod-network-cidr必须与你选的 CNI 插件 YAML 中声明的 CIDR 完全一致。例如 Flannel 官方 manifest 默认用10.244.0.0/16,那kubeadm init --pod-network-cidr=10.244.0.0/16就不能写成10.244.0.0/24 - kubelet 必须显式启用 CNI:
--network-plugin=cni(kubeadm 默认已设,但自建 kubelet 服务时容易漏) - 容器运行时(containerd 或 dockerd)的
cri配置里,plugins."io.containerd.grpc.v1.cri".network_plugin必须为"cni",否则即使装了插件,运行时也不会调用它
验证网络是否真正就绪的最小检查清单
别只看 kubectl get pods -n kube-system 全 Running —— Calico 的 calico-node Pod 跑起来,不代表 BGP 邻居已建立;Flannel 的 kube-flannel-ds 启动成功,也不代表 VXLAN 设备已创建。
- 在任一节点执行
ip link show | grep -E "(cni|flannel|cali|lxc)",应看到类似cni0、flannel.1、caliXXXXXXXX的接口 - 运行
curl -s http://localhost:10249/metrics | grep cni_plugins_exec_total(kubelet metrics 端口),非零值表示 CNI 调用已发生 - 部署两个 Pod(如
kubectl run a --image=busybox -- sleep 3600和kubectl run b --image=busybox -- sleep 3600),用kubectl exec a -- ping -c 2 $(kubectl get pod b -o jsonpath='{.status.podIP}')测试直连;失败则立刻查iptables -t nat -L POSTROUTING是否含 SNAT 规则
最常被忽略的是:CNI 配置文件写入节点后,kubelet 不会自动 reload —— 必须重启 kubelet(systemctl restart kubelet)或等其下一次 sync loop(最长 30 秒)。这个延迟会让很多人误判插件未生效。

















