news 2026/10/21 11:58:37

Calico v3.20.6 离线部署实战:镜像包与 calico.yaml 配套使用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Calico v3.20.6 离线部署实战:镜像包与 calico.yaml 配套使用指南

简介:本资源面向在 Kubernetes 集群中部署与运维容器网络的工程师,提供 Calico v3.20.6 所需的容器镜像与核心部署清单,帮助解决离线环境或内网集群无法直接拉取镜像、网络策略难以落地的问题。压缩包共 5 个文件,包含 4 个 tar 镜像包与 1 个 yaml 配置文件,整体约 96.68MB;镜像分别对应节点代理、CNI 插件、控制器以及 FlexVol 挂载插件,yaml 则用于定义 DaemonSet、CNI 配置、策略控制器与 BGP 参数等部署对象。已有 1084 人学习下载,说明该版本在社区中具备一定参考价值。读者可借助这套材料完成 Calico 的离线导入与集群集成,理解各组件在 Pod 网络分配、跨节点路由和网络策略执行中的分工,并据此搭建可复用的容器网络实验环境,为多租户隔离与安全通信场景提供实践基础。

1. 从一次 Pod 跨节点不通说起:calico v3.20.6 离线包到底装了什么

上个月帮一个朋友排查环境,两个节点上的 Pod 互相 ping 不通,kubectl get pods -n kube-system一看 calico-node 全是 Running,但calicoctl node status里 BGP 邻居死活建不起来。折腾半天发现是镜像版本和 yaml 里的 image 字段对不上——他手动改了 tag,结果拉的是另一个小版本的镜像。这种玄学问题,在离线环境里尤其常见,因为你没法随手docker pull一个来试。

这次要拆的这个资源,就是解决这类问题的:calico v3.20.6 版本的容器镜像包,外加配套的 calico.yaml 部署文件。它面向的是那些 Kubernetes 集群没法直连公网、或者内网 registry 还没同步 calico 镜像的场景。你拿到的是一个已经锁定版本的组合——镜像和 yaml 是配套的,不用自己去猜 tag、不用去翻 release notes 对版本。适合谁?正在搭离线 K8s 集群的人、需要固定 calico 版本做验证的人、以及被版本漂移坑过一次、想把手头环境钉死的人。下面我从这个包的结构开始,一路讲到怎么把它塞进集群、怎么验证、以及几个我踩过的坑。

2. 拆开这个包:镜像清单与 calico.yaml 的对应关系

2.1 镜像包里到底有几个 tar

calico 不是单个二进制,它是一组组件的集合。v3.20.6 这个版本,核心镜像通常包括calico/node、calico/cni、calico/kube-controllers,如果用到 typha 做 datastore 代理,还会有calico/typha。离线包一般会把这些打成独立的 tar 文件,或者一个大的 tar 里包含多层。你拿到手第一件事不是急着docker load,而是先列一下内容,确认没有缺件。

# 查看离线包里的 tar 文件列表,确认组件齐全 tar -tf calico-v3.20.6-images.tar | grep -E '\.tar$' # 如果是分开的 tar,直接看目录 ls -lh *.tar

逻辑说明:tar -tf只列出内容不解压,避免污染当前目录。参数上没什么特别的,关键是看输出里有没有node、cni、kube-controllers这三个核心件。如果只有 node 一个,那说明这个包是残缺的,部署到一半会卡在 CNI 插件初始化。

2.2 calico.yaml 里哪些字段和镜像直接挂钩

打开 calico.yaml,搜image:这个关键字,你会看到 DaemonSet、Deployment 里引用的镜像地址。v3.20.6 的 yaml 里,默认写的是docker.io/calico/node:v3.20.6这种形式。离线环境里,你要么把镜像 load 进本地 docker 后不改 yaml 直接跑(前提是节点上 docker 能识别这个 tag),要么把 yaml 里的地址改成你的内网 registry 地址。

# calico.yaml 中 DaemonSet 的容器定义片段(示意) containers: - name: calico-node image: docker.io/calico/node:v3.20.6 env: - name: DATASTORE_TYPE value: "kubernetes"

逻辑说明:DATASTORE_TYPE设为kubernetes表示用 K8s API 做 datastore,这是大多数中小集群的默认选择。如果你改成etcd,那还得额外配 etcd 端点,v3.20.6 里这个字段的取值就这两种,别写别的。参数上,image字段的 tag 必须和离线包里的镜像 tag 完全一致,差一个字符都会导致 ImagePullBackOff。

2.3 版本锁定带来的好处与代价

锁定 v3.20.6 意味着你不用面对跨大版本的 API 变更。calico 从 v3.20 到 v3.21 有一些 CRD 字段的调整,离线环境里一旦 yaml 和镜像版本错位,kube-controllers 可能起不来,日志里报failed to sync之类的错。代价是,这个版本的一些新特性你用不上,比如后续版本对 eBPF 数据面的增强。但如果你只是要一个稳定跑通的 CNI,这个版本足够。

