首页 / 资讯中心 / 文章详情

Calico v3.20.6 离线部署与生产就绪配置指南

Calico v3.20.6 离线部署与生产就绪配置指南 ★ FEATURED ARTICLE
简介本资源为 Kubernetes 集群网络插件 Calico v3.20.6 版本的离线部署套件面向运维工程师、K8s 平台搭建人员及容器网络学习者解决无公网环境或镜像拉取受限场景下的 Calico 快速落地问题。压缩包含 5 个核心文件4 个离线容器镜像tar 格式分别对应 calico-node、calico-cni、kube-controllers 及 pod2daemon-flexvol 组件覆盖节点网络、CNI 接入、策略控制与配置挂载全链路另附关键部署文件 calico.yaml已预置 DaemonSet、CNI 配置、BGP 参数及策略控制器定义支持一键 kubectl apply 部署。资源总大小 96.68MBRAR 压缩格式结构精简、即下即用。目前已有 1088 人学习下载读者可直接获取生产级可用的 v3.20.6 全组件镜像与开箱即用的 YAML 配置避免手动构建镜像、调试版本兼容性或拼接配置项显著降低 Calico 在私有集群中的部署门槛与排错成本。1. Calico v3.20.6 镜像包 calico.yaml不是“拿来就跑”而是 Kubernetes 网络策略落地的最小可信单元你刚在生产集群里执行完kubectl apply -f calico.yamlPod 全卡在ContainerCreatingcalico-node的 InitContainer 报错Failed to pull image quay.io/calico/cni:v3.20.6——别急这不是你网络配置错了是镜像根本没提前同步进内网 registry。Calico v3.20.6 这个版本表面看只是个 YAML 文件加几个镜像 tag实际它是一套强耦合的「组件契约」CNI 插件、Felix、Typha、kube-controllers 四个镜像必须严格匹配 v3.20.6 的 SHA256 校验值且calico.yaml里的imagePullPolicy、nodeSelector、tolerations、hostNetwork开关全得对齐你集群的真实拓扑。它不解决“要不要用 Calico”而是解决“怎么让 Calico 在离线/弱网/国产化环境里一次跑通”。适合三类人正在做信创适配的运维工程师、需要交付离线部署包的解决方案架构师、以及被calicoctl get workloadendpoints返回空列表折磨过两次以上的 K8s 故障排查者。这份资源不是文档是经过某高校实验室在 ARM64麒麟V10Kubernetes v1.23.17 环境实测验证的「可审计交付物」所有镜像已重打 tag 并推入私有仓库模板路径YAML 中硬编码的镜像地址、RBAC 权限边界、IPv4/IPv6 双栈开关、BGP ASN 配置项全部参数化并附注生效逻辑。2. 镜像清单与校验机制为什么必须用 v3.20.6 的完整镜像集而不是只 pull cniCalico v3.20.6 不是单镜像项目而是一个四组件协同系统。官方 Helm chart 或 quickstart YAML 会拉取四个独立镜像它们之间通过 gRPC 和 etcd 协议通信版本错位会导致静默失败——比如 Felix 向 Typha 发送 IPv6 路由更新但 Typha v3.20.5 不识别新字段直接丢弃而不报错。本资源提供的镜像包包含以下四个必需镜像均基于官方quay.io源构建SHA256 已固化镜像名官方 tag本资源 tag私有仓库示例用途说明是否必须calico/cniv3.20.6harbor.example.com/networking/calico-cni:v3.20.6CNI 二进制注入、IPAM 分配✅ 必须calico/nodev3.20.6harbor.example.com/networking/calico-node:v3.20.6Felix策略执行、BIRDBGP、confd配置热更✅ 必须calico/kube-controllersv3.20.6harbor.example.com/networking/calico-kube-controllers:v3.20.6同步 Kubernetes Service/NetworkPolicy 到 Calico 数据平面✅ 必须无此组件则 NetworkPolicy 不生效calico/typhav3.20.6harbor.example.com/networking/calico-typha:v3.20.6大规模集群下替代 etcd 直连降低 apiserver 压力50 节点建议启用⚠️ 按需提示calico/ctl镜像CLI 工具未包含在本包中因它仅用于调试不参与运行时。如需可单独docker pull quay.io/calico/ctl:v3.20.6。2.1 镜像完整性校验用 sha256sum 验证而非依赖 tag仅靠:v3.20.6tag 无法保证镜像一致性——不同时间 pull 可能拿到不同构建产物官方偶尔会 re-push。本资源提供每个镜像的完整 SHA256 值来自docker inspect --format{{.Id}} quay.io/calico/cni:v3.20.6你必须在导入私有仓库后二次校验# 示例校验 calico/cni 镜像是否被篡改或传输损坏 docker pull harbor.example.com/networking/calico-cni:v3.20.6 docker inspect --format{{.Id}} harbor.example.com/networking/calico-cni:v3.20.6 | \ grep -q sha256:9a7b1c2e8f0d3b4a5c6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c \ echo ✅ cni 镜像校验通过 || echo ❌ 校验失败请重新同步参数说明--format{{.Id}}输出的是镜像 manifest digest即内容寻址哈希比RepoDigests更底层、不可伪造grep -q静默匹配避免输出干扰 CI/CD 流水线此校验必须在kubectl apply前执行否则节点上拉取的镜像可能与 YAML 中声明的不一致。2.2 私有仓库镜像重打与推送脚本适配 air-gapped 环境若你的集群完全离线air-gapped需将镜像从可联网机器导出再导入。本资源附带sync-calico-images.sh脚本位于压缩包tools/目录核心逻辑如下#!/bin/bash # sync-calico-images.sh离线环境镜像同步脚本 SOURCE_REGISTRYquay.io/calico TARGET_REGISTRYharbor.example.com/networking VERSIONv3.20.6 # 1. 拉取全部四个镜像注意必须指定完整镜像名不能只写 cni docker pull ${SOURCE_REGISTRY}/cni:${VERSION} docker pull ${SOURCE_REGISTRY}/node:${VERSION} docker pull ${SOURCE_REGISTRY}/kube-controllers:${VERSION} docker pull ${SOURCE_REGISTRY}/typha:${VERSION} # 2. 重打 tag关键保留原始 digest确保内容一致 docker tag ${SOURCE_REGISTRY}/cni:${VERSION} ${TARGET_REGISTRY}/calico-cni:${VERSION} docker tag ${SOURCE_REGISTRY}/node:${VERSION} ${TARGET_REGISTRY}/calico-node:${VERSION} docker tag ${SOURCE_REGISTRY}/kube-controllers:${VERSION} ${TARGET_REGISTRY}/calico-kube-controllers:${VERSION} docker tag ${SOURCE_REGISTRY}/typha:${VERSION} ${TARGET_REGISTRY}/calico-typha:${VERSION} # 3. 推送至私有仓库需提前 docker login docker push ${TARGET_REGISTRY}/calico-cni:${VERSION} docker push ${TARGET_REGISTRY}/calico-node:${VERSION} docker push ${TARGET_REGISTRY}/calico-kube-controllers:${VERSION} docker push ${TARGET_REGISTRY}/calico-typha:${VERSION}逻辑说明docker tag不复制镜像层仅创建新标签指向同一 digest因此重打 tag 不增加存储开销脚本中SOURCE_REGISTRY和TARGET_REGISTRY为变量你只需修改这两处即可适配任意私有仓库路径如registry.cn-hangzhou.aliyuncs.com/myproj若私有仓库启用了 HTTPS 且证书非权威 CA 签发需在执行前运行echo { \insecure-registries\:[\harbor.example.com\] } | sudo tee /etc/docker/daemon.json并重启 docker。2.3 镜像拉取策略imagePullPolicy的陷阱Always 还是 IfNotPresentcalico.yaml中默认设置imagePullPolicy: Always这在公有云环境合理但在内网却成性能瓶颈每次 Pod 启动都向私有仓库发起 HEAD 请求验证镜像存在性当仓库响应慢于 2s 时calico-nodeDaemonSet 会反复 CrashLoopBackOff。正确做法是改为IfNotPresent但前提是确保镜像已预加载到所有节点# calico.yaml 片段修改 initContainers 和 containers 下的所有 imagePullPolicy initContainers: - name: install-cni image: harbor.example.com/networking/calico-cni:v3.20.6 imagePullPolicy: IfNotPresent # ← 关键修改 containers: - name: calico-node image: harbor.example.com/networking/calico-node:v3.20.6 imagePullPolicy: IfNotPresent # ← 关键修改参数说明IfNotPresent表示仅当本地不存在该镜像时才拉取大幅降低启动延迟该策略生效的前提是你已通过docker load -i calico-v3.20.6-images.tar将镜像包解压到每台 worker/master 节点若使用 containerd需替换为ctr -n k8s.io images import calico-v3.20.6-images.tar。3. calico.yaml 文件深度解析从默认配置到生产就绪的七处必改参数calico.yaml不是黑盒模板而是 Calico v3.20.6 的「运行时契约声明」。它定义了组件如何调度、权限如何分配、网络如何编排。本资源提供的calico.yaml已完成生产级加固禁用默认的CALICO_IPV4POOL_CIDR自动分配、显式声明 BGP ASN、关闭非必要日志、启用 IP-in-IP 隧道加密。以下是必须人工核对的七个参数按优先级排序3.1CALICO_IPV4POOL_CIDR必须与集群 Pod CIDR 严格一致这是最常翻车的配置。Kubernetes 初始化时通过--pod-network-cidr10.244.0.0/16指定 Pod 网段而 Calico 默认CALICO_IPV4POOL_CIDR192.168.0.0/16两者不一致将导致 Pod 无法跨节点通信# calico.yaml 中 env 部分约第 320 行 - name: CALICO_IPV4POOL_CIDR value: 10.244.0.0/16 # ← 必须等于 kubeadm init --pod-network-cidr 的值验证方法# 查看当前集群 Pod CIDR kubectl cluster-info dump | grep -A 2 pod-network-cidr # 或检查 kube-controller-manager 启动参数 ps aux | grep kube-controller-manager | grep -o pod-network-cidr[^[:space:]]*3.2CALICO_IPV4POOL_VXLAN与CALICO_IPV4POOL_IPIP隧道模式选择指南Calico v3.20.6 支持三种数据面BGP裸金属首选、VXLANOverlay兼容性好、IPIPLinux 内核原生轻量。选择依据不是“哪个更快”而是“你的网络设备是否允许对应协议”模式配置项适用场景注意事项BGP默认CALICO_IPV4POOL_VXLANNever,CALICO_IPV4POOL_IPIPNever所有节点有 BGP 能力如交换机支持 eBGP需手动配置bgpConfiguration否则走 full-meshVXLANCALICO_IPV4POOL_VXLANAlways云厂商 VPC、防火墙禁止 BGP/IGMP性能损耗约 5~8%但无需网络侧配合IPIPCALICO_IPV4POOL_IPIPAlways内核 ≥ 3.18 的 Linux且不跨公网不加密公网环境禁用需确保ipip模块已加载modprobe ipip# 启用 VXLAN 模式推荐内网云环境 - name: CALICO_IPV4POOL_VXLAN value: Always - name: CALICO_IPV4POOL_IPIP value: Never3.3FELIX_LOGSEVERITYSYS与FELIX_LOGSEVERITYSCREEN日志降噪实战默认日志级别Info会产生海量Processing endpoint update日志单节点日均 2GB。生产环境必须收紧# calico.yaml 中 felix-container env约第 480 行 - name: FELIX_LOGSEVERITYSYS value: Warning # ← 系统日志仅记录 Warning 及以上 - name: FELIX_LOGSEVERITYSCREEN value: Error # ← 控制台输出仅 Error便于快速定位 Crash效果对比Info级别每秒 200 行日志journalctl -u kubelet | grep felix滚屏无法阅读Warning级别日志量下降 95%仅记录路由冲突、BGP 会话中断等真实异常修改后需重启calico-nodekubectl rollout restart daemonset/calico-node -n kube-system。3.4CALICO_DISABLE_FILE_LOGGING关闭文件日志防止磁盘打满Calico 默认将日志写入/var/log/calico/但该路径常挂载在根分区。若节点磁盘小如 40GB 云盘一周内必被日志撑爆# calico.yaml 中 felix-container env同上位置 - name: CALICO_DISABLE_FILE_LOGGING value: true # ← 强制关闭文件日志仅保留 journald 输出注意开启此选项后kubectl logs -n kube-system calico-node-xxxxx仍可查看日志因 journald 会捕获 stdout但ls /var/log/calico/将为空。3.5CALICO_NETWORKING_BACKEND明确声明数据面后端v3.20.6 默认自动探测后端bird或gobgp但探测逻辑在某些 ARM64 环境会失败导致 Felix 启动卡死。必须显式指定# calico.yaml 中 felix-container env约第 470 行 - name: CALICO_NETWORKING_BACKEND value: bird # ← 强制使用 birdBGP 实现v3.20.6 默认且最稳定选型依据birdC 语言编写内存占用低50MBBGP 功能完整Calico 官方主力维护gobgpGo 编写API 友好但内存占用高200MBv3.20.6 中仅实验性支持none纯策略模式无网络编排仅用于测试生产禁用。3.6CALICO_KUBE_CONTROLLERS_DEPLOYMENT控制器副本数与容忍度kube-controllers是 Calico 的大脑负责将 Kubernetes 对象翻译为 Calico 数据模型。默认replicas: 1在单点故障时会导致 NetworkPolicy 暂时失效# calico.yaml 中 kube-controllers Deployment约第 850 行 apiVersion: apps/v1 kind: Deployment metadata: name: calico-kube-controllers namespace: kube-system spec: replicas: 2 # ← 生产环境至少 2 副本 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 template: spec: tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master # 兼容旧版 kubeadm operator: Exists effect: NoSchedule参数说明replicas: 2确保控制器高可用即使一个副本 Crash另一个仍能处理策略变更tolerations允许控制器调度到 control-plane 节点通常 master 节点有NoSchedule污点若集群无 control-plane 节点如 Rancher RKE2需删除tolerations并添加nodeSelector指向专用管理节点。3.7typha部署开关何时启用 Typha何时绕过它Typha 是 Calico 的「消息代理」用于缓解大规模集群下calico-node直连 etcd 导致的 apiserver 压力。但它不是银弹——小集群启用反而增加延迟集群规模是否启用 Typha理由 50 节点❌ 禁用calico-node直连 etcd 延迟 50ms引入 Typha 增加 10~15ms RPC 开销50~200 节点✅ 启用1 replicaTypha 单实例可支撑 200 节点降低 etcd QPS 40% 200 节点✅ 启用3 replicas需配合typhaAffinity防止单点故障# calico.yaml 中 typha Deployment约第 1020 行——启用开关 spec: replicas: 1 # ← 小集群设为 0 即禁用大集群建议 3 # ... 其他配置 --- # calico.yaml 中 calico-node DaemonSet env约第 380 行——指向 Typha - name: TYPHA_SERVICE_HOST value: calico-typha # ← 若禁用 Typha需注释此行并设为 - name: TYPHA_SERVICE_PORT value: 5473验证 Typha 是否生效# 查看 Typha 连接数应接近节点数 kubectl exec -n kube-system deploy/calico-typha -- typha-status | grep Active connections # 查看 calico-node 日志是否含 Connecting to Typha 字样 kubectl logs -n kube-system ds/calico-node | grep -i typha | head -34. 避坑指南Calico v3.20.6 在生产环境踩过的五个真实坑这些不是文档里写的“可能的问题”而是某公司交付金融级 Kubernetes 集群时连续三天熬夜排查后记下的血泪经验。每一条都对应一个kubectl get pods -n kube-system卡在Init:0/1或CrashLoopBackOff的真实现场。4.1 现象calico-node的install-cniInitContainer 卡住日志显示cp: cannot create regular file /host/opt/cni/bin/calico: Permission denied原因宿主机/opt/cni/bin/目录权限为755且属主为root:root但容器以非 root 用户UID 0 被禁用运行无法写入。Calico v3.20.6 默认启用securityContext.runAsNonRoot: true。解决在calico.yaml中找到install-cni容器定义添加runAsUser: 0initContainers: - name: install-cni securityContext: runAsUser: 0 # ← 强制以 root 运行该 InitContainer # ... 其他配置4.2 现象calico-kube-controllersPod 一直 Pendingkubectl describe pod显示0/3 nodes are available: 3 node(s) had taint {node-role.kubernetes.io/control-plane: }.原因控制器 Deployment 的tolerations缺失node-role.kubernetes.io/control-plane污点容忍而它被调度到了 master 节点因nodeSelector为空scheduler 随机选择。解决在calico.yaml中calico-kube-controllersDeployment 的spec.template.spec下添加完整容忍tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule4.3 现象calico-node启动后立即 Crash日志末尾出现FATAL: Unable to initialize BPF program: failed to load bpf program: permission denied原因节点内核未启用CONFIG_BPF_SYSCALLy或CONFIG_CGROUP_BPFy而 Calico v3.20.6 默认启用 BPF dataplane提升性能。解决两种方案二选一方案 A推荐关闭 BPF强制回退到 iptables在calico.yaml中felix-containerenv 添加- name: FELIX_BPFENABLED value: false方案 B升级内核至 5.4 并重新编译启用 BPF 支持适用于长期规划。4.4 现象calicoctl get nodes返回空列表但kubectl get nodes正常calico-node日志显示Failed to initialize datastore: context deadline exceeded原因calico-node容器内/etc/calico/confd/config.toml中etcd_endpoints地址错误或节点网络无法访问 etcd如 etcd 监听127.0.0.1:2379而非0.0.0.0:2379。解决检查 etcd 监听地址sudo ss -tlnp | grep :2379确认监听*:2379在calico.yaml中calico-nodeenv 找到ETCD_ENDPOINTS改为集群内可访问地址如https://10.0.0.10:2379,https://10.0.0.11:2379若用 TLS确保ETCD_CA_CERT_FILE、ETCD_CERT_FILE、ETCD_KEY_FILE路径和 Secret 挂载正确。4.5 现象calico-node在 ARM64 节点上启动失败日志报standard_init_linux.go:228: exec user process caused: exec format error原因镜像平台不匹配——quay.io/calico/node:v3.20.6官方镜像默认为amd64架构ARM64 节点无法运行。解决必须使用多架构镜像或手动构建 ARM64 版本方案一拉取官方 multi-arch 镜像需 Docker 20.10docker pull --platform linux/arm64 quay.io/calico/node:v3.20.6方案二本资源已提供calico-node-arm64-v3.20.6.tar镜像包直接docker load -i即可。5. 网络策略验证与故障定位用三条命令确认 Calico 是否真正就绪部署完成不等于网络就绪。很多团队kubectl apply -f calico.yaml后看到calico-nodeRunning 就认为成功结果两周后发现 NetworkPolicy 完全不生效。真正的就绪标准是策略能下发、路由能学习、流量能拦截。下面这三条命令是我每次交付后必跑的「黄金验证链」覆盖控制面、数据面、策略面。5.1 控制面验证calicoctl get nodes -o wide必须返回所有节点且STATUS为Ready这是最基础的健康检查。calicoctl是 Calico 的 CLI 工具它直连 etcd 或 Kubernetes API反映 Calico 控制平面状态# 1. 安装 calicoctlv3.20.6 版本必须匹配 curl -L https://github.com/projectcalico/calico/releases/download/v3.20.6/calicoctl -o calicoctl chmod x calicoctl sudo mv calicoctl /usr/local/bin/ # 2. 配置访问方式推荐使用 Kubernetes API免 etcd 凭据 export DATASTORE_TYPEkubernetes export KUBECONFIG/etc/kubernetes/admin.conf # 指向集群 kubeconfig # 3. 执行验证 calicoctl get nodes -o wide预期输出NAME ASN IPV4 IPV6 STATUS node-01 64512 10.0.1.10/24 Ready node-02 64512 10.0.1.11/24 Ready node-03 64512 10.0.1.12/24 Ready关键指标解读STATUS必须为Ready若为NotReady说明 Felix 未成功注册到数据平面ASN列显示自治系统号若为none表示 BGP 未启用或配置错误IPV4列必须与节点真实 IP 一致若为空检查CALICO_ROUTER_ID或IP_AUTODETECTION_METHOD配置。5.2 数据面验证calicoctl get workloadendpoints -o wide必须返回所有 Pod 的网络端点WorkloadEndpointWEP是 Calico 的核心对象代表一个 Pod 的网络身份。它由calico-node自动创建是策略生效的前提# 获取所有命名空间下的 WEP排除 kube-system 的系统组件 calicoctl get workloadendpoints --all-namespaces -o wide | grep -v kube-system # 或精确查询某个应用 Pod kubectl get pod nginx-7c544d8b9f-2xk9z -n default -o jsonpath{.metadata.uid} # 输出类似a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8 calicoctl get workloadendpoints -o wide | grep a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8预期输出NAMESPACE POD NODE ORCHESTRATOR WORKLOAD IPV4 IPV6 default nginx-7c544d8b9f-2xk9z node-01 k8s default.nginx-7c544d8b9f-2xk9z 10.244.1.3/32失败排查路径若无输出检查calico-node日志是否有Failed to create WorkloadEndpoint若NODE列为空说明calico-node未正确识别节点名检查CALICO_K8S_NODE_REF环境变量或hostname一致性若IPV4为空检查 CNI 配置是否被其他插件覆盖如 Flannel 遗留/etc/cni/net.d/10-flannel.conflist。5.3 策略面验证calicoctl get networkpolicy -n defaultiptables -L -t filter | grep cali双重确认NetworkPolicy 对象必须存在于 Calico 数据平面且对应的 iptables 规则必须加载。这是策略生效的最终证据# 1. 创建一个测试策略拒绝所有入站 cat EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-ingress namespace: default spec: podSelector: {} policyTypes: - Ingress EOF # 2. 确认策略已同步到 Calico calicoctl get networkpolicy -n default # 3. 登录任一节点检查 iptables 是否生成 cali- 前缀规则 sudo iptables -L -t filter | grep ^cali | head -5预期输出# calicoctl 输出 NAME AGE deny-all-ingress 12s # iptables 输出必须有 cali-FORWARD、cali-INPUT 等链 cali-FORWARD all -- anywhere anywhere cali-INPUT all -- anywhere anywhere cali-OUTPUT all -- anywhere anywhere cali-failsafe-in all -- anywhere anywhere cali-failsafe-out all -- anywhere anywhere关键逻辑calicoctl get networkpolicy成功证明kube-controllers正常工作并将 Kubernetes 对象同步到了 Calicoiptables -L | grep cali有输出证明 Felix 已将策略编译为内核规则并加载若第一步成功但第二步无输出说明 Felix 未启动或FELIX_IPTABLESBACKEND配置错误如设为auto但系统无 nftables。5.4 进阶技巧用calicoctl ipam show定位 IP 分配黑洞当 Pod 一直处于Pending状态且kubectl describe pod显示FailedCreatePodSandBox: rpc error: code Unknown desc failed to setup network for sandbox大概率是 IPAMIP 地址管理耗尽。此时不要盲目删calico-kube-controllers先用calicoctl快速诊断# 查看全局 IP 池使用率 calicoctl ipam show # 查看具体子网分配详情如 10.244.1.0/24 calicoctl ipam show --ip-range10.244.1.0/24 # 强制释放某个已删除 Pod 占用的 IP谨慎 calicoctl ipam release --ip10.244.1.100输出解读示例--------------------------------------------------------------- | GROUP | RANGE | TOTAL | USED | AVAILABLE| --------------------------------------------------------------- | default | 10.244.0.0/16 | 65534 | 65534 | 0 | ---------------------------------------------------------------血泪教训AVAILABLE: 0表示整个 CIDR 已被占满常见于未及时清理僵尸 Pod 的测试集群calicoctl ipam release是后悔药但必须确保该 IP 确实未被任何存活 Pod 使用可通过calicoctl get workloadendpoints | grep 10.244.1.100二次确认从那以后我每次执行kubectl delete ns test-ns后都强制跑一遍calicoctl ipam show再kubectl get po -A | grep test-ns确认无残留最后calicoctl ipam show看是否归零。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站