news 2026/9/13 17:33:38

Cilium 在 kind 集群中的镜像预加载(Preload):原理、完整部署流程与故障排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cilium 在 kind 集群中的镜像预加载(Preload):原理、完整部署流程与故障排查

Cilium 在 kind 集群中的镜像预加载(Preload):原理、完整部署流程与故障排查

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

导读

本指南围绕 Cilium 官方文档中“在 kind 集群每个 worker 节点预加载cilium镜像”这一关键步骤展开,讲解为什么需要在 kind 集群里预加载镜像、如何通过docker pullkind load docker-image完成预加载,并串起从依赖安装、kind 配置、建集群、Helm 部署到连通性验证的完整落地流程。读完本文,你将掌握在本地多节点 kind 环境(尤其是离线或受限网络环境)中快速、可靠地部署 Cilium 的完整实战方案,并理解镜像预加载与image.pullPolicy=IfNotPresent之间的配合关系。

说明:本文所有文件路径均以当前仓库根目录为起点。核心操作依据见 Documentation/installation/kind.rst 及其引用的 Documentation/installation/kind-preload.rst。

为什么需要预加载 Cilium 镜像

kind(Kubernetes in Docker)会在 Docker 上以容器方式模拟多节点 Kubernetes 集群。这意味着每个“节点”本质上是一个 Docker 容器,节点内的容器运行时(containerd)与宿主机上的 Docker 是隔离的:

  • 宿主机 Docker 拉取的镜像,并不会自动出现在kind 节点容器内;
  • kind 节点内的 containerd 如果需要拉取镜像,会直接从远端镜像仓库(如quay.io)拉取;
  • 在本地开发、内网或离线(air-gapped)场景下,直接从quay.io/cilium/cilium拉取镜像可能缓慢、不稳定甚至不可达。

因此,Cilium 官方在 kind 部署流程中专门设计了**预加载(preload)**环节:先在宿主机上用 Docker 拉取 Cilium 镜像,再通过kind load docker-image把它导入每个 kind 节点的 containerd,从而让集群内的镜像分发不再依赖外部网络。该环节在文档中位于 “Install Cilium” 一节,紧跟在 Helm 仓库准备之后、helm install之前,见 Documentation/installation/kind.rst。

核心操作:预加载 Cilium 镜像

Documentation/installation/kind-preload.rst 给出的完整操作只有两条命令:

docker pull quay.io/cilium/cilium:<IMAGE_TAG> kind load docker-image quay.io/cilium/cilium:<IMAGE_TAG>

下面逐一拆解其含义与注意事项。

第一步:docker pull拉取镜像到宿主机

docker pull quay.io/cilium/cilium:<IMAGE_TAG>
  • 镜像仓库为quay.io/cilium/cilium,即 Cilium 的官方镜像仓库;
  • <IMAGE_TAG>是版本占位符,由文档系统在渲染时替换为当前文档对应版本的标签;
  • 在仓库中,当前版本号记录在根目录的 VERSION 文件,stable.txt则记录稳定版本信息。实际部署时,请将<IMAGE_TAG>替换为你希望安装的版本标签(例如v1.x.y),并保证与后续 Helm chart 使用的镜像版本一致。

这一步骤把镜像放进宿主机 Docker 的本地镜像缓存,为下一步导入做准备。如果你的网络能正常访问quay.io,此步即可完成;若身处受限网络,则需要提前在可达环境中完成 pull 并导出/导入镜像。

第二步:kind load docker-image导入每个节点

kind load docker-image quay.io/cilium/cilium:<IMAGE_TAG>
  • 该命令会把宿主机 Docker 中的镜像导入 kind 集群所有节点(包括 control-plane 与全部 worker)的 containerd;
  • 默认作用于当前kubectlcontext 指向的 kind 集群;若存在多个 kind 集群,可结合kind get clusters确认,并使用--name指定目标集群;
  • 也可以使用--nodes参数只向部分节点导入,但默认的“全部节点”行为恰好满足 Cilium DaemonSet 在每个节点运行 agent 的诉求。

执行成功后,kind 节点内的 containerd 已拥有该镜像,后续创建 Pod 时无需再从远端拉取,从而显著缩短部署时间并规避网络不稳定带来的失败。

预加载在整个 kind 部署流程中的位置

预加载并非孤立步骤,它位于 Cilium kind 安装流程的“Install Cilium”阶段。完整流程按 Documentation/installation/kind.rst 的编排如下:

1. 安装依赖(Install Dependencies)

按 Documentation/installation/kind-install-deps.rst 要求准备:

  • docker稳定版;
  • kubectl>= v1.14.0;
  • helm>= v3.13.0;
  • kind>= v0.7.0。

2. 配置 kind(Configure kind)

kind 集群的创建通过 YAML 配置完成。这一步必须禁用默认 CNI,否则无法替换为 Cilium。仓库提供了可直接下载的模板 Documentation/installation/kind-config.yaml:

kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker - role: worker networking: disableDefaultCNI: true

该配置会创建 1 个 control-plane + 3 个 worker 的 4 节点集群。详见 Documentation/installation/kind-configure.rst。