提示:不要试图用 v3.20.6 的 yaml 去配 v3.21 的镜像,反过来也不行。CRD 定义在 yaml 里是写死的,版本错位时 apply 可能不报错,但运行时行为会诡异。

3. 把镜像塞进集群:load、tag、push 三步走

3.1 在能联网的机器上 load 并重打 tag

如果你拿到的是 tar 包,第一步是在一台有 docker 的机器上把镜像 load 进去。这台机器可以是你的跳板机,也可以是集群的某个节点。load 完之后,docker images应该能看到calico/node等条目。这时候如果你要用内网 registry,就得重新打 tag。

# 加载离线镜像包 docker load -i calico-v3.20.6-images.tar # 确认加载结果 docker images | grep calico # 重新打 tag,指向内网 registry docker tag calico/node:v3.20.6 registry.internal:5000/calico/node:v3.20.6 docker tag calico/cni:v3.20.6 registry.internal:5000/calico/cni:v3.20.6 docker tag calico/kube-controllers:v3.20.6 registry.internal:5000/calico/kube-controllers:v3.20.6

逻辑说明:docker load会保留原镜像的 repository 和 tag,所以 load 完不用猜名字。docker tag是给同一个镜像 ID 再贴一个标签,不占额外空间。参数上,registry.internal:5000换成你自己的 registry 地址和端口,别照抄。

3.2 push 到内网 registry 并验证

tag 打完就 push。push 完之后,在集群的任意一个节点上docker pull一下,确认能拉下来。这一步别省,我见过 registry 权限没配好、push 成功但 pull 403 的情况。

# 推送镜像到内网 registry docker push registry.internal:5000/calico/node:v3.20.6 docker push registry.internal:5000/calico/cni:v3.20.6 docker push registry.internal:5000/calico/kube-controllers:v3.20.6 # 在集群节点上验证拉取 docker pull registry.internal:5000/calico/node:v3.20.6

逻辑说明:push 和 pull 用的是同一套认证,如果 push 成功但 pull 失败,多半是 registry 的存储后端或者证书有问题。参数上,如果你的 registry 用的是自签证书,节点上的 docker 需要配insecure-registries,否则 pull 会报 x509 错误。

3.3 改 calico.yaml 里的 image 地址

镜像就位后,把 calico.yaml 里所有image:字段改成内网 registry 的地址。可以用 sed 批量替换,但替换完要肉眼扫一遍,确认没有漏网的。

# 批量替换镜像地址(先备份) cp calico.yaml calico.yaml.bak sed -i 's|docker.io/calico/|registry.internal:5000/calico/|g' calico.yaml # 确认替换结果 grep 'image:' calico.yaml

逻辑说明:sed的-i是原地修改,所以先cp备份。替换模式里用了|做分隔符,因为地址里有/,用/做分隔符会冲突。参数上,g表示全局替换,不加的话每行只替换第一个匹配。

注意:如果你的集群节点上 docker 已经能识别docker.io/calico/node:v3.20.6这个 tag(比如你 load 到了每个节点),那不改 yaml 也能跑。但生产环境不建议这么做,节点多了之后手动 load 容易漏。

4. 部署与验证:从 apply 到 BGP 邻居建立

4.1 apply 之前先确认 CRD 不会冲突

如果你的集群之前装过其他版本的 calico,或者残留了 calico 的 CRD,直接 apply 新的 yaml 可能会报already exists。稳妥的做法是先看看现有的 CRD。

# 查看现有 calico CRD kubectl get crd | grep calico # 如果有残留,先删除(确认没有业务依赖再操作) kubectl delete crd $(kubectl get crd | grep calico | awk '{print $1}')

逻辑说明:kubectl get crd列出所有自定义资源定义,grep calico过滤出 calico 相关的。awk '{print $1}'取第一列也就是 CRD 名字。参数上,删除 CRD 会连带删除对应的自定义资源,所以执行前确认没有业务在用。

4.2 apply calico.yaml 并观察 Pod 状态

apply 之后,calico-node 是以 DaemonSet 形式跑的,每个节点一个 Pod。calico-kube-controllers 是 Deployment,通常一个副本。

# 应用 calico 部署文件 kubectl apply -f calico.yaml # 观察 Pod 启动情况 kubectl get pods -n kube-system -w

逻辑说明:-w是 watch 模式,实时刷新。calico-node 启动需要一点时间,因为它要初始化 CNI 配置、建立 BGP 会话。如果超过两分钟还是 ContainerCreating,去看 describe。

4.3 用 calicoctl 验证节点状态

