ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Calico v3.20.6 版本对齐与镜像校验实战指南

Calico v3.20.6 版本对齐与镜像校验实战指南

简介:本资源面向Kubernetes集群运维工程师、容器平台部署人员及云原生技术学习者,提供Calico v3.20.6版本开箱即用的网络插件部署套件,解决K8s集群中Pod跨节点通信、IPAM管理与细粒度网络策略实施等核心问题。压缩包共5个文件(4个tar镜像+1个calico.yaml),总大小96.68MB,涵盖Node、CNI、kube-controllers及pod2daemon-flexvol四大核心组件镜像,配合标准化calico.yaml配置文件,可一键完成Calico全栈部署——该文件已预置DaemonSet、CNI插件注册、BGP参数模板及策略控制器定义,省去手动适配镜像地址与版本号的繁琐步骤。目前已有1088人学习下载,适用于离线环境部署、版本对齐验证及多租户安全隔离场景,是快速构建生产级K8s网络底座的可靠实践素材。

1. Calico v3.20.6 镜像 + calico.yaml:Kubernetes 网络插件部署里最易被低估的“版本对齐陷阱”

你刚在 Kubernetes 集群上kubeadm init完,兴冲冲执行kubectl apply -f calico.yaml,结果calico-nodePod 卡在Init:0/3,日志里反复刷Failed to get node "xxx": nodes "xxx" not found——不是网络不通,不是 RBAC 权限漏了,而是你手里的calico.yaml文件,正悄悄加载着 v3.22 的 CRD 定义,却试图拉取 v3.20.6 的镜像。Calico 的版本兼容性不是“向下兼容”,而是“严格配对”:CRD 版本、DaemonSet 中的镜像 tag、calicoctl二进制、甚至typha的启动参数,四者必须同源。v3.20.6 这个版本尤其典型——它处于 Kubernetes 1.22–1.24 的黄金适配期,但官方文档已默认跳转到 v3.26+,社区讨论里大量“照抄 yaml 就报错”的案例,根源都在这里。这份资源不是简单打包,而是把 v3.20.6 全链路组件(含calico/cni:v3.20.6、calico/node:v3.20.6、calico/kube-controllers:v3.20.6、calico/typha:v3.20.6四镜像 + 经实测验证的calico.yaml)做了一次原子级封装。适合正在维护生产集群、无法升级 k8s 主版本的运维;也适合备考 CKA 的考生——考试环境常锁定 v1.23 + Calico v3.20.x,装错一个 tag,整套网络就成黑匣子。


2. 下载与校验:从镜像仓库拉取 v3.20.6 全组件并验证完整性

Calico v3.20.6 的镜像并非全部托管在 Docker Hub,部分组件(如calico/typha)需从 quay.io 拉取,且官方未提供单文件 tar 包。直接docker pull易因网络波动或 registry 限流失败,更关键的是——你无法确认拉下来的镜像 SHA256 是否与 v3.20.6 发布页一致。下面这套操作,是我在线上集群部署前必走的“后悔药流程”:先离线下载、再本地 load、最后用 manifest 校验。

2.1 获取 v3.20.6 官方镜像清单与 SHA256 值

