ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

Calico calicoctl 二进制安装与集群网络排障实战

Calico calicoctl 二进制安装与集群网络排障实战

1. 先想清楚:为什么还要单独装一个 calicoctl

很多人在集群里排查网络问题,第一反应是kubectl get pods -n kube-system,看看 calico-node 的 Pod 是不是 Running,然后就卡住了。Pod 是 Running 不等于网络是通的,BGP 会话可能断着、IPPool 可能被耗尽、某个节点可能还在用旧的 Felix 配置。这些信息,用kubectl describe一层层翻 CRD 也能看到,但效率极低,而且很容易看漏字段。这时候就需要calicoctl。

calicoctl 是 Calico 官方提供的命令行工具,专门用来读写 Calico 的数据模型:IPPool、IPReservation、BGPConfiguration、BGP Peer、FelixConfiguration、GlobalNetworkPolicy、Node 等等。它做的事情本质上和kubectl get那些 CRD 是一回事,但它多做了一层校验和格式化。比如你手写一个 IPPool 的 YAML,字段名拼错了、CIDR 写成了非法格式,kubectl apply可能直接给你塞进 etcd 或者 API Server 里,等到某个组件读取时才报错;calicoctl 会在发送之前就告诉你哪个字段非法。对于网络这种"改错一次全集群抖三抖"的东西,这层校验很值钱。

标题里强调的是"二进制安装"。这里要先说清楚:calicoctl 不是一个必须装的东西,它有三种使用形态,选哪种取决于你在什么环境里干活。

1.1 三种调用形态的取舍

第一种是kubectl直接操作 Calico 的 CRD。这是零成本方案,集群里有什么就能操作什么,不需要额外装东西。缺点是没有任何 Calico 侧的语义校验,你写的 YAML 只要符合 CRD 的 OpenAPI Schema 就能进去,而 Calico 的一些业务约束(比如两个 IPPool 的 CIDR 不允许重叠、BlockSize 必须是 2 的幂且不能超过 CIDR 掩码)在 Schema 层是表达不出来的。我曾经在一个测试集群里手滑创建了两个 CIDR 重叠的 IPPool,kubectl apply一路绿灯,直到新 Pod 调度上去拿不到地址,才发现问题。

第二种是把 calicoctl 做成 kubectl 的插件,也就是放到 PATH 里命名为kubectl-calicoctl,然后就能用kubectl calicoctl get ippools这样的形式调用。本质还是那个二进制,只是调用入口变了。适合那种习惯"万物皆 kubectl"的人,但对排障没什么实质帮助,反而多一层记忆负担。

第三种就是本文要讲的独立二进制。下载一个单文件,赋予执行权限,放到/usr/local/bin,配好配置文件就能用。它不依赖集群里跑着什么,也不依赖 Python 或 Go 运行时,静态编译,扔到任何一台能连上 API Server 的机器上都能跑。我个人的习惯是在跳板机、每个 Master 节点、以及自己笔记本上都放一份,出问题时不用现去下载。

1.2 二进制方式适合的场景

说几个我实际遇到、二进制方式明显更顺手的场景。

集群网络故障时的"外部视角"。当 API Server 本身有问题、或者 calico-node 大面积 CrashLoopBackOff 时,你在集群内起一个 Pod 跑容器版 calicoctl 是很别扭的——调度器可能因为网络问题压根调不上去。而二进制版本在宿主机上直接执行,只要能curl通 6443 端口就能工作,这个独立性在故障现场非常关键。

离线与内网环境。很多生产集群不允许节点访问外网,也不允许随便拉镜像。二进制文件可以走内部文件服务器分发,一个scp就完事,比维护一个私有镜像仓库简单得多。

自动化脚本和巡检。二进制可以被 Ansible、Shell 脚本直接调用,输出还能用-o json交给jq处理。容器方式每次都要docker run --rm -v ...,参数一长就容易写错,尤其是 kubeconfig 的挂载路径。

版本对齐的确定性。容器方式经常出现"我拉的是 latest,集群是 3.26"这种错配。二进制方式下载时版本号是写死在文件名和路径里的,反而更不容易搞混。

需要说明的是,calicoctl 对 Calico 的数据存储有两种接入模式:走 Kubernetes API(读写 CRD),或者直连 etcd(v3)。前者是现在的主流,后者主要用于非 Kubernetes 场景或者非常老的部署。下面讲的配置以 Kubernetes API 模式为主,etcd 模式我会在后面单独提一句。


2. 动手前的三项确认

