Flannel 启动中的问题排查

2025/10/09 k8s 共 1612 字,约 5 分钟

Kubernetes 网络与 Flannel 故障排查


1. API Server + DaemonSet + kubelet 协作流程

Kubernetes 中,DaemonSet 用于保证每个节点上都运行特定的 Pod,例如 Flannel、Node Exporter 等。其协作流程如下:

  1. 创建 DaemonSet 对象
     kubectl apply -f kube-flannel.yml
    
    • kubectl 客户端将 YAML 文件发送给 API Server
    • API Server 将 YAML 解析为 DaemonSet 对象,并存储在 etcd 中,记录集群的期望状态。
  2. API Server 下发期望状态
    • “下发”意味着 API Server 将集群的资源对象状态(例如 Pod 应该在每个节点运行)告知各个节点的 kubelet。
    • kubelet 会定期向 API Server 查询自己负责节点的资源对象。
  3. kubelet 执行任务
    • 如果 kubelet 发现节点上缺少 DaemonSet 管理的 Pod:
      • 拉取容器镜像
      • 创建并启动容器
      • 挂载卷、配置网络
    • 当 Pod 成功运行,状态同步回 API Server。

总结

  • API Server = 指挥中心,存储期望状态
  • DaemonSet = 工作清单,定义每个节点必须运行的 Pod
  • kubelet = 执行者,按照清单在本地节点创建 Pod

这样,即使只在 master 节点执行 kubectl apply,DaemonSet 也会确保 Flannel Pod 自动在所有节点运行。


2. br_netfilter 未加载导致的 Flannel 启动问题

Flannel 在启动时依赖 Linux 内核模块 br_netfilter 来处理网桥流量。

  • 错误日志示例:
    Failed to check br_netfilter: stat /proc/sys/net/bridge/bridge-nf-call-iptables: no such file or directory
    
  • 发生原因:

    1. 内核没有加载 br_netfilter 模块。
    2. /proc/sys/net/bridge/bridge-nf-call-iptables 不存在,Flannel 无法配置 iptables 转发规则。
  • 结果:

    • Flannel Pod 启动失败,状态 CrashLoopBackOff
    • Pod 网络无法建立,业务 Pod 无法通信。

3. Flannel 修复方法

3.1 加载内核模块

sudo modprobe br_netfilter

检查模块是否加载:

lsmod | grep br_netfilter

3.2 配置 sysctl 参数

sudo sysctl -w net.bridge.bridge-nf-call-iptables=1
sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=1
sudo sysctl -w net.ipv4.ip_forward=1

3.3 永久保存配置

创建或编辑 /etc/sysctl.d/k8s.conf

sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

应用配置:

sudo sysctl --system

3.4 重启 Flannel Pod

kubectl delete pod -n kube-flannel --all

等待 Pod 自动重建:

kubectl get pods -n kube-flannel -o wide

结果

  • 所有 Flannel Pod 变为 1/1 Running
  • Pod 网络恢复
  • 业务 Pod 可以正常启动并通信

✅ 总结

  • DaemonSet + API Server + kubelet 确保 Flannel Pod 自动部署到每个节点。
  • br_netfilter 模块必须加载,否则 Flannel 无法启动,Pod 网络不可用。
  • 修复方法:加载模块、设置 sysctl 参数、删除 Pod 让 DaemonSet 自动重建。

文档信息

Search

    Table of Contents