4. 容器网络基础:CNI插件、Pod网络模型与DNS映射
容器网络是Kubernetes集群的神经中枢,它决定了Pod如何通信、Service如何负载均衡、以及CoreDNS如何将服务名解析为可访问的IP地址。本章深入剖析CNI插件(Calico/Flannel/Weave)的实现原理、Pod网络模型的核心机制,以及Service与Endpoint的DNS映射关系,为后续的CoreDNS治理和网络运维打下坚实基础。
4.1 CNI插件:容器网络的基石
CNI(Container Network Interface)是Kubernetes与容器运行时之间的网络配置标准。每个CNI插件负责为Pod分配IP地址、配置网络接口、以及实现网络策略。生产环境中,Calico、Flannel和Weave是最主流的三种选择。
| 特性 | Calico | Flannel | Weave |
|---|---|---|---|
| 网络模型 | 纯三层BGP路由 | Overlay VXLAN/Host-GW | Overlay UDP/VXLAN |
| 性能 | 接近原生(无封包开销) | 中等(VXLAN封包约50字节开销) | 中等(UDP封包开销较大) |
| 网络策略 | 原生支持(iptables/IPVS) | 不支持(需额外组件) | 原生支持(内置加密) |
| 跨节点通信 | BGP路由直接交换 | VXLAN隧道或Host-GW | 自建Overlay隧道 |
| 加密支持 | 需额外配置(WireGuard) | 不支持 | 内置加密(Weave Net) |
| 规模上限 | 数千节点(BGP可扩展) | 数百节点(VXLAN组播限制) | 数百节点(隧道开销) |
| 运维复杂度 | 中高(需BGP配置) | 低(开箱即用) | 中(需管理Weave Router) |
选型建议: 生产环境优先选择Calico,其三层路由模型性能最优,且原生支持NetworkPolicy。Flannel适合开发测试环境或对网络策略无要求的场景。Weave适合需要跨集群加密通信的合规场景。
4.2 Pod网络模型:IP-per-Pod与通信路径
Kubernetes采用“IP-per-Pod”模型,即每个Pod拥有独立的IP地址,Pod内的所有容器共享该IP和网络命名空间。这种模型简化了端口映射和通信逻辑,但要求CNI插件必须解决跨节点Pod的连通性问题。
关键路径解析: Pod A(10.0.1.2)访问 Pod B(10.0.2.3)时,数据包经过:Pod A eth0 → veth pair → cbr0 网桥 → 宿主机路由表 → CNI插件封装(VXLAN/BGP)→ 对端宿主机 → cbr1 网桥 → veth pair → Pod B eth0。CNI插件决定了中间封装方式。
4.3 Service与Endpoint的DNS映射关系
Service是Kubernetes中访问Pod的抽象层,它通过标签选择器动态关联一组Pod(Endpoint)。CoreDNS负责将Service名称解析为Cluster IP,而Cluster IP再通过iptables/IPVS规则转发到后端Pod IP。理解这个映射链是CoreDNS治理的核心。
4.3.1 映射链路全景
4.3.2 DNS记录类型与解析行为
| DNS记录类型 | 查询名称 | 返回结果 | 典型场景 |
|---|---|---|---|
| A记录 | my-svc.default.svc.cluster.local |
Cluster IP(如 10.96.0.10) | 普通Service访问 |
| SRV记录 | _http._tcp.my-svc.default.svc.cluster.local |
端口号 + 域名 | 服务发现与端口协商 |
| PTR记录 | 10.0.1.2.in-addr.arpa |
Pod域名 | 反向DNS查询 |
| CNAME | my-svc.default.svc.cluster.local |
外部域名(ExternalName Service) | 服务别名 |
常见陷阱: 当Service的
publishNotReadyAddresses 为false(默认)时,未就绪的Pod不会出现在EndpointSlice中,CoreDNS也不会返回其IP。这会导致滚动更新期间出现短暂的DNS解析“空窗期”,需要配合就绪探针和优雅终止来规避。
4.4 实战:CoreDNS与CNI插件的协同工作
在真实集群中,CoreDNS的Pod本身也运行在CNI插件管理的网络之上。CoreDNS需要能够访问kube-apiserver获取Service和Endpoint信息,同时需要监听集群DNS查询流量。以下是一个典型的CoreDNS部署配置片段:
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
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
containers:
- name: coredns
image: coredns/coredns:1.11.1
args: [ "-conf", "/etc/coredns/Corefile" ]
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 8181
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
CNI对CoreDNS的影响: 如果使用Calico且启用了NetworkPolicy,需要确保CoreDNS的Pod能够被集群内所有命名空间访问。通常建议为CoreDNS创建一个独立的网络策略,允许所有来源的DNS查询(UDP/TCP 53端口),避免因策略误配导致集群DNS解析中断。
4.5 网络排查常用命令
- 检查Pod网络连通性:
kubectl exec -it <pod> -- ping <target-ip> - 查看CNI插件状态:
kubectl get pods -n kube-system | grep calico或kubectl get pods -n kube-system | grep flannel - 验证DNS解析:
kubectl exec -it <pod> -- nslookup kubernetes.default.svc.cluster.local - 查看Endpoint变化:
kubectl get endpointslices -n <namespace> -o yaml - 追踪数据包路径:
kubectl exec -it <pod> -- traceroute <target-ip>
核心结论: CNI插件决定了Pod IP的分配和跨节点通信方式,Service提供了稳定的DNS名称和负载均衡入口,CoreDNS将服务名解析为Cluster IP,kube-proxy再将Cluster IP转发到具体的Pod IP。这四个组件构成了Kubernetes容器网络的完整链路,任何一环出现问题都会导致服务访问异常。