Kubernetes 网络模型:Pod 通信、Service 网络与 CNI

摘要:网络是 Kubernetes 最复杂的部分之一。本文从基本原则出发,详解 K8s 网络四大要求、Pod 内/间通信机制、Service 网络实现、DNS 解析、CNI 插件对比及 NetworkPolicy 配置,并提供生产环境排查与选型建议。

一、K8s 网络四大基本要求

Kubernetes 网络模型遵循四条基本原则,保证 Pod 网络扁平、可预测,便于服务发现与负载均衡。

规则 说明
Pod 内容器通信 同一 Pod 内多容器通过 localhost 通信,共享网络命名空间
Pod 间通信 所有 Pod 之间可不经 NAT 直接互通,无需端口映射
节点与 Pod 通信 节点可直接与所有 Pod 通信,无需额外网关
Pod IP 一致性 Pod 自身 IP 与其它 Pod 看到的 IP 一致,无地址转换

核心是:每个 Pod 拥有独立 IP,Pod 网络是扁平的。
Pod 内容器: localhost 通信
Pod 与 Pod: 无 NAT 直接互通
Node 与 Pod: 直接通信
Pod IP 一致性
每个 Pod 独立 IP

说明:以上规则保证 Pod 网络扁平、可预测,便于服务发现与负载均衡。

二、K8s 三层网络

Kubernetes 中存在三种网络:节点网络(物理/虚拟机的宿主机网络)、Pod 网络(由 CNI 管理的虚拟网络)、Service 网络(ClusterIP 等虚拟 IP,存在于 iptables/IPVS 规则中)。
Service 网络
Svc-A: 10.96.0.100
Pod 网络 Pod Network
Pod-A: 10.244.1.5
Pod-B: 10.244.2.3
节点网络 Node Network
Node-1: 192.168.1.10
Node-2: 192.168.1.11
CNI 插件管理
kube-proxy

说明:节点网络承载节点间通信;Pod 网络由 CNI 分配和管理;Service 网络为虚拟 IP,由 kube-proxy 通过 iptables/IPVS 实现。

网络类型 IP 范围示例 说明
节点网络 192.168.1.0/24 宿主机物理/虚拟网络
Pod 网络 10.244.0.0/16 CNI 管理的 Pod IP
Service 网络 10.96.0.0/12 ClusterIP,仅存在于规则中

三、Pod 内通信

同一 Pod 内多个容器共享网络命名空间,通过 localhost 通信。容器间通过回环接口(lo)通信,延迟极低,无跨网络栈开销。
Pod 共享网络命名空间
App 容器 :8080
localhost
Sidecar :9090

工作原理 :kubelet 创建 Pod 时,先创建 pause 容器作为网络命名空间占位,其他容器通过 container.network 共享该命名空间。App 访问 Sidecar 时使用 http://localhost:9090。同一 Pod 内不同容器不能绑定相同端口。

3.1 完整示例

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: app
    image: nginx:alpine
    ports:
    - containerPort: 80
  - name: sidecar
    image: busybox
    command: ["sleep", "3600"]
bash 复制代码
# 验证:从 app 容器访问 sidecar 的 localhost
kubectl exec multi-container-pod -c app -- wget -qO- http://localhost:80

# 查看 Pod 网络命名空间内的网络接口
kubectl exec multi-container-pod -c app -- ip addr
# 可见 eth0(veth)、lo(回环),与同 Pod 其他容器共享

四、Pod 间通信

4.1 同节点 Pod 间通信

同一节点上的 Pod 通过 Linux Bridge(如 cbr0)进行二层转发。数据包经 veth 对进入 Bridge,再转发到目标 Pod。
Node 1
veth pair
veth pair
Pod A 10.244.1.2
cbr0 10.244.1.0/24
Pod B 10.244.1.3

工作原理:每个 Pod 的 veth 一端在 Pod 网络命名空间,另一端连接到 cbr0。Pod A 的数据包经 veth 进入 cbr0,由 Bridge 二层转发到 Pod B 的 veth,无需经过节点网络栈。

4.2 跨节点 Pod 间通信

不同节点上的 Pod 需经过节点网络。流量从源 Pod 经 cbr0 到 eth0,经物理网络或隧道到达目标节点的 eth0,再经 cbr0 到目标 Pod。
Node 2
Node 1
物理网络/隧道
Pod A 10.244.1.2
cbr0 10.244.1.0/24
eth0 192.168.1.10
eth0 192.168.1.11
cbr0 10.244.2.0/24
Pod B 10.244.2.3

