Calico 是 Kubernetes 生态中应用非常广泛的容器网络插件之一,它不依赖传统的二层 Overlay 网络,而是通过三层路由和 BGP 协议把每个节点的路由信息同步到整个集群。在 Debian 系统上部署 Calico 时,不少集群管理员会遇到 Pod 网络不通、跨节点访问超时、NetworkPolicy 不生效等问题。这往往不是因为 Calico 本身不稳定,而是 Debian 的内核模块、防火墙后端、网卡自动检测等细节没有配置到位。本文从实际部署角度出发,梳理 Debian 与 Calico 配合时的关键配置和排障方法。

Calico 的网络模型与 Debian 的适配点
Calico 的核心组件 Felix 运行在每个节点上,负责监听 Kubernetes API 中的网络策略和节点信息,并把规则同步到内核的路由表和防火墙中。BIRD 则负责在节点之间通过 BGP 协议交换路由,让每个节点都知道其他节点上的 Pod 网段应该从哪个节点转发。这种设计使 Calico 在数据平面可以直接使用 Linux 内核的路由转发能力,不需要额外的虚拟网桥或 VXLAN 封装,因此在吞吐量和延迟上表现很好。
当节点位于不同二层网络时,直接路由无法到达,Calico 会使用 IPIP 或 VXLAN 封装模式来跨网段传输数据包。Debian 系统默认内核通常已经包含 ipip 模块,但也有精简安装环境缺少对应模块,导致隧道接口 tunl0 无法创建。可以通过 modprobe ipip 和 lsmod | grep ipip 来确认模块是否加载。如果模块缺失,需要安装 linux-modules-extra-$(uname -r) 软件包,然后重新加载模块。另一个常见适配点是防火墙后端,Debian 12 默认使用 nftables,而部分旧版本 Calico 仍以 iptables 为主。两者共存时可能出现规则冲突,Pod 访问 Service 的流量被意外丢弃。建议在安装 Calico 前通过 update-alternatives --config iptables 确认后端一致,或者在 Calico 配置中显式指定 FELIX_IPTABLESBACKEND 参数。
Debian 的网络接口命名也可能影响 Calico 的自动检测。如果节点有多个网卡,Calico 需要确定用于 BGP 通信的 IP 地址。默认情况下它可能选错网卡,导致 BGP 邻居建立不起来。此时可以通过 IP_AUTODETECTION_METHOD 指定匹配规则,例如使用 interface=ens* 或 cidr=10.0.0.0/24 来精确选择。这个配置在 Debian 云主机和物理服务器上都能显著减少网络不稳定的情况。
在 Debian 节点上安装 Calico 的关键步骤
正式安装前需要确保 Kubernetes 集群已经初始化完成,且所有节点的 kubelet 处于运行状态。使用 kubeadm 初始化集群时,一定要指定 --pod-network-cidr 参数,例如 kubeadm init --pod-network-cidr=192.168.0.0/16。这个参数不会因为后面使用 Calico 而失效,Calico 的默认 IPPool 会与这个网段保持一致。如果初始化时没有指定,后续修改会很麻烦,需要重建节点或者手动调整 Calico 的 IPPool 配置。
Calico 官方提供两种安装方式:Operator 和 Manifest。对于大多数 Debian 环境,直接使用静态 Manifest 更加直观,也便于在安装前修改配置。可以先下载官方的 calico.yaml 文件,然后根据实际网络环境修改其中的几个关键字段。下面是一个简化的安装流程,假设 Pod 网段为 192.168.0.0/16,节点网卡前缀为 ens。
# 下载 Calico Manifest
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
# 修改 Pod 网段
sed -i 's#192.168.0.0/16#192.168.0.0/16#' calico.yaml
# 修改自动检测方式
sed -i '/name: IP_AUTODETECTION_METHOD/{n;s/value: ".*"/value: "interface=ens*"/}' calico.yaml
# 应用配置
kubectl apply -f calico.yaml执行完成后,Calico 会在 kube-system 命名空间下创建 calico-node 和 calico-kube-controllers 等 Pod。等待几分钟让所有 Pod 进入 Running 状态,再执行 kubectl get nodes 查看节点是否变成 Ready。Debian 上常见的问题是 calico-node 一直 CrashLoopBackOff,可以通过 kubectl logs -n kube-system calico-node-xxxxx 查看具体报错。如果日志中出现 ipip: unknown protocol 或 tunl0: No such device,说明内核模块没有加载,使用 modprobe ipip 即可解决。
安装完成后需要检查每个节点上的路由表,确认 Calico 已经正确插入去往其他节点 Pod 网段的路由。在任意节点执行 ip route show,应该能看到类似 192.168.1.0/24 via 10.0.0.2 dev tunl0 proto bird onlink 的条目。其中 10.0.0.2 是目标节点的真实 IP,tunl0 是 IPIP 隧道接口。如果这里出现 dev ens33 而不是 dev tunl0,说明路由没有经过封装,跨二层网络的 Pod 流量可能会在物理交换机上被丢弃,需要检查 IPPool 的 ipipMode 是否为 Always 或 CrossSubnet。
NetworkPolicy 落地与 Calico 排障命令
Calico 在 Kubernetes 中的另一个重要作用是执行 NetworkPolicy。默认情况下 Kubernetes 集群中的 Pod 之间可以互相访问,这在实际生产环境中风险较高。通过定义 NetworkPolicy,可以实现基于标签、命名空间、端口的访问控制。下面是一个常用的策略示例,它只允许带有 app=web 标签的 Pod 访问当前命名空间中的数据库服务。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-access-policy
namespace: production
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 5432这个策略提交后,Calico 的 Felix 组件会把它转换成 iptables 或 nftables 规则。验证策略是否生效,可以在不带 app=web 标签的 Pod 中尝试连接数据库端口,正常情况下应该被拒绝。需要注意的是,如果 Debian 上的防火墙后端与 Felix 预期不一致,策略可能完全不会执行。可以在 calico-node 的环境变量中检查 FELIX_IPTABLESBACKEND 的值,Debian 12 建议设置为 nft,但需要确保 Calico 版本支持 nftables 后端。较新的 Calico 版本已经默认使用 nftables,如果集群是从旧版本升级而来,可能需要重新生成 iptables 规则。
排障时最常用的工具是 calicoctl。如果还没有安装,可以通过 kubectl 插件方式运行,或者直接下载二进制文件。以下命令可以查看 IPPool 的详细信息、节点之间的 BGP 状态以及路由同步情况。
# 查看 IPPool calicoctl get ippool -o wide # 查看节点状态 calicoctl node status # 查看全部节点信息 calicoctl get nodes -o wide # 查看某个节点上的路由条目 ip route show | grep bird
在 Debian 上使用 calicoctl node status 时,如果发现 BGP 邻居一直处于 Idle 状态,大概率是节点之间的 TCP 179 端口被防火墙拦截。Debian 默认没有开启防火墙,但如果使用 ufw 或 firewalld,需要放行 179 端口。另外,如果节点分布在不同的子网,还需要确认 ipipMode 不是 Never。可以编辑 ippool 资源把 ipipMode 改为 CrossSubnet,这样同子网内仍然走直连路由,跨子网则自动启用 IPIP 封装,兼顾性能和灵活性。
当 Pod 可以访问外部网络,但无法访问 Service 的 ClusterIP 时,问题往往不在 Calico 而在 kube-proxy。Calico 只负责 Pod 网络和网络策略,Service 的负载均衡由 kube-proxy 或 eBPF 实现。如果 kube-proxy 使用 iptables 模式而 Calico 使用 nftables 后端,两者会导致规则链混乱。此时可以将 Calico 的后端改回 iptables,或者将 kube-proxy 切换为 IPVS 模式。无论哪种方案,都需要先清理旧的规则再重启相关组件,否则会出现重复 NAT 导致连接建立后无数据返回。
最后还需要关注 MTU 问题。IPIP 封装会增加 20 字节的 IP 头,VXLAN 会增加 50 字节。如果物理网卡的 MTU 是 1500,启用封装后 Pod 内部接口的 MTU 应该调整为 1480 或 1450,否则大包会被分片,而某些中间设备会丢弃分片流量。Calico 默认会自动检测 MTU,但在 Debian 上如果使用了 bond 或 vlan 子接口,自动检测可能不准确。此时可以在 calico-node 的环境变量中设置 FELIX_IPINIPMTU 或 FELIX_VXLANMTU 来显式指定。这个细节经常被忽略,但却是跨节点传输大文件时速度骤降或超时的主要原因。

