Calico:生产环境运维与排障
第一部分:Calico 的可观测性 - 监控与告警
一个无法被观测的系统,就是一个黑盒。幸运的是,Calico 组件(尤其是 calico-node
)暴露了大量丰富的 Prometheus 格式的指标,能让我们清晰地看到其内部的运行状态。
SRE 需要关注的关键 Prometheus 指标:
- Felix 指标 (规则执行):
felix_active_local_endpoints
: 节点上活跃的 Calico 端点(通常是 Pod)数量。felix_iptables_restore_failures
,felix_iptables_save_failures
: Felix 更新iptables
规则失败的次数。任何非零值都应触发高优先级告警,因为它意味着网络策略可能没有被正确应用。felix_policy_active
: 节点上当前生效的网络策略数量。
- BGP 指标 (如果使用 BGP 模式):
calico_bgp_peers_num_up
,calico_bgp_peers_num_down
: 已建立的和已断开的 BGP 对等体(Peer)会话数量。calico_bgp_peers_num_down > 0
是一个需要立即关注的严重问题。
- IPAM 指标 (IP 地址管理):
calico_ipam_addrs_per_pool
: 每个 IP 地址池中的总地址数。calico_ipam_addrs_in_use
: 已分配的地址数。calico_ipam_pool_utilization
: (通常由(in_use / total) * 100
计算得出) IP 池利用率。这是进行容量规划和预警的核心指标。
关键告警:
- 集群健康:
calico-node
(DaemonSet) 或calico-typha
(Deployment) 的可用副本数低于期望值。 - BGP 状态 (BGP 模式):
calico_bgp_peers_num_down > 0
持续 N 分钟。 - 规则编程:
rate(felix_iptables_restore_failures[5m]) > 0
。 - IP 地址池:
calico_ipam_pool_utilization > 85%
(警告),> 95%
(紧急)。
第二部分:瑞士军刀 - calicoctl
命令行工具详解
calicoctl
是与 Calico 集群交互、进行诊断和管理的最核心的命令行工具。SRE 必须熟练掌握它。
- 安装与配置: 你可以在本地安装
calicoctl
二进制文件,并配置它连接到你的集群数据存储(Kubernetes API 或 etcd)。一个更快捷的方式是直接在calico-node
Pod 内部执行它。
核心排障命令:
calicoctl node status
:
- 用途: 排查节点间连通性的第一步。它会显示当前节点与其他所有 Calico 节点的 BGP 对等体会话状态。
- 输出 (BGP 模式):
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+------------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+-------------------+-------+------------+-------------+
| 172.18.0.2 | node-to-node mesh | up | 2025-07-25 | Established |
| 172.18.0.4 | node-to-node mesh | up | 2025-07-25 | Established |
+---------------+-------------------+-------+------------+-------------+
- 解读:
STATE
列应为up
,INFO
列应为Established
。任何其他状态(如Active
,Connect
)都表明 BGP 会话存在问题。
calicoctl get <resource>
:
- 用途: 以 YAML 或 JSON 格式查看 Calico 的自定义资源。
- 示例:
calicoctl get ippool -o yaml
: 查看 IP 地址池的配置。calicoctl get globalnetworkpolicy -o yaml
: 查看全局网络策略。calicoctl get hostendpoint -o yaml
: 查看主机端点。
calicoctl ipam show
:
- 用途: 排查 IP 地址分配 (IPAM) 问题的首选命令。
- 输出:
+----------+----------------+-----------+------------+-------------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+----------------+-----------+------------+-------------------+
| IP Pool | 192.168.0.0/16 | 65536 | 128 (0%) | 65408 (100%) |
+----------+----------------+-----------+------------+-------------------+
--show-blocks
标志: 使用calicoctl ipam show --show-blocks
可以看到每个 IP 地址块 (Block) 被分配给了哪个节点。这对于诊断“为什么某个节点无法再分配新的 Pod IP”至关重要。
calicoctl node diags
:
- 用途: 收集一个节点上与 Calico 相关的所有诊断信息,包括日志、进程状态、路由表、iptables 规则、Calico 资源状态等,并打包成一个
.tar.gz
文件。 - 用法: 当你需要寻求社区帮助或向 Tigera (Calico 的商业公司) 提交支持工单时,这个命令极其有用。
第三部分:常见问题排障场景
场景一:Pod 启动失败,长时间处于 ContainerCreating
- 症状:
kubectl describe pod
的事件中显示 "failed to set up pod network: CNI plugin failed..." 或类似的 CNI 错误。 - 排障流程:
- 第一步:看 Kubelet 日志: 登录到 Pod 所在的节点,查看
kubelet
的日志,通常会包含 CNI 插件返回的更详细的错误信息。journalctl -u kubelet
- 第二步:看
calico-node
日志: 这是最有可能发现问题的地方。kubectl logs -n calico-system calico-node-xxxxx
,查找与失败的 Pod 相关的错误日志。 - 第三步:检查 IPAM: 运行
calicoctl ipam show
。是不是整个 IP 地址池都用完了?或者运行calicoctl ipam show --show-blocks
,查看该节点是否已经没有可用的 IP 地址块了? - 第四步:检查 CNI 配置: 在节点上检查
/etc/cni/net.d/
目录下的 CNI 配置文件是否正确,以及calico-cni
的二进制文件是否存在于/opt/cni/bin
。
场景二: 不同节点的Pods无法通信
- 症状: 同一节点上的 Pod 可以互相通信,但跨节点的 Pod 无法通信。
- 排障流程:
- BGP 模式:
- 检查 BGP 会话:
calicoctl node status
。确保所有节点间的会话都是Established
。如果不是,检查节点间的网络连通性(ping
),以及是否有防火墙阻止了 BGP 的 TCP 端口(默认 179)。 - 检查路由表: 登录源节点和目标节点,使用
ip route
查看。源节点是否有到达目标 Pod IP 网段的路由?下一跳是否正确指向了目标节点?
- 覆盖网络模式 (IPIP/VXLAN):
- 检查网络封装协议: 检查节点间的防火墙是否允许 IPIP 协议(IP 协议号 4)或 VXLAN 的 UDP 端口(默认 4789)。
- 检查隧道接口: 在节点上使用
ip a
,查看tunl0
(IPIP) 或vxlan.calico
(VXLAN) 接口是否存在且处于UP
状态。
- 检查
NetworkPolicy
: 是否有一条(可能是GlobalNetworkPolicy
)意料之外的网络策略阻止了这些流量?(见下一场景)。
场景三:NetworkPolicy
不按预期工作
- 症状: 应该被允许的流量被拒绝了,或者应该被拒绝的流量被允许了。
- 排障流程:
- 标签!标签!标签!: 这是最最最常见的错误。请仔细、反复地核对:
- 策略的
podSelector
是否精确地选中了你想要保护的 Pod? - 规则的
from
/to
部分,其podSelector
和namespaceSelector
是否精确地选中了你想要允许的流量源/目的地? kubectl get pod <name> --show-labels
和kubectl get ns <name> --show-labels
是你的好朋友。
- 检查策略的
order
(顺序): 如果你同时使用了 Calico 的NetworkPolicy
或GlobalNetworkPolicy
,记住数字小的order
优先级更高。是不是有一条更高优先级的策略(例如,一条全局拒绝策略)覆盖了你的允许规则? - 检查策略的
types
字段: 你是否忘记了在policyTypes
中同时声明Ingress
和Egress
?如果只声明了Ingress
,那么该 Pod 的所有出向流量都会被拒绝(如果它被策略选中)。 - 最终的真相来源: 如果还是无法解决,可以使用
calicoctl node diags
收集诊断包,解压后查看其中的iptables-save
文件,这里面包含了 Felix 在内核中编程的、最原始的iptables
规则。虽然阅读起来很复杂,但它能告诉你策略最终被翻译成了什么。
总结与系列收官
今天,我们为 Calico 的学习之旅画上了圆满的句号。我们不再仅仅是 Calico 的使用者,更成为了它的“运维官”和“诊断医生”。我们学习了需要监控哪些核心指标,掌握了calicoctl 这把瑞士军刀的用法,并对几个最常见的生产问题建立了系统性的排障思路。