Kubernetes 1.28 集群网络插件 Calico 深度部署与集群可用性全面验证

摘要:在上一篇完成 Docker-CE + cri-dockerd + K8S 1.28 集群部署后,所有节点处于 NotReady 状态——缺少 CNI 网络插件。本文以 Calico 3.26 为核心,从 Kubernetes 网络模型的三层约束出发,深入剖析 Calico 的 IPIP/VXLAN/BGP 三种组网模式、Felix/BIRD/confd 核心组件的协作机制,到生产级部署配置、集群可用性全面验证(Pod 通信、Service 负载均衡、CoreDNS 解析、NetworkPolicy 网络策略),构建完整的集群网络认知体系。


一、Kubernetes 网络模型基础

1.1 三大网络约束

Kubernetes 网络模型定义了三条不可违背的约束(来自 Kubernetes 网络设计文档):

  1. Pod 间通信:所有 Pod 可以在不使用 NAT 的情况下与其他所有 Pod 通信
  2. Node 与 Pod 通信:所有 Node 可以在不使用 NAT 的情况下与所有 Pod 通信(反之亦然)
  3. Pod 自身 IP 感知:Pod 看到的自身 IP 与其他 Pod 看到的该 Pod IP 一致

这三条约束构成了一个扁平的、可路由的网络空间,CNI 插件的核心职责就是实现这个空间。

1.2 CNI 工作流程

当 kubelet 创建一个 Pod 时,网络配置流程如下:

kubelet                              CRI (cri-dockerd)              CNI Plugin
  │                                        │                            │
  │──── CreatePod ────────────────────────>│                            │
  │                                        │── 创建 pause 容器 ────────>│
  │                                        │── 创建 Network Namespace ─>│
  │                                        │                            │
  │──── SetUpPod(namespace, name, id) ────────────────────────────────>│
  │                                        │                            │
  │                                        │         ┌──────────────────┤
  │                                        │         │ 1. 创建 veth pair │
  │                                        │         │ 2. 分配 IP 地址   │
  │                                        │         │ 3. 配置路由规则   │
  │                                        │         │ 4. 返回 IP 信息   │
  │                                        │         └──────────────────┤
  │<─── {IP: 10.244.x.x, Gateway: ...} ──────────────────────────────│

CNI 插件本质上是一个可执行二进制文件(位于 /opt/cni/bin/),kubelet 通过标准输入传入 JSON 配置,插件完成网络配置后通过标准输出返回结果。

1.3 为什么选择 Calico

特性 Calico Flannel Cilium
网络模式 BGP/IPIP/VXLAN VXLAN/host-gw eBPF/VXLAN
NetworkPolicy 原生支持 不支持 原生支持
性能 高(BGP 纯路由无封装)
大规模集群 5000+ 节点生产验证 适合中小规模 1000+ 节点
运维复杂度
社区活跃度 极高(Tigera 维护)

Calico 在性能、网络策略支持和大规模验证三个维度具有综合优势,是生产环境的主流选择。


二、Calico 架构深度解析

2.1 核心组件

┌─────────────────────────── Node ───────────────────────────┐
│                                                             │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌─────────┐ │
│  │  Felix   │   │   BIRD   │   │  confd   │   │ CNI Bin │ │
│  │(数据平面)│   │(路由分发) │   │(配置生成)│   │(IP分配) │ │
│  └────┬─────┘   └────┬─────┘   └────┬─────┘   └────┬────┘ │
│       │              │              │              │       │
│       ▼              ▼              │              │       │
│  iptables/ipsets  BGP Sessions      │              │       │
│  路由表            对等连接          │              │       │
└───────┼──────────────┼──────────────┼──────────────┼───────┘
        │              │              │              │
        └──────────────┼──────────────┼──────────────┘
                       │              │
                ┌──────▼──────────────▼──────┐
                │        etcd / K8S API      │
                │     (Calico 数据存储)       │
                └────────────────────────────┘

各组件职责详解

