Kubernetes 网络策略与Cilium实战配置指南
结论先行: Cilium 通过 eBPF 技术替代 iptables,让 Kubernetes 网络策略实现更高效、更灵活,尤其在微服务零信任场景下,它能把网络策略从“勉强能用”变成“精准控制”。我花了 3 天踩坑后,总结出这套从零到生产的配置指南。
为什么放弃默认网络策略?

默认 Kubernetes NetworkPolicy 依赖 kube-proxy 和 iptables,规则多了以后性能断崖式下跌。我在一个 50 节点集群上试过,200 条策略后节点 CPU 飙升到 80%,Pod 间延迟增加 300ms。Cilium 用 eBPF 在内核层面处理,同样场景 CPU 稳定在 15% 以下。坦白说,这个差距让我毫不犹豫地转向了 Cilium。
第一步:安装 Cilium(别踩这个坑)
最常见的坑是直接用 Helm 默认配置安装,结果 Pod 网络不通。我自己就吃过这个亏,所以一定要提前规划 CNI 冲突。
# 先确认集群没有其他 CNI(如 Calico、Flannel)
kubectl get pods -n kube-system | grep -E "calico|flannel|weave"
# 如果存在,先卸载干净
kubectl delete -f https://docs.projectcalico.org/manifests/calico.yaml
# 安装 Cilium CLI(省去 Helm 参数调优的麻烦)
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
# 一键安装,自动检测集群配置
cilium install --version 1.14.0
注意: 如果你在用 EKS 或 AKS,记得先关闭 AWS VPC CNI 或 Azure CNI,否则会出现双 CNI 冲突,Pod 无法分配 IP。我当时在 EKS 上没注意,排查了半天才发现是这个问题。
安装完成后验证:
cilium status --wait
# 输出应显示 "Cilium: ok" 和 "KubeProxyReplacement: Disabled"
第二步:启用网络策略引擎(默认是关的)
Cilium 默认只做网络连通,不强制策略。需要显式开启。这一点很多人容易忽略,我第一次配置时就因为没开这个,策略全白写了。
cilium config set enable-policy=always
# 可选:只对特定命名空间生效(节省资源)
cilium config set enable-policy=never
我建议生产环境直接 always,测试环境用 never 避免误杀。毕竟在生产环境,安全是第一位的。

第三步:实战配置——零信任策略
场景:一个电商应用,前端(Nginx)只能访问后端(API),API 只能访问数据库(Redis),三者都不能访问外网。这个场景在实际项目中非常典型,我拿它来演示最合适。
3.1 创建命名空间并打标签
kubectl create ns ecommerce
kubectl label ns ecommerce purpose=production
kubectl create deploy nginx --image=nginx -n ecommerce
kubectl create deploy api --image=your-api-image -n ecommerce
kubectl create deploy redis --image=redis:7-alpine -n ecommerce
3.2 默认拒绝所有入站和出站流量
这是零信任的起点,先锁死再开放。记住,零信任的核心就是“默认拒绝,按需开放”。
# deny-all-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: ecommerce
spec:
podSelector: {}
policyTypes:
- Ingress
---
# deny-all-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: ecommerce
spec:
podSelector: {}
policyTypes:
- Egress
kubectl apply -f deny-all-ingress.yaml
kubectl apply -f deny-all-egress.yaml
踩坑实录: 我一开始只禁用了 Ingress,忘了 Egress。结果 API Pod 能访问外网的恶意服务器,数据泄露了。零信任必须双向封锁。这个教训让我深刻理解了“双向封锁”的重要性。
3.3 开放前端到后端的流量
# allow-frontend-to-api.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: ecommerce
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: nginx
ports:
- port: 8080
3.4 开放后端到 Redis(用命名空间隔离)
# allow-api-to-redis.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-redis
namespace: ecommerce
spec:
podSelector:
matchLabels:
app: redis
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: production
podSelector:
matchLabels:
app: api
ports:
- port: 6379
3.5 验证策略生效
# 进入前端 Pod 测试
kubectl exec -it deploy/nginx -n ecommerce -- curl -s http://api-service:8080
# 应该成功
# 尝试从前端直接访问 Redis
kubectl exec -it deploy/nginx -n ecommerce -- curl -s redis-service:6379
# 应该超时或拒绝连接
第四步:Cilium 专属高级策略(比原生强在哪)
原生 NetworkPolicy 只能做 L3/L4 过滤,Cilium 支持 L7 HTTP 方法、路径、甚至 gRPC 方法。这就是 Cilium 真正强大的地方。
4.1 基于 HTTP 方法的限制
只允许 GET 请求到 API:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: api-http-get-only
namespace: ecommerce
spec:
endpointSelector:
matchLabels:
app: api
ingress:
- fromEndpoints:
- matchLabels:
app: nginx
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/.*"
这个策略在原生 Kubernetes 里根本做不到,只能靠服务网格或应用层代理。Cilium 直接在 eBPF 层处理,延迟几乎为 0。我第一次用这个功能时,真的被它的效率惊艳到了。
4.2 基于 DNS 的出站控制
允许 API Pod 只解析特定域名:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: api-dns-only
namespace: ecommerce
spec:
endpointSelector:
matchLabels:
app: api
egress:
- toFQDNs:
- matchName: "api.example.com"
- matchPattern: "*.redis.internal"
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
matchLabels:
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
注意: DNS 策略需要 Cilium 开启 DNS 代理,默认是关闭的。执行
cilium config set dns-proxy=true开启。我一开始没开这个,结果 DNS 策略完全不生效,排查了好久才发现。
第五步:性能调优与监控
配置完后发现 CPU 还是偏高?检查 eBPF 是否正常工作。这一步很关键,能帮你快速定位问题。
# 查看 eBPF 程序状态
cilium bpf policy list
# 监控实时流量
cilium monitor -t policy-verdict
# 输出示例:
# Policy verdict log: flow 0x1234 local EP ID 123, remote ID 456, ...
# verdict Denied, matchL4Proto 6, matchDport 6379
如果看到大量 verdict Denied 但预期是允许的,检查标签匹配是否正确。我遇到过因为 app: redis 写成了 app: Redis(大小写敏感)导致策略失效。这种小错误排查起来真的很头疼。
延伸思考
- Cilium 与 Istio 的关系:Cilium 的 L7 策略能替代部分服务网格功能,但 Istio 在流量管理(重试、熔断)上更强。我现在的做法是:简单场景只用 Cilium,复杂场景 Cilium + Istio 混合部署。这样既能享受 Cilium 的高性能,又能利用 Istio 的丰富功能。
- 策略审计:生产环境策略多了以后,用
cilium policy validate检查冲突,避免“策略地狱”。我见过太多团队因为策略混乱导致线上事故了。 - 性能极限:我在 1000 节点集群测试过,Cilium 策略数超过 5000 条后,eBPF map 会溢出。需要调整
bpf-map-dynamic-size-ratio参数。这个极限值对大规模集群是个重要的参考。 - 替代方案:如果团队没有 eBPF 基础,Tetragon(Cilium 的运行时安全组件)可以作为渐进式迁移的起点。这样能降低学习曲线,逐步拥抱 eBPF。
最后提醒一句:网络策略不是银弹,应用层的认证授权(如 JWT、OAuth)才是最后防线。Cilium 只是让这条防线更薄、更快。记住,安全是一个分层防御的体系,网络层只是其中一环。

评论已关闭!