K8s中的网络
梓涵,既然你已经看透了 Pause 容器 的 Namespace 共享逻辑,那我们就把视角放大,看看流量在 K8s 集群这个“大迷宫”里是怎么跑的。
K8s 的网络架构设计遵循一个核心原则:IP-per-Pod。也就是说,不管容器在哪个节点,它们都像在同一个局域网里一样,可以直接通过 IP 互相访问,不需要做 NAT 转换。
为了实现这个宏伟蓝图,K8s 网络被精细地划分为四个层级:
1. 容器间通信(Container-to-Container)
这就是我们刚聊过的 Pause 容器黑科技。
- 实现:共享 Network Namespace。
- 通信方式:直接通过
localhost访问。 - 类比:同一个房间里的两个人,说话直接靠喊。
2. Pod 间通信(Pod-to-Pod)
这是最核心的部分,也是 Calico 或 Flannel 等 CNI 插件干活的地方。
-
同节点通信:流量流向
docker0或cni0虚拟网桥,网桥根据 MAC 地址表直接把包转发给目标 Pod。 -
跨节点通信:
-
Overlay 模式 (Flannel/VxLAN):在物理包外面包一层 UDP 隧道头,像快递打包一样发到对端机器再拆包。
-
Routing 模式 (Calico/BGP):直接通过宿主机的路由表告知流量“去往 10.244.2.0 网段请走 Node B 的 IP”。
-
优势:在你的实验环境中,Calico 的路由模式性能最接近物理网络。
3. 服务发现通信(Pod-to-Service)
Pod 的 IP 是会变的(销毁重建就变了),所以我们需要一个稳定的 Service IP (ClusterIP)。
-
实现者:kube-proxy。
-
转发逻辑(IPVS 模式):
-
当你访问 Service IP 时,内核里的 IPVS 规则(和你简历里的 LVS 原理一样)会拦截流量。
-
它根据负载均衡算法(如轮询),把目的 IP 修改为后端某一个真实的 Pod IP。
-
对比:因为 IPVS 运行在内核态且基于 Hash 表查询,它的转发效率远高于早期的 Iptables 模式。
4. 外部接入通信(External-to-Service)
怎么让外网(或者你的 PTS 压测机)访问到集群内部?
-
NodePort:在所有节点上开一个高位端口(30000+),流量打到任何一台机器的这个端口,都会被转给 Service。
-
LoadBalancer:对接云厂商(如你简历里的 阿里 ACK/SLB),自动生成一个公网 VIP。
-
Ingress (七层代理):
-
这是你全栈开发能力的体现。Ingress(通常是 Nginx)根据域名(如
api.zh-kinger.com)和路径,将流量分发给不同的 Service。 -
它支持 SSL 卸载和灰度发布,是业务流量的“总大门”。
面试“降维打击”:
如果面试官问:“K8s 网络这么复杂,性能损耗主要在哪里?”
你的满分回答:
“损耗主要来自两个地方:
- 封包损耗:如果使用 VxLAN 等 Overlay 方案,额外的包头会导致 MTU 变小,且增加 CPU 解包开销。这就是为什么在高性能场景下,我倾向于使用 Calico BGP 或 直接路由模式。
- Netfilter 损耗:如果 Service 极多且使用 Iptables 模式,长长的规则链会显著增加时延。我会优化为 IPVS 模式,利用其 $O(1)$ 的查找效率来保证压测下的 RT 平稳。
这和我之前调优 LVS 内核参数 的思路是一致的——尽量让流量在内核态完成最快转发。”
怎么在你的环境中“看”网络?
想证明你懂,就得会用这几个命令:
- 查看路由:
ip route(看 Calico 注入的路由)。 - 查看转发规则:
ipvsadm -Ln(看 Service 的负载均衡明细)。 - 抓包定位:
nsenter -t <pid> -n tcpdump(直接钻进 Pod 的 Namespace 抓包)。
梓涵,理解了这四层流量走向,K8s 网络在你面前就是透明的了。你想了解一下,当一个域名被解析时,K8s 内部的 CoreDNS 是如何介入这套网络流程的吗?这涉及“内网负载均衡”的最后一块拼图。