Felix(数据平面引擎)
  • 运行在每个节点,以 DaemonSet 方式部署
  • 负责编程主机的数据平面
    • 管理路由表(ip route):为本节点 Pod 添加路由条目
    • 管理 iptables 规则:实现 NetworkPolicy 的 Ingress/Egress 规则
    • 管理 ipsets:高效匹配大量 IP/端口组合(O(1) 查找 vs iptables 链式遍历 O(n))
    • 管理 IPIP/VXLAN 隧道接口(tunl0 / vxlan.calico
BIRD(BGP 路由守护进程)
  • Bird Internet Routing Daemon,业界成熟的 BGP 实现
  • 职责:
    • 从 Felix 写入的路由表中读取 Pod 网段路由
    • 通过 BGP 协议将路由信息广播给集群中其他节点的 BIRD 实例
    • 接收其他节点的路由广播并写入本机路由表
  • 支持两种 BGP 拓扑:
    • Full-Mesh(默认):每对节点建立 BGP Session,适合 < 100 节点
    • Route Reflector:指定若干节点为路由反射器,其他节点只与 RR 建立 Session,适合大规模集群
confd(配置生成器)
  • 监听 Calico 数据存储(etcd 或 Kubernetes API)的变更
  • 将 BGP 配置模板渲染为 BIRD 的配置文件
  • 触发 BIRD 重载配置
Calico CNI 插件
  • 位于 /opt/cni/bin/calico/opt/cni/bin/calico-ipam
  • 负责 Pod 创建/删除时的网络配置:
    • 创建 veth pair(一端在 Pod 内,一端在宿主机)
    • 从 IPAM 分配 IP 地址(基于 IPPool 的块分配策略)
    • 配置 Pod 内路由(默认网关指向 169.254.1.1)
    • 在宿主机添加指向 Pod 的路由

2.2 三种组网模式对比

模式一:IPIP(默认)
Node A (10.0.0.10)                              Node B (10.0.0.11)
┌─────────────────────┐                         ┌─────────────────────┐
│  Pod-A: 10.244.0.5  │                         │  Pod-B: 10.244.1.8  │
│       │              │                         │       ▲              │
│  veth pair           │                         │  veth pair           │
│       │              │                         │       │              │
│  ┌────▼────┐         │                         │  ┌────┴────┐         │
│  │  tunl0  │ IPIP封装 │                         │  │  tunl0  │ IPIP解封 │
│  └────┬────┘         │                         │  └────▲────┘         │
│       │              │                         │       │              │
│  ┌────▼────┐         │                         │  ┌────┴────┐         │
│  │  eth0   │─────────┼────── 物理网络 ──────────┼──│  eth0   │         │
│  └─────────┘         │                         │  └─────────┘         │
└─────────────────────┘                         └─────────────────────┘
  • 原理:在原始 IP 包外再包裹一层 IP 头(协议号 4),形成 IP-in-IP 隧道
  • 优点:对底层网络无要求,任何三层可达即可
  • 缺点:20 字节额外头部开销,MTU 从 1500 降为 1480;IP 协议号 4 可能被某些云防火墙拦截
  • 适用场景:跨子网节点通信、公有云环境
模式二:VXLAN
封装格式:
┌──────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
│ Outer Eth    │ Outer IP     │ Outer UDP    │ VXLAN Header │ Original Pkt │
│ (14 bytes)   │ (20 bytes)   │ (8 bytes)    │ (8 bytes)    │              │
└──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
                                              VNI = 4096
  • 原理:在原始二层帧外包裹 UDP + VXLAN 头,使用 UDP 端口 4789
  • 优点:标准 UDP 封装,穿透性好,所有网络设备都能转发
  • 缺点:50 字节额外开销,MTU 降为 1450;封装/解封装消耗 CPU
  • 适用场景:云环境(AWS/Azure/GCP)、防火墙严格的网络
模式三:BGP Direct(纯路由)
Node A (10.0.0.10)                              Node B (10.0.0.11)
┌─────────────────────┐                         ┌─────────────────────┐
│  Pod-A: 10.244.0.5  │                         │  Pod-B: 10.244.1.8  │
│       │              │                         │       ▲              │
│  veth pair           │                         │  veth pair           │
│       │              │                         │       │              │
│  路由: 10.244.1.0/24 │                         │  路由: 10.244.0.0/24 │
│    via 10.0.0.11     │                         │    via 10.0.0.10     │
│       │              │                         │       │              │
│  ┌────▼────┐         │                         │  ┌────┴────┐         │
│  │  eth0   │─────────┼────── 二层网络 ──────────┼──│  eth0   │         │
│  └─────────┘         │                         │  └─────────┘         │
└─────────────────────┘                         └─────────────────────┘
  • 原理:无封装,纯三层路由转发。BIRD 通过 BGP 协议交换 Pod 网段路由
  • 优点:零封装开销,最高性能(接近裸机网络),MTU 无损
  • 缺点:要求节点在同一二层网络(同一 VLAN),或物理路由器支持 BGP peering
  • 适用场景:裸金属数据中心、同子网部署、对网络性能有极致要求
CrossSubnet 混合模式(推荐)
ipipMode: CrossSubnet   # 同子网纯路由,跨子网 IPIP
  • 同子网内节点:BGP Direct 纯路由(零封装,最高性能)
  • 跨子网节点:自动切换为 IPIP 封装(保证连通性)
  • 兼顾性能与兼容性,是生产环境的推荐配置

三、Calico 部署实战

3.1 下载 Calico 清单

# 在 Master 节点执行
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml

# 国内加速(如 GitHub 不可达)
wget https://ghproxy.com/https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml

3.2 关键配置修改

3.2.1 配置 Pod CIDR
# 确认与 kubeadm init 时的 podSubnet 一致
grep -A 1 "CALICO_IPV4POOL_CIDR" calico.yaml

修改为:

- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/16"

CIDR 规划原理/16 网段提供 65534 个 IP。Calico 默认将其切分为 /26 的块(每块 64 个 IP)分配给各节点,支持最多 1024 个节点 × 每节点 64 个 Pod。可通过 blockSize 调整。

3.2.2 配置网络模式
# IPIP 模式配置
- name: CALICO_IPV4POOL_IPIP
  value: "Always"           # Always | CrossSubnet | Never

# VXLAN 模式配置(与 IPIP 互斥)
- name: CALICO_IPV4POOL_VXLAN
  value: "Never"            # Always | CrossSubnet | Never

生产推荐配置(CrossSubnet 混合模式):

- name: CALICO_IPV4POOL_IPIP
  value: "CrossSubnet"
- name: CALICO_IPV4POOL_VXLAN
  value: "Never"
3.2.3 配置 IP 自动检测

对于多网卡节点,必须指定 Calico 使用正确的网卡:

- name: IP_AUTODETECTION_METHOD
  value: "interface=eth0"
  # 或使用 CIDR 匹配:
  # value: "cidr=10.0.0.0/24"
  # 或使用正则:
  # value: "interface=ens.*"

错误的 IP 检测会导致:节点间 BGP Session 建立在错误的接口上,Pod 跨节点通信完全不通。

3.2.4 镜像替换(国内环境)
# 替换为国内镜像源
sed -i 's|docker.io/calico/|registry.cn-hangzhou.aliyuncs.com/google_containers/calico-|g' calico.yaml

或手动预拉取:

images=(
  "docker.io/calico/cni:v3.26.4"
  "docker.io/calico/node:v3.26.4"
  "docker.io/calico/kube-controllers:v3.26.4"
)
for img in "${images[@]}"; do
  docker pull "$img"
done

3.3 部署 Calico

kubectl apply -f calico.yaml

# 监控部署进度
kubectl get pods -n kube-system -l k8s-app=calico-node -w
# 等待所有节点的 calico-node Pod 变为 Running(1/1)

3.4 部署后验证

# 1. 检查节点状态(应全部变为 Ready)
kubectl get nodes
# NAME           STATUS   ROLES           AGE   VERSION
# k8s-master01   Ready    control-plane   30m   v1.28.2
# k8s-worker01   Ready    <none>          25m   v1.28.2
# k8s-worker02   Ready    <none>          24m   v1.28.2

# 2. 检查 Calico 组件
kubectl get pods -n kube-system | grep calico
# calico-node-xxxxx              1/1   Running   0   2m   ← 每节点一个
# calico-kube-controllers-xxx    1/1   Running   0   2m   ← 集群一个

# 3. 检查 IPAM 分配
kubectl exec -n kube-system $(kubectl get pod -n kube-system -l k8s-app=calico-node -o name | head -1) -- calico-node -bird-ready
# 返回 0 表示 BIRD 就绪

# 4. 检查 BGP Session 状态(进入 calico-node 容器)
kubectl exec -it -n kube-system $(kubectl get pod -n kube-system -l k8s-app=calico-node -o name | head -1) -- birdcl show protocols
# 所有 peer 应显示 Established

3.5 安装 calicoctl(管理工具)

wget https://github.com/projectcalico/calico/releases/download/v3.26.4/calicoctl-linux-amd64
chmod +x calicoctl-linux-amd64
mv calicoctl-linux-amd64 /usr/local/bin/calicoctl

# 配置 datastore 连接
export KUBECONFIG=/root/.kube/config
export DATASTORE_TYPE=kubernetes

# 查看节点状态
calicoctl node status
# Calico process is running.
#
# IPv4 BGP status
# +---------------+-------------------+-------+----------+-------------+
# | PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
# +---------------+-------------------+-------+----------+-------------+
# | 10.0.0.11     | node-to-node mesh | up    | 10:30:00 | Established |
# | 10.0.0.12     | node-to-node mesh | up    | 10:30:05 | Established |
# +---------------+-------------------+-------+----------+-------------+

# 查看 IPPool 配置
calicoctl get ippool -o wide
# NAME                  CIDR            NAT    IPIPMODE      VXLANMODE   ...
# default-ipv4-ippool   10.244.0.0/16   true   CrossSubnet   Never       ...

# 查看各节点的 IP 块分配
calicoctl ipam show --show-blocks

四、集群可用性全面验证

4.1 Pod 跨节点通信验证

4.1.1 部署测试 Pod
# 创建跨节点调度的 busybox Pod
cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: test-pod-a
  labels:
    app: net-test
spec:
  nodeName: k8s-worker01
  containers:
  - name: busybox
    image: busybox:1.36
    command: ["sleep", "3600"]
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod-b
  labels:
    app: net-test
spec:
  nodeName: k8s-worker02
  containers:
  - name: busybox
    image: busybox:1.36
    command: ["sleep", "3600"]
EOF

# 等待就绪
kubectl wait --for=condition=ready pod/test-pod-a pod/test-pod-b --timeout=60s
4.1.2 Pod → Pod 通信
# 获取 Pod IP
POD_B_IP=$(kubectl get pod test-pod-b -o jsonpath='{.status.podIP}')
echo "Pod-B IP: $POD_B_IP"

# 从 Pod-A ping Pod-B(跨节点)
kubectl exec test-pod-a -- ping -c 4 $POD_B_IP
# PING 10.244.1.8 (10.244.1.8): 56 data bytes
# 64 bytes from 10.244.1.8: seq=0 ttl=62 time=0.543 ms
# 64 bytes from 10.244.1.8: seq=1 ttl=62 time=0.387 ms
# ...
# ✅ TTL=62(经过两跳路由:Pod-A → Node-A → Node-B → Pod-B)
4.1.3 路由追踪分析
# 在 Worker01 上查看路由表
ip route | grep 10.244
# 10.244.0.0/26   via 10.0.0.10  dev tunl0  proto bird onlink  ← Master 的 Pod 网段
# 10.244.1.0/26   via 10.0.0.12  dev tunl0  proto bird onlink  ← Worker02 的 Pod 网段
# 10.244.2.0/26   via 10.0.0.11  dev eth0   scope link         ← 本节点 Pod 网段(直连)

# 在 Worker01 上抓包分析 IPIP 封装
tcpdump -i eth0 proto 4 -nn -c 5
# 10.0.0.11 > 10.0.0.12: 10.244.2.5 > 10.244.1.8: ICMP echo request
# ↑ 外层 IP(节点间)        ↑ 内层 IP(Pod 间)

4.2 Service 负载均衡验证

4.2.1 部署 Nginx 服务
cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx-test
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
EOF

kubectl wait --for=condition=available deployment/nginx-test --timeout=120s
4.2.2 ClusterIP 验证
SVC_IP=$(kubectl get svc nginx-svc -o jsonpath='{.spec.clusterIP}')
echo "Service ClusterIP: $SVC_IP"

# 从集群内 Pod 访问 Service
for i in $(seq 1 6); do
  kubectl exec test-pod-a -- wget -qO- --timeout=2 http://$SVC_IP 2>/dev/null | grep "Server name"
done
# 观察请求被负载均衡到不同的后端 Pod
4.2.3 NodePort 验证
# 暴露为 NodePort
kubectl expose deployment nginx-test --type=NodePort --port=80 --name=nginx-nodeport

NODE_PORT=$(kubectl get svc nginx-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
echo "NodePort: $NODE_PORT"

# 从集群外部访问
curl http://10.0.0.10:$NODE_PORT
curl http://10.0.0.11:$NODE_PORT
curl http://10.0.0.12:$NODE_PORT
# 三个节点 IP 均可访问 ✅
4.2.4 iptables 规则分析
# 查看 kube-proxy 生成的 Service DNAT 规则链
iptables -t nat -L KUBE-SERVICES -n | grep nginx
# -A KUBE-SERVICES -d 10.96.x.x/32 -p tcp --dport 80 -j KUBE-SVC-XXXXX

# 查看后端 Endpoint 负载均衡
iptables -t nat -L KUBE-SVC-XXXXX -n
# -A KUBE-SVC-XXXXX -m statistic --mode random --probability 0.333 -j KUBE-SEP-AAA
# -A KUBE-SVC-XXXXX -m statistic --mode random --probability 0.500 -j KUBE-SEP-BBB
# -A KUBE-SVC-XXXXX -j KUBE-SEP-CCC
# ↑ 三个后端 Pod 的概率负载均衡(1/3 → 1/2 → 1/1)

4.3 CoreDNS 服务发现验证

# 验证 CoreDNS 运行状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# coredns-xxxxx-yyy   1/1   Running   0   30m
# coredns-xxxxx-zzz   1/1   Running   0   30m

# DNS 解析测试
kubectl exec test-pod-a -- nslookup nginx-svc
# Server:    10.96.0.10        ← CoreDNS ClusterIP
# Name:      nginx-svc.default.svc.cluster.local
# Address:   10.96.x.x         ← Service ClusterIP ✅

# 跨 Namespace DNS 解析
kubectl exec test-pod-a -- nslookup kubernetes.default.svc.cluster.local
# Address: 10.96.0.1           ← API Server Service IP ✅

# 外部域名解析
kubectl exec test-pod-a -- nslookup www.baidu.com
# Address: 110.242.68.66       ✅

CoreDNS 解析链路

Pod(/etc/resolv.conf: nameserver 10.96.0.10)
  → CoreDNS Service (10.96.0.10:53)
    → CoreDNS Pod
      → 集群内域名?→ 查询 K8S API 获取 Service/Endpoint
      → 集群外域名?→ 转发到上游 DNS(/etc/resolv.conf 的 nameserver)

4.4 NetworkPolicy 网络策略验证

Calico 的一个核心优势是原生支持 Kubernetes NetworkPolicy。

4.4.1 默认拒绝所有入站流量
cat << 'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
EOF

# 验证:Pod-A 无法访问 nginx-svc
kubectl exec test-pod-a -- wget -qO- --timeout=3 http://$SVC_IP 2>&1
# wget: download timed out ← 被 NetworkPolicy 拦截 ✅
4.4.2 精确放行指定流量
cat << 'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-net-test-to-nginx
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginx-test
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: net-test
    ports:
    - protocol: TCP
      port: 80
EOF

# 验证:带 app=net-test 标签的 Pod 可以访问
kubectl exec test-pod-a -- wget -qO- --timeout=3 http://$SVC_IP 2>/dev/null | head -5
# <!DOCTYPE html>... ← 访问成功 ✅
4.4.3 清理策略
kubectl delete networkpolicy deny-all-ingress allow-net-test-to-nginx

底层实现:Calico 的 Felix 组件将 NetworkPolicy 翻译为 iptables 规则和 ipsets:

# 查看 Calico 生成的 iptables 规则
iptables -L cali-tw-calixxxxxxxxx -n -v
# 每个 Pod 的 veth 接口都有对应的 Calico iptables 链

五、生产环境高级配置

5.1 BGP Route Reflector(大规模集群)

当节点数超过 100 时,Full-Mesh BGP 的 Session 数量为 n ( n − 1 ) / 2 n(n-1)/2 n(n1)/2,增长为 O ( n 2 ) O(n^2) O(n2)。使用 Route Reflector 将其降为 O ( n ) O(n) O(n)

# 指定节点为 Route Reflector
calicoctl patch node k8s-worker01 -p '{"spec":{"bgp":{"routeReflectorClusterID":"244.0.0.1"}}}'

# 为 RR 节点添加标签
kubectl label node k8s-worker01 route-reflector=true

# 创建 BGPPeer 配置:非 RR 节点与 RR 建立 Session
cat << 'EOF' | calicoctl apply -f -
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: peer-with-route-reflectors
spec:
  nodeSelector: "!has(route-reflector)"
  peerSelector: has(route-reflector)
EOF

# 禁用 Full-Mesh
calicoctl patch bgpconfiguration default -p '{"spec":{"nodeToNodeMeshEnabled":false}}'

5.2 MTU 调优

# 查看当前 MTU
kubectl exec -n kube-system $(kubectl get pod -n kube-system -l k8s-app=calico-node -o name | head -1) -- cat /var/lib/calico/mtu
# IPIP 默认 1480,VXLAN 默认 1450

# 在 calico.yaml 中配置
# - name: FELIX_IPINIPMTU
#   value: "1480"
# - name: FELIX_VXLANMTU
#   value: "1450"

MTU 不匹配的后果:大包(> MTU)被分片或丢弃,表现为小文件传输正常但大文件传输卡住或超时。

5.3 IPAM 块大小调整

# 查看当前块大小
calicoctl get ippool default-ipv4-ippool -o yaml | grep blockSize
# blockSize: 26  → 每节点 64 个 IP

# 若节点 Pod 密度高,可调整为 /24(256 个 IP)
# 注意:必须在集群初始化时配置,事后修改需重建 IPPool

六、故障排查手册

6.1 节点持续 NotReady

# 检查 calico-node Pod 日志
kubectl logs -n kube-system -l k8s-app=calico-node --tail=50

# 常见原因
# 1. IP_AUTODETECTION_METHOD 检测到错误网卡
# 2. Pod CIDR 与 kubeadm 配置不一致
# 3. 镜像拉取失败

6.2 Pod 跨节点不通

# 排查清单
# Step 1: 检查节点间物理网络连通性
ping <other-node-ip>

# Step 2: 检查 BGP Session
calicoctl node status
# 确保所有 peer 显示 Established

# Step 3: 检查路由表
ip route | grep 10.244
# 确保有指向其他节点 Pod 网段的路由

# Step 4: 检查 IPIP 隧道接口
ip addr show tunl0
# 确保 tunl0 接口 UP 且有 IP

# Step 5: 检查 iptables 是否拦截
iptables -L -n | grep -i drop
iptables -L FORWARD -n -v | head -20

# Step 6: 抓包定位
tcpdump -i tunl0 -nn host <pod-ip> -c 10
tcpdump -i eth0 proto 4 -nn -c 10  # IPIP 封装包

6.3 CoreDNS 解析失败

# 检查 CoreDNS Pod 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20

# 检查 Pod 的 DNS 配置
kubectl exec test-pod-a -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local

# 直接测试 CoreDNS 端口
kubectl exec test-pod-a -- nc -zvu 10.96.0.10 53

七、总结

本文从 Kubernetes 网络模型的三层约束出发,完成了以下内容:

  1. 网络模型理论:三大约束、CNI 工作流程、Calico 选型理由
  2. 架构深度剖析:Felix/BIRD/confd/CNI 四大组件的协作机制,IPIP/VXLAN/BGP 三种组网模式的封装原理与适用场景
  3. 生产级部署:Pod CIDR 配置、网络模式选择(推荐 CrossSubnet)、IP 自动检测、镜像替换
  4. 可用性全面验证
    • Pod 跨节点通信(ping + 路由追踪 + 抓包分析)
    • Service 负载均衡(ClusterIP + NodePort + iptables 规则分析)
    • CoreDNS 服务发现(集群内/集群外域名解析 + 解析链路)
    • NetworkPolicy 网络策略(默认拒绝 + 精确放行 + 底层 iptables 实现)
  5. 高级配置:BGP Route Reflector 大规模拓扑、MTU 调优、IPAM 块大小
  6. 故障排查:节点 NotReady、Pod 跨节点不通、DNS 解析失败的系统化排查清单

至此,基于 Docker-CE 部署 K8S 1.28 版本集群的完整流程——从容器运行时安装、集群引导初始化、CNI 网络插件部署到集群可用性验证——全部完成。集群已具备生产就绪的网络能力,可以进行后续的应用部署、监控体系搭建和持续交付流水线集成。


参考资料

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