安装本身只有三条命令,但装错了版本、装错了架构,后面排查的时间会远超安装省下的时间。所以在curl之前,先把这三件事确认掉。

2.1 版本对齐:client 与集群别跨大版本

calicoctl 的版本必须和集群里运行的 Calico 版本匹配。官方的说法是 client 与集群的版本需要一致,实际操作中同一个 minor 版本内的小版本差异一般能容忍,但跨 minor 就不好说了——Calico 的 API 是projectcalico.org/v3,虽然 API 版本号没变,但字段是会增删的。比如某个版本新增了某个配置项,老版本 calicoctl 读到不认识的字段可能直接报解析错误,或者更糟,写入时把不认识的字段丢掉。

先查集群版本。最直接的是看 calico-node 镜像的 tag:

kubectl get daemonset calico-node -n kube-system \ -o jsonpath='{.spec.template.spec.containers[0].image}'

输出类似calico/node:v3.26.1,那你的 calicoctl 就用v3.26.1。如果集群是用 operator 部署的,也可以看kubectl get installation default -o yaml里的spec.calicoVersion或者spec.componentVersion(不同版本字段名略有差异)。

因为是二进制安装,版本选择完全由你自己控制,所以我的做法是:把版本号写成 shell 变量,后续所有命令都引用这个变量,避免手敲出错,也方便以后批量升级。

export CALICO_VERSION="v3.26.1"

注意:不要把 calicoctl 的版本号理解成 Kubernetes 的版本号。见过有人拿 k8s 1.26 去对应 calicoctl v1.26,这个思路是错的,Calico 有自己的版本序列。

2.2 架构、OS 与权限

确认目标机器的 CPU 架构和操作系统,直接决定下载哪个文件。这一步在混合架构集群里特别容易翻车——你以为所有节点都是 amd64,结果混进来一台 ARM 的边缘设备。

uname -m

x86_64对应amd64,aarch64对应arm64,ppc64le和s390x官方也有构建。Windows 节点对应的是.exe后缀的文件,macOS 是darwin。文件名规则统一是calicoctl-<os>-<arch>,比如calicoctl-linux-amd64。

权限方面,写/usr/local/bin需要 root 或者 sudo。如果你不想用 root,可以放到~/.local/bin并确保它在 PATH 里,这在个人笔记本上很常见。但在生产节点上我建议还是放系统路径,因为排障时你往往是sudo -i切换过去的,PATH 环境和登录用户可能不一样。

另外要确认目标机器能访问 API Server。二进制 calicoctl 本身不跑在集群里,它是作为一个外部客户端去连 6443 的,所以网络策略、防火墙规则、证书 SAN 这些都要考虑进去。如果是从笔记本连生产集群,还要确认 kubeconfig 里的 server 地址在笔记本上是可达的。

2.3 离线环境的物料准备

内网环境不能直接下载,需要一台"跳板"机器中转。我一般会一次性把这几样东西准备好:

物料说明是否必需
calicoctl-linux-amd64主程序二进制必需
校验文件或哈希值校验下载完整性强烈建议
calicoctl.cfg配置文件模板必需
kubeconfig访问 API Server 的凭证必需
版本对照说明记录当前各集群 Calico 版本建议

传输方式看环境,scp、内部文件服务器、甚至 U 盘都行。有个细节:如果经过 Windows 机器中转,注意文件可能被加上.exe后缀或者被某些安全软件标记,传输完成后先file命令确认一下是 ELF 可执行文件,不是的话说明中转过程出问题了。

file calicoctl-linux-amd64 # 期望输出:ELF 64-bit LSB executable, x86-64, ...

还有一点容易被忽略:某些企业内网会对下载的可执行文件做哈希白名单,新版本二进制可能被拦截或隔离。这个事提前和负责安全的同事沟通,比装到一半发现文件被删要省事。


3. 二进制安装的完整实操

前面铺垫完了,这里进入正题。整个安装过程三步:下载、落盘赋权、写配置。

3.1 下载与完整性校验

以 Linux amd64、Calico v3.26.1 为例。下载命令用curl的-L跟随重定向,-O保留远程文件名,--fail让 HTTP 错误码直接变成命令失败,避免把一段 HTML 错误页当成二进制存下来——这个坑我踩过,存下来的文件只有几 KB,赋权执行时报"cannot execute binary file",白折腾半天。

export CALICO_VERSION="v3.26.1" export CALICO_ARCH="amd64" curl -L --fail -o calicoctl \ "https://github.com/projectcalico/calico/releases/download/${CALICO_VERSION}/calicoctl-linux-${CALICO_ARCH}"