注意子网冲突:kind 默认 Pod 子网为10.244.0.0/16、Service 子网为10.96.0.0/12。若与本地网络冲突,务必在networking段显式指定不冲突的podSubnetserviceSubnet,否则部署 Cilium 后可能出现连通性问题。例如:

networking: disableDefaultCNI: true podSubnet: "10.10.0.0/16" serviceSubnet: "10.11.0.0/16"

3. 创建集群(Create a cluster)

按 Documentation/installation/kind-create-cluster.rst 执行:

kind create cluster --config=kind-config.yaml

等待数十秒到数分钟后,一个 4 节点集群即创建完成。此时会新增名为kind-kindkubectlcontext(写入KUBECONFIG,未设置时写入~/.kube/config),可用以下命令确认:

kubectl cluster-info --context kind-kind

注意:在 Cilium 部署完成前,节点会一直处于NotReady状态,这是预期行为,无需惊慌。

4. 安装 Cilium(Install Cilium)

这是预加载步骤所在的阶段。完整顺序为:

a. 配置 Helm 仓库(见 Documentation/installation/k8s-install-download-release.rst):

helm repo add cilium https://helm.cilium.io/

Cilium chart 也同时发布在 Quay.io 与 Docker Hub 的 OCI Registry 上,可直接使用oci://协议安装,无需先添加仓库。

b. 预加载镜像(本文核心,见 Documentation/installation/kind-preload.rst):

docker pull quay.io/cilium/cilium:<IMAGE_TAG> kind load docker-image quay.io/cilium/cilium:<IMAGE_TAG>

c. 通过 Helm 安装

helm install cilium cilium/cilium --namespace kube-system \ --set image.pullPolicy=IfNotPresent \ --set ipam.mode=kubernetes

这里有两个关键配置与预加载步骤紧密配合:

  • image.pullPolicy=IfNotPresent:告知 kubelet“镜像已存在于节点时不要重新拉取”。由于镜像已经通过kind load docker-image注入每个节点,使用该策略可确保 Pod 直接使用本地预加载的镜像,避免因尝试再次访问远端仓库而失败或变慢;
  • ipam.mode=kubernetes:使用 Kubernetes 原生的 Pod IP 分配(默认的 CRD 模式在 kind 场景下也可用,此处按官方 kind 指南明确指定)。

5. 验证安装(Validate the Installation)

安装后可用两种方式验证(详见 Documentation/installation/k8s-install-validate.rst)。

方式一:Cilium CLI

先按 Documentation/installation/cli-status.rst 检查集群状态,再运行连通性测试(见 Documentation/installation/cli-connectivity-test.rst):

cilium connectivity test

正常情况下输出类似:

✅ 69/69 tests successful (0 warnings)

方式二:kubectl 手动验证

先观察组件是否就绪(见 Documentation/installation/kubectl-status.rst):

kubectl -n kube-system get pods --watch

所有cilium-*coredns-*Pod 变为Running即说明安装成功(通常需要几分钟)。

随后部署官方连通性检查清单(见 Documentation/installation/kubectl-connectivity-test.rst):

kubectl create ns cilium-test kubectl apply -n cilium-test -f examples/kubernetes/connectivity-check/connectivity-check.yaml

清单会部署一系列覆盖“带/不带 Service 负载均衡”“多种网络策略组合”等连通路径的 Pod;Pod 名称标识测试变体,READY/STATUS即结果:

kubectl get pods -n cilium-test

提示:若在单节点kind 集群中部署,涉及多节点的 Pod 会一直停留在Pending,这是预期行为(多节点测试至少需要 2 个节点才能调度成功)。另外,若 Pod 因 “too many open files” 部署失败,可在宿主机上调大inotify资源限制。测试完成后清理:

kubectl delete ns cilium-test

进阶:Socket LB 在 kind 下的 cgroup 前提

如果你希望在 kind 中启用 Cilium 的 Socket LB(即 kubeproxy-free 模式),Documentation/installation/kind.rst 明确列出了三个前提条件:

  1. 必须启用cgroup v2(例如内核参数systemd.unified_cgroup_hierarchy=1);
  2. kind 节点必须运行在独立的 cgroup namespace中,且与宿主机底层 cgroup namespace 不同,这样 Cilium 才能在正确的 cgroup 层级上挂载 BPF 程序。可用以下命令验证三个值互不相同:
docker exec kind-control-plane ls -al /proc/self/ns/cgroup docker exec kind-worker ls -al /proc/self/ns/cgroup ls -al /proc/self/ns/cgroup
  1. 在 Docker 中需设置dockerd --default-cgroupns-mode=private以启用 cgroup namespace;同时要求禁用 cgroup v1 的net_cls/net_prio控制器(或直接cgroup_no_v1="all"),或宿主内核 >= 5.14(含相关修复)。

故障排查

无法连接 k8s api-server

若 Cilium agent 日志中出现:

level=error msg="Unable to contact k8s api-server" error="Get https://10.96.0.1:443/api/v1/namespaces/kube-system: dial tcp 10.96.0.1:443: connect: no route to host"

