恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Calico v3.20.6 离线部署实战:镜像包与 calico.yaml 配套使用指南
首页
资讯中心
/
Calico v3.20.6 离线部署实战:镜像包与 calico.yaml 配套使用指南
Calico v3.20.6 离线部署实战:镜像包与 calico.yaml 配套使用指南
发布时间:2026/10/21 11:58:45
简介本资源面向在 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 镜像包里到底有几个 tarcalico 不是单个二进制它是一组组件的集合。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 --imagebusybox --restartNever -- sleep 3600 kubectl run test-pod-2 --imagebusybox --restartNever -- sleep 3600 # 查看 Pod IP 和所在节点 kubectl get pods -o wide # 从一个 Pod ping 另一个 kubectl exec -it test-pod-1 -- ping test-pod-2-ip逻辑说明--restartNever让 Pod 不会自动重启方便清理。-o wide显示 Pod IP 和节点名。ping 通说明 calico 的跨节点路由生效了。参数上busybox 镜像小适合做测试但注意它默认没有 ping 命令的某些选项简单 ping 够用。5. 避坑与排查那些让我重装过集群的瞬间5.1 坑一镜像 tag 和 yaml 不一致导致 ImagePullBackOff现象calico-node Pod 一直卡在 ImagePullBackOffdescribe 里报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 显示 RunningBGP 也 Established但新建的 Pod 就是不通。原因之前装过其他 CNI 或者旧版 calicoiptables 里残留了 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 和镜像只要对得上跑起来很省心。如果你手头正好有这套资源按上面的步骤走一遍应该能少踩几个我踩过的坑。希望帮到你。本文还有配套的精品资源点击获取