第280篇:云原生网络策略 NetworkPolicy 实现

关键词:NetworkPolicy、Kubernetes、网络策略、Calico、Cilium、Iptables、eBPF、安全组


一、引言

Kubernetes NetworkPolicy是K8s原生的网络安全策略API,用于控制Pod之间的网络访问权限。NetworkPolicy本身只是一个API规范,其实际执行依赖于CNI插件的数据面实现。

本文将深入解析NetworkPolicy的工作原理、不同CNI插件的实现差异,以及在实际生产环境中的最佳实践。

二、核心概念

2.1 NetworkPolicy API

NetworkPolicy的核心字段:

字段 说明
podSelector 选择策略应用的Pod
ingress 入站规则列表
egress 出站规则列表
policyTypes 策略类型(Ingress/Egress)
namespaceSelector 选择源/目的命名空间

规则匹配元素:

元素 说明
podSelector 匹配Pod标签
namespaceSelector 匹配命名空间标签
ipBlock 匹配CIDR地址段
ports 匹配端口和协议

2.2 NetworkPolicy 匹配逻辑

NetworkPolicy的匹配规则:

条件 匹配逻辑
多个ingress规则 任一规则匹配即允许(OR)
规则内的多个from 任一from匹配即允许(OR)
from内的多个条件 满足任一条件即匹配(OR)
无ingress规则 拒绝所有入站流量
policyTypes不含Ingress 不限制入站流量

NetworkPolicy 匹配逻辑 - 图示

2.3 不同 CNI 的实现差异

CNI 数据面 实现方式 L4支持 L7支持
Calico(Iptables) Iptables 每个Pod生成iptables规则 ✓ ✗
Calico(eBPF) eBPF eBPF程序+Map ✓ ✗
Cilium eBPF 原生eBPF策略引擎 ✓ ✓
OVS OpenFlow OVS流表 ✓ ✗
kube-router Iptables iptables规则 ✓ ✗

2.4 NetworkPolicy 与 安全组对比

特性 云安全组 K8s NetworkPolicy
粒度 实例级 Pod级
选择器 IP/安全组 Pod标签/命名空间标签
状态检测 有(状态型) 有(有状态策略)
L7策略 不支持 Cilium支持
动态更新 API K8s API
默认策略 云厂商定义 取决于CNI

三、技术细节

3.1 Calico Iptables 模式实现

Calico在iptables模式下,为每个Pod生成两条iptables链:

FORWARD链处理流程:

Calico Iptables 模式实现 - 图示

3.2 Calico eBPF 模式实现

Calico的eBPF模式使用eBPF程序替代iptables:

组件 说明
CNI插件 创建veth pair, 加载eBPF程序
eBPF TC程序 挂载到veth的ingress/egress
Policy Map eBPF Map存储策略规则
Identity 每个Pod分配唯一的Security Identity

3.3 Cilium 原生实现

Cilium的eBPF原生实现是最为高效的:

特性 说明
端点标识 每个Pod分配唯一的Security ID
eBPF程序 直接在内核网络栈执行策略检查
L7策略 基于eBPF Socket程序实现HTTP/gRPC过滤
策略编译 策略编译为高效的eBPF字节码

3.4 NetworkPolicy 有状态策略

有状态(Stateful)策略:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: stateful-web-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: client
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
    ports:
    - protocol: TCP
      port: 443
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53

3.5 策略即代码(Policy as Code)

将NetworkPolicy纳入GitOps工作流,实现策略的版本管理和自动化部署:

策略即代码(Policy as Code) - 图示

GitOps策略管理流程:

步骤 工具 说明
编写策略 编辑器 YAML格式NetworkPolicy
语法校验 kubeval/kubeconform 检查YAML语法和API版本
策略模拟 Cilium NP Simulator 模拟策略效果, 预览允许/拒绝的流量
冲突检测 kubectl-np-viewer 检测策略冲突和重叠
代码审查 Git PR Review 团队审核策略变更
自动部署 ArgoCD/Flux GitOps控制器自动同步到集群

3.6 NetworkPolicy 可视化与调试

工具 功能 特点
kubectl-np-viewer NetworkPolicy可视化 生成HTML拓扑图
Cilium Hubble 流量观察和策略调试 实时流日志, 服务拓扑
Calico CLI 策略查询和调试 calicoctl get networkpolicy
Cyclonus 默认拒绝策略批量部署 一键部署default-deny
Network Policy Editor 在线策略编辑器 图形化编辑NetworkPolicy

Cilium Hubble调试示例:

# 1. 观察特定Pod的入站流量
hubble observe --pod app-pod --protocol tcp --verdict forwarded

# 2. 观察被策略拒绝的流量
hubble observe --verdict dropped --reason policy_DENIED

# 3. 生成服务依赖图
hubble lens graph --json

