AI 协助说明: 本页由 Codex 协助核验和修复站内链接;正文的技术事实和适用范围未因本次修改而改变,仍以文中来源及当前官方文档为准。
定位:本文只建立跨层心智图和排障入口。Service、DNS、kube-proxy、Calico 与 Netfilter 的实现细节分别放在对应专题,避免同一条数据路径在多篇文章中重复展开。
先建立一张心智地图#
Kubernetes 网络问题之所以容易混乱,是因为“解析名字”“选择后端”和“把报文送到目标 Pod”是三件不同的事:
flowchart LR
A["应用访问 orders.default"] --> B["CoreDNS\n名字 → 地址"]
B --> C["Service\n稳定入口"]
C --> D["kube-proxy 或 CNI eBPF\n选择 Endpoint 并改写目标"]
D --> E["目标 Pod IP"]
E --> F["CNI + Linux 内核\n路由、策略与跨节点传输"]
F --> G["目标 Pod"]| 层次 | 主要职责 | 典型症状 |
|---|---|---|
| DNS | 将服务名解析为 ClusterIP、CNAME 或 Pod 地址 | 名称解析失败,但直接访问 IP 可用 |
| Service | 为一组会变化的 Pod 提供稳定入口 | selector 或端口错误、没有可用后端 |
| Service 数据面 | 按 EndpointSlice 把 VIP / NodePort 流量送到后端 | ClusterIP 不通,但目标 Pod IP 可达 |
| Pod 网络 | 分配 Pod IP、路由、封装和 NetworkPolicy | Pod IP 跨节点不通、策略拒绝、MTU 问题 |
| 入口 TLS | 在 Ingress、Gateway 或负载均衡器处终止或透传 TLS | 域名、证书或握手错误,而非 Pod 路由错误 |
先按现象分层,比从一开始就翻查所有 CNI 规则有效得多:
服务名不通 → CoreDNS、Pod DNS 配置
Service 不通 → Service、EndpointSlice、Service 数据面
Pod IP 不通 → CNI、路由、封装、NetworkPolicy、MTU
TLS / Host 报错 → Ingress / Gateway / 负载均衡器的入口配置三类地址不要混在一起#
| 地址 | 示例 | 谁通常认识它 | 作用 |
|---|---|---|---|
| Node IP | 192.168.10.21 | 底层网络、VPC、交换机和路由器 | 节点间 underlay 通信 |
| Pod IP | 10.244.1.7 | 集群 CNI 和节点路由 | 实际工作负载的三层地址 |
| Service ClusterIP | 10.96.0.80 | 集群节点的 Service 数据面 | 一组后端的稳定虚拟入口 |
ClusterIP 通常不绑定到某个真实网卡;它需要节点上的 kube-proxy 规则或 CNI eBPF 程序把流量选到真实 Endpoint。普通 Pod 的 IP 则配置在 Pod 网络命名空间中,能否跨节点或出集群取决于 CNI 和底层网络设计。
hostNetwork: true 是例外:该 Pod 使用节点网络命名空间,不能把它当作拥有独立普通 Pod IP 的工作负载来排查。
一次集群内请求如何穿过这些层#
假设 frontend 访问 orders.default.svc.cluster.local:80:
1. frontend 的 DNS 查询到达 CoreDNS。
2. CoreDNS 返回 orders 的 ClusterIP(普通 ClusterIP Service)。
3. frontend 向 ClusterIP:80 建立连接。
4. 当前节点上的 Service 数据面根据 Service 和 EndpointSlice 选择一个 Ready 后端,
将目标改写为 PodIP:targetPort。
5. 如果该 Pod 在本机,内核按本机 veth / 路由交付;如果在另一节点,CNI 按路由或
Overlay 将其送到目标节点。
6. 目标节点按 Pod 路由和策略将报文交给目标 Pod;回包由 conntrack 的 NAT 状态恢复。这条链路中,DNS 不代理业务连接,Service 不负责跨节点路由,Calico 也不负责替应用决定 Service 后端;它们是前后相接的不同阶段。
Node 上运行的组件与网络的关系#
在 kubeadm 等自管集群里,控制平面节点也是 Node,通常仍运行 kubelet、容器运行时、CNI 节点组件和(若未替代)kube-proxy。控制面组件常以 static Pod 运行:kubelet 监视 /etc/kubernetes/manifests,再通过 CRI 启动 API Server、scheduler、controller-manager 与堆叠式 etcd。
NoSchedule taint 只限制不匹配的普通工作负载;带对应 toleration 的系统 DaemonSet 仍可以在控制平面节点运行。因此,不能仅凭“它是控制平面节点”推断 kube-proxy、CNI 或日志 Agent 一定不存在或一定存在,应查看实际 DaemonSet、selector 与 toleration。
从 Service 到 Calico 的边界#
Service 数据面和 CNI 数据面最常被混为一谈。可以用下面的分界记忆:
访问 Service VIP
→ Service 数据面选择 Endpoint,DNAT 到目标 Pod IP
→ CNI / Linux 内核解决“这个 Pod IP 在哪里、如何到达、能否访问”跨节点时,Calico 常见的选择属于不同层次:
| 层次 | 选项 | 回答的问题 |
|---|---|---|
| 路由控制面 | BGP | 谁知道某段 Pod CIDR 的下一跳 |
| 跨节点传输 | 原生三层路由、IPIP、VXLAN | 节点之间在线路上发送什么报文 |
| 节点数据面 | Linux 路由 / iptables,或 eBPF | 如何执行策略、转发和部分 Service 逻辑 |
因此,BGP、IPIP、VXLAN 与 eBPF 不能简单地当作四个互斥选项。eBPF 不是一种隧道;它可能替代部分 kube-proxy 和传统规则处理,而跨节点报文仍需走原生路由或适用的 Overlay。
NAT、回包与 veth:只记住必要边界#
- DNAT:Service 入口常把目的从
ClusterIP:port改为PodIP:targetPort。 - SNAT / MASQUERADE:当回包路由不可达、外部流量策略或出集群访问需要时,可能改写源地址;是否发生取决于入口、Service 类型、策略和 CNI 配置。
- conntrack:记录一个连接的 NAT 状态,使回包能够恢复为客户端预期的地址和端口。
- veth:连接 Pod 网络命名空间和宿主机网络命名空间的一对虚拟接口;同节点 Pod 通信通常不会离开物理网卡。
需要精确追包时,转到 Service 转发链路、Calico 流量走向 和 Linux 目录的 iptables 数据包流转。
一套从上到下的排查顺序#
先收集对象状态,再逐层缩小范围:
# 1. Service、selector 和后端端点
kubectl get svc <service-name> -n <namespace> -o wide
kubectl get pod -n <namespace> -l <selector> -o wide
kubectl get endpointslice -n <namespace> \
-l kubernetes.io/service-name=<service-name> -o yaml
# 2. 同时测试“服务名、ClusterIP、目标 Pod IP”三种入口
kubectl run net-debug --rm -it --restart=Never --image=busybox:1.36 -- sh
# 在调试 Pod 内按实际工具测试 DNS 和连通性
nslookup <service-name>.<namespace>.svc.cluster.local
# 3. 节点上的 Service 数据面与 CNI 状态(工具取决于节点镜像和模式)
kubectl -n kube-system get pods -o wide
ip route get <target-pod-ip>然后按观测到的分支继续:
| 结果 | 下一步 |
|---|---|
| DNS 失败 | 检查 CoreDNS、Pod /etc/resolv.conf、namespace 和 DNS policy。 |
| DNS 成功、ClusterIP 失败、Pod IP 成功 | 检查 Service 端口、EndpointSlice、kube-proxy 或 eBPF Service 数据面。 |
| ClusterIP 与 Pod IP 都失败 | 检查 NetworkPolicy、目标 Pod 监听、CNI 路由、封装与 MTU。 |
| 仅跨节点失败 | 在两侧节点检查路由、IPPool、隧道 / BGP、网络策略和防火墙。 |
| 仅外部入口失败 | 检查 NodePort / LoadBalancer / Ingress 配置、externalTrafficPolicy 与安全组。 |
抓包和规则检查只在已经确定层次后使用。例如,已经确认 Endpoint 是远端 Pod IP 时,再检查 ip route get <pod-ip>、IPPool 和 VXLAN/IPIP 报文;不要仅看到一条 NAT 规则就认定完整链路已经通了。
深读地图#
| 想深入的问题 | 对应文章 |
|---|---|
| DNS 记录、Corefile 与故障排查 | CoreDNS 详解 |
| Service 类型、端口、Selector 与流量策略 | Service 详解 |
| EndpointSlice、ClusterIP、kube-proxy 与 DNAT | Service 转发链路 |
| kube-proxy 的模式和节点规则 | kube-proxy 详解 |
| BGP、IPIP、VXLAN、eBPF 和跨节点报文 | Calico 流量走向 |
| Pod 间访问控制 | NetworkPolicy 详解 |
| Service、RuntimeClass 和网络数据面选型 | 网络与运行时选型速记 |
| HTTPS / 证书报错 | Ingress、证书与 cert-manager |