说实话,K8s 网络是我见过最让新手头疼的知识点,没有之一。记得我刚接触 K8s 那会儿,看着流量在 Pod、Service、Node 之间穿梭,完全是一脸懵。后来踩了无数坑,熬了无数夜,总算把这套网络模型摸透了。今天这篇文章,我会用最接地气的方式,带你彻底搞懂 K8s 网络。
在云栈社区的讨论中,大家普遍认为,只要啃下网络这块硬骨头,K8s 的学习曲线就会平坦一大截。
一、概述
1.1 背景介绍
在传统的虚拟机时代,网络相对简单——每台 VM 一个 IP,通过交换机互联,顶多再加个负载均衡。但到了容器时代,事情变得复杂了:
- 一台宿主机上可能跑着几十上百个容器
- 容器随时可能被销毁重建,IP 地址不固定
- 跨主机的容器需要互相通信
- 还要对外暴露服务
K8s 的网络模型就是为了解决这些问题而生的。它定义了一套清晰的网络规范,让不同的网络插件(CNI)可以按照统一的标准来实现。
K8s 网络的四大通信场景:
┌─────────────────────────────────────────────────────────────┐
│ K8s 网络通信场景 │
├─────────────────────────────────────────────────────────────┤
│ 1. 容器间通信 同一 Pod 内的容器通过 localhost 通信 │
│ 2. Pod 间通信 不同 Pod 之间直接通过 Pod IP 通信 │
│ 3. Pod-Service Pod 通过 Service 的 ClusterIP 访问服务 │
│ 4. 外部-Service 外部流量通过 NodePort/LB/Ingress 进入集群 │
└─────────────────────────────────────────────────────────────┘
1.2 技术特点
K8s 网络模型有几个核心设计原则,理解了这些,后面的内容就好懂多了:
- 扁平化网络:所有 Pod 都在一个扁平的网络空间中,可以直接通过 IP 互访,不需要 NAT
- IP-per-Pod:每个 Pod 拥有独立的 IP 地址,Pod 内的所有容器共享这个 IP
- 无 NAT 通信:Pod 看到的自己的 IP 就是其他 Pod 看到的 IP,没有地址转换的困扰
- 插件化架构:通过 CNI 标准接口,支持各种网络插件(Calico、Cilium、Flannel 等)
2026年主流 CNI 插件对比:
| CNI 插件 |
网络模式 |
性能 |
NetworkPolicy |
eBPF 支持 |
适用场景 |
| Cilium |
Overlay/路由 |
极高 |
完整+扩展 |
原生 |
大规模生产、安全敏感 |
| Calico |
BGP/IPIP/VXLAN |
高 |
完整 |
可选 |
通用生产环境 |
| Flannel |
VXLAN/host-gw |
中 |
不支持 |
不支持 |
小规模、学习环境 |
| Weave |
VXLAN |
中 |
支持 |
不支持 |
简单部署场景 |
| Antrea |
Geneve/VXLAN |
高 |
完整 |
可选 |
VMware 生态 |
个人建议:2026年了,新集群直接上 Cilium。eBPF 带来的性能提升和可观测性是传统方案没法比的。我们公司去年从 Calico 迁移到 Cilium 后,网络延迟降低了约 15%,而且 Hubble 的可视化简直是排障神器。
1.3 适用场景
不同的网络方案适用于不同场景,选错了后期改造成本很高(别问我是怎么知道的...):
1.4 环境要求
| 组件 |
版本要求 |
说明 |
| Kubernetes |
1.28+ |
建议使用 1.29/1.30,支持最新网络特性 |
| Linux 内核 |
5.10+ |
使用 eBPF 特性建议 5.15+,生产推荐 6.1 LTS |
| CNI 插件 |
Cilium 1.15+ / Calico 3.27+ |
2026年主流版本 |
| kube-proxy |
可选 |
使用 Cilium 可完全替代 kube-proxy |
| CoreDNS |
1.11+ |
集群 DNS 服务 |
内核版本检查:
# 检查当前内核版本
uname -r
# 检查 eBPF 支持情况
# 如果输出包含 CONFIG_BPF=y 说明支持
grep CONFIG_BPF /boot/config-$(uname -r)
# 检查 BTF 支持(Cilium 需要)
ls -la /sys/kernel/btf/vmlinux
二、详细步骤
2.1 准备工作
2.1.1 网络基础概念回顾
在深入 K8s 网络之前,先确保你理解这些基础概念(老手可以跳过):
┌────────────────────────────────────────────────────────────────┐
│ Linux 网络命名空间 │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ veth pair ┌─────────────┐ │
│ │ 容器网络 │◄──────────────────►│ 宿主机网络 │ │
│ │ namespace │ (虚拟网线) │ namespace │ │
│ │ │ │ │ │
│ │ eth0 │ │ vethXXX │ │
│ │ 10.244.1.5 │ │ │ │
│ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ cni0/ │ │
│ │ cilium_ │ │
│ │ host │ │
│ │ (网桥) │ │
│ └─────────────┘ │
└────────────────────────────────────────────────────────────────┘
关键概念解释:
- Network Namespace:Linux 内核提供的网络隔离机制,每个 Pod 有自己的网络命名空间
- veth pair:虚拟以太网设备对,像一根网线连接两个网络命名空间
- Bridge(网桥):二层交换设备,连接同一主机上的多个 veth 设备
- 路由表:决定数据包下一跳去哪里
2.1.2 实验环境搭建
为了更好地理解网络原理,建议搭建一个测试环境:
# 使用 kind 快速创建多节点集群(推荐用于学习)
cat <<EOF > kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
disableDefaultCNI: true # 禁用默认 CNI,手动安装
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
kind create cluster --config kind-config.yaml --name network-lab
# 安装 Cilium(2026年推荐方案)
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.15.0 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set k8sServiceHost=kind-control-plane \
--set k8sServicePort=6443
2.1.3 网络诊断工具准备
这些工具是排查网络问题的必备神器:
# 创建一个网络调试 Pod
kubectl run netshoot --image=nicolaka/netshoot --command -- sleep infinity
# 常用诊断命令
kubectl exec -it netshoot -- bash
# 在 Pod 内可以使用:
# - ip addr / ip route / ip neigh
# - ping / traceroute / mtr
# - curl / wget
# - tcpdump / tshark
# - nslookup / dig
# - ss / netstat
# - iperf3(性能测试)
2.2 核心配置
2.2.1 CNI 插件工作原理
CNI(Container Network Interface)是 K8s 网络的核心。当 kubelet 创建 Pod 时,会调用 CNI 插件来配置网络。
CNI 调用流程:
┌─────────────────────────────────────────────────────────────────────┐
│ CNI 插件调用流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. kubelet 创建 Pod │
│ │ │
│ ▼ │
│ 2. 创建 pause 容器(持有网络命名空间) │
│ │ │
│ ▼ │
│ 3. 调用 CNI 插件(/opt/cni/bin/) │
│ │ │
│ ├──► 读取配置(/etc/cni/net.d/) │
│ │ │
│ ├──► 创建 veth pair │
│ │ │
│ ├──► 配置 IP 地址(IPAM) │
│ │ │
│ └──► 配置路由规则 │
│ │ │
│ ▼ │
│ 4. 返回网络配置给 kubelet │
│ │ │
│ ▼ │
│ 5. 启动业务容器(共享网络命名空间) │
│ │
└─────────────────────────────────────────────────────────────────────┘
CNI 配置文件示例(Cilium):
# 查看 CNI 配置
cat /etc/cni/net.d/05-cilium.conflist
{
"cniVersion": "0.3.1",
"name": "cilium",
"plugins": [
{
"type": "cilium-cni",
"enable-debug": false,
"log-file": "/var/run/cilium/cilium-cni.log"
}
]
}
2.2.2 Pod 网络模型详解
这是理解 K8s 网络的关键!每个 Pod 都有自己的网络栈:
┌─────────────────────────────────────────────────────────────────────┐
│ Pod 网络模型 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Pod │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Container A │ │ Container B │ │ Pause │ │ │
│ │ │ (app) │ │ (sidecar) │ │ (infra容器) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ localhost: │ │ localhost: │ │ 持有网络 │ │ │
│ │ │ 8080 │ │ 9090 │ │ 命名空间 │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────┴────────────────┘ │ │
│ │ │ │ │
│ │ 共享网络命名空间 │ │
│ │ │ │ │
│ │ ┌─────▼─────┐ │ │
│ │ │ eth0 │ │ │
│ │ │10.244.1.5 │ │ │
│ │ └───────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
关键点:
- 同一 Pod 内的容器共享网络命名空间,可以通过
localhost 互访
- Pause 容器(也叫 infra 容器)负责持有网络命名空间
- 每个 Pod 有独立的 IP,端口空间也是独立的
验证 Pod 网络:
# 创建测试 Pod
kubectl run nginx --image=nginx:alpine
# 查看 Pod IP
kubectl get pod nginx -o wide
# 进入 Pod 查看网络配置
kubectl exec -it nginx -- sh
/ # ip addr
/ # ip route
/ # cat /etc/resolv.conf
2.2.3 Service 四种类型详解
Service 是 K8s 网络的核心抽象,它为一组 Pod 提供稳定的访问入口。说白了,Pod IP 会变,但 Service IP 不会变。
┌─────────────────────────────────────────────────────────────────────┐
│ Service 四种类型对比 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│ │ ClusterIP │ │ NodePort │ │LoadBalancer │ │ExternalName│ │
│ │ (默认) │ │ │ │ │ │ │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ ├───────────┤ │
│ │ 仅集群内部 │ │ 节点端口 │ │ 云LB + NP │ │ DNS别名 │ │
│ │ 访问 │ │ 30000-32767 │ │ 自动创建 │ │ 无代理 │ │
│ │ │ │ │ │ │ │ │ │
│ │ 10.96.x.x │ │ NodeIP:Port │ │ External IP │ │ CNAME记录 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │
│ │
│ 适用场景: │
│ - ClusterIP: 内部微服务通信 │
│ - NodePort: 开发测试、简单暴露 │
│ - LoadBalancer: 生产环境对外服务 │
│ - ExternalName: 访问集群外部服务 │
│ │
└─────────────────────────────────────────────────────────────────────┘
1. ClusterIP(默认类型)
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # 可省略,默认就是 ClusterIP
selector:
app: my-app
ports:
- port: 80 # Service 端口
targetPort: 8080 # Pod 端口
2. NodePort
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 可选,不指定会自动分配 30000-32767
3. LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: my-lb-service
annotations:
# 云厂商特定注解
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
4. ExternalName
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com # 返回 CNAME 记录
2.2.4 kube-proxy 三种模式深度解析
kube-proxy 是实现 Service 负载均衡的关键组件。它有三种工作模式,理解它们的区别对于性能调优和故障排查非常重要。
模式对比:
| 特性 |
iptables |
IPVS |
nftables (1.31+) |
| 性能 |
O(n) 规则匹配 |
O(1) 哈希查找 |
O(1) 集合查找 |
| 大规模支持 |
差(>1000 Service 性能下降) |
优秀 |
优秀 |
| 负载均衡算法 |
随机 |
rr/lc/dh/sh/sed/nq |
随机 |
| 连接追踪 |
依赖 conntrack |
内置 |
依赖 conntrack |
| 调试难度 |
中等 |
较难 |
中等 |
| 内核要求 |
3.10+ |
4.0+ |
5.13+ |
1. iptables 模式(传统默认)
┌─────────────────────────────────────────────────────────────────────┐
│ iptables 模式工作原理 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Client Pod │
│ │ │
│ │ dst: 10.96.0.10:80 (ClusterIP) │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ iptables 规则链 │ │
│ │ │ │
│ │ PREROUTING → KUBE-SERVICES → KUBE-SVC-XXX │ │
│ │ │ │ │
│ │ ┌───────────────┼───────────────┐ │ │
│ │ ▼ ▼ ▼ │ │
│ │ KUBE-SEP-A KUBE-SEP-B KUBE-SEP-C │ │
│ │ (Pod A) (Pod B) (Pod C) │ │
│ │ 33.3% 33.3% 33.3% │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ DNAT: dst → 10.244.1.5:8080 (Pod IP) │
│ ▼ │
│ Backend Pod │
│ │
└─────────────────────────────────────────────────────────────────────┘
iptables 规则查看:
# 查看 iptables 规则
iptables -t nat -L KUBE-SERVICES -n --line-numbers
# 查看特定 Service 的规则
iptables -t nat -L KUBE-SVC-XXXXXXXXXXXXXXXX -n
2. IPVS 模式(推荐大规模集群)
┌─────────────────────────────────────────────────────────────────────┐
│ IPVS 模式工作原理 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Client Pod │
│ │ │
│ │ dst: 10.96.0.10:80 │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ IPVS Virtual Server │ │
│ │ │ │
│ │ VIP: 10.96.0.10:80 │ │
│ │ 调度算法: rr (round-robin) │ │
│ │ │ │
│ │ Real Servers: │ │
│ │ ├── 10.244.1.5:8080 weight=1 │ │
│ │ ├── 10.244.2.3:8080 weight=1 │ │
│ │ └── 10.244.3.7:8080 weight=1 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 直接转发到选中的 Real Server │
│ ▼ │
│ Backend Pod │
│ │
└─────────────────────────────────────────────────────────────────────┘
# 启用 IPVS 模式
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "ipvs"
# 查看 IPVS 规则
ipvsadm -Ln
# 查看特定 Service
ipvsadm -Ln -t 10.96.0.10:80
3. nftables 模式(K8s 1.31+ 新增)
这是 2025 年底新增的模式,用于替代老旧的 iptables。如果你的内核版本够新(5.13+),建议尝试。
# 启用 nftables 模式(需要 K8s 1.31+)
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "nftables"
# 查看 nftables 规则
nft list ruleset | grep -A 20 "chain services"
踩坑经验:我们在一个 500+ Service 的集群上从 iptables 切换到 IPVS 后,Service 访问延迟从平均 2ms 降到了 0.5ms。但要注意,IPVS 模式下需要确保 ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh 等内核模块已加载。
2.3 DNS 解析流程
2.3.1 CoreDNS 工作原理
K8s 集群内的服务发现主要依赖 DNS。CoreDNS 是集群的 DNS 服务器,负责解析 Service 名称到 ClusterIP。
┌─────────────────────────────────────────────────────────────────────┐
│ K8s DNS 解析流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Pod (curl my-service) │
│ │ │
│ │ 1. 查询 my-service │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ /etc/resolv.conf │ │
│ │ nameserver 10.96.0.10 (CoreDNS ClusterIP) │ │
│ │ search default.svc.cluster.local svc.cluster.local │ │
│ │ cluster.local │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 2. 依次尝试: │
│ │ - my-service.default.svc.cluster.local │
│ │ - my-service.svc.cluster.local │
│ │ - my-service.cluster.local │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ CoreDNS │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ kubernetes │ │ forward │ │ │
│ │ │ plugin │ │ plugin │ │ │
│ │ │ │ │ │ │ │
│ │ │ 查询 K8s API│ │ 转发到上游 │ │ │
│ │ │ 获取 Service│ │ DNS 服务器 │ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 3. 返回 ClusterIP: 10.96.100.50 │
│ ▼ │
│ Pod 访问 10.96.100.50 │
│ │
└─────────────────────────────────────────────────────────────────────┘
DNS 记录类型:
| 记录类型 |
格式 |
示例 |
| Service A 记录 |
<service>.<namespace>.svc.cluster.local |
nginx.default.svc.cluster.local |
| Pod A 记录 |
<pod-ip>.<namespace>.pod.cluster.local |
10-244-1-5.default.pod.cluster.local |
| Headless Service |
返回所有 Pod IP |
用于 StatefulSet |
| SRV 记录 |
_<port>._<protocol>.<service>.<namespace>.svc.cluster.local |
包含端口信息 |
2.3.2 CoreDNS 配置优化
# CoreDNS ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
常见 DNS 问题排查:
# 测试 DNS 解析
kubectl run dnstest --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns -f
# 检查 CoreDNS Pod 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 查看 DNS 配置
kubectl get configmap coredns -n kube-system -o yaml
踩坑提醒:曾经遇到过一个诡异的问题,Pod 内 DNS 解析偶发超时。排查了半天,发现是 ndots 配置的锅。默认 ndots:5 意味着域名中点数少于 5 个时,会先尝试加上 search 域。建议在 Pod spec 中显式设置:
spec:
dnsConfig:
options:
- name: ndots
value: "2" # 减少不必要的 DNS 查询
- name: single-request-reopen # 避免 conntrack 竞争
三、NetworkPolicy 实战
3.1 NetworkPolicy 基础
NetworkPolicy 是 K8s 的网络安全策略,用于控制 Pod 之间的流量。默认情况下,K8s 集群内所有 Pod 可以互相访问,这在生产环境是很危险的。
┌─────────────────────────────────────────────────────────────────────┐
│ NetworkPolicy 工作原理 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 默认行为(无 NetworkPolicy): │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Pod A│◄───►│Pod B│◄───►│Pod C│ 所有 Pod 互通 │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ 应用 NetworkPolicy 后: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Pod A│────►│Pod B│ ✗ │Pod C│ 只允许特定流量 │
│ └─────┘ └─────┘ └─────┘ │
│ │ ▲ │
│ │ │ 只允许来自 Pod A 的流量 │
│ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
重要概念:
- NetworkPolicy 是白名单机制
- 一旦对 Pod 应用了 NetworkPolicy,默认拒绝所有未明确允许的流量
- 需要 CNI 插件支持(Flannel 不支持!)
3.2 实战案例
案例一:默认拒绝所有入站流量
# deny-all-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {} # 选择该命名空间所有 Pod
policyTypes:
- Ingress
# 没有 ingress 规则 = 拒绝所有入站
案例二:只允许特定 Pod 访问数据库
# allow-app-to-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: mysql # 应用到 mysql Pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend # 只允许 backend Pod 访问
ports:
- protocol: TCP
port: 3306
案例三:允许来自特定命名空间的流量
# allow-from-namespace.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring # 允许 monitoring 命名空间的所有 Pod
ports:
- protocol: TCP
port: 9090 # Prometheus 指标端口
案例四:限制出站流量(防止数据泄露)
# restrict-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-egress
namespace: production
spec:
podSelector:
matchLabels:
app: sensitive-app
policyTypes:
- Egress
egress:
# 允许访问 DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# 允许访问内部数据库
- to:
- podSelector:
matchLabels:
app: mysql
ports:
- protocol: TCP
port: 3306
# 禁止其他所有出站流量
3.3 NetworkPolicy 调试技巧
# 查看命名空间下的所有 NetworkPolicy
kubectl get networkpolicy -n production
# 查看详细规则
kubectl describe networkpolicy allow-app-to-db -n production
# 使用 Cilium 的话,可以用 Hubble 可视化流量
hubble observe --namespace production
# 测试连通性
kubectl exec -it test-pod -- nc -zv mysql-service 3306
生产经验:建议采用"默认拒绝 + 显式允许"的策略。先在每个命名空间部署 deny-all 策略,然后根据实际需求逐步开放。这样可以最大程度减少攻击面。
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 CNI 选型建议
根据我这些年的经验,给出以下选型建议:
| 场景 |
推荐方案 |
理由 |
| 学习/测试环境 |
Flannel |
简单易用,资源占用少 |
| 中小规模生产 |
Calico |
成熟稳定,社区活跃 |
| 大规模生产 |
Cilium |
eBPF 性能优异,可观测性强 |
| 多集群/混合云 |
Cilium Cluster Mesh |
原生支持跨集群通信 |
| 安全敏感场景 |
Cilium + Tetragon |
内核级安全监控 |
4.1.2 性能优化
# 1. 启用 IPVS 模式(大规模集群必备)
kubectl edit configmap kube-proxy -n kube-system
# 设置 mode: "ipvs"
# 2. 调整 conntrack 参数
cat >> /etc/sysctl.conf << EOF
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600
EOF
sysctl -p
# 3. 如果使用 Cilium,启用 BPF 主机路由
helm upgrade cilium cilium/cilium \
--set bpf.masquerade=true \
--set routingMode=native \
--set autoDirectNodeRoutes=true
4.1.3 高可用配置
# CoreDNS 高可用配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
spec:
replicas: 3 # 至少 3 副本
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
k8s-app: kube-dns
topologyKey: kubernetes.io/hostname # 分散到不同节点
4.2 注意事项
4.2.1 常见陷阱
| 问题 |
原因 |
解决方案 |
| Pod 无法访问 Service |
kube-proxy 未运行或规则未同步 |
检查 kube-proxy 日志,重启 Pod |
| 跨节点 Pod 不通 |
CNI 配置错误或防火墙阻断 |
检查节点间网络,开放 VXLAN 端口 |
| DNS 解析超时 |
CoreDNS 资源不足或 ndots 配置 |
增加副本数,调整 ndots |
| Service 负载不均 |
会话亲和性或 IPVS 调度算法 |
检查 sessionAffinity 配置 |
| NetworkPolicy 不生效 |
CNI 不支持或规则配置错误 |
确认 CNI 支持,检查 selector |
4.2.2 安全加固
# 1. 禁用 NodePort 范围外的端口
# 在 kube-apiserver 配置中设置
--service-node-port-range=30000-32767
# 2. 启用 Pod 安全策略(或 Pod Security Standards)
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted
# 3. 限制 hostNetwork 使用
# 在 NetworkPolicy 中明确禁止
五、故障排查和监控
5.1 故障排查
5.1.1 网络排查流程图
┌─────────────────────────────────────────────────────────────────────┐
│ K8s 网络故障排查流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Pod 网络不通? │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ 1. 检查 Pod 状态 │ │
│ │ kubectl get pod -o wide │ │
│ │ Pod 是否 Running?IP 是否分配? │ │
│ └─────────────────┬───────────────────────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ Pod 异常 Pod 正常 │
│ 检查 CNI 日志 │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ 2. 检查同节点 Pod 互通 │ │
│ │ kubectl exec pod1 -- ping pod2 │ │
│ └─────────────────┬───────────────────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ 同节点不通 同节点通 │
│ 检查 CNI/网桥 │ │
│ ▼ │
│ ┌─────────────────────────────┐ │
│ │ 3. 检查跨节点 Pod 互通 │ │
│ └─────────────────┬───────────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ 跨节点不通 跨节点通 │
│ 检查 Overlay/路由 │ │
│ 检查防火墙 ▼ │
│ ┌─────────────┐ │
│ │ 4. 检查 │ │
│ │ Service/DNS │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
5.1.2 常用排查命令
# === Pod 层面 ===
# 查看 Pod 网络配置
kubectl exec -it <pod> -- ip addr
kubectl exec -it <pod> -- ip route
kubectl exec -it <pod> -- cat /etc/resolv.conf
# 测试连通性
kubectl exec -it <pod> -- ping <target-ip>
kubectl exec -it <pod> -- curl -v <service-name>:<port>
kubectl exec -it <pod> -- nslookup <service-name>
# === 节点层面 ===
# 查看网桥和 veth
ip link show type bridge
ip link show type veth
brctl show # 如果使用网桥模式
# 查看路由表
ip route show
ip route get <pod-ip>
# 查看 iptables 规则
iptables -t nat -L -n -v | grep <service-ip>
iptables -t filter -L -n -v
# 查看 IPVS 规则
ipvsadm -Ln
ipvsadm -Ln --stats
# === CNI 层面 ===
# Cilium 状态检查
cilium status
cilium connectivity test
# Calico 状态检查
calicoctl node status
calicoctl get ippool -o wide
5.1.3 抓包分析
# 在节点上抓取特定 Pod 的流量
# 首先找到 Pod 的 veth 接口
POD_ID=$(crictl pods --name <pod-name> -q)
VETH=$(ip link | grep -A1 "veth" | grep $POD_ID | awk '{print $2}' | tr -d ':')
# 抓包
tcpdump -i $VETH -nn -w pod-traffic.pcap
# 或者使用 nsenter 进入 Pod 网络命名空间
PID=$(crictl inspect $POD_ID | jq '.info.pid')
nsenter -t $PID -n tcpdump -i eth0 -nn
5.2 性能监控
5.2.1 关键指标
| 指标 |
正常范围 |
告警阈值 |
说明 |
| DNS 查询延迟 |
< 5ms |
> 50ms |
CoreDNS 响应时间 |
| Service 延迟 |
< 1ms |
> 10ms |
kube-proxy 转发延迟 |
| 跨节点延迟 |
< 1ms |
> 5ms |
Overlay 网络开销 |
| conntrack 使用率 |
< 70% |
> 85% |
连接跟踪表使用 |
| 丢包率 |
0% |
> 0.1% |
网络丢包 |
5.2.2 Prometheus 监控配置
# 网络相关告警规则
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: network-alerts
spec:
groups:
- name: network
rules:
- alert: HighDNSLatency
expr: histogram_quantile(0.99, rate(coredns_dns_request_duration_seconds_bucket[5m])) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "DNS 查询延迟过高"
- alert: ConntrackTableFull
expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.85
for: 5m
labels:
severity: critical
annotations:
summary: "Conntrack 表即将满"
六、总结
6.1 技术要点回顾
- Pod 网络模型:每个 Pod 独立 IP,同 Pod 容器共享网络命名空间
- CNI 插件:2026年首选 Cilium,eBPF 带来性能和可观测性优势
- Service 类型:ClusterIP(内部)、NodePort(测试)、LoadBalancer(生产)、ExternalName(外部)
- kube-proxy 模式:大规模集群用 IPVS,新集群可尝试 nftables
- DNS 解析:CoreDNS 负责服务发现,注意 ndots 配置优化
- NetworkPolicy:白名单机制,生产环境必须配置
6.2 进阶学习方向
-
eBPF 深入学习
- 学习资源:Cilium 官方文档、eBPF.io
- 实践建议:部署 Hubble 可视化,学习 BPF 程序编写
-
服务网格(Service Mesh)
- 学习资源:Istio、Linkerd 官方文档
- 实践建议:理解 Sidecar 模式,对比 Cilium Service Mesh
-
多集群网络
- 学习资源:Cilium Cluster Mesh、Submariner
- 实践建议:搭建跨集群通信实验环境
6.3 参考资料
- Kubernetes 官方网络文档
- Cilium 官方文档
- Calico 官方文档
- CoreDNS 官方文档
附录
A. 命令速查表
# Pod 网络
kubectl get pod -o wide # 查看 Pod IP
kubectl exec -it <pod> -- ip addr # 查看 Pod 网络配置
# Service
kubectl get svc # 查看 Service
kubectl get endpoints # 查看 Endpoints
# DNS
kubectl run -it --rm debug --image=busybox -- nslookup <service>
# CNI
cilium status # Cilium 状态
calicoctl node status # Calico 状态
# kube-proxy
iptables -t nat -L KUBE-SERVICES -n # iptables 规则
ipvsadm -Ln # IPVS 规则
B. 术语表
| 术语 |
英文 |
解释 |
| CNI |
Container Network Interface |
容器网络接口标准 |
| IPAM |
IP Address Management |
IP 地址管理 |
| VXLAN |
Virtual Extensible LAN |
虚拟可扩展局域网 |
| BGP |
Border Gateway Protocol |
边界网关协议 |
| eBPF |
extended Berkeley Packet Filter |
扩展伯克利包过滤器 |
写在最后:K8s 网络确实复杂,但只要理解了核心概念,剩下的就是实践和积累。建议大家多动手搭建测试环境,用 tcpdump 抓包分析,这样才能真正掌握。