下载完先看大小。正常应该在几十 MB 量级,如果只有几百 KB,基本可以判定下错了。

ls -lh calicoctl

然后是完整性校验。官方 releases 页面通常会提供校验信息,能拿到就对比一下:

sha256sum calicoctl

拿输出的哈希值和官方发布页给出的值逐位比对。别嫌麻烦,二进制文件是被赋予执行权限的,一旦被替换后果比丢一个配置文件严重得多。在没有官方哈希可查的环境里,我的做法是:第一次在可信网络下载后自己记录哈希,之后所有节点分发时都用这份记录比对,至少能保证"所有机器上的 calicoctl 是同一个文件"。

3.2 落盘位置与可执行权限

给文件加执行权限,然后挪到系统路径:

chmod +x calicoctl sudo mv calicoctl /usr/local/bin/calicoctl sudo chown root:root /usr/local/bin/calicoctl sudo chmod 755 /usr/local/bin/calicoctl

显式设置755而不是依赖chmod +x的结果,是为了保证所有用户可读可执行。为什么关心这个?因为有些运维脚本是用非 root 的运维账号跑的,如果权限是700,脚本执行时会报 Permission denied,而这个错误信息很容易被误认为"calicoctl 没装"。

验证一下 PATH 是否生效:

which calicoctl calicoctl --help

如果which找不到,说明/usr/local/bin不在当前用户的 PATH 里。这时候要么改 PATH,要么用绝对路径。我倾向于在排障文档里统一用绝对路径,少一层环境依赖。

如果你有几台机器要装,写个小循环更省事:

for host in node-a node-b node-c; do scp calicoctl "root@${host}:/usr/local/bin/calicoctl" ssh "root@${host}" 'chmod 755 /usr/local/bin/calicoctl && calicoctl version' done

3.3 两种 datastore 接入方式的配置

二进制装好了,但它还不知道去哪读数据。calicoctl 支持两种配置途径:命令行参数/环境变量,或者配置文件。我强烈推荐配置文件,因为参数一多就容易漏,而且写进文件的配置是可审计、可版本管理的。

默认配置文件路径是/etc/calico/calicoctl.cfg。创建目录并写文件:

sudo mkdir -p /etc/calico sudo tee /etc/calico/calicoctl.cfg > /dev/null <<'EOF' apiVersion: projectcalico.org/v3 kind: CalicoAPIConfig metadata: spec: datastoreType: "kubernetes" kubeconfig: "/root/.kube/config" EOF

这里的关键是datastoreType: kubernetes,表示走 Kubernetes API Server 读写projectcalico.org/v3这一组 CRD。kubeconfig指向你平时kubectl用的那份配置。

如果你不想用默认路径(比如多集群场景,每个集群一份配置),可以放在别处然后用--config指定:

calicoctl --config /etc/calico/prod-cluster.cfg get ippools

也可以用环境变量全替代配置文件,适合临时调试:

export DATASTORE_TYPE=kubernetes export KUBECONFIG=/root/.kube/config calicoctl get ippools

环境变量的优先级高于配置文件,这一点在做临时覆盖时要知道,否则会出现"我明明改了配置文件怎么没生效"的困惑——其实是上次 shell 里 export 的变量还在。

再说 etcd 模式,虽然现在少见,但老集群或者非 K8s 场景还会遇到。配置长这样:

apiVersion: projectcalico.org/v3 kind: CalicoAPIConfig metadata: spec: datastoreType: "etcdv3" etcdEndpoints: "https://10.0.0.10:2379" etcdKeyFile: "/etc/calico/key.pem" etcdCertFile: "/etc/calico/cert.pem" etcdCACertFile: "/etc/calico/ca.pem"

判断标准很简单:集群里kubectl get crd | grep projectcalico有输出,就用 kubernetes 模式;没有的话大概率是 etcd 直连模式。

注意:/etc/calico/calicoctl.cfg里如果写了 kubeconfig 的绝对路径,这个路径是 calicoctl 运行时去读的,不是你的 shell 去读的。如果 calicoctl 用 sudo 运行而 kubeconfig 在某个普通用户的家目录下,且家目录权限是 700,那么 root 读不到这个文件,会报 permission denied。最稳的做法是给 calicoctl 单独准备一份只读的 kubeconfig,比如放在/etc/calico/kubeconfig。

3.4 验证链路是否真的打通

装完别急着用,先做三级验证,一层层确认。