原因通常是:kind 节点是 Docker 容器、与宿主机共享内核,若 Socket LB 未被禁用,Cilium 挂载的 eBPF 程序可能已过期,不再把 api-server 请求路由到当前的kind-control-plane容器。解决办法是重建 kind 集群并重新执行本文的 Helm 安装命令,以分离过期的 eBPF 程序。

Cilium agent Pod 持续崩溃

若 agent Pod 崩溃且日志中出现:

level=warning msg="+ bpftool cgroup attach /var/run/cilium/cgroupv2 connect6 pinned /sys/fs/bpf/tc/globals/cilium_cgroups_connect6" subsys=datapath-loader level=warning msg="Error: failed to attach program" subsys=datapath-loader

这通常说明你正在一个已经运行着 Cilium 的环境(例如 Cilium 开发 VM)里再部署 kind 集群,或父级 cgroup 层级上存在重叠的 BPF cgroup 程序。此时应停止原有 Cilium,或按 bpftool 文档手动分离父级 cgroup 层级上的重叠 BPF cgroup 程序,参见 Documentation/installation/kind.rst 的 Troubleshooting 章节。

扩展:用 kind 模拟 Cluster Mesh

预加载的思路同样适用于更复杂的场景——官方文档还演示了如何用 kind 在沙箱中模拟Cluster Mesh(见 Documentation/installation/kind.rst):创建两份不重叠子网的 kind 配置(如集群 1 用podSubnet: "10.0.0.0/16"serviceSubnet: "10.1.0.0/16",集群 2 用10.2.0.0/1610.3.0.0/16),分别执行:

kind create cluster --name=cluster1 --config=kind-cluster1.yaml kind create cluster --name=cluster2 --config=kind-cluster2.yaml

随后在两个集群中分别完成镜像预加载与 Cilium 部署,再按 Cluster Mesh 指南进行配置(kind 场景下需将NodePortService 部署到kube-system命名空间)。多个集群并存时,记得为kind load docker-image使用--name指定目标集群,这正是预加载命令在多集群场景下的正确用法。

小结

镜像预加载(docker pull+kind load docker-image)是 Cilium 官方 kind 部署流程中承上启下的关键一步:它让 Cilium 镜像在无外部网络依赖的情况下抵达每个 kind 节点,配合image.pullPolicy=IfNotPresent实现本地快速部署,并在多集群(Cluster Mesh)场景下同样适用。按本文梳理的“依赖 → 配置 → 建集群 → 预加载 → Helm 安装 → 验证”流程执行,即可获得一个稳定、可复现的本地 Cilium 多节点环境。

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 17:29:20

嵌入式开发五大后悔事:硬件协同、技术债与文档意识

1. 这不是一篇“成功经验总结”&#xff0c;而是一份嵌入式老兵的坦白书 干了十多年嵌入式&#xff0c;从51单片机焊板子开始&#xff0c;到ARM Cortex-M跑RTOS&#xff0c;再到Linux BSP适配、驱动开发、低功耗优化&#xff0c;带过三届应届生&#xff0c;踩过无数坑&#xff…

作者头像 李华
网站建设 2026/9/13 17:28:05

Java final关键字:不可变性的实现原理与最佳实践

1. final关键字的本质与设计哲学final关键字在Java中代表着"不可变"的设计理念&#xff0c;这种不可变性体现在三个层面&#xff1a;类不可继承、方法不可重写、变量不可重新赋值。这种设计哲学源于对代码安全性、可读性和性能优化的综合考量。在Java语言设计中&…

作者头像 李华
网站建设 2026/9/13 17:27:17

如何根据 Ubuntu 版本选择 PPA 或官方 .deb 安装最新版 fastfetch?

如何根据 Ubuntu 版本选择 PPA 或官方 .deb 安装最新版 fastfetch&#xff1f; 【免费下载链接】fastfetch A maintained, feature-rich and performance oriented, neofetch like system information tool. 项目地址: https://gitcode.com/GitHub_Trending/fa/fastfetch …

作者头像 李华
网站建设 2026/9/13 17:23:02

Delphi 12.3 安装 KonopkaControls 7.0:兼容性判断与编译实战指南

简介&#xff1a;KonopkaControls 是一套功能全面的 Delphi VCL 界面控件集&#xff0c;特别适合需要快速搭建专业桌面程序的 Win32/Win64 开发者。这套控件包对应 7.0&#xff08;build 290&#xff09;版本&#xff0c;适配 Delphi 12.3/12.1 环境&#xff0c;并以 7z 格式整…

作者头像 李华
网站建设 2026/9/13 17:22:19

JVM类加载机制详解:加载、连接、初始化与异常排查

你是不是也遇到过这种情况&#xff1a;项目编译没有任何问题&#xff0c;代码里new个对象明明能点出方法&#xff0c;可一到运行环境就甩给你一句“错误: 找不到或无法加载主类 org.apache.dolphinscheduler.standaloneserver”&#xff0c;或者更气人的“java.lang.NoClassDef…

作者头像 李华