4、Kubernetes网络模型:Pod网络通信原理、Service与kube-proxy、网络策略(NetworkPolicy)基础
好,咱们进入第四讲。这一章可以说是Kubernetes网络的骨架。你想想看,一个Pod怎么跟另一个Pod通信?Service到底是怎么做到负载均衡的?NetworkPolicy又是怎么把流量管住的?这些搞不清楚,后面玩OVS集成就是空中楼阁。
我个人习惯,讲网络模型之前,先让大家忘掉物理网络。Kubernetes的网络是一个逻辑网络,它有自己的规则。说白了,就是一套“虚拟世界”的通信协议。
4.1 Pod网络通信原理:扁平网络的核心
Kubernetes网络模型最核心的一条:每个Pod都有一个独立的IP地址,并且所有Pod之间可以直接通信,不需要NAT。这就是所谓的“扁平网络”。
我在项目中遇到过不少新手问:“Pod的IP是物理机的IP吗?”不是的。Pod的IP是CNI插件分配的,比如Flannel、Calico,或者我们后面要讲的OVS。这个IP只在集群内部可达。
Pod通信分三种场景:
- 同一个Pod内的容器:共享网络命名空间,通过localhost通信。这个最简单。
- 同一个Node上的Pod:通过Node上的虚拟网桥(比如cbr0、ovs-br)直接转发。
- 跨Node的Pod:需要Overlay网络或者路由协议。这就是CNI插件干的事。
关键点:Kubernetes不关心你怎么实现Pod网络,它只要求结果——每个Pod拿到一个唯一的IP,并且能无NAT地访问其他Pod。
嗯,这里要注意。扁平网络听起来简单,但实现起来坑不少。比如IP地址冲突、路由表维护、MTU问题。我曾经在一个生产集群里,因为MTU设置不对,导致跨Node的Pod通信时不时丢包。查了两天才发现是Overlay网络的封装头把MTU撑爆了。
4.2 Service与kube-proxy:服务发现的基石
Pod是“临时工”。它随时可能被销毁、重建,IP也会变。那问题来了:客户端怎么找到它?
答案就是Service。Service给一组Pod提供一个稳定的虚拟IP(ClusterIP),客户端只管访问这个IP,剩下的转发工作交给kube-proxy。
kube-proxy有三种模式,我列个表对比一下:
| 模式 | 工作原理 | 性能 | 适用场景 |
|---|---|---|---|
| userspace | 用户态代理,监听端口,转发到后端Pod | 低(需要上下文切换) | 早期版本,已废弃 |
| iptables | 利用iptables规则做DNAT | 中等(规则多时性能下降) | 小规模集群,默认模式 |
| IPVS | 利用内核IPVS模块,哈希表转发 | 高(适合大规模) | 生产环境推荐 |
我个人习惯,生产环境一律用IPVS模式。为什么?iptables模式在Service数量超过1000个时,规则更新会变得很慢,甚至导致kube-proxy CPU飙升。我经历过一次,那感觉就像在泥潭里跑步。
小技巧:切换IPVS模式很简单,在kube-proxy的配置里设置 mode: ipvs,然后确保节点上安装了ipvsadm和内核模块。
Service还有一个重要概念——EndpointSlice。以前叫Endpoints,但Endpoints对象会把所有后端Pod的IP都塞到一个对象里,Pod数量一多就爆炸。EndpointSlice把后端切分成多个片段,每个片段最多100个端点。这个改进很实用。
4.3 网络策略(NetworkPolicy)基础
默认情况下,Kubernetes集群里的Pod是“来者不拒”的。任何Pod都可以访问任何Pod。这显然不安全。NetworkPolicy就是用来做流量控制的。
NetworkPolicy的工作原理,说白了就是“白名单”。你定义哪些Pod可以访问目标Pod,其他的统统拒绝。
看一个简单的例子:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
这个策略的意思是:只有带有 app: frontend 标签的Pod,才能访问带有 app: backend 标签的Pod的8080端口。其他流量全部被拒绝。
注意:NetworkPolicy需要CNI插件支持。不是所有CNI插件都实现了NetworkPolicy。比如Flannel就不支持,Calico和OVS-Kubernetes是支持的。如果你用了Flannel又想用NetworkPolicy,那得再装一个插件,比如Antrea。
我曾经在一个金融项目里,客户要求严格隔离不同环境的Pod。开发环境、测试环境、预发布环境,每个环境之间不能互通。我们用NetworkPolicy配合命名空间标签,实现了“环境隔离”。效果很好,但调试起来也费劲。因为NetworkPolicy是“隐式拒绝”,一旦策略写错了,Pod就变成“孤岛”了。
这里分享一个避坑指南:先放通,再收紧。刚开始不要写太严格的策略,先写一个允许所有流量的策略,确认Pod能正常通信后,再逐步收紧。我曾经一上来就写了个“拒绝所有”,结果整个集群的服务都挂了,连kubectl exec都进不去Pod。嗯,那场面,挺尴尬的。
4.4 小结
这一章我们讲了三个核心概念:
- Pod网络通信:扁平网络,无NAT,CNI插件负责实现。
- Service与kube-proxy:稳定虚拟IP,三种模式选IPVS。
- NetworkPolicy:白名单机制,需要CNI插件支持。
下一章,我们会正式进入OVS的世界。到时候你会发现,OVS在Kubernetes网络里能做的事情,比你想的要多得多。
公众号:蓝海资料掘金营,微信deep3321