第一层,确认二进制本身能跑:

calicoctl version

这个命令不需要连集群,输出 Client Version 就说明二进制没问题。如果这一步就报错,问题一定在文件本身(架构不对、下载不完整、权限不足)。

第二层,确认能连上集群并识别版本:

calicoctl version

正常输出会包含两段信息,客户端版本和集群端版本,大致是这样:

Client Version: v3.26.1 Git commit: xxxxxxx Cluster Version: v3.26.1 Cluster Type: k8s

看到Cluster Version有值,说明 calicoctl 已经成功通过 API Server 读到了 Calico 的版本信息,链路通了。如果这一行是空的或者报错,说明配置有问题,往下看第五节。

第三层,确认能读到实际数据:

calicoctl get nodes calicoctl get ippools

get nodes返回的节点列表应该和kubectl get nodes的数量一致。如果不一致,说明有节点的 Calico 数据没同步上,这本身就是个问题信号。

get ippools会列出集群的地址池。如果你看到不止一个 pool,别急着删,先搞清楚哪个是给 Pod 用的、哪个是给隧道或者特定节点组用的,后面第 4 节会讲。

顺带提一下,calicoctl version有个--short参数,输出精简,适合塞进脚本判断。


4. 装完之后最常用的几组命令

工具装好了只是开始,真正体现价值的是日常怎么用。这一节挑几组我实际高频使用的命令,配合场景说明。

4.1 IPPool 与 IPAM 的日常管理

calicoctl get ippools -o wide是我查网络问题的第一条命令。-o wide会多显示 CIDR、封装的 IPIP/VXLAN 模式、NAT 出站开关等关键字段,比默认输出信息量大得多。

calicoctl get ippools -o wide

如果怀疑地址不够用,就看 IPAM 的整体水位:

calicoctl ipam show

输出会列出每个 IPPool 的总量、已分配、已预留、剩余。这个数字比翻 Node 的 podCIDR 靠谱得多,尤其是用了多 Pool、按节点或按机架分池的场景。

想看到块(Block)级别的分布:

calicoctl ipam show --show-blocks

每个节点会拿到若干个 Block(默认 /26,也就是 64 个地址),Block 的分配情况能帮你判断是不是某些节点占用了大量地址却没有实际使用——这在频繁创建删除 Pod 的 CI 环境里很常见,地址释放有延迟。

要单独查某个地址的状态:

calicoctl ipam show --ip=10.244.3.17

这个命令能告诉你这个 IP 属于哪个 Pool、哪个 Block、绑在哪个节点、关联的 Pod 或命名空间是什么。排查"某个 IP 被占用但找不到是谁"的时候特别有用。

需要留意的是,calicoctl ipam release这类释放命令会直接改动 IPAM 状态,用之前一定确认清楚,最好先get出来备份一份。

实操心得:定期把 IPPool 和 IPAM 状态导出存档,对于事后回溯很有帮助。一行命令的事:

calicoctl get ippools -o yaml > ippools-$(date +%F).yaml

这个习惯在我经历过一次误删 IPPool 之后就一直保持着。

4.2 节点与 BGP 会话状态

IPIP 或 BGP 模式的集群,节点间能不能通,核心看 BGP 会话。calicoctl node status是必查项,它列出本节点和其他节点的对等会话状态,Established是正常,Active、Connect、Idle都是异常。

calicoctl node status

注意这条命令的行为和前面几条不太一样,它通常需要在 Node 上本地执行(读取本地的 BGP 状态),而不是从远程通过 API 读。这个差异第一次用时很容易迷惑——在笔记本上跑可能没有输出或者报错,别急着怀疑安装有问题。

想看 BGP 的全局配置:

calicoctl get bgpconfiguration -o yaml calicoctl get bgppeers -o wide

bgpconfiguration是全局配置,bgppeers是具体的对等体。跨机架、跨可用区的集群,通常会针对性地设置peerSelector和nodeSelector,这些内容在-o yaml下才能看全。

还一个常被忽略的是节点的 AS 号。如果 AS 号配错了,BGP 会话可能压根起不来,而错误信息藏在 calico-node 的日志里,node status只告诉你 Active。查 AS 号:

calicoctl get nodes -o yaml | grep -i asnumber

4.3 声明式变更:apply、patch、delete

calicoctl 支持create、apply、replace、patch、delete几个动作,理解它们的语义差异能少踩不少坑。

  • create:只新建,已存在则报错。适合确定资源不存在的场景。
  • apply:不存在则创建,存在则合并更新。日常最常用。
  • replace:整份替换,未出现在文件里的字段会被清掉。危险,慎用。
  • patch:只改指定字段,不用提供完整对象。适合小范围调整。
  • delete:删除,配-f按文件删。

