在 Kubernetes 集群中,网络是最容易被忽视、却最容易出问题的部分。前面我们部署了 Pod、Service 和 Ingress,但你是否想过:一个 Pod 如何与另一个 Pod 通信?Service 的 ClusterIP 为什么能在没有真实网卡的情况下被访问?跨节点的流量又是如何被正确路由的?这些问题背后,都依赖 Kubernetes 的网络模型以及负责实现它的 CNI 插件。今天我们就来深入拆解 K8s 网络模型的底层逻辑,并通过 Calico 和 NetworkPolicy 真正落地一套可管控的网络策略。

一、Kubernetes 网络模型的三大基本假设
Kubernetes 网络模型定义了一套统一的行为规范,无论底层使用哪种 CNI 插件,都必须满足以下三条核心假设:
- 每个 Pod 拥有自己独立的 IP 地址,不需要做 NAT 就能与其他 Pod 通信。
- 同一个节点上的 Pod 可以像在同一台主机上的进程一样,直接通过 IP 互通。
- Pod 看到的自身 IP,与集群内其他节点、其他 Pod 看到的 IP 完全一致(即 IP-per-Pod 模型)。
这意味着在 K8s 的世界里,你不需要像 Docker 默认网络那样做端口映射,也不需要关心容器在哪个节点。Pod 与 Pod 之间的通信被抽象成一个扁平的、可以直接寻址的网络空间。这种设计大幅简化了服务发现与负载均衡的实现,但也把”如何真正打通网络”的责任交给了 CNI 插件。
二、CNI:网络插件的统一标准接口
CNI(Container Network Interface)是由 CNCF 维护的一套规范,它定义了两个核心接口:一个是 ADD,用于在容器启动时为其配置网络(分配 IP、创建网卡、配置路由);另一个是 DEL,用于在容器销毁时回收网络资源。CNI 本身并不实现网络,它只是给各家插件(Calico、Flannel、Cilium 等)提供了一套统一的调用协议。
当 kubelet 准备启动一个 Pod 时,会调用 CNI 二进制,并传入类似下面的 JSON 配置:
{
"cniVersion": "0.4.0",
"name": "k8s-pod-network",
"type": "calico",
"ipam": {
"type": "calico-ipam",
"subnet": "10.244.0.0/16"
},
"capabilities": {
"portMappings": true
}
}
每个 CNI 插件负责解析这份配置,完成 IP 分配、路由下发等工作。常见的 CNI 插件包括:
- Flannel:实现简单,通过 VXLAN 或 host-gw 打通跨节点网络,适合入门和小规模集群。
- Calico:基于 BGP 或 VXLAN,支持丰富的网络策略,性能好,适合生产环境。
- Cilium:基于 eBPF,提供可观测性与安全能力,面向云原生高级场景。
选择 CNI 插件的核心考量是:是否需要细粒度的网络策略、对性能和可观测性的要求,以及运维团队的熟悉程度。
三、Calico 架构与数据面工作原理
Calico 是目前生产环境最主流的 CNI 方案之一,它的架构可以拆成控制面和数据面两层。控制面由 Calico 的 calico-kube-controllers 和 Felix 组件组成,负责监听 K8s API、维护策略与 IP 池;数据面则负责实际转发数据包。
Calico 支持两种数据面模式。第一种是 BGP 模式,每台节点上的 Felix 会把本节点的 Pod 网段通过 BGP 协议通告给其他节点,从而在每个节点上生成完整的路由表,数据包直接走三层路由,性能最好。第二种是 IPIP/VXLAN 隧道模式,当节点之间不能二层直连或底层网络不支持 BGP 时,通过隧道封装实现跨节点通信,牺牲少量性能换取普适性。
下面是一个典型的 Calico 安装命令,通过官方 manifest 一键部署:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
安装完成后,可以通过下面的命令查看 Calico 的节点状态和 IP 池配置:
# 查看 Calico 节点连接状态
calicoctl node status
# 查看 IP 地址池
calicoctl get ippool -o wide
如果使用 Calico 的 YAML 配置自定义 IP 池和隧道模式,可以这样写:
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 10.244.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
四、NetworkPolicy:用策略管住流量
很多团队部署完集群后,默认是”全通”状态:任何 Pod 都能访问任何其他 Pod,这存在很大的安全隐患。Kubernetes 提供的 NetworkPolicy 资源可以解决这个问题。它允许你声明式地定义”允许哪些流量进入/离开某个 Pod”,而由 CNI 插件(如 Calico)负责真正执行这些规则。
需要特别注意的是:NetworkPolicy 默认是”全放行”的。只有当你为某个命名空间或某组 Pod 创建了 NetworkPolicy 并选中它们后,规则才会生效,且一旦被选中,未明确允许的流量会被默认拒绝。
下面这条策略表示:只允许来自 app=frontend 标签的 Pod 访问 app=backend 的 8080 端口:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
五、实战:为应用加上最小权限网络策略
下面我们做一个完整的小实验。首先部署一个测试用的后端服务和一个数据库,给它们打上标签:
kubectl create deployment backend --image=nginx --port=80
kubectl label deployment backend app=backend
kubectl run db --image=mysql:5.7 --restart=Never
kubectl label pod db app=db
接着创建一个默认拒绝所有入站流量的策略,把 db 保护起来,只允许 backend 访问:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-isolation
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 3306
创建后,可以用下面的命令验证策略是否生效。在没有策略时,任意 Pod 都能访问 db;加上策略后,只有带 app=backend 标签的 Pod 才能连接 3306 端口:
kubectl apply -f db-isolation.yaml
kubectl get networkpolicy -n default
kubectl describe networkpolicy db-isolation
六、常见问题与排查思路
在实际运维中,网络问题是 K8s 故障排查的高发区。这里总结几个高频问题与解决思路:
- Pod 无法获取 IP:检查 CNI 插件是否正常安装,
kubectl get pods -n kube-system看 calico 相关 Pod 是否 Running,查看其日志是否有 IPAM 报错。 - 跨节点 Pod 无法互通:检查节点间路由是否正常,BGP 模式看
calicoctl node status是否 Established,VXLAN 模式检查 UDP 端口 4789 是否被防火墙拦截。 - Service 无法访问:先区分是 kube-proxy 问题还是 CNI 问题,可以用
kubectl exec进入 Pod 内直接 curl 目标 Pod 的 IP 来判断链路。 - NetworkPolicy 不生效:确认使用的 CNI 插件支持 NetworkPolicy(Flannel 默认不支持,Calico/Cilium 支持),并检查标签选择器是否匹配。
排查网络问题时,一个很有用的技巧是查看某个 Pod 的详细网络信息:
kubectl describe pod <pod-name> | grep -A5 "IP:"
kubectl exec -it <pod-name> -- ip addr
kubectl exec -it <pod-name> -- ping <目标Pod-IP>
七、总结
今天我们从 K8s 网络模型的三大假设出发,理解了为什么 K8s 能做到 Pod 扁平直连,随后介绍了 CNI 这一统一标准接口,并以 Calico 为例深入分析了它的 BGP 与隧道两种数据面模式,最后通过 NetworkPolicy 演示了如何为应用构建最小权限的网络访问策略。网络是集群的”毛细血管”,只有把网络模型和策略治理吃透,才能在生产环境中做到既畅通又安全。
下一期预告:第 11 天我们将进入权限安全主题,详细讲解 RBAC 与 ServiceAccount 的实战用法,看看 K8s 如何做细粒度的身份与授权管理,敬请期待。


















暂无评论内容