# 4. 查询特定流量路径
hubble flow get --source-pod app-pod --destination-pod db-pod

# 5. 查看策略覆盖率
hubble status

3.7 NetworkPolicy 与 外部防火墙协同

协同维度 NetworkPolicy 外部防火墙 协同策略
作用范围 Pod间(L3/L4) 集群边界(L3-L7) 分层防御
granularity Pod级 IP/端口级 内外互补
策略管理 K8s API 防火墙管理台 统一策略平台
审计 K8s审计日志 防火墙日志 集中日志分析
故障隔离 Pod间隔离 南北向隔离 全向防护

四、实战配置/案例分析

4.1 完整的租户网络策略模板

# 1. 默认拒绝所有入站和出站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: tenant-a
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
# 2. 允许同命名空间内通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-ns
  namespace: tenant-a
spec:
  podSelector: {}
  ingress:
  - from:
    - podSelector: {}
  policyTypes:
  - Ingress
---
# 3. 允许DNS解析
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: tenant-a
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
  policyTypes:
  - Egress
---
# 4. 允许Ingress访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ingress-nginx
  policyTypes:
  - Ingress

4.2 故障案例:NetworkPolicy Egress规则遗漏导致应用异常

现象:某应用Pod无法连接外部API服务,但同命名空间内的其他Pod通信正常。

排查过程:

# 1. 检查NetworkPolicy
kubectl get networkpolicy -n app-ns
# 存在default-deny策略和有限的egress规则

# 2. 从Pod测试外部连接
kubectl exec app-pod -- curl https://api.external.com/data
# 连接超时

# 3. 检查egress规则
kubectl get networkpolicy -n app-ns -o yaml
# egress规则只允许DNS(UDP 53)和内部K8s服务
# 没有放行HTTPS(TCP 443)到外部地址的规则

# 4. 添加egress规则
kubectl apply -f external-api-egress.yaml

根因:NetworkPolicy的egress规则配置不完整,只放行了DNS和内部K8s服务的流量,未放行到外部API的HTTPS流量。

解决: 1. 添加egress规则放行外部API的HTTPS流量 2. 建议在NetworkPolicy模板中包含常见的egress规则(DNS、HTTP/HTTPS、NTP等) 3. 使用kubectl-np-viewer等可视化工具审计NetworkPolicy

4.3 故障案例:Calico策略链性能下降

现象:当集群中NetworkPolicy数量超过1000条时,Pod间通信延迟明显增加。

排查过程:

# 1. 检查iptables规则数量
iptables -L -n | wc -l
# 规则数超过5000条

# 2. 检查Calico策略链长度
iptables -S CALICO-FORWARD | wc -l
# 策略链非常长

# 3. 分析性能瓶颈
# Iptables模式需要线性遍历所有规则
# 规则越多, 匹配时间越长

# 4. 切换到Calico eBPF模式
# 升级Calico到支持eBPF的版本
# 配置CALICO_DATASTORE_TYPE=kubernetes
# 配置FELIX_BPFENABLEDTYPE=Fat

根因:Calico的iptables模式需要线性遍历策略链,当NetworkPolicy数量众多时,每条报文的策略检查时间线性增加,导致延迟上升。

解决: 1. 迁移到Calico eBPF模式,利用哈希查找替代线性遍历 2. 精简NetworkPolicy规则,减少不必要的策略 3. 使用命名空间级别的默认策略,减少Pod级别的细粒度策略

五、总结

CNI实现 数据面 性能 L7支持 推荐场景
Calico Iptables iptables 中(规则多时下降) ✗ 中小集群
Calico eBPF eBPF 高 ✗ 大规模集群
Cilium eBPF 最高 ✓ 微服务/L7需求
OVS OpenFlow 中 ✗ OVS环境
最佳实践 说明
默认拒绝 始终部署default-deny策略
最小权限 只开放必要的端口和地址
策略分层 命名空间级+Pod级策略结合
定期审计 使用可视化工具审计策略
eBPF优先 大规模集群使用eBPF数据面
策略即代码 GitOps管理策略变更
策略模拟 部署前使用模拟器验证策略效果

思考

  1. NetworkPolicy只能控制L3/L4流量,如何控制L7(HTTP/gRPC)级别的访问权限?
  2. NetworkPolicy的podSelector: {}(空选择器)匹配什么Pod?与不指定podSelector有什么区别?
  3. 如果集群中同时存在多个NetworkPolicy匹配同一个Pod,它们之间如何交互?
  4. 策略即代码(Policy as Code)模式下,如何避免策略变更导致业务中断?
  5. Cilium Hubble如何帮助调试NetworkPolicy?与传统的tcpdump抓包相比有什么优势?

下篇预告:第281篇:华为 CloudFabric 数据中心方案简介