一个典型场景:给集群增加一个新的 IPPool 供特定命名空间使用。

apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: extra-pool-1 spec: cidr: 10.245.0.0/16 blockSize: 26 ipipMode: Never vxlanMode: CrossSubnet natOutgoing: true nodeSelector: "zone == 'b'"
calicoctl apply -f extra-pool.yaml

这里nodeSelector用标签选节点,标签必须先在节点上打好。blockSize: 26意味着一台节点最多能拿 1024 个地址,对于容器密度高的节点够用,对于低密度的节点会浪费。选值的时候拿预期最大 Pod 数 ÷ 64估一下,向上取整往上一个可用值。这个计算不用太精确,但方向要对——Block 太小会导致节点地址池频繁申请,太大则浪费。

需要改字段时用patch,避免整份对象重写:

calicoctl patch ippool extra-pool-1 \ -p '{"spec":{"natOutgoing":false}}'

注意:apply之前先get -o yaml备份当前状态。replace和delete之前更要备份。Calico 的这些对象删掉之后重建,名字可以一样,但内部的分配关系(比如 Block 归属)是重新算的,对已经在跑的 Pod 可能造成地址冲突。

delete一个 IPPool 时,如果里面还有已分配的地址,calicoctl 会拒绝或者给出警告,不要用--force绕过去,先确认那些地址背后的 Pod 是不是真的该重建。


5. 报错现场实录与排查思路

安装环节最容易出问题的就是配置部分。这一节按我遇到的频率排序,把典型报错和解法整理出来。

5.1 版本与 CRD 相关的报错

症状一:version能看到客户端版本,但集群版本显示为空。

这种情况通常是 datastore 配置指向了错误的集群,或者集群里根本没有 Calico 的 CRD。先确认:

kubectl get crd | grep projectcalico

正常应该有ippools.projectcalico.org、felixconfigurations.projectcalico.org、bgpconfigurations.projectcalico.org等一系列 CRD。如果一条都没有,说明这个集群压根没装 Calico(可能用的是别的 CNI),那 calicoctl 自然无从下手。

症状二:执行任何 get 命令都报解析错误,提示某个字段 unrecognized。

这是典型的 client 与 cluster 版本跨了 minor。比如集群是 v3.24,calicoctl 是 v3.26,新版本客户端读老数据可能没问题,但反过来就会出问题。解法很简单,卸掉换版本:

sudo rm -f /usr/local/bin/calicoctl # 重新下载对应版本

症状三:apply时报某个字段是必填项,但文件里明明写了。

检查 YAML 缩进。Calico 的配置对象嵌套比较深,spec下面再套spec的情况是存在的(比如 BGPConfiguration 里嵌套的nodeToNodeMeshEnabled和具体的prefixAdvertisements)。用python -m yaml或者yamllint先过一遍,比肉眼看靠谱。

5.2 权限、证书与网络连通性

症状四:Error getting cluster information: connection is unauthorized: Unauthorized。

这是 RBAC 问题。calicoctl 用的那个 kubeconfig 身份,没有读写projectcalico.org这组资源的权限。验证方法:

kubectl auth can-i get ippools.projectcalico.org --as=<你的用户>

如果输出 no,就需要补权限。生产环境不建议直接用 cluster-admin,可以绑定一个只包含 Calico CRD 的 ClusterRole。但排障时临时用高权限账号快速定位问题是可以接受的,定位完再把权限收回去。

症状五:x509: certificate signed by unknown authority或certificate is valid for ... not ...。

这跟 calicoctl 没关系,是 kubeconfig 里的证书信息有问题。前者说明 CA 不对(常见于从别处拷来的 kubeconfig),后者说明 API Server 的证书 SAN 里没有你使用的访问地址。二进制方式装在集群外的机器上时,这个错误出现得比容器方式多得多——因为你连的可能是公网地址或者 VIP,而证书只签了内网地址。

一个快速的验证方式是把 server 地址临时换成127.0.0.1:6443或者实际的节点 IP 试一下,看是不是只对某个地址报错。

症状六:dial tcp ...: i/o timeout。

