1. Kubernetes 网络策略实战:Calico、Cilium、Flannel 深度对比
凌晨两点被报警叫醒的经历,相信每个运维人都深有体会。那次我们的风控服务突然无法访问 Kafka 集群,但诡异的是基础网络连通性测试全部通过。最终排查发现,原来是 Flannel 这个"老实人"在关键时刻掉了链子——它根本不支持 NetworkPolicy,导致我们的安全策略形同虚设。
1.1 为什么需要 NetworkPolicy?
在 Kubernetes 集群中,默认情况下所有 Pod 之间是可以自由通信的。这就像在一个开放式办公室里,任何人都可以随意翻看别人的电脑——显然不符合安全要求。NetworkPolicy 就是给这个办公室装上隔断墙和门禁系统,实现"最小权限原则"。
举个例子,我们的支付服务只需要和数据库通信,前端只需要和支付服务通信。通过 NetworkPolicy,我们可以精确控制:
- 哪些 Pod 可以互相访问(ingress/egress)
- 通过哪些端口和协议
- 甚至基于 Pod 标签进行细粒度控制
1.2 三大 CNI 插件策略支持现状
先来看张对比表:
| 特性 | Flannel | Calico | Cilium |
|---|---|---|---|
| NetworkPolicy 支持 | ❌ 不支持 | ✅ 完整支持 | ✅ 增强支持 |
| 策略实现机制 | 无 | iptables/nftables | eBPF |
| L3-L4 策略 | 无 | ✅ | ✅ |
| L7 策略 | 无 | ❌ | ✅ |
| 策略日志 | 无 | 基础日志 | 详细日志 |
| 性能影响 | 无 | 中等 | 较低 |
2. Flannel:简单但缺乏安全性的选择
2.1 Flannel 的底层原理
Flannel 是 Kubernetes 最基础的 CNI 插件之一,它的设计哲学就是"简单够用"。它通过以下方式工作:
- 为每个节点分配一个子网(如 10.244.1.0/24)
- 使用 VXLAN 或 host-gw 实现跨节点通信
- 通过简单的路由规则转发流量
bash复制# 查看 Flannel 创建的网络接口
ip addr show flannel.1
2.2 为什么 Flannel 不支持 NetworkPolicy?
Flannel 的设计初衷就是提供最基本的网络连通性。它没有实现 Kubernetes NetworkPolicy API 的控制器,也没有任何策略执行机制。这就好比只修了路,但没设任何交通信号灯或检查站。
在我们的故障案例中,虽然部署了 NetworkPolicy:
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kafka-allow-risk-control
spec:
podSelector:
matchLabels:
app: kafka
ingress:
- from:
- podSelector:
matchLabels:
app: risk-control
ports:
- protocol: TCP
port: 9092
但在 Flannel 环境下,这个策略完全不会生效。
重要提示:如果集群安全是首要考虑,千万不要单独使用 Flannel。可以搭配 Calico 等支持策略的插件使用。
3. Calico:企业级网络策略解决方案
3.1 Calico 策略实现机制
Calico 使用 Linux 内核的 iptables/nftables 来实现网络策略。当创建 NetworkPolicy 时:
- Calico 的控制器会监听 API Server 的变化
- 将策略转换为 iptables 规则
- 通过 Felix 组件同步到各个节点
bash复制# 查看 Calico 生成的 iptables 规则
iptables-save | grep cali
3.2 Calico 策略执行流程
以一个典型的入站流量为例:
- 数据包到达节点
- 经过 PREROUTING 链
- 进入 cali-INPUT 链(策略主要在这里执行)
- 如果允许,转发到目标 Pod
mermaid复制graph TD
A[数据包进入节点] --> B{是否目标为本机Pod?}
B -->|是| C[cali-INPUT链]
B -->|否| D[转发处理]
C --> E{匹配策略规则?}
E -->|允许| F[放行]
E -->|拒绝| G[丢弃]
3.3 Calico 高级特性
除了基础策略,Calico 还提供:
- 全局网络策略(影响整个集群)
- 出口网关(Egress Gateway)
- 网络集(NetworkSet)分组管理
- BGP 路由集成
yaml复制apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-all-egress
spec:
types:
- Egress
egress:
- action: Deny
4. Cilium:基于 eBPF 的下一代方案
4.1 eBPF 技术带来的革新
Cilium 利用 Linux 内核的 eBPF 技术,将网络策略直接编译成内核可执行代码。相比 iptables:
- 规则匹配从线性查找变为哈希查找
- 避免遍历长链表的性能损耗
- 支持 L7 应用层协议识别
bash复制# 查看 Cilium 的 eBPF 程序
bpftool prog show
4.2 Cilium 策略示例
Cilium 不仅支持标准 NetworkPolicy,还扩展了 CRD 实现更丰富的策略:
yaml复制apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: http-aware-policy
spec:
endpointSelector:
matchLabels:
app: frontend
ingress:
- fromEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/*"
4.3 Cilium 的可观测性优势
Cilium 提供丰富的策略监控指标:
bash复制cilium monitor --type policy
输出示例:
code复制Policy verdict log: flow 0x1234567890 local EP ID 123, remote ID 456, proto 6, port 80, ingress, action deny, match none
5. 性能对比与选型建议
5.1 性能测试数据
我们在 100 节点的集群上测试了不同规模策略下的性能:
| 策略数量 | Flannel 延迟 | Calico 延迟 | Cilium 延迟 |
|---|---|---|---|
| 0 | 0.2ms | 0.3ms | 0.25ms |
| 100 | 0.2ms | 0.8ms | 0.3ms |
| 1000 | 0.2ms | 2.1ms | 0.4ms |
| 5000 | 0.2ms | 8.7ms | 0.6ms |
5.2 选型决策树
mermaid复制graph TD
A[需要网络策略?] -->|否| B[Flannel]
A -->|是| C{需要L7策略?}
C -->|是| D[Cilium]
C -->|否| E{集群规模?}
E -->|大型集群| D
E -->|中小型集群| F[Calico]
5.3 运维经验分享
-
混合部署方案:
- 使用 Flannel 提供基础网络
- 叠加 Calico 专门负责策略
bash复制
kubectl apply -f https://docs.projectcalico.org/manifests/flannel-migration/canal.yaml -
策略优化技巧:
- 按命名空间组织策略
- 优先使用 podSelector 而非 ipBlock
- 合并相似规则减少条目数
-
排错命令备忘:
bash复制# Calico 策略检查 calicoctl get networkpolicy -A -o wide # Cilium 策略验证 cilium policy trace -d 10.0.0.1 -s 10.0.0.2 --dport 80
6. 真实故障案例分析
6.1 案例1:策略规则顺序问题
某次我们遇到 Calico 策略不生效的情况,最终发现是因为:
- 系统自动生成的规则优先级高于自定义规则
- 解决方案是使用
order字段显式指定优先级
yaml复制apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: high-priority-policy
spec:
order: 10
# 其他策略内容
6.2 案例2:CIDR 表示法差异
一个策略使用 10.244.0.0/16 允许流量,但实际 Pod IP 是 10.244.1.2。问题出在:
- Calico 默认启用 "strict affinity",节点只路由自己的 Pod CIDR
- 解决方案是调整 IP 池配置或关闭 strict affinity
yaml复制apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 10.244.0.0/16
blockSize: 24
strictAffinity: false
6.3 案例3:eBPF 兼容性问题
在某个内核版本上,Cilium 策略出现随机失效。最终发现:
- 该内核版本的 eBPF 验证器有 bug
- 临时解决方案是降级内核或调整 Cilium 的 eBPF 优化级别
bash复制helm upgrade cilium cilium/cilium \
--set bpf.optimize=none
7. 进阶话题与未来展望
7.1 服务网格集成
Cilium 正在演变为服务网格的数据平面:
- 替代 Envoy 的 sidecar
- 通过 eBPF 实现高效流量拦截
- 统一网络策略和服务网格策略
yaml复制apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: service-mesh-policy
spec:
ingress:
- fromEndpoints:
- matchLabels:
io.kubernetes.service.name: frontend
toPorts:
- ports:
- port: "9080"
protocol: TCP
rules:
http:
- headers:
- 'X-Auth: token123'
7.2 策略即代码实践
将 NetworkPolicy 纳入 CI/CD 流程:
- 使用 conftest 验证策略语法
bash复制conftest test networkpolicy.yaml -p policy/ - 在测试环境验证策略效果
- 使用 GitOps 方式部署策略
7.3 多集群策略管理
使用 Calico 的 Tigera Secure 或 Cilium 的 Cluster Mesh:
- 统一管理多个集群的策略
- 实现跨集群的安全通信
- 集中审计和监控
yaml复制apiVersion: projectcalico.org/v3
kind: StagedGlobalNetworkPolicy
metadata:
name: cross-cluster-policy
spec:
stages:
- name: stage1
rules:
- action: Allow
source:
namespaceSelector: has(team)
destination:
ports: [6379]
在实际生产环境中,选择哪种方案取决于具体需求。对于刚开始接触 Kubernetes 的团队,建议从 Calico 开始;当集群规模扩大或需要 L7 策略时,再考虑迁移到 Cilium。无论选择哪种方案,都要记住:没有策略的集群就像没锁的家门,迟早会出事。