4. 镜像拉取数据流分析:从kubelet到containerd,再到镜像仓库的完整数据路径,Cilium如何介入
在多集群环境中,Pod启动时的镜像拉取是网络流量的关键场景。理解从kubelet → containerd → 镜像仓库的完整数据路径,以及Cilium在每一跳中的介入方式,是定位拉取超时、速率受限、DNS解析失败等故障的基础。
4.1 镜像拉取数据流的四阶段模型
整个镜像拉取过程可拆分为四个核心阶段,每个阶段对应不同的网络栈和Cilium干预点:
| 阶段 | 发起方 | 目标 | 协议 | Cilium介入点 |
|---|---|---|---|---|
| 1. kubelet → containerd gRPC | kubelet (主机网络) | containerd socket (Unix) | gRPC over Unix Domain Socket | 不经过Cilium(本地IPC) |
| 2. containerd → 镜像仓库 DNS | containerd (主机网络或Pod网络) | CoreDNS / coredns Pod | UDP/TCP :53 | Endpoint策略、DNS策略、NAT |
| 3. containerd → 镜像仓库 HTTPS | containerd (主机网络或Pod网络) | 镜像仓库 (registry:443) | TCP :443 (HTTPS) | 网络策略、带宽管理、加密观测 |
| 4. 镜像层数据回传 | 镜像仓库 | containerd → 本地存储 | TCP 数据流 (分块下载) | 连接跟踪、XDP加速、带宽限制 |
关键认知: 阶段1走Unix Domain Socket,完全绕过Cilium的eBPF数据路径。阶段2-4才是Cilium网络策略和可观测性真正生效的范围。故障排查时,应优先确认阶段1是否完成,再进入阶段2-4的网络诊断。
4.2 完整数据路径的SVG流程图
下图展示了从kubelet发起拉取请求到镜像层数据落盘的完整路径,并标注了Cilium的eBPF钩子挂载点:
4.3 Cilium在每一跳中的具体介入机制
4.3.1 阶段1:kubelet → containerd(本地IPC)
- 通信方式: kubelet通过gRPC调用containerd的CRI接口,使用
unix:///run/containerd/containerd.sock。 - Cilium介入: 无。Unix Domain Socket完全在主机内核的VFS层完成,不经过网络协议栈,eBPF TC/XDP钩子无法挂载。
- 故障排查要点: 如果kubelet报
failed to pull image,先检查crictl info和systemctl status containerd,排除本地socket通信问题。
4.3.2 阶段2:containerd → DNS解析
- 通信方式: containerd根据
/etc/containerd/config.toml中的sandbox_image配置,或Pod的imagePullPolicy,发起DNS查询解析镜像仓库域名。 - Cilium介入:
- DNS策略: CiliumNetworkPolicy中的
toFQDNs规则控制containerd可以解析哪些域名。 - DNS代理: Cilium内置DNS代理可拦截、缓存、审计DNS查询。
- NAT: 如果containerd运行在Pod网络命名空间,Cilium负责SNAT。
- DNS策略: CiliumNetworkPolicy中的
- 故障排查要点: 使用
cilium monitor观察DNS流量,检查cilium-dnsproxy日志。
4.3.3 阶段3:containerd → 镜像仓库HTTPS
- 通信方式: containerd向镜像仓库的443端口发起TLS握手,随后通过HTTP/2协议拉取镜像manifest和blob。
- Cilium介入:
- 网络策略: 通过CiliumNetworkPolicy限制containerd的出站目标,仅允许访问特定仓库CIDR或FQDN。
- 带宽管理: 使用
bandwidth注解或Cilium的BandwidthManager限制镜像拉取速率,防止带宽抢占。 - 加密观测: 通过TLS-aware策略或eBPF的
tls_handshake钩子观测TLS握手元数据。
- 故障排查要点: 检查
cilium endpoint list确认containerd端点的策略状态,使用cilium bpf ct list global查看连接跟踪表。
4.3.4 阶段4:镜像层数据回传与本地存储
- 通信方式: 镜像仓库将镜像层以分块形式通过TCP流回传,containerd接收后解压并写入本地文件系统。
- Cilium介入:
- 连接跟踪: Cilium的conntrack模块维护TCP连接状态,确保数据包正确路由。
- XDP加速: 如果启用XDP,Cilium在网卡驱动层直接处理数据包,降低延迟。
- 负载均衡: 如果镜像仓库通过Kubernetes Service暴露,Cilium的eBPF kube-proxy替代方案负责后端分发。
- 故障排查要点: 使用
cilium bpf lb list查看Service后端,使用cilium monitor --type trace观察数据包路径。
4.4 多集群场景下的数据路径差异
当镜像仓库位于另一个集群时,数据路径增加跨集群跳转,Cilium ClusterMesh引入额外介入点:
| 组件 | 单集群路径 | 多集群路径(ClusterMesh) | Cilium新增介入 |
|---|---|---|---|
| DNS解析 | 本地CoreDNS | 本地CoreDNS → 远程集群CoreDNS | ClusterMesh DNS互解析 |
| HTTPS连接 | containerd → 本地Service IP | containerd → 本地Service IP → 隧道 → 远程Pod IP | Geneve/VXLAN隧道封装、加密 |
| 数据回传 | 直接TCP流 | 跨集群隧道 + 可能的路由不对称 | 隧道解封装、MTU处理 |
| 策略执行 | 本地CiliumAgent | 本地CiliumAgent + 远程CiliumAgent | 集群间策略同步 |
实战提示: 多集群镜像拉取故障中,最常见的根因是MTU不一致。隧道封装(Geneve/VXLAN)增加50-100字节开销,如果物理网络MTU未调整,会导致TCP分片或丢包。排查时使用
cilium debuginfo查看隧道MTU配置,并在containerd节点上执行ping -M do -s 1472 <仓库IP>测试路径MTU。
4.5 数据路径故障排查命令速查表
| 故障现象 | 排查命令 | 预期输出/关注点 |
|---|---|---|
| kubelet报"failed to pull image" | crictl pull <image> |
确认containerd能否直接拉取,排除kubelet→containerd通信问题 |
| DNS解析超时 | cilium monitor --type dns |
观察DNS请求/响应是否被策略丢弃 |
| HTTPS连接拒绝 | cilium endpoint list | grep containerd |
检查端点策略是否允许出站443 |
| 拉取速度慢 | cilium bpf bandwidth list |
查看是否配置了带宽限制 |
| 跨集群拉取失败 | cilium clustermesh status |
确认集群间隧道状态和连接数 |
| 数据包被丢弃 | cilium monitor --type drop |
查看丢弃原因(策略、CT冲突、MTU等) |
4.6 数据路径的eBPF观测点
Cilium在镜像拉取数据路径上挂载了多个eBPF程序,用于观测和干预:
- XDP入口: 在网卡驱动层处理镜像仓库回传的数据包,适用于高速率拉取场景。
- TC ingress/egress: 在主机veth对或物理接口上执行策略和连接跟踪。
- Socket filter: 在containerd的socket层拦截DNS查询和TLS握手。
- cgroup skb: 在cgroup级别对containerd进程的网络流量进行带宽控制。
注意: 如果containerd以
--network=host模式运行(常见于系统组件),其网络流量直接使用主机网络命名空间。此时Cilium的策略和观测仍然生效,但端点标识不再是Pod,而是主机端点(hostEndpoint)。排查时需使用cilium endpoint list --host查看主机端点状态。