为什么Kubernetes集群需要零信任网络策略
Kubernetes默认的网络模型是”扁平互通”——同一集群内所有Pod可以直接通信,没有隔离边界。这种设计简化了开发调试,但一旦某个服务被攻陷,攻击者可以横向移动到集群内任意Pod。2026年WAIC安全分论坛上,多位安全专家指出:容器逃逸和横向移动已成为云原生环境最主要的攻击路径。NetworkPolicy是Kubernetes原生提供的网络隔离机制,配合CNI插件实现Pod级别的流量控制,是构建零信任微服务网络的基础设施。
NetworkPolicy核心概念与工作原理
NetworkPolicy定义了Pod的入站(Ingress)和出站(Egress)规则。未匹配任何NetworkPolicy的Pod默认行为取决于CNI实现——Calico和Cilium默认Allow All,而某些企业级CNI可以配置Default Deny。
# 默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
这条策略应用后,production命名空间内所有Pod的入站流量被拒绝,只有显式允许的规则才能放行。这是零信任网络的第一步:Default Deny。
微服务间流量白名单配置
典型的微服务架构中,前端API网关需要访问后端服务,后端服务需要访问数据库。每个服务的访问范围必须精确限定:
# 允许API网关访问订单服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-gateway
namespace: production
spec:
podSelector:
matchLabels:
app: order-service
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api-gateway
ports:
- protocol: TCP
port: 8080
---
# 允许订单服务访问MySQL和Redis
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-order-egress
namespace: production
spec:
podSelector:
matchLabels:
app: order-service
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: mysql
ports:
- protocol: TCP
port: 3306
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
# 允许DNS解析(必须,否则服务发现会失败)
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
一个常见踩坑点:忘记放行DNS出站规则。Kubernetes服务发现依赖CoreDNS,如果Egress默认拒绝且未放行53端口的UDP流量,所有基于Service名的访问都会失败,Pod只能通过IP通信。排查时检查Pod内nslookup是否正常即可定位。
Cilium网络策略:超越L3/L4的七层控制
原生NetworkPolicy仅支持L3(IP)和L4(端口)层过滤,无法基于HTTP路径或gRPC方法做细粒度控制。Cilium提供的CNP(Cilium Network Policy)扩展了L7能力:
# 限制订单服务只允许GET /api/orders路径
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: order-service-http-rule
namespace: production
spec:
endpointSelector:
matchLabels:
app: order-service
ingress:
- fromEndpoints:
- matchLabels:
app: api-gateway
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/orders/.*"
L7策略的代价是性能:每个HTTP请求都需要经过L7代理检查,延迟增加约0.5-1ms。对于P99延迟要求<5ms的服务,需要权衡安全粒度和性能预算。建议对高风险接口(支付、用户数据)启用L7策略,对低风险内部API保持L4策略。
跨命名空间策略与namespaceSelector
跨命名空间通信需要同时使用podSelector和namespaceSelector:
# 允许monitoring命名空间的Prometheus抓取production的指标
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus-scrape
namespace: production
spec:
podSelector:
matchLabels:
monitoring: enabled
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
注意namespaceSelector要求目标命名空间必须被正确打标。Kubernetes不会自动给命名空间添加标签,需要手动维护:
kubectl label namespace monitoring name=monitoring
如果忘记打标签,NetworkPolicy的namespaceSelector匹配不到任何命名空间,流量会被静默拒绝——不会报错,但访问不通。这是生产环境中最常见的NetworkPolicy配置失误之一。
策略审计与可视化
当集群内NetworkPolicy数量超过50条,人工检查策略是否完备已不现实。Cilium的Hubble组件提供实时流量可视化,可以直接在UI上看到被拒绝的连接:
# 启用Hubble
helm upgrade cilium cilium/cilium \
--set hubble.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.relay.enabled=true
# 查看被拒绝的流量
kubectl exec -n kube-system cilium-xxxx -- hubble observe \
--type trace:network \
--verdict DROPPED
Calico用户可以使用calicoctl的NetworkPolicy审计日志:
calicoctl get networkpolicy -A -o yaml | calicoctl audit
建议在策略上线前,先用Audit模式运行:将Default Deny策略的policyTypes设为空,不实际阻断流量,但通过日志记录”如果启用会阻断哪些连接”。观察1-2周后再正式启用。
生产环境分阶段落地路径
NetworkPolicy的落地不能一步到位,需要分阶段推进:
第一阶段:Default Deny + 关键服务白名单。仅对数据库、消息队列等高价值目标启用Ingress白名单,其余服务暂时Allow All。验证核心业务不受影响。
第二阶段:Egress管控。对出站流量添加限制,禁止Pod访问非预期外部IP。此阶段容易踩DNS坑,务必先放行DNS再收紧其他出站规则。
第三阶段:L7策略。对支付、用户数据等敏感接口添加HTTP层过滤。引入Hubble监控,持续观察拒绝事件。
第四阶段:自动化策略生成。基于Service Mesh的流量拓扑自动生成NetworkPolicy。Istio 1.22+支持从访问日志自动推导推荐策略,减少人工编写工作量。
每个阶段间隔至少2周,确保充分观察和回滚窗口。NetworkPolicy配置失误导致服务中断的案例中,超过60%发生在Egress收紧阶段,原因就是遗漏了DNS规则或健康检查端口的放行。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-wang-luo-ce-lyue-shi-zhan-ling-xin-ren-wei-fu-wu/