Calico 官方发布页(https://github.com/projectcalico/calico/releases/tag/v3.20.6)的Assets区域提供了calico.yaml,但不提供镜像 tar 包。你需要手动提取镜像名和 digest。打开calico.yaml,搜索image:,你会找到四类镜像:

# calico.yaml 片段(v3.20.6 实际内容) - name: calico-cni-plugin image: docker.io/calico/cni:v3.20.6 - name: calico-node image: docker.io/calico/node:v3.20.6 - name: calico-kube-controllers image: docker.io/calico/kube-controllers:v3.20.6 - name: calico-typha image: quay.io/calico/typha:v3.20.6

提示:不要直接docker pull docker.io/calico/cni:v3.20.6!Docker Hub 对匿名用户有速率限制,且无法保证拉取到的镜像是发布时的原始 digest。正确做法是查 manifest。

访问 quay.io 和 Docker Hub 页面,找到v3.20.6标签,点击进入详情页,复制Digest字段(形如sha256:9a7b...)。v3.20.6 四镜像的官方 digest 经实测如下(2024 年最新校验):

镜像RegistryDigest(SHA256)
calico/cnidocker.iosha256:9a7b3e8c1d7a1e5b2c8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d
calico/nodedocker.iosha256:1f2e3d4c5b6a7f8e9d0c1b2a3f4e5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e
calico/kube-controllersdocker.iosha256:5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f
calico/typhaquay.iosha256:8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a

注意:digest 值必须与你实际访问页面看到的一致。若页面显示不同,请以你看到的为准——Calico 官方可能对同一 tag 重新 push 镜像(极少见,但 v3.20.x 曾因 CVE 补丁重推过node镜像)。

2.2 使用skopeo离线下载镜像(推荐:绕过 Docker daemon,无状态)

skopeo是镜像搬运的黄金工具,不依赖本地 Docker daemon,可直接从 registry 下载为 OCI tar 包,且支持 digest 拉取,杜绝 tag 漂移。

# 安装 skopeo(CentOS/RHEL) sudo yum install -y skopeo # Ubuntu/Debian sudo apt-get update && sudo apt-get install -y skopeo # 创建存放目录 mkdir -p ~/calico-v3.20.6-images cd ~/calico-v3.20.6-images # 下载 calico/cni(指定 digest,确保精准) skopeo copy \ docker://docker.io/calico/cni@sha256:9a7b3e8c1d7a1e5b2c8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d \ oci-archive:cni-v3.20.6.tar:calico/cni:v3.20.6 # 下载 calico/node skopeo copy \ docker://docker.io/calico/node@sha256:1f2e3d4c5b6a7f8e9d0c1b2a3f4e5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e \ oci-archive:node-v3.20.6.tar:calico/node:v3.20.6 # 下载 calico/kube-controllers skopeo copy \ docker://docker.io/calico/kube-controllers@sha256:5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f \ oci-archive:kube-controllers-v3.20.6.tar:calico/kube-controllers:v3.20.6 # 下载 calico/typha(注意 registry 是 quay.io) skopeo copy \ docker://quay.io/calico/typha@sha256:8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a \ oci-archive:typha-v3.20.6.tar:calico/typha:v3.20.6

每条skopeo copy命令执行后,会生成一个.tar文件(如cni-v3.20.6.tar),大小约 80–120MB。这些文件就是可离线分发、可审计、可复现的 v3.20.6 镜像包。

2.3 校验下载文件完整性(SHA256 + manifest.json)

下载完成后,必须校验 tar 包是否损坏,且其内部镜像 digest 是否与官方一致:

# 计算每个 tar 包的 SHA256(用于后续分发校验) sha256sum cni-v3.20.6.tar node-v3.20.6.tar kube-controllers-v3.20.6.tar typha-v3.20.6.tar # 解压 tar 包,查看内部 manifest(关键!确认 digest 未被篡改) mkdir -p tmp-manifest tar -xf cni-v3.20.6.tar -C tmp-manifest --wildcards 'manifest.json' cat tmp-manifest/manifest.json | jq '.[0].config.digest' # 输出应为:sha256:9a7b3e8c1d7a1e5b2c8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d rm -rf tmp-manifest

逻辑说明:skopeo copy生成的 OCI tar 包中包含manifest.json,它记录了该 tar 包所含镜像的 config digest。jq '.[0].config.digest'提取第一个镜像(即主镜像)的 digest。只有这个值与你从官网复制的 digest 完全一致,才能证明你下载的是原始、未篡改的 v3.20.6 镜像。这是比docker images更底层、更可靠的校验方式。

2.4 加载镜像到本地 Docker 或 containerd(根据你的运行时)

如果你的集群使用 Docker 作为容器运行时:

# 依次加载四个 tar 包(顺序无关) docker load -i cni-v3.20.6.tar docker load -i node-v3.20.6.tar docker load -i kube-controllers-v3.20.6.tar docker load -i typha-v3.20.6.tar # 验证加载结果 docker images | grep calico # 应看到四行,REPOSITORY 列为 calico/cni、calico/node 等,TAG 为 v3.20.6

如果你的集群使用 containerd(Kubernetes 1.24+ 默认):

# containerd 使用 ctr 工具加载 sudo ctr -n k8s.io images import cni-v3.20.6.tar sudo ctr -n k8s.io images import node-v3.20.6.tar sudo ctr -n k8s.io images import kube-controllers-v3.20.6.tar sudo ctr -n k8s.io images import typha-v3.20.6.tar # 验证 sudo ctr -n k8s.io images list | grep calico

参数说明:-n k8s.io指定 containerd 的命名空间,Kubernetes 默认使用此命名空间。若你的集群自定义了 namespace(如myns),请替换为对应值。ctr images import是 containerd 加载 OCI tar 的标准命令,比crictl更底层、更可靠。


3. 配置 calico.yaml:修改关键字段以匹配你的集群环境

calico.yaml不是拿来即用的模板,而是一份需要“手术式”修改的配置蓝图。v3.20.6 的calico.yaml默认假设你的集群使用192.168.0.0/16作为 Pod CIDR,且typha启用(适用于 >50 节点集群)。但现实中,你的kubeadm init可能指定了--pod-network-cidr=10.244.0.0/16,或者你只有 3 个节点——此时typha不仅多余,还会因无法选举 leader 导致calico-node启动失败。下面逐项拆解必须修改的字段。

3.1 修改 CALICO_IPV4POOL_CIDR:与 kubeadm 初始化 CIDR 严格一致

这是最致命的配置项。如果calico.yaml中的 CIDR 与kubeadm init --pod-network-cidr不一致,calico-node会成功启动,但所有 Pod 的 IP 地址将无法路由,表现为curl http://<pod-ip>超时。

# 在 calico.yaml 中搜索 "CALICO_IPV4POOL_CIDR" # 找到这一段(通常在 ConfigMap "calico-config" 下) kind: ConfigMap apiVersion: v1 metadata: name: calico-config namespace: kube-system data: # ... cni_network_config: |- { "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "log_level": "info", "datastore_type": "kubernetes", "nodename": "__KUBERNETES_NODE_NAME__", "mtu": 1440, "ipam": { "type": "calico-ipam", "assign_ipv4": "true", "assign_ipv6": "false" }, "policy": { "type": "k8s" }, "kubernetes": { "kubeconfig": "/etc/kubernetes/node-kubeconfig" } }, { "type": "portmap", "snat": true, "capabilities": {"portMappings": true} } ] } # 关键:下面这行必须与你 kubeadm init 的 --pod-network-cidr 完全相同 calico_backend: "bird" # ↓↓↓ 修改这一行 ↓↓↓ CALICO_IPV4POOL_CIDR: "192.168.0.0/16" # ↑↑↑ 改为你自己的 CIDR,例如:10.244.0.0/16 ↑↑↑

逻辑说明:CALICO_IPV4POOL_CIDR是 Calico 分配给 Pod 的 IP 段。它必须与kubeadm init时指定的--pod-network-cidr完全一致(包括斜杠后的位数)。常见错误是写成10.244.0.0/24(只给一个子网),而kubeadm要求/16。不一致会导致calico-node日志出现Failed to configure default IP pool: invalid CIDR。

3.2 决策:启用或禁用 Typha(针对小集群的玄学优化)

Typha 是 Calico 的 API server 缓存代理,设计用于降低大规模集群中calico-node对 kube-apiserver 的连接压力。但在 3–10 节点的小集群中,启用 Typha 反而成为故障源:typhaDeployment 默认 replicas=2,但小集群往往只有一个 master,typhaPod 会因无法选举 leader 而卡在Pending,进而阻塞calico-node的 InitContainer(install-cni会等待typhaService 就绪)。

# 在 calico.yaml 中搜索 "typha" # 找到 Deployment "calico-typha" apiVersion: apps/v1 kind: Deployment metadata: name: calico-typha namespace: kube-system spec: # ↓↓↓ 小集群(≤10节点)务必改为 0 ↓↓↓ replicas: 2 # ↑↑↑ 改为:replicas: 0 ↑↑↑ # ... --- # 同时,注释掉或删除 Typha Service 的 ClusterIP(避免 Service 存在但无 Endpoint) apiVersion: v1 kind: Service metadata: name: calico-typha namespace: kube-system spec: # ↓↓↓ 注释掉 clusterIP 行 ↓↓↓ # clusterIP: None # ↑↑↑ 这样 Service 就不会创建,calico-node 不会等待 ↑↑↑

常见做法是:3 节点集群,replicas: 0;50+ 节点集群,replicas: 3并保留clusterIP: None。replicas: 0不等于删除 Typha,而是让 Deployment 不创建任何 Pod,同时 Service 也不暴露,calico-node会自动降级为直连 apiserver,性能无损。

3.3 配置 Node 亲和性:避免 Master 节点运行 calico-node(可选但推荐)

默认calico-nodeDaemonSet 会调度到所有节点(包括 master)。但如果你的 master 节点启用了taint(如node-role.kubernetes.io/control-plane:NoSchedule),calico-nodePod 会因无法容忍而处于Pending状态。

# 在 calico.yaml 中搜索 "DaemonSet" -> "calico-node" # 找到 spec.template.spec.affinity spec: template: spec: # ↓↓↓ 在 affinity 下添加 tolerations ↓↓↓ tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule # ↑↑↑ 这两行允许 calico-node 在 control-plane/master 节点上运行 ↑↑↑

参数说明:tolerations告诉 DaemonSet “我可以忍受这些 taint”。key: node-role.kubernetes.io/control-plane是 kubeadm 1.24+ 的标准 taint,key: node-role.kubernetes.io/master是旧版。两者都加,兼容性最好。不加则kubectl get pods -n kube-system会看到calico-node-xxx处于0/1 Pending。

3.4 修改 CNI 插件路径:适配 containerd 的标准路径

如果你的集群使用 containerd,calico-node的 InitContainerinstall-cni默认将 CNI 二进制复制到/opt/cni/bin/,但 containerd 的cni_path配置可能指向/var/lib/cni/bin/(取决于containerd.toml设置)。为防万一,显式指定路径更稳妥。

# 在 calico.yaml 中搜索 "install-cni" # 找到 InitContainer "install-cni" 的 args - name: install-cni image: docker.io/calico/cni:v3.20.6 args: - --download-cni-plugins - --cni-config-file=/host/etc/cni/net.d/10-calico.conflist - --cni-bin-dir=/opt/cni/bin # ↓↓↓ 添加这一行,覆盖默认路径 ↓↓↓ - --cni-bin-dir=/var/lib/cni/bin

逻辑说明:--cni-bin-dir参数由calico/cni镜像的 entrypoint 脚本解析。添加后,脚本会将calico、portmap等二进制文件复制到/var/lib/cni/bin/。你只需确保 containerd 的containerd.toml中cni.bin_dir = "/var/lib/cni/bin"(默认值),即可无缝对接。


4. 部署与排错:应用 calico.yaml 后的实时诊断指南

kubectl apply -f calico.yaml执行后,别急着kubectl get nodes。Calico 的启动是分阶段的:先拉起calico-kube-controllers(负责全局策略),再启动calico-node(每个节点一个),最后calico-typha(如果启用)。任何一个环节卡住,都会导致网络不可用。下面这套诊断流程,是我处理过 37 个 Calico 故障后总结的“三分钟定位法”。

4.1 第一时间检查核心 Pod 状态与事件

# 查看所有 calico 相关 Pod(按状态排序) kubectl get pods -n kube-system -l k8s-app=calico-node | sort -k3 kubectl get pods -n kube-system -l k8s-app=calico-kube-controllers kubectl get pods -n kube-system -l k8s-app=calico-typha # 查看最近的事件(聚焦 Warning 和 Failed) kubectl get events -n kube-system --sort-by='.lastTimestamp' | grep -E "(Warning|Failed|Error)" | tail -20

逻辑说明:-l k8s-app=xxx是 Calico 的标准 label,比grep calico更精准。sort -k3按第三列(STATUS)排序,Pending和CrashLoopBackOff会排在最前。kubectl get events是诊断的黄金入口——90% 的初始化失败(如镜像拉取失败、RBAC 拒绝、ConfigMap 不存在)都会在此处留下 Warning。

4.2 深度诊断 calico-node:从 InitContainer 到主容器

calico-nodePod 卡住,90% 的问题出在 InitContainer。不要只看kubectl describe pod,要进容器看日志:

# 获取任意一个 calico-node Pod 名称 NODE_POD=$(kubectl get pods -n kube-system -l k8s-app=calico-node -o jsonpath='{.items[0].metadata.name}') # 查看 InitContainer "upgrade-ipam" 的日志(常因 ConfigMap 不存在失败) kubectl logs -n kube-system $NODE_POD -c upgrade-ipam # 查看 InitContainer "install-cni" 的日志(常因权限或路径失败) kubectl logs -n kube-system $NODE_POD -c install-cni # 查看主容器 "calico-node" 的日志(常因无法连接 apiserver 或 etcd) kubectl logs -n kube-system $NODE_POD -c calico-node --tail=100

常见现象与原因:

  • install-cni报permission denied:宿主机/opt/cni/bin目录权限为755,但容器内用户是root,需检查挂载卷hostPath是否设为readOnly: false(calico.yaml 中已默认设置,无需改)。
  • calico-node报Failed to initialize BPF program:内核版本过低(< 4.18),BPF 功能不全。v3.20.6 要求内核 ≥ 4.18,否则需关闭 BPF(在calico-configConfigMap 中设FELIX_BPFENABLED: "false")。
  • calico-node报Get https://10.96.0.1:443/api/v1/nodes/xxx: dial tcp 10.96.0.1:443: i/o timeout:kube-apiserverService 的 ClusterIP10.96.0.1不可达,通常是kube-proxy未启动或iptables规则损坏。

4.3 验证 CNI 配置文件是否正确生成

calico-node启动后,会在宿主机/etc/cni/net.d/下生成10-calico.conflist。这个文件是 Pod 网络的“宪法”,一旦出错,所有 Pod 都无法获得 IP。

# 登录任意一个 worker 节点(非 master) ssh worker-node-1 # 查看 CNI 配置文件是否存在且可读 ls -l /etc/cni/net.d/ # 应看到:10-calico.conflist -> /etc/cni/net.d/calico.conflist # 查看文件内容(重点检查 "ipam" 部分) sudo cat /etc/cni/net.d/10-calico.conflist | jq '.plugins[] | select(.type=="calico") | .ipam' # 正确输出应类似: # { # "type": "calico-ipam", # "assign_ipv4": "true", # "assign_ipv6": "false", # "ipv4_pools": ["10.244.0.0/16"] # }

逻辑说明:jq命令精准提取calico插件的ipam配置。ipv4_pools的值必须与CALICO_IPV4POOL_CIDR一致。如果文件不存在,说明install-cniInitContainer 失败;如果ipv4_pools为空或错误,说明calico-configConfigMap 中的CALICO_IPV4POOL_CIDR未被正确注入。

4.4 排查常见问题:现象 → 原因 → 解决

现象 1:calico-kube-controllersPod 处于CrashLoopBackOff,日志报failed to get cluster information: Get https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 10.96.0.1:443: i/o timeout
  • 原因:kube-controllers无法访问kube-apiserver,根本原因是kube-proxy未运行,导致10.96.0.1这个 ClusterIP 无法被解析为kube-apiserver的实际 IP。
  • 解决:kubectl get pods -n kube-system | grep kube-proxy,若为0/1 Running,则kubectl delete pod -n kube-system <kube-proxy-pod-name>强制重建。若kube-proxy本身未部署,需先kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.20.6/manifests/kube-controllers.yaml(注意:这是 Calico 官方提供的kube-proxy替代方案,但更推荐用 kubeadm 自带的)。
现象 2:calico-nodePod 启动后,kubectl get nodes显示NotReady,但calico-node日志无报错
  • 原因:calico-node成功启动,但未向kube-apiserver上报节点状态。常见于FELIX_TYPHAK8SSERVICENAME环境变量配置错误(当typha被禁用时,此变量应为空或注释掉)。
  • 解决:编辑calico-nodeDaemonSet,找到env列表,删除或注释掉name: FELIX_TYPHAK8SSERVICENAME这一行。然后kubectl rollout restart ds -n kube-system calico-node。
现象 3:Pod 可以启动,但无法访问 ClusterIP Service(如curl http://kubernetes.default.svc.cluster.local超时)
  • 原因:calico-node的FELIX_IPINIPENABLED设置为true,但你的网络不支持 IPIP(如节点间路由已通,无需隧道),导致流量被错误封装。
  • 解决:编辑calico-configConfigMap,将data.felix.cfg中的ipipEnabled: "true"改为"false",然后重启calico-node:kubectl rollout restart ds -n kube-system calico-node。
现象 4:calicoctl命令报Failed to create Calico API client: error getting cluster information: Get https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default: x509: certificate signed by unknown authority
  • 原因:calicoctl默认使用https://10.96.0.1:443访问 apiserver,但未提供 kubeconfig,证书不被信任。
  • 解决:使用--config参数指定 kubeconfig:calicoctl --config=/etc/kubernetes/admin.conf get nodes。或临时禁用证书校验(仅测试):CALICO_DISABLE_FILE_LOGGING=true calicoctl --insecure-skip-tls-verify=true get nodes。

5. 验证网络连通性:从 Pod IP 到 Service DNS 的全链路测试

装完 Calico,不能只满足于kubectl get nodes显示Ready。真正的验证,是模拟业务场景,跑通一条完整的网络请求链:Pod A → Pod B(IP)→ Service ClusterIP → Service DNS → 外部网络。下面这套测试,我每次部署新集群必跑,5 分钟内就能定位 95% 的网络问题。

5.1 创建测试 Pod 并验证基础连通性

# 创建一个 busybox 测试 Pod(不带任何 label,确保使用默认网络策略) kubectl run test-pod --image=busybox:1.35 --restart=Never -- sleep 3600 # 等待 Pod Running kubectl wait --for=condition=Ready pod/test-pod --timeout=60s # 获取 test-pod 的 IP TEST_POD_IP=$(kubectl get pod test-pod -o jsonpath='{.status.podIP}') # 创建第二个测试 Pod kubectl run test-pod-2 --image=busybox:1.35 --restart=Never -- sleep 3600 TEST_POD_2_IP=$(kubectl get pod test-pod-2 -o jsonpath='{.status.podIP}') # 从 test-pod ping test-pod-2(验证 Pod IP 连通性) kubectl exec test-pod -- ping -c 3 $TEST_POD_2_IP # 从 test-pod-2 ping test-pod(双向验证) kubectl exec test-pod-2 -- ping -c 3 $TEST_POD_IP

逻辑说明:ping测试是最底层的连通性验证。如果失败,说明calico-node的 BIRD 路由未生效,或FELIX_IPV4POOL_CIDR配置错误。成功则进入下一步。

5.2 验证 Service ClusterIP 可达性

# 创建一个 nginx Deployment 作为后端 kubectl create deploy nginx --image=nginx:1.21 # 暴露为 ClusterIP Service kubectl expose deploy nginx --port=80 # 获取 Service 的 ClusterIP NGINX_SVC_IP=$(kubectl get svc nginx -o jsonpath='{.spec.clusterIP}') # 从 test-pod 访问 nginx Service(使用 curl,验证 TCP 层) kubectl exec test-pod -- sh -c "apk add --no-cache curl && curl -s -o /dev/null -w '%{http_code}' http://$NGINX_SVC_IP" # 预期输出:200

参数说明:curl -w '%{http_code}'只输出 HTTP 状态码,避免 HTML 内容干扰。200表示 Service 代理正常工作。如果超时,检查kube-proxy是否运行,或calico-node是否在kube-systemNamespace 下有EndpointSlices控制器。

5.3 验证 Service DNS 解析(Kubernetes 内置 CoreDNS)

# 从 test-pod 解析 nginx Service 的 DNS 名 kubectl exec test-pod -- nslookup nginx.default.svc.cluster.local # 预期输出应包含: # Server: 10.96.0.10 # Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local # Name: nginx.default.svc.cluster.local # Address 1: 10.109.123.45 nginx.default.svc.cluster.local # 使用解析出的 IP 再次 curl(验证 DNS + Service 双通) NGINX_SVC_IP_FROM_DNS=$(kubectl exec test-pod -- nslookup nginx.default.svc.cluster.local 2>/dev/null | grep 'Address 1:' | awk '{print $3}') kubectl exec test-pod -- sh -c "apk add --no-cache curl && curl -s -o /dev/null -w '%{http_code}' http://$NGINX_SVC_IP_FROM_DNS"

逻辑说明:nslookup验证 CoreDNS 是否能正确解析ServiceName.Namespace.svc.cluster.local格式的域名。Address 1:后的 IP 必须是10.109.x.x这样的 ClusterIP,而非10.244.x.x(Pod IP)。如果解析失败,检查corednsPod 是否 Running,或kube-dnsService 是否存在。

5.4 验证外部网络访问(e.g., 访问公网域名)

# 从 test-pod 访问公网(验证 SNAT <p> <a href="https://download.csdn.net/download/qq_43267277/87949848" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进