Kubernetes 网络是容器编排中最复杂的领域之一。每个 Pod 都需要独立的 IP、跨节点互通、Service 发现——而实现这些的 CNI 插件选择,直接影响集群的性能、安全性和可观测性。
目录
- 1. Kubernetes 网络模型
- 2. CNI 接口规范
- 3. 主流 CNI 插件对比
- 4. Service 网络实现
- 5. Ingress 与 Gateway API
- 6. DNS 服务发现
- 7. 网络排错工具箱
- 8. CNI 选型建议
1. Kubernetes 网络模型
Kubernetes 对网络有四个基本要求,这是所有 CNI 插件必须实现的契约:
- Pod IP 全局唯一:每个 Pod 拥有独立的 IP,且在集群内不冲突
- Pod 之间直接通信:无需 NAT,Pod A 可以直接用 Pod B 的 IP 访问
- Pod 与 Node 互通:节点和 Pod 可以双向通信
- Service IP 可达:集群内部可以通过 Service 的 ClusterIP 访问后端 Pod
┌─────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Node 1 │─────────│ Node 2 │ ← 节点间三层互通 │
│ │10.0.1.0/24│ │10.0.2.0/24│ │
│ │ │ Overlay │ │ │
│ │ ┌──────┐ │ Network │ ┌──────┐ │ │
│ │ │Pod-A │ │◄────────►│ │Pod-B │ │ ← 无需 NAT │
│ │ │10.1.1│ │ │ │10.1.2│ │ │
│ │ └──┬───┘ │ │ └──┬───┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌──▼───┐ │ │ ┌──▼───┐ │ │
│ │ │CNI │ │ │ │CNI │ │ ← CNI 插件实现 │
│ │ └──────┘ │ │ └──────┘ │ │
│ └──────────┘ └──────────┘ │
│ │
│ Service IP (ClusterIP) → kube-proxy → 后端 Pod │
└─────────────────────────────────────────────────────────┘
2. CNI 接口规范
CNI(Container Network Interface)是一组标准化的网络配置接口,由 CNCF 维护。
CNI 插件调用流程
当 kubelet 创建 Pod 时,通过 CRI(containerd/CRI-O)调用 CNI 插件:
kubelet → CRI (containerd) → CNI Plugin
│ │
│ 1. 调用 CNI ADD │ → 创建 veth pair、分配 IP、设置路由
│ 2. 调用 CNI CHECK │ → 验证网络配置是否正确
│ 3. 调用 CNI DEL │ → Pod 删除时清理网络资源
CNI 配置格式
# /etc/cni/net.d/10-calico.conflist
{
"cniVersion": "0.3.1",
"name": "k8s-pod-network",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "node-1",
"ipam": {
"type": "calico-ipam",
"assign_ipv4": "true",
"ipv4_pools": ["10.1.0.0/16"]
}
},
{
"type": "portmap",
"snat": true,
"capabilities": {"portMappings": true}
}
]
}
CNI 链式调用:CNI 支持多个插件按顺序执行(如 calico → portmap → bandwidth),每个插件处理不同的网络层面。
3. 主流 CNI 插件对比
3.1 Flannel
最老牌、最简单的 CNI 插件,由 CoreOS 开发。
后端模式:
| 后端 | 原理 | 性能 | 适用场景 |
|---|---|---|---|
| VXLAN | UDP 封装,默认端口 8472 | 中等 | 通用场景,跨云 |
| UDP | 用户态封装 | 较差 | 仅调试 |
| Host-GW | 直接路由,无封装 | 最好 | 二层互通的局域网 |
| WireGuard | 加密隧道 | 好 | 需要加密 |
Flannel 配置示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
}
]
}
net-conf.json: |
{
"Network": "10.1.0.0/16",
"Backend": {
"Type": "vxlan",
"VNI": 1,
"Port": 8472
}
}
Flannel 优点:
- 部署简单,单 DaemonSet 即可运行
- 资源占用低,适合小集群
- 文档丰富,上手快
Flannel 缺点:
- 无 NetworkPolicy 支持(需配合 Calico policy 组件)
- 无高级网络策略(如 L7 过滤)
- VXLAN 带来封装开销(~20% 性能下降)
3.2 Calico
功能全面的 CNI 插件,支持路由模式和策略模式。
BGP 模式:Calico 使用 BGP 在节点间交换路由,无需 VXLAN 封装:
节点A 通告:10.1.1.0/24 可达
节点B 通告:10.1.2.0/24 可达
通过 BGP 反射器或直接会话同步路由
当集群节点在同一二层网络时,BGP 模式提供最佳性能(无封装开销)。跨三层网络时可启用 IPIP 或 VXLAN 封装。
Calico 配置(BGP 模式):
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 10.1.0.0/16
blockSize: 26 # 每个节点分配的 IP 块大小(64 个 IP)
natOutgoing: true
disabled: false
nodeSelector: all()
Calico 的核心能力:
| 能力 | 说明 |
|---|---|
| NetworkPolicy | 原生支持 L3/L4 策略,配合 Calico Enterprise 支持 L7 |
| eBPF 加速 | Calico eBPF 模式(替代 kube-proxy)提供更高性能 |
| WireGuard 加密 | 节点间流量自动加密 |
| 多网卡 | 支持每个 Pod 多网卡(电信 NFV 场景) |
| BGP 社区功能 | 通过 BGP 社区属性控制路由发布(如阻止某些节点被外部访问) |
Calico eBPF 模式:
# 启用 eBPF 模式
kubectl patch installation default --type=merge -p '{"spec": {"calicoNetwork": {"linuxDataplane": "BPF"}}}'
eBPF 模式的优势:
- 替代 kube-proxy,Service NAT 在 eBPF 中完成(O(1) 查找)
- 绕过 iptables/ipvs,减少内核数据包处理路径
- 支持源 IP 保留(Direct Server Return)
- 降低 CPU 使用率(大规模集群效果明显)
3.3 Cilium
基于 eBPF 的下一代 CNI 插件,提供原生 L3-L7 安全策略和可观测性。
┌──────────────────────────────────────┐
│ Cilium Architecture │
│ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Hubble │←───│ Cilium │ │
│ │(可观测性) │ │ Agent │ │
│ └──────────┘ │ (eBPF) │ │
│ └──────┬───────┘ │
│ │ eBPF │
│ ┌──────▼───────┐ │
│ │ Kernel │ │
│ │ (XDP/TC) │ │
│ └──────────────┘ │
└──────────────────────────────────────┘
Cilium 配置示例:
apiVersion: cilium.io/v2alpha1
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny-ingress
spec:
endpointSelector: {}
ingressDeny:
- {}
---
# 允许 frontend → backend 的 HTTP GET /api
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/.*"
Cilium 的核心优势:
| 能力 | Flannel | Calico | Cilium |
|---|---|---|---|
| NetworkPolicy (L3/L4) | ❌ | ✅ | ✅ |
| NetworkPolicy (L7/HTTP) | ❌ | ⚠️ Enterprise | ✅ 原生 |
| 可观测性 (Hubble) | ❌ | ⚠️ 有限 | ✅ 原生 |
| eBPF 加速 | ❌ | ✅ | ✅ 原生 |
| 多集群连接 | ❌ | ✅ | ✅ |
| mTLS (SPIFFE) | ❌ | ❌ | ✅ (Roadmap) |
| 复杂度 | 低 | 中 | 中高 |
Hubble 可观测性:
# 安装 Hubble CLI
hubble status
hubble observe --namespace production --from-pod frontend
hubble observe --protocol http --http-status 500
3.4 其他 CNI 插件
| 插件 | 特点 | 适用场景 |
|---|---|---|
| Weave Net | 加密默认、自动发现、简单 | 中小集群、安全要求高 |
| Antrea | VMware 出品、基于 OVS | vSphere 环境、NSX 集成 |
| Canal | Flannel + Calico 政策 | 历史方案,现已被 Calico 替代 |
| Kube-OVN | 基于 OVN/OVS | 需要高级网络功能(VPC、QoS) |
| Multus | 多网卡 CNI 元插件 | NFV、5G、SR-IOV 场景 |
4. Service 网络实现
kube-proxy 的三种代理模式
kube-proxy 是实现 Service 虚拟 IP 的核心组件,支持三种模式:
iptables 模式(默认):
Client → Service IP:80
→ iptables PREROUTING 链
→ DNAT 到 Pod IP:8080
→ Pod 处理请求
→ SNAT 回 Service IP(返回路径)
# 查看 iptables 规则
iptables -t nat -L KUBE-SERVICES -n | grep api-service
# 输出:KUBE-MARK-MASQ + KUBE-SVC-... 链 + 概率分配到各 Pod
iptables 模式的会话亲和(sessionAffinity: ClientIP)通过概率规则实现,但大集群下规则数量激增(O(n),n=Service 数量),更新延迟增加。
ipvs 模式:
使用内核 IPVS 模块,基于哈希表查找,O(1) 复杂度:
# ipvs 支持的负载均衡算法
ipvsadm -Ln | grep Scheduling
# 输出:rr (轮询) / lc (最少连接) / dh (目标哈希) / sh (源哈希) / sed (最短期望延迟) / nq (永不排队)
性能对比(不同 Service 数量下的规则更新延迟):
| Service 数量 | iptables 规则更新 | ipvs 更新 |
|---|---|---|
| 1,000 | ~100ms | ~5ms |
| 10,000 | ~5s | ~5ms |
| 50,000 | ~30s+ | ~10ms |
推荐:1,000 Service 以下用 iptables(简单),以上强烈建议 ipvs。
nftables 模式(K8s 1.29+):
mode: "nftables"
- 使用 nf_tables 子系统(iptables 的后继者)
- 规则更清晰、性能更好
- 新集群推荐,旧集群迁移需谨慎
ExternalTrafficPolicy
spec:
externalTrafficPolicy: Local # 保留源 IP,但可能导致负载不均
# 或
externalTrafficPolicy: Cluster # 默认,负载均衡但丢失源 IP
Local 模式的流量不平衡问题:如果 3 个 Pod 分布在 2 个节点上,节点 A 有 1 个 Pod,节点 B 有 2 个 Pod,外部 LB 将流量均匀分到节点 A 和 B,导致节点 A 上的 Pod 获得 50% 流量,节点 B 上的每个 Pod 仅获得 25%。
解决方案:topologyKeys 或 PodTopologySpread + 外部 LB 的健康检查配置。
5. Ingress 与 Gateway API
Ingress 控制器对比
| 控制器 | 特点 | 适用场景 |
|---|---|---|
| NGINX Ingress | 最流行、功能全面、稳定 | 通用场景 |
| Traefik | 自动服务发现、原生支持 Let’s Encrypt | 云原生、动态环境 |
| HAProxy | 高性能、低延迟 | 金融、高频交易 |
| Kong | API 网关功能(限流、认证、插件) | 需要 API 管理 |
| Emissary-ingress | 基于 Envoy、支持 gRPC | 微服务、gRPC |
Gateway API:Ingress 的下一代
Ingress 的局限:所有规则放在单个资源中,难以多团队共享管理。Gateway API 引入分层模型:
GatewayClass → Gateway → HTTPRoute
↑ ↑ ↑
集群管理员 平台工程师 应用开发者
# GatewayClass:集群级别,定义控制器类型
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
---
# Gateway:定义监听端口和 TLS
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public-gateway
namespace: ingress-nginx
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: wildcard-cert
allowedRoutes:
namespaces:
from: All # 允许所有 namespace 绑定路由
---
# HTTPRoute:应用团队定义路由规则
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-routes
namespace: production
spec:
parentRefs:
- name: public-gateway
namespace: ingress-nginx
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /orders
backendRefs:
- name: order-service
port: 80
- matches:
- path:
type: PathPrefix
value: /users
backendRefs:
- name: user-service
port: 80
Gateway API 优势:
- 角色分离:集群管理员、平台团队、应用团队各司其职
- 多协议支持:HTTP、TCP、UDP、gRPC、TLS
- 增强路由:权重分流、重定向、重写、跨 Namespace 引用
- 可扩展性:支持自定义策略(如限流、认证通过 PolicyAttachment)
现状(2025):Ingress 仍是主流,Gateway API 成熟度稳步提升,新项目可考虑直接使用 Gateway API。
6. DNS 服务发现
CoreDNS 架构
CoreDNS 是 K8s 默认的集群 DNS,通过 Watch API Server 自动同步 Service/Endpoint 信息:
Pod DNS 查询
↓
/etc/resolv.conf → nameserver 10.96.0.10(CoreDNS ClusterIP)
↓
CoreDNS
├── kubernetes 插件:处理 .cluster.local 域名
├── cache 插件:缓存 DNS 结果
├── forward 插件:转发外部查询到上游 DNS
└── prometheus 插件:暴露 DNS 指标
默认 DNS 解析路径:
<service>.<namespace>.svc.cluster.local
# 短域名(同 namespace)
<service>
<service>.<namespace>
CoreDNS 配置优化
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
# K8s 插件配置
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure # 创建 Pod A 记录
fallthrough in-addr.arpa ip6.arpa
ttl 30 # 缓存 TTL
}
# 缓存配置
cache 30 {
success 9984 300 # 成功响应缓存 5 分钟
denial 9984 60 # NXDOMAIN 缓存 1 分钟
}
# 转发到外部 DNS
forward . /etc/resolv.conf {
max_concurrent 1000
}
# 循环避免热点
loadbalance round_robin
prometheus :9153
}
生产优化:
- cache 调优:根据应用 DNS 查询频率调整 TTL
- autopath:减少短域名查询的 search 域遍历(
ndots:5问题) - NodeLocal DNSCache:每个节点运行 DNS 缓存 DaemonSet,减少 CoreDNS 压力
7. 网络排错工具箱
常用诊断命令
# 1. 查看 Pod IP 和所在节点
kubectl get pods -o wide
# 2. Pod 内执行网络诊断
kubectl exec -it <pod> -- /bin/sh
# Ping 测试
ping <target-pod-ip>
# DNS 解析
nslookup kubernetes.default.svc.cluster.local
# 端口连通
nc -zv <service-ip> 80
# 3. 查看 Service 的 Endpoint
kubectl get endpoints <service>
# 4. 跨节点抓包
kubectl debug node/<node> -it --image=nicolaka/netshoot
tcpdump -i any -n host <pod-ip>
CNI 专用工具
# Calico
calicoctl node status # 查看 BGP 状态
calicoctl get ippool -o wide # 查看 IP 池
kubectl logs -n calico-system -l k8s-app=calico-node
# Cilium
cilium status # Cilium 健康状态
cilium endpoint list # 查看端点
cilium policy get # 查看策略
cilium monitor --type drop # 查看被丢弃的包
# Flannel
kubectl logs -n kube-flannel -l app=flannel
# 查看子网分配
cat /run/flannel/subnet.env
常见网络问题
| 问题 | 症状 | 排查 | 解决 |
|---|---|---|---|
| Pod 无法访问 Service | 连接超时 | kubectl get endpoints | 检查 selector 标签匹配、Pod 是否 Running |
| DNS 解析失败 | nslookup 超时 | kubectl logs -n kube-system -l k8s-app=kube-dns | 检查 CoreDNS Pod 运行状态、NetworkPolicy 限制 |
| 跨节点 Pod 不通 | 同节点通、跨节点不通 | 检查 CNI 后端(VXLAN 端口、BGP 会话) | 防火墙放行 VXLAN 端口(8472/4789) |
| CNI IP 耗尽 | Pod 无法创建 | kubectl get ippools (Calico) | 扩容 IP 池或减小 blockSize |
8. CNI 选型建议
| 场景 | 推荐 CNI | 理由 |
|---|---|---|
| 小规模集群(<50 节点) | Flannel 或 Calico | 简单够用 |
| 中大规模集群(50-500 节点) | Calico (BGP) 或 Cilium | 性能 + 策略 |
| 需要 NetworkPolicy | Calico 或 Cilium | Flannel 不原生支持 |
| 需要 L7 策略(HTTP/gRPC) | Cilium | 原生 eBPF L7 过滤 |
| 金融/高安全要求 | Cilium + Hubble 或 Calico Enterprise | 审计日志 + 策略 |
| 电信/NFV(多网卡) | Multus + Calico/Cilium | 多网卡支持 |
| vSphere/NSX 环境 | Antrea | 与 NSX 集成 |
| 阿里云/腾讯云 ACK/TKE | 托管集群自带(通常 Flannel 或 Terway) | 云厂商优化 |
| AWS EKS | VPC CNI(原生 AWS 网络)或 Calico | VPC 原生 IP 或 overlay |
总结
| 主题 | 核心要点 |
|---|---|
| 网络模型 | 四大基本原则:唯一 IP、无 NAT、节点互通、Service 可达 |
| CNI 规范 | ADD/CHECK/DEL 三大操作,支持链式调用 |
| Flannel | 最简单,VXLAN 封装,适合入门和小集群 |
| Calico | 功能全面,BGP 模式高性能,eBPF 加速 |
| Cilium | eBPF 原生,L7 策略,Hubble 可观测性,面向未来 |
| Service 实现 | iptables(默认)→ ipvs(大规模)→ nftables(新方向) |
| Ingress | NGINX 主流,Gateway API 为未来标准 |
| DNS | CoreDNS 默认,NodeLocal DNSCache 减负载 |
| 排错 | describe pod → endpoint → service → CNI 日志 → tcpdump |
网络是 Kubernetes 的基石,也是最容易出问题的环节。选择合适的 CNI 插件、合理配置 Service 和 NetworkPolicy,是保障集群稳定运行的关键。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。