Pod 跑起来不代表网络通了。最直接的验证是看 BGP 邻居状态。你需要先有 calicoctl 这个二进制,版本最好和 calico 一致。

# 查看节点状态和 BGP 邻居 calicoctl node status # 预期输出里每个节点应该显示 Established

逻辑说明:calicoctl node status会列出本节点和其他节点的 BGP 会话状态。如果显示Connect或者Active,说明 BGP 没建起来。参数上,calicoctl 需要能访问 datastore,默认走 K8s API,所以要在能访问集群的机器上跑。

4.4 跑一个跨节点 Pod 验证连通性

最后一步,起两个 Pod 分别调度到不同节点,互相 ping。这是最实在的验证。

# 创建测试 Pod kubectl run test-pod-1 --image=busybox --restart=Never -- sleep 3600 kubectl run test-pod-2 --image=busybox --restart=Never -- sleep 3600 # 查看 Pod IP 和所在节点 kubectl get pods -o wide # 从一个 Pod ping 另一个 kubectl exec -it test-pod-1 -- ping <test-pod-2-ip>

逻辑说明:--restart=Never让 Pod 不会自动重启,方便清理。-o wide显示 Pod IP 和节点名。ping 通说明 calico 的跨节点路由生效了。参数上,busybox 镜像小,适合做测试,但注意它默认没有 ping 命令的某些选项,简单 ping 够用。

5. 避坑与排查:那些让我重装过集群的瞬间

5.1 坑一:镜像 tag 和 yaml 不一致导致 ImagePullBackOff

现象:calico-node Pod 一直卡在 ImagePullBackOff,describe 里报manifest unknown或not found。原因:yaml 里写的 tag 是v3.20.6,但离线包里的镜像 tag 可能是v3.20.6-amd64或者别的后缀,也可能是你 push 到 registry 时改了 tag 但忘了同步改 yaml。解决:docker images确认本地镜像的准确 tag,然后grep image: calico.yaml逐行核对。改完重新 apply。

5.2 坑二:节点上 iptables 规则残留导致新 Pod 不通

现象:calico-node 显示 Running,BGP 也 Established,但新建的 Pod 就是不通。原因:之前装过其他 CNI 或者旧版 calico,iptables 里残留了 FORWARD 链的 DROP 规则。解决:iptables -L FORWARD -n看看有没有异常的 DROP。如果有,清理掉旧规则,或者重启节点让 calico 重新刷。我一般会在部署前先iptables-save备份一份,出问题好回滚。

5.3 坑三:MTU 不匹配导致大包被丢

现象:小包 ping 通,但 curl 大文件或者跑 HTTP 请求时卡住。原因:calico 默认的 MTU 是 1440,但如果你的节点网络 MTU 是 1500,且中间有隧道封装,实际可用 MTU 会更小。解决:在 calico.yaml 的calico-node环境变量里加FELIX_IPINIPMTU或者FELIX_VXLANMTU,根据你用的封装模式调整。v3.20.6 里这两个变量都支持。

5.4 坑四:kube-controllers 报错但 Pod 是 Running

现象:calico-kube-controllers 的 Pod 状态是 Running,但日志里一直在刷failed to sync。原因:通常是 RBAC 权限不够,或者 ServiceAccount 没绑对。离线环境里如果 yaml 里的 RBAC 部分被裁剪过,就会这样。解决:kubectl logs -n kube-system <kube-controllers-pod>看具体报错。如果是权限问题,检查 ClusterRoleBinding 是否完整。

5.5 坑五:节点重启后 calico-node 起不来

现象:节点维护重启后,calico-node 一直 CrashLoopBackOff。原因:节点上的 CNI 配置文件/etc/cni/net.d/里的 conflist 文件损坏,或者 calico 的 datastore 连接信息丢失。解决:删掉/etc/cni/net.d/下的 calico 相关文件,让 calico-node 重新生成。同时检查/var/lib/calico/下的节点标识文件是否还在。

提示:每次动 calico 之前,calicoctl get nodes和calicoctl get ippools各存一份,出问题能快速对比。

6. 进阶:把 v3.20.6 的 IPPool 调优和版本回退技巧

6.1 调整 IPPool 的块大小和封装模式

默认的 IPPool 是192.168.0.0/16,块大小 26 位。如果你的集群节点多、Pod 密度高,这个块大小可能不够用。v3.20.6 支持通过 calicoctl 修改 IPPool。

# ippool.yaml apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: default-ipv4-ippool spec: cidr: 10.244.0.0/16 blockSize: 24 ipipMode: CrossSubnet natOutgoing: true
# 应用 IPPool 配置 calicoctl apply -f ippool.yaml # 查看当前 IPPool calicoctl get ippool -o yaml