实现方式:跨节点通信由 CNI 实现,常见方式包括 VXLAN 等 Overlay、BGP 路由通告、或云厂商 VPC 路由。

五、Service 网络工作原理

Service 的 ClusterIP 是虚拟 IP,没有对应的网络接口。kube-proxy 在 iptables/IPVS 中配置 DNAT 规则,将访问 ClusterIP 的流量转发到后端 Pod IP。
访问 my-svc 10.96.0.100:80
10.96.0.100:80 → 10.244.2.3:8080
Pod A
DNS 解析
iptables/IPVS DNAT
Pod B

iptables 模式:kube-proxy 为每个 Service 创建 KUBE-SERVICES 链,规则匹配 ClusterIP:port 后 DNAT 到 KUBE-SEP-xxx 链,再随机选择 Endpoint 做 DNAT。

IPVS 模式:kube-proxy 使用 ipvs 模块,支持 rr、lc、dh 等负载均衡算法,规则数量多时性能优于 iptables。

bash 复制代码
# 查看 kube-proxy 模式
kubectl get cm -n kube-system kube-proxy -o yaml | grep mode

六、DNS 解析

6.1 域名格式

集群内使用 CoreDNS 解析 Service 域名。Pod 的 /etc/resolv.conf 指向 CoreDNS(如 10.96.0.10)。

域名格式 示例 说明
短名称 my-svc 同命名空间内使用
命名空间 my-svc.namespace 跨命名空间
完整 FQDN my-svc.namespace.svc.cluster.local 完整域名

6.2 CoreDNS 配置

yaml 复制代码
# 典型 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
    }

6.3 ndots 优化

Pod 的 resolv.confoptions ndots:5 表示域名中少于 5 个点则先尝试加集群后缀。频繁访问外部域名时,建议使用完整域名或调整 ndots 以减少无效查询。

yaml 复制代码
# 自定义 ndots
spec:
  dnsConfig:
    options:
    - name: ndots
      value: "2"

七、CNI 插件

CNI 是 kubelet 与网络插件之间的标准接口。kubelet 在创建/删除 Pod 时调用 CNI 插件,完成 IP 分配、网络配置和清理。
创建 Pod
删除 Pod
kubelet
CNI 插件
分配 IP 配置网络
回收 IP 清理网络

7.1 CNI 插件对比

插件 架构 性能 NetworkPolicy 适用场景
Calico BGP/VXLAN 高,无 Overlay 时最优 原生支持 生产环境、多集群
Cilium eBPF 极高,内核旁路 原生支持 高性能、可观测性
Flannel VXLAN/host-gw 中等 需额外组件 入门、简单场景
Weave Net VXLAN 中等 支持 小规模集群
AWS VPC CNI VPC 直连 支持 AWS 环境

7.2 Calico

  • 架构:支持 BGP 直连或 VXLAN Overlay,BGP 模式下无封装开销
  • NetworkPolicy:原生实现,支持 Ingress/Egress、命名空间选择器
  • 适用:生产环境、需要细粒度网络策略

7.3 Cilium

  • 架构:基于 eBPF,在内核层面实现网络策略与负载均衡
  • 性能:绕过 iptables,规则规模大时性能优势明显
  • 可观测性:内置 Hubble 提供网络可观测性

7.4 Flannel

  • 架构:VXLAN 或 host-gw,部署简单
  • NetworkPolicy:默认不支持,需配合 Calico 等
  • 适用:开发测试、小规模集群

八、NetworkPolicy

NetworkPolicy 用于限制 Pod 之间的网络访问。通过 podSelectornamespaceSelectorports 定义入站/出站规则。依赖 CNI 实现,Calico、Cilium 支持,Flannel 默认不支持。

8.1 完整示例

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - port: 8080
      protocol: TCP
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - port: 5432
      protocol: TCP
  - to:
    - namespaceSelector: {}
    ports:
    - port: 53
      protocol: UDP

8.2 字段说明

字段 说明
podSelector 选择应用策略的 Pod
policyTypes Ingress(入站)、Egress(出站)
ingress.from 允许访问的来源:podSelector、namespaceSelector、ipBlock
ingress.ports 允许的端口列表
egress.to 允许访问的目标
egress.ports 允许的出站端口

允许 port 8080
允许
拒绝
frontend role=frontend
backend app=backend
monitoring ns
other-pod 无标签

九、kubectl 网络相关命令

bash 复制代码
# 查看 Pod IP
kubectl get pods -o wide

# 查看 Service
kubectl get svc

# 从 Pod 内测试 DNS
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes

# 查看 CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 查看 kube-proxy 模式
kubectl get cm -n kube-system kube-proxy -o yaml | grep mode

