说实话,K8s 网络是我见过最让新手头疼的知识点,没有之一。记得我刚接触 K8s 那会儿,看着流量在 Pod、Service、Node 之间穿梭,完全是一脸懵逼。后来踩了无数坑,熬了无数夜,总算把这套网络模型摸透了。今天这篇文章,我会用最接地气的方式,带你彻底搞懂 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 适用场景
不同的网络方案适用于不同场景,选错了后期改造成本很高(别问我怎么知道的...):
Overlay 网络(VXLAN/Geneve):
适合:跨云部署、网络环境复杂、IP 地址受限
缺点:有封装开销,性能略低
典型:Flannel VXLAN、Calico IPIP
路由网络(BGP/Host-Gateway):
适合:数据中心内部、对性能要求高、有 BGP 基础设施
缺点:需要网络团队配合,配置相对复杂
典型:Calico BGP、Cilium Native Routing
eBPF 网络:
适合:大规模集群、需要高级网络策略、追求极致性能
缺点:内核版本要求高(建议 5.10+)
典型:Cilium、Calico eBPF 模式
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 <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 -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 记录 |
|
nginx.default.svc.cluster.local |
| Pod A 记录 |
|
10-244-1-5.default.pod.cluster.local |
| Headless Service | 返回所有 Pod IP | 用于 StatefulSet |
| SRV 记录 |
_ |
包含端口信息 |
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-- ip addr kubectl exec -it -- ip route kubectl exec -it -- cat /etc/resolv.conf # 测试连通性 kubectl exec -it -- ping kubectl exec -it -- curl -v : kubectl exec -it -- nslookup # === 节点层面 === # 查看网桥和 veth ip link show type bridge ip link show type veth brctl show # 如果使用网桥模式 # 查看路由表 ip route show ip route get # 查看 iptables 规则 iptables -t nat -L -n -v | grep 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-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-- ip addr # 查看 Pod 网络配置 # Service kubectl get svc # 查看 Service kubectl get endpoints # 查看 Endpoints # DNS kubectl run -it --rm debug --image=busybox -- nslookup # 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 抓包分析,这样才能真正掌握。有问题欢迎交流,我们下篇文章见!
全部0条评论
快来发表一下你的评论吧 !