3. Kubernetes 网络策略(NetworkPolicy):Ingress/Egress规则、Pod选择器、命名空间隔离

Kubernetes 网络策略(NetworkPolicy)是集群内微服务间通信的“防火墙规则”。它通过标签选择器定义 Pod 组之间的访问控制,实现基于身份的零信任网络隔离。在 Helm 应用交付中,NetworkPolicy 的配置质量直接影响 eBPF 策略命中率与误报率——规则过松则安全失效,规则过紧则业务中断。

3.1 核心概念与策略模型

NetworkPolicy 采用白名单模型:未显式允许的流量默认被拒绝。策略生效范围由 podSelector 决定,规则类型分为 Ingress(入站)和 Egress(出站)。

概念 说明 典型配置
Pod 选择器 通过 label 匹配目标 Pod 组 podSelector: matchLabels: app: frontend
Ingress 规则 允许哪些来源访问目标 Pod from: - ipBlock/podSelector/namespaceSelector
Egress 规则 允许目标 Pod 访问哪些目的地 to: - ipBlock/podSelector/namespaceSelector
命名空间隔离 跨命名空间流量控制,结合 namespaceSelector namespaceSelector: matchLabels: tier: prod
策略类型 声明策略生效方向 policyTypes: [Ingress, Egress]
eBPF 视角提示: 当 NetworkPolicy 规则数量超过 100 条时,内核 iptables 规则膨胀会导致连接跟踪(conntrack)性能下降。eBPF 程序(如 Cilium)通过哈希表直接匹配策略,将 O(n) 复杂度降为 O(1),显著降低策略命中延迟。

3.2 Ingress/Egress 规则详解

3.2.1 Ingress 规则结构

Ingress 规则定义在 spec.ingress 字段中,每个条目包含 from 和 ports 子字段。以下是一个典型的三层隔离示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api-gateway
    - namespaceSelector:
        matchLabels:
          name: monitoring
      podSelector:
        matchLabels:
          app: prometheus
    ports:
    - protocol: TCP
      port: 8080

规则解析:

  • 目标 Pod:命名空间 production 中标签为 app: frontend 的所有 Pod。
  • 允许来源:同一命名空间下 app: api-gateway 的 Pod,以及 monitoring 命名空间中 app: prometheus 的 Pod。
  • 端口限制:仅允许 TCP 8080 端口。

3.2.2 Egress 规则结构

Egress 规则控制 Pod 对外发起的连接。以下示例限制 backend 服务只能访问数据库和 DNS:

spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53
误报高发区: 当 Egress 规则未包含 DNS(UDP 53)时,Pod 无法解析域名,导致业务报错。eBPF 监控中会显示大量“连接超时”事件,但实际是策略配置遗漏而非攻击行为。建议在 Egress 规则中始终保留 DNS 出口。

3.3 Pod 选择器与命名空间隔离

Pod 选择器支持三种匹配模式,组合使用可实现精细的流量隔离:

选择器类型 匹配范围 使用场景
podSelector 同一命名空间内的 Pod 微服务间东西向流量控制
namespaceSelector 跨命名空间的 Pod 多租户隔离、共享基础设施
ipBlock 集群外 IP 地址段 外部 API 访问、遗留系统对接

命名空间隔离最佳实践:

  • 使用 namespaceSelector: matchLabels: name: kube-system 允许访问集群核心组件。
  • 空选择器 namespaceSelector: {} 匹配所有命名空间,谨慎使用。
  • 结合 podSelector 与 namespaceSelector 实现“跨命名空间+指定 Pod”的精确控制。

3.4 策略命中率与误报关联分析

在 eBPF 策略审计中,NetworkPolicy 的配置质量直接影响以下指标:

指标 定义 NetworkPolicy 影响
策略命中率 被策略允许的流量占总流量的比例 规则过严导致命中率偏低,正常业务被阻断
误报率 被策略拒绝但实际为正常业务的流量比例 命名空间选择器遗漏、端口未开放是主要误报源
策略覆盖率 已配置策略的 Pod 占全部 Pod 的比例 未覆盖的 Pod 默认全通,降低整体安全水位
Helm 交付检查清单:
  1. 确认 policyTypes 字段已显式声明,避免默认行为歧义。
  2. 验证 namespaceSelector 的 label 与目标命名空间实际标签一致。
  3. 使用 kubectl describe networkpolicy 查看策略生效状态。
  4. 在 eBPF 监控中设置告警:策略拒绝事件 > 阈值时触发人工复核。

3.5 NetworkPolicy 与 eBPF 协同架构

下图展示了 NetworkPolicy 在 Kubernetes 集群中的生效路径,以及 eBPF 如何实时捕获策略命中与拒绝事件:

NetworkPolicy 与 eBPF 协同架构图 NetworkPolicy 与 eBPF 策略审计协同架构 Kubernetes API Server NetworkPolicy 对象 CNI 策略控制器 eBPF 策略引擎 Pod 工作负载 eBPF 监控采集 策略命中/拒绝日志 数据流说明: 1. 用户创建 NetworkPolicy 对象,存储于 API Server。 2. CNI 控制器监听策略变更,将规则下发至 eBPF 数据面。 3. eBPF 程序在 Pod 网络数据路径上执行策略匹配。 4. 监控采集器通过 eBPF map 读取策略命中/拒绝计数,生成审计日志。

3.6 常见误报场景与规避策略

误报场景 根因分析 eBPF 观测特征 规避方案
跨命名空间服务调用被拒 namespaceSelector 标签不匹配 目标 Pod 的 policy_verdict=deny 计数激增 使用 kubectl get ns --show-labels 核对标签
健康检查探针失败 Ingress 规则未放通 kubelet 来源 IP liveness/readiness 探针超时,Pod 重启 添加 ipBlock: 0.0.0.0/0 或节点 CIDR
DNS 解析超时 Egress 规则遗漏 UDP 53 端口 DNS 查询被 drop,应用报 NXDOMAIN 显式添加 DNS 出口规则
Helm 升级后策略冲突 多个 Chart 部署同名策略导致覆盖 策略版本号未变更,但规则内容不一致 使用 Helm 3 的 --force 或资源命名前缀
生产环境警告: 在启用 NetworkPolicy 的命名空间中,kube-system 的 DNS Pod 默认可能被隔离。务必在全局策略中放通 kube-dns 的 53 端口,否则整个命名空间将无法解析服务名。

3.7 策略生效验证与 eBPF 复核

部署 NetworkPolicy 后,建议通过以下步骤验证策略正确性:

  1. 静态验证:使用 kubectl describe networkpolicy 确认规则字段。
  2. 连通性测试:部署测试 Pod,使用 kubectl exec 执行 curl 或 nc 命令。
  3. eBPF 实时监控:通过 cilium monitor 或 bpftrace 捕获策略命中事件。
  4. 审计日志分析:收集 policy_verdict 指标,计算命中率与误报率。

以下是一个 eBPF 策略审计的典型输出片段:

# cilium monitor -t policy-verdict
Policy verdict log: flow 0x1234: TCP 10.0.1.5:34567 -> 10.0.2.10:8080, identity 123->456, verdict Denied
  Reason: Ingress rule missing for port 8080 on pod with label app=frontend
  Recommendation: Add port 8080 to existing Ingress rule or create new rule
Helm Chart 集成建议: 在 Chart 的 templates/ 目录中为每个微服务创建独立的 NetworkPolicy 模板,使用 values.yaml 控制开关。通过 helm test 运行连通性验证 Job,确保策略变更不破坏现有业务。