kaisawind's blog
  • 关于
  • 所有帖子

k8s的flannel网络pod之间不通 - Sun, Apr 12, 2020

k8s的flannel网络pod之间不通

k8s的flannel网络pod之间不通

在 Kubernetes 集群中,Flannel 是一个常用的网络插件,负责为集群提供跨主机的容器网络。当 Pod 之间无法通信时,通常与网络配置、防火墙规则、路由表等问题有关。本文将系统地介绍 Flannel 网络故障排查方法。

Flannel 网络基础

Flannel 工作原理

Flannel 通过以下方式实现跨主机容器通信:

  1. 为每个节点分配一个子网(如 10.244.0.0/16)
  2. 使用 VTEP(Virtual Tunnel End Point)设备封装网络数据包
  3. 支持多种后端网络模式:
    • VxLAN(默认,性能较好)
    • Host-GW(要求所有节点在同一二层网络)
    • UDP(兼容性好但性能较差)

网络架构

Node A                      Node B
+--------+                 +--------+
| Pod 1  |                 | Pod 2  |
| 10.244 |                 | 10.244 |
+--------+                 +--------+
    |                         |
    v                         v
+--------+                 +--------+
| cni0   |                 | cni0   |
+--------+                 +--------+
    |                         |
    v                         v
+--------+                 +--------+
| flannel|                 | flannel|
| .1     |                 | .1     |
+--------+                 +--------+
    |                         |
    +----------+              |
               |              |
           +-------+          |
           | Switch|          |
           +-------+          |
               |              |
    +----------+              v
+--------+                 +--------+
| eth0   |                 | eth0   |
+--------+                 +--------+

常见故障排查步骤

1. 检查 Pod 状态

# 查看 Pod 状态
kubectl get pods -o wide

# 查看 Pod 详情
kubectl describe pod <pod-name>

# 查看 Pod 日志
kubectl logs <pod-name>

2. 检查 Flannel Pod 状态

# 查看 kube-system 命名空间中的 Flannel Pod
kubectl get pods -n kube-system -l app=flannel

# 查看 Flannel 日志
kubectl logs -n kube-system -l app=flannel

# 查看特定节点的 Flannel 日志
kubectl logs -n kube-system flannel-xxxxx -c kube-flannel

3. 检查网络接口

# 查看网络接口
ip addr show

# 检查 cni0 接口
ip addr show cni0

# 检查 flannel.1 接口
ip addr show flannel.1

# 查看 VTEP 信息
bridge fdb show | grep flannel.1

4. 检查路由表

# 查看路由表
ip route

# 查看特定路由
ip route show | grep 10.244

# 跟踪数据包路径
traceroute <target-pod-ip>

5. 检查防火墙规则

# 查看 iptables 规则
iptables -L -n -v

# 查看 NAT 规则
iptables -t nat -L -n -v

# 查看 FILTER 规则
iptables -L FORWARD -n -v

# 清空防火墙规则(仅用于测试)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -L -n

详细的故障排查命令

完整诊断脚本

#!/bin/bash
# Flannel 网络诊断脚本

echo "=== Flannel 网络诊断 ==="
echo ""

# 1. 检查 Flannel Pod 状态
echo "1. Flannel Pod 状态:"
kubectl get pods -n kube-system -l app=flannel
echo ""

# 2. 检查网络接口
echo "2. 网络接口状态:"
echo "cni0:"
ip addr show cni0 2>/dev/null || echo "cni0 接口不存在"
echo ""
echo "flannel.1:"
ip addr show flannel.1 2>/dev/null || echo "flannel.1 接口不存在"
echo ""

# 3. 检查路由表
echo "3. 路由表 (10.244.x.x):"
ip route show | grep 10.244
echo ""

# 4. 检查 iptables 规则
echo "4. iptables FORWARD 链:"
iptables -L FORWARD -n -v | head -20
echo ""

# 5. 检查 Flannel 日志
echo "5. Flannel 最近日志:"
kubectl logs -n kube-system -l app=flannel --tail=20 2>/dev/null || echo "无法获取日志"
echo ""

# 6. 测试 Pod 连通性
echo "6. 测试 Pod 连通性:"
pods=$(kubectl get pods -o wide --no-headers | awk '{print $6}')
for pod_ip in $pods; do
    echo "测试连接到 $pod_ip:"
    ping -c 2 $pod_ip 2>&1 | grep -E "PING|bytes from|unreachable"
done
echo ""

echo "=== 诊断完成 ==="

手动测试连通性

# 进入 Pod 测试
kubectl exec -it <pod-name> -- /bin/sh

# 在 Pod 内执行
ping <target-pod-ip>
traceroute <target-pod-ip>
curl http://<target-pod-ip>:<port>

常见问题和解决方案

1. 防火墙阻止通信

症状: Pod 之间无法 ping 通,其他服务正常

解决方案:

# 临时清空防火墙规则(测试用)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F

# 永久解决方案 - 添加 Flannel 规则
iptables -A INPUT -p udp --dport 8472 -j ACCEPT
iptables -A INPUT -p udp --dport 4789 -j ACCEPT
iptables -A FORWARD -i cni0 -j ACCEPT
iptables -A FORWARD -o cni0 -j ACCEPT

2. Flannel Pod 异常

症状: Flannel Pod 处于 CrashLoopBackOff 状态

排查步骤:

# 查看详细状态
kubectl describe pod -n kube-system flannel-xxxxx

# 查看日志
kubectl logs -n kube-system flannel-xxxxx -c kube-flannel

# 查看事件
kubectl get events -n kube-system --sort-by='.lastTimestamp'

常见原因:

  • etcd 连接失败
  • 配置文件错误
  • 端口冲突
  • 资源不足

3. 路由表错误

症状: 数据包无法正确路由到目标节点