逻辑说明:blockSize: 24表示每个节点分到 /24 的块,能容纳 254 个 Pod,比默认的 /26 大四倍。ipipMode: CrossSubnet表示只在跨子网时走 IPIP 隧道,同子网直接路由,减少封装开销。参数上,natOutgoing: true让 Pod 访问集群外时做 SNAT,这个一般都要开。

6.2 用 calicoctl 做版本回退的检查点

如果你从 v3.20.6 往上升级,或者从别的版本降回来,最怕的是 datastore 里的数据格式不兼容。我的习惯是,在动版本之前,先把关键资源导出成 yaml 存着。

# 导出关键资源作为回退检查点 calicoctl get ippools -o yaml > backup-ippools.yaml calicoctl get nodes -o yaml > backup-nodes.yaml calicoctl get felixconfigurations -o yaml > backup-felix.yaml

逻辑说明:-o yaml输出完整资源定义,包含 metadata 和 spec。回退时如果发现新版本写入了不兼容的字段,可以用这些备份对比差异。参数上,felixconfigurations是全局配置,升级时容易被改,单独存一份。

6.3 一个验证 calico 数据面是否真正生效的小技巧

很多人看 Pod Running 就以为网络好了,其实不一定。我习惯用一个更直接的办法:在节点上抓包,看 Pod 发出的包有没有被正确封装。

# 在节点上抓 IPIP 或 VXLAN 包 tcpdump -i any -n 'proto 4 or udp port 4789' -c 20

逻辑说明:proto 4是 IPIP 协议号,udp port 4789是 VXLAN 默认端口。如果跨节点 Pod 通信时能看到这些包,说明封装生效了。参数上,-c 20抓 20 个包就停,避免刷屏。这个办法比看日志直观,尤其适合排查“看起来通但实际不通”的玄学问题。

6.4 版本锁定的长期维护习惯

从那以后我每次部署离线 calico,都会强制走一遍:先docker images核对 tag,再grep image:核对 yaml,然后calicoctl node status确认 BGP,最后跨节点 ping 一次。这套流程走下来,基本不会再出现版本错位导致的翻车。v3.20.6 这个版本虽然不算新,但胜在稳定,配套的 yaml 和镜像只要对得上,跑起来很省心。如果你手头正好有这套资源,按上面的步骤走一遍,应该能少踩几个我踩过的坑。希望帮到你。

本文还有配套的精品资源,点击获取

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

CentOS离线安装GCC完整指南:依赖整理与RPM脚本实战

简介&#xff1a;GCC离线安装资源包&#xff0c;面向无网络或网络受限的Linux运维人员与开发者&#xff0c;解决因缺少依赖而无法编译源码的痛点。压缩包共12个文件&#xff0c;包含11个针对CentOS/RHEL 6的RPM安装包和1个自动化安装脚本&#xff0c;覆盖gcc、gcc-c、cpp、glib…

作者头像 李华
网站建设 2026/10/21 11:56:11

Python老页游自动化实战:登录器与强化学习环境构建

简介&#xff1a;对Python在游戏辅助与AI训练方向感兴趣的开发者&#xff0c;可以借由《赛尔号》场景了解登陆器的网络交互封装、自动化操作思路&#xff0c;以及强化学习在战斗与任务中的试探性实现。压缩包共2000个文件&#xff0c;总体量约42.75MB&#xff0c;其中1258个txt…

作者头像 李华
网站建设 2026/10/21 11:44:24

你的空压机为什么费电?

摘要&#xff1a; 面对市面上琳琅满目的螺杆空压机&#xff0c;很多用户在搜索“永磁螺杆空压机哪家好”时感到困惑——尤其是老厂气压不足想换机、新厂房配套气源&#xff0c;又担心买到“电老虎”或故障停机拖垮产线。本文从能效、稳定性、服务响应三个维度&#xff0c;对比无…

作者头像 李华
网站建设 2026/10/21 11:38:14

35岁程序员转Agent,别焦虑!你的经验是优势,收藏这份完整学习路线

转行AI方向的Java后端程序员常感到焦虑&#xff0c;认为自己的年龄、非Python背景等会成为障碍。然而&#xff0c;文章指出&#xff0c;他们的主要误区在于低估了自身经验的价值。Agent开发并非要求成为算法专家&#xff0c;而是需要将AI能力落地到业务系统中。文章强调&#x…

作者头像 李华
网站建设 2026/10/21 11:38:11

CDS 里没读到的 Join,HANA 真的会跳过吗,一次基于真实执行计划的实测

写 ABAP CDS 久了,很容易形成一种经验判断。一个 CDS View 里虽然关联了很多表,但上层程序只读取主表字段,SAP HANA 应该会聪明地把那些没用到的 Join 干掉。 这个判断有时完全正确,有时却会把我们带进一个很隐蔽的坑。 真正麻烦的地方并不是 Join 有没有被执行,而是 ca…

作者头像 李华