# 验证 NetworkPolicy
kubectl get networkpolicy -A

十、网络诊断

10.1 Pod 之间不通

bash 复制代码
# 检查 Pod 是否在同一 CNI 网络
kubectl get pods -o wide

# 从 Pod A ping Pod B IP
kubectl exec -it <pod-a> -- ping <pod-b-ip>

# 检查 NetworkPolicy 是否阻断
kubectl get networkpolicy -A

# 检查 CNI 插件状态
kubectl get pods -n kube-system -l k8s-app=calico-node

10.2 Service 无法访问

bash 复制代码
# 检查 Service 的 endpoints
kubectl get endpoints <service-name>

# 检查 kube-proxy 是否正常运行
kubectl get pods -n kube-system -l k8s-app=kube-proxy

# 检查 iptables 规则(Node 上执行)
iptables-save | grep <service-clusterip>

10.3 DNS 解析失败

bash 复制代码
# 检查 CoreDNS 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 检查 CoreDNS 配置
kubectl get configmap coredns -n kube-system -o yaml

# 从 Pod 内测试
kubectl run -it --rm debug --image=busybox -- nslookup kubernetes.default.svc.cluster.local

十一、FAQ

11.1 Pod 网络不通如何排查?

  1. 确认 Pod 状态与 IP:kubectl get pods -o wide
  2. 检查 CNI 插件:kubectl get pods -n kube-system 中 Calico/Cilium/Flannel 是否 Running
  3. 检查 NetworkPolicy:kubectl get networkpolicy -A 是否有限制规则
  4. 跨节点时检查节点间路由或 Overlay 隧道是否正常

11.2 DNS 解析慢如何优化?

  1. 调整 ndots:外部域名多时降低 ndots 减少无效查询
  2. 使用完整域名:避免多次 DNS 查询
  3. 增加 CoreDNS 副本数:kubectl scale deployment coredns -n kube-system --replicas=3
  4. 启用 CoreDNS 缓存:确认 cache 30 等配置

11.3 CNI 选型建议?

  • 云厂商环境:优先考虑 VPC CNI(如 AWS VPC CNI)以利用 VPC 安全组
  • 自建集群:Calico(BGP 直连)或 Cilium(eBPF 高性能)
  • 需要 NetworkPolicy:排除 Flannel 单机部署,选 Calico 或 Cilium
  • 小规模/开发:Flannel 部署简单,可快速验证

11.4 Service ClusterIP 无法 ping 通?

ClusterIP 是虚拟 IP,仅存在于 iptables/IPVS 规则中,不绑定网卡。ping 使用 ICMP,kube-proxy 只配置了 TCP/UDP 的 DNAT,因此 ClusterIP 无法 ping 通。使用 curlwget 测试 HTTP 服务即可。

十二、生产建议

类别 建议
CNI 生产环境选用 Calico 或 Cilium,确保 NetworkPolicy 支持
DNS 合理配置 ndots,外部域名使用完整 FQDN
kube-proxy 大规模集群优先 IPVS 模式
NetworkPolicy 按最小权限配置 Ingress/Egress,默认拒绝、显式放行
监控 监控 CoreDNS、kube-proxy、CNI 组件健康状态

十三、总结

组件 职责
CNI Pod 网络分配与管理,跨节点通信
kube-proxy Service ClusterIP 转发,iptables/IPVS 规则
CoreDNS 集群内 DNS 解析,服务发现
NetworkPolicy 网络访问控制,依赖 CNI 实现

CNI 插件
Pod 网络
kube-proxy
Service 网络
CoreDNS
服务发现
NetworkPolicy
访问控制

相关推荐
2401_848009722 小时前
Docker学习后续
docker·云原生·eureka
封奚泽优2 小时前
Docker常用命令(Windows 11)
运维·docker·容器
was1723 小时前
你的私有知识库:自托管 Markdown 笔记方案 NoteDiscovery
笔记·云原生·自部署
崎岖Qiu3 小时前
【计算机网络 | 第十一篇】图解交换机的自学习功能
网络·学习·计算机网络
Zach_yuan3 小时前
数据链路层核心技术解析:以太网与ARP协议
服务器·网络·网络协议
only_Klein6 小时前
kubernetes-ReplicaSet控制器
容器·kubernetes
上海合宙LuatOS7 小时前
LuatOS核心库API——【io】 io操作(扩展)
java·服务器·前端·网络·单片机·嵌入式硬件·物联网
她说彩礼65万8 小时前
I/O密集型 CPU密集型
网络
only_Klein8 小时前
Kubernetes-DaemonSet控制器
容器·kubernetes