检查路由表:

# 查看当前路由
ip route show

# 应该看到类似这样的路由
# 10.244.0.0/24 via 10.244.0.0 dev flannel.1 onlink
# 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink

修复方法:

# 重启 Flannel Pod
kubectl delete pod -n kube-system -l app=flannel

# 或者手动添加路由(不推荐)
ip route add 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink

4. MTU 问题

症状: 大数据包传输失败,小包正常

解决方案:

# 检查 MTU 设置
ip link show flannel.1

# 如果需要,调整 MTU
ip link set dev flannel.1 mtu 1450

# Flannel 配置中设置 MTU
# 在 ConfigMap 中添加:
# "net-conf.json": |
#   {
#     "Network": "10.244.0.0/16",
#     "Backend": {
#       "Type": "vxlan",
#       "Port": 8472,
#       "MTU": 1450
#     }
#   }

5. 主机防火墙冲突

症状: 部分节点间无法通信

解决方案:

# Ubuntu/Debian
sudo ufw allow 8472/udp
sudo ufw allow 4789/udp
sudo ufw reload

# CentOS/RHEL
sudo firewall-cmd --permanent --add-port=8472/udp
sudo firewall-cmd --permanent --add-port=4789/udp
sudo firewall-cmd --reload

6. CNI 插件冲突

症状: 网络配置混乱

解决方案:

# 检查已安装的 CNI 插件
ls /etc/cni/net.d/

# 确保只有一个 CNI 配置文件
# 如果有冲突,删除不需要的配置

# 重启 kubelet
sudo systemctl restart kubelet

配置优化

Flannel 配置示例

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "SubnetLen": 24,
      "Backend": {
        "Type": "vxlan",
        "Port": 8472,
        "VNI": 1
      }
    }

使用 Host-GW 模式(性能更好)

net-conf.json: |
  {
    "Network": "10.244.0.0/16",
    "Backend": {
      "Type": "host-gw"
    }
  }

注意: Host-GW 模式要求所有节点在同一个二层网络中。

防火墙规则详解

基本规则

# 1. 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 2. 允许已建立的和相关的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 3. 允许 Flannel VxLAN 通信
iptables -A INPUT -p udp --dport 8472 -j ACCEPT

# 4. 允许 VTEP 通信(如果使用标准 VxLAN)
iptables -A INPUT -p udp --dport 4789 -j ACCEPT

# 5. 允许 Pod 网络通信
iptables -A INPUT -s 10.244.0.0/16 -j ACCEPT

# 6. 允许转发
iptables -A FORWARD -i cni0 -j ACCEPT
iptables -A FORWARD -o cni0 -j ACCEPT

# 7. 拒绝其他
iptables -A INPUT -j DROP

持久化防火墙规则

# Ubuntu/Debian - 使用 iptables-persistent
sudo apt-get install iptables-persistent
sudo netfilter-persistent save

# CentOS/RHEL - 使用 firewalld
sudo firewall-cmd --permanent --add-port=8472/udp
sudo firewall-cmd --permanent --add-port=4789/udp
sudo firewall-cmd --reload

网络故障排查工具

常用工具命令

# ping - 测试基本连通性
ping <target-ip>

# traceroute - 跟踪路由路径
traceroute <target-ip>

# mtr - 结合 ping 和 traceroute
mtr -r <target-ip>

# tcpdump - 抓包分析
tcpdump -i flannel.1 -n
tcpdump -i eth0 -n port 8472

# ip route - 查看路由
ip route get <target-ip>

# ip neigh - 查看 ARP 表
ip neigh show

# bridge fdb - 查看 VTEP 表
bridge fdb show | grep flannel

# ethtool - 查看网络接口统计
ethtool -S flannel.1

抓包分析示例

# 抓取 Flannel VxLAN 数据包
tcpdump -i eth0 -n 'udp port 8472' -w flannel.pcap

# 抓取 Pod 之间的数据包
tcpdump -i cni0 -n host <pod-ip-1> and host <pod-ip-2>

# 分析抓包文件
tcpdump -r flannel.pcap -v

性能优化

优化 VxLAN 性能

# 1. 启用 offload
ethtool -K eth0 tx-offload on
ethtool -K flannel.1 tx-offload on

# 2. 调整 conntrack 表大小
echo "net.netfilter.nf_conntrack_max = 1000000" >> /etc/sysctl.conf
echo "net.netfilter.nf_conntrack_buckets = 200000" >> /etc/sysctl.conf
sysctl -p

# 3. 优化 TCP 参数
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf
sysctl -p

监控和日志

# 监控 Flannel 性能
watch -n 1 'kubectl top pods -n kube-system -l app=flannel'

# 持续查看日志
kubectl logs -n kube-system -f -l app=flannel

# 查看网络统计
sar -n DEV 1 10

最佳实践

  1. 规划网络段: 合理规划 Pod 网络段,避免与物理网络冲突
  2. 选择合适的后端: 根据网络环境选择 VxLAN 或 Host-GW
  3. 监控网络状态: 定期检查网络接口、路由表和防火墙规则
  4. 备份配置: 备份 Flannel ConfigMap 和防火墙规则
  5. 测试恢复: 在测试环境中验证网络恢复流程
  6. 文档化: 记录网络配置和故障处理流程
  7. 使用网络策略: 配置 NetworkPolicy 控制网络流量

相关资源

  • Flannel GitHub: https://github.com/flannel-io/flannel
  • Kubernetes 网络: https://kubernetes.io/docs/concepts/cluster-administration/networking/
  • iptables 教程: https://www.frozentux.net/iptables-tutorial/
  • VxLAN 协议: https://tools.ietf.org/html/rfc7348


辽ICP备2021007608号 | © 2026 | kaisawind

Facebook Twitter GitHub