网络不通。按这个顺序查:目标端口能不能通(nc -zv或curl -k https://ip:6443/healthz)、有没有防火墙规则拦截、是不是需要经过代理(注意这里指的是网络层的转发,具体策略找网络管理员确认)、kubeconfig 里的地址是不是内网地址而你在外网。

症状七:配置文件明明写了,但calicoctl好像没读到。

先确认它到底在读哪个文件:

calicoctl --config /etc/calico/calicoctl.cfg version

显式指定路径。如果显式指定后正常,说明默认路径的读取有问题,检查文件权限和是否拼错目录名。另外别忘了环境变量的覆盖优先级,env | grep -i calico看一眼有没有残留。

5.3 一张速查表

现象最可能的原因排查命令
version只有 Client 无 Clusterdatastore 配置错 / 无 Calico CRDkubectl get crd | grep projectcalico
字段解析错误client 与 cluster 版本跨 minor查 calico-node 镜像 tag
Unauthorizedkubeconfig 身份 RBAC 不足kubectl auth can-i
x509相关CA 错误或证书 SAN 不匹配换 server 地址重试
i/o timeout网络不通或防火墙nc -zv、curl -k
改了配置不生效环境变量覆盖、配置文件路径不对env | grep -i calico
node status无输出在远端执行,需本地运行到节点上执行
apply报资源已存在用了create而非apply改命令
删除 IPPool 失败池内仍有分配地址calicoctl ipam show --show-blocks

6. 长期维护视角的几点经验

装一次用几年,但有几点是长期维护中绕不开的。

6.1 升级与回滚

Calico 升级时,calicoctl 也要跟着升。顺序上我建议先升 calicoctl,再升集群组件——新版本客户端兼容老集群的概率,比老客户端兼容新集群高得多。反过来的话,在升级窗口期可能出现命令执行失败,而这时候恰恰最需要工具可用。

升级过程其实就是覆盖文件:

# 下载新版本 curl -L --fail -o calicoctl-new \ "https://github.com/projectcalico/calico/releases/download/${NEW_VERSION}/calicoctl-linux-amd64" chmod +x calicoctl-new # 备份当前版本 sudo cp /usr/local/bin/calicoctl /usr/local/bin/calicoctl.bak # 替换 sudo mv calicoctl-new /usr/local/bin/calicoctl calicoctl version

留一份bak是我固定的习惯。回滚就是mv回来,十秒钟的事。有一次升级后发现新版对某个旧字段的处理变了,导致一个巡检脚本输出格式不对,直接回滚顶到有精力改脚本为止。

6.2 把 calicoctl 纳入日常运维脚本

单独手工敲命令终究效率有限。我一般会写几个小脚本固化下来。

一个是巡检脚本,每天跑一次,输出关键指标:

#!/bin/bash echo "=== IPPool ===" calicoctl get ippools -o wide echo "=== IPAM Usage ===" calicoctl ipam show echo "=== Nodes ===" calicoctl get nodes

另一个是 IPPool 备份脚本,配合定时任务:

#!/bin/bash BACKUP_DIR=/var/backup/calico mkdir -p "$BACKUP_DIR" calicoctl get ippools -o yaml > "$BACKUP_DIR/ippools-$(date +%F-%H%M).yaml" find "$BACKUP_DIR" -name "ippools-*.yaml" -mtime +30 -delete

再给常用命令起个别名,减少敲字:

alias cctl='calicoctl' alias cpool='calicoctl get ippools -o wide' alias cipam='calicoctl ipam show --show-blocks'

注意:别名只对交互式 shell 有效,脚本里必须用完整命令。见过有人在脚本里写了cpool,然后疑惑为什么 crontab 跑不起来——crontab 的环境不加载.bashrc,别名自然不存在。

还有个小技巧:calicoctl get ... -o json配合jq能做出很灵活的过滤。比如找出所有 IPIP 模式为 Always 的 Pool:

calicoctl get ippools -o json | \ jq -r '.items[] | select(.spec.ipipMode=="Always") | .metadata.name'

这个组合在跨多个集群做配置一致性检查时特别好使,把各集群的输出抓下来对比一下,配置漂移一目了然。

最后分享一个我个人踩过的坑:曾经在一台机器上装了 calicoctl 之后,所有命令都正常,唯独apply一个很大的 YAML 文件时超时。折腾了半天发现是那台机器到 API Server 的网络链路 MTU 有问题,小请求过得去,大一点的 POST 就被分片卡住。这类问题跟 calicoctl 本身无关,但现象会误导你去怀疑工具。判断方法是用kubectl apply同一个文件做对照,如果 kubectl 也慢,那就是网络问题,别在 calicoctl 上耗时间。

RELATED READING

延伸阅读

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