# 从 Linux 网络到 Kubernetes 网络:彻底理解 Pod 是如何通信的
很多人学习 Kubernetes 网络时,一上来就接触:
- Pod
- Service
- Ingress
- CNI
- Flannel
- Calico
结果越学越乱。
真正的问题在于:
Kubernetes 网络并不是一个独立体系,而是建立在 Linux 网络之上的一层抽象。
如果不了解 Linux 网络,那么 Pod、Service、VXLAN 这些概念都会变成黑盒。
一、网络世界只有三个核心概念
整个网络可以抽象成三件事:
设备
地址
转发
对应:
设备:
网卡
交换机
路由器
地址:
MAC
IP
转发:
交换
路由
NAT
二、MAC 与 IP
MAC 地址
MAC 是二层地址。
00:11:22:33:44:55
作用是在同一个局域网内定位设备。
IP 地址
IP 是三层地址。
192.168.1.10
10.244.1.2
8.8.8.8
作用是跨网络定位设备。
三、交换机、ARP、路由器
交换机工作在二层,只看 MAC 地址,不看 IP、TCP、HTTP。
ARP 负责:
IP -> MAC
路由器工作在三层:
查看目标 IP
↓
查路由表
↓
决定下一跳
路由表示例:
ip route
192.168.1.0/24 dev eth0
default via 192.168.1.1
含义:
同网段直接发送
其他流量交给默认网关
四、NAT
私网地址不能直接在公网路由:
192.168.x.x
172.16.x.x
10.x.x.x
所以路由器会做 SNAT:
SRC 192.168.1.10
↓
SRC 公网 IP
并通过 conntrack 记录连接映射,用于回包恢复。
五、Linux Network Namespace
Namespace 是 Linux 的隔离机制。
Network Namespace 隔离的是一整套网络栈:
网卡
IP
路由表
ARP 表
iptables
端口空间
所以容器不是虚拟机,而是:
普通 Linux 进程
+
Namespace 隔离
+
Cgroups 限制
+
RootFS 文件系统
六、veth Pair
Namespace 之间需要连接,Linux 提供了 veth pair。
vethA <====> vethB
它像一根虚拟网线:
从 vethA 发出的包,会从 vethB 出来
从 vethB 发出的包,会从 vethA 出来
七、Linux Bridge
Bridge 是软件交换机。
ContainerA
|
Bridge
|
ContainerB
它和物理交换机一样:
学习 MAC
查 MAC 表
转发数据帧
八、Docker 网络
Docker 默认网络结构:
Container
eth0
│
veth
│
docker0
│
Host
其中 docker0 是 Linux Bridge,同时被 Docker 配置了 IP:
docker0 = 172.17.0.1
所以 docker0 既是交换机,也是容器默认网关。
Docker 自己维护 IPAM:
172.17.0.0/16
容器 IP 通常由 Docker 分配:
172.17.0.2
172.17.0.3
172.17.0.4
九、Pod 是什么
Pod 不是容器。
一个 Pod 里可以有多个容器:
Pod
├── app
└── sidecar
真正持有网络命名空间的是 pause container。
pause container
└── Network Namespace
app
└── 加入 pause 的 Network Namespace
sidecar
└── 加入 pause 的 Network Namespace
所以同一个 Pod 内多个容器共享:
IP
localhost
端口空间
十、Kubernetes 单节点网络
很多 CNI 会在 Node 上创建类似 docker0 的网桥,比如:
cni0
结构:
PodA
|
veth
|
cni0
|
veth
|
PodB
同节点 Pod 通信时:
PodA ARP 查询 PodB MAC
↓
cni0 广播
↓
PodB 回复
↓
cni0 根据 MAC 表转发
这个过程本质是二层交换。
十一、CNI 是什么
Kubernetes 本身不直接实现网络。
它通过 CNI 插件处理 Pod 网络。
常见 CNI:
Flannel
Calico
Cilium
CNI 负责:
创建 veth
配置 IP
配置路由
接入 Bridge 或其他数据平面
维护跨节点通信
Pod IP 通常由 CNI 的 IPAM 模块分配,不是 Kubernetes 或 Linux 自动分配。
十二、跨节点 Pod 通信
假设:
Node1
PodA = 10.244.1.2
Node2
PodB = 10.244.2.2
PodA 访问 PodB:
10.244.1.2 -> 10.244.2.2
问题是:
Node1 怎么知道 10.244.2.0/24 在 Node2?
这就是 CNI 要解决的问题。
十三、VXLAN
VXLAN 是:
L2 Overlay over L3
意思是:
把二层网络封装到三层 IP 网络里面
原始 Pod 包:
SRC 10.244.1.2
DST 10.244.2.2
经过 VXLAN 封装:
Outer IP:
SRC Node1IP
DST Node2IP
UDP
VXLAN Header
Inner IP:
SRC 10.244.1.2
DST 10.244.2.2
包结构:
Outer Ethernet
Outer IP
UDP
VXLAN
Inner Ethernet
Inner IP
TCP
HTTP
中间物理网络只看到:
Node1IP -> Node2IP
Node2 收到后解 VXLAN,再把原始 Pod 包送给 PodB。
十四、flannel.1 是什么
flannel.1 不是进程。
它是 Linux VXLAN 网络设备。
类似:
eth0
docker0
cni0
vethxxx
路由表里:
10.244.2.0/24 dev flannel.1
意思是:
去 10.244.2.0/24 的流量
交给 flannel.1 这个 VXLAN 设备处理
然后 Linux 内核负责 VXLAN 封装。
flanneld 才是进程,它负责:
创建 flannel.1
写路由表
维护 Node 和 PodCIDR 的映射
十五、Service 的本质
Service 提供稳定访问入口。
例如:
Service IP = 10.96.0.10
但这个 IP 通常不是某张真实网卡上的 IP。
Service 本质是:
虚拟 IP
+
iptables / IPVS 转发规则
十六、kube-proxy
kube-proxy 监听:
Service
Endpoint / EndpointSlice
然后生成转发规则。
例如:
10.96.0.10:8080
↓ DNAT
10.244.1.2:8080
所以访问 Service 时,真实过程是:
访问 Service IP
↓
iptables / IPVS 命中规则
↓
DNAT 到某个后端 Pod IP
↓
通过 CNI 网络转发到目标 Pod
十七、CoreDNS
Pod 内访问服务名:
curl user-service
解析过程:
user-service
↓
CoreDNS
↓
Service ClusterIP
↓
kube-proxy
↓
Pod IP
十八、Ingress
Ingress 是规则,不是真正的网关进程。
真正处理流量的是 Ingress Controller,比如:
Nginx Ingress Controller
Traefik
APISIX
Kong
外部请求链路:
Browser
↓
LoadBalancer / NodePort
↓
Ingress Controller
↓
Service
↓
Pod
Ingress Controller 通常是七层反向代理,会解析:
Host
Path
TLS
HTTP Header
十九、完整链路总结
Linux 网络基础:
MAC
↓
ARP
↓
交换机
↓
路由器
↓
路由表
↓
NAT
容器网络基础:
Namespace
↓
veth
↓
Bridge
↓
IPAM
↓
Docker 网络
Kubernetes 网络:
Pod
↓
CNI
↓
PodCIDR
↓
cni0 / route / eBPF
↓
VXLAN / BGP
↓
Service
↓
CoreDNS
↓
Ingress
二十、最终结论
Kubernetes 网络不是凭空出现的新体系。
它本质是:
Linux 网络能力
+
CNI 自动化
+
Kubernetes 声明式编排
更具体地说:
Kubernetes 网络
=
Namespace
+
veth
+
Bridge
+
Route
+
NAT
+
iptables / IPVS
+
VXLAN / BGP / eBPF
+
CNI
理解 Kubernetes 网络,正确路径不是先背 Pod、Service、Ingress,而是先理解:
Linux 如何转发一个包
容器如何拥有自己的网络栈
Pod 如何通过 CNI 接入网络
跨节点 Pod 如何通过 VXLAN 或路由互通
Service 如何通过 DNAT 找到后端 Pod
Ingress 如何作为七层入口转发流量