摘要

在云原生架构中,传统的边界防御模型(防火墙、VPN)已不足以应对复杂的内部威胁和横向移动风险。零信任安全的核心理念是“从不信任,始终验证”。在Kubernetes环境中,NetworkPolicy(网络策略) 是实现零信任网络微隔离的核心机制。

本文将深入剖析Kubernetes网络策略的工作原理,从基础语法到高阶实战,结合CNI插件选型、Ingress/Egress双向控制、DNS策略、多租户隔离以及策略即代码(GitOps)等维度,提供一套完整的集群网络零信任落地指南。


第一章:零信任与K8s网络模型

1.1 为什么K8s需要网络策略?

默认情况下,Kubernetes 采用的是 “扁平化网络” 模型。即:集群内的所有 Pod 都可以相互通信,无论它们位于哪个命名空间或节点上。

  • 风险:一旦攻击者通过漏洞攻破一个 Pod,即可利用该 Pod 作为跳板,扫描并攻击集群内的其他微服务(横向移动)。

  • 需求:实现 微隔离,定义“谁可以访问谁”的规则。

1.2 零信任三要素在K8s中的映射

  1. 明确验证:不仅验证身份(ServiceAccount),还要验证来源(IP、端口)。

  2. 最小权限:只开放业务必需的端口和协议。

  3. 假设失陷:默认拒绝所有流量,仅放行白名单流量。


第二章:NetworkPolicy 核心原理解析

2.1 资源规范

NetworkPolicy 是 Kubernetes 的 API 对象(networking.k8s.io/v1)。它通过标签选择器(Label Selector)来定义哪些 Pod 受策略管理,并定义允许访问它们的来源(Ingress)和目标(Egress)。

2.2 关键字段详解

  • podSelector:策略生效的目标Pod组。

  • policyTypes:指定策略是 IngressEgress 还是两者兼有。如果不指定,默认只应用 Ingress

  • ingress:入站规则。

    • from:来源。

      • ipBlock:CIDR地址块。

      • namespaceSelector:选择特定的命名空间。

      • podSelector:选择特定的Pod。

  • egress:出站规则。

  • ports:目标端口和协议(TCP/UDP/SCTP)。

2.3 工作机制:CNI 的作用

NetworkPolicy 本身只是一个“配置文件”,真正的强制执行依赖 CNI 插件

  • 未安装支持策略的 CNI:创建 NetworkPolicy 对象不会报错,但策略不会生效(例如 Flannel)。

  • 支持策略的 CNI:Calico, Cilium, Weave, Antrea 等。它们通过 iptableseBPF 或 OVS 在数据平面拦截并过滤流量。


第三章:实战基础篇 —— 从“全开放”到“默认拒绝”

3.1 场景一:命名空间级隔离(默认拒绝所有入站流量)

这是实现零信任的第一步。确保每个命名空间默认是封闭的。

yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production # 目标命名空间
spec:
  podSelector: {} # 匹配该命名空间下所有 Pod
  policyTypes:
  - Ingress
  # 没有定义 ingress 规则 => 拒绝所有入站流量

注意:此策略不会影响已经建立的连接,也不影响 Egress(Pod 对外发起的连接)。

3.2 场景二:允许同命名空间内的访问

假设我们有一个前端 Pod(标签 app=frontend)和一个后端 Pod(标签 app=backend)。我们允许前端访问后端的 8080 端口。

后端策略(应用在 backend Pod 上):

yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend # 策略保护的对象
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend # 只允许带有此标签的 Pod 访问
    ports:
    - protocol: TCP
      port: 8080

3.3 场景三:跨命名空间访问(多租户)

零信任要求明确区分租户。允许 monitoring 命名空间下的 Prometheus Pod 抓取 production 命名空间下 app=backend Pod 的 metrics 端口(9100)。

yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring # 注意:namespace 的 label 是 name
      podSelector:
        matchLabels:
          app: prometheus
    ports:
    - port: 9100

关键点namespaceSelector 和 podSelector 是 “且” 的关系。上述规则的意思是:来源 Pod 必须位于 name: monitoring 的命名空间 并且 带有 app: prometheus 标签。


第四章:高级实战篇 —— 细粒度与 Egress 控制

4.1 Egress 策略:阻止数据外泄

零信任不仅防入侵,还要防数据外泄。通常需要限制 Pod 只能访问必要的集群内服务和特定的外部 API(如数据库、云元数据服务)。

场景:禁止 Pod 访问集群外互联网,仅允许访问 kube-dns 和特定的云数据库 IP。

yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-server-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  policyTypes:
  - Egress
  egress:
  # 规则1: 允许访问 kube-system 的 DNS (CoreDNS)
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
  # 规则2: 允许访问特定外部 IP (例如 RDS 数据库)
  - to:
    - ipBlock:
        cidr: 10.0.10.0/32 # 云数据库内网IP
    ports:
    - protocol: TCP
      port: 5432
  # 如果没有默认允许所有,其他所有流量(如 apt-get, curl google.com)将被拒绝

4.2 结合 DNS 策略(解决 IP 漂移问题)

在云原生环境中,外部服务通常通过域名访问,IP 经常变化。仅靠 ipBlock 难以维护。利用 Egress DNS 策略(需 CNI 支持,如 Cilium)可以实现域名粒度的访问控制。

Cilium 高级 DNS 策略示例:

yaml

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-external-api
spec:
  endpointSelector:
    matchLabels:
      app: my-app
  egress:
  - toFQDNs:
    - matchName: "api.github.com"
    - matchPattern: "*.s3.amazonaws.com"
    ports:
    - ports:
      - port: "443"
        protocol: TCP
  # 允许解析这些域名所需的 DNS 请求
  - toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchName: "api.github.com"
        - matchPattern: "*.s3.amazonaws.com"

4.3 七层策略(L7)与 四层策略(L4)的区别

  • L4 策略:标准 K8s NetworkPolicy,基于 IP、端口、协议。不关心 HTTP 路径或 Header。

  • L7 策略:需要 Service Mesh(如 Istio)或 高级 CNI(如 Cilium)。可以实现基于 HTTP Method、Path、Header 的细粒度控制。

示例(Istio AuthorizationPolicy):

yaml

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: http-bin-policy
spec:
  selector:
    matchLabels:
      app: http-bin
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/sleep"]
    to:
    - operation:
        methods: ["GET"]
        paths: ["/get"]

第五章:CNI 选型与性能考量

要实现零信任,CNI 的选择至关重要。

CNI 数据平面 策略性能 特色功能 适用场景
Calico iptables / eBPF 高 (eBPF模式) 业界标准,支持 BGP 路由,策略丰富 生产环境首选,混合云
Cilium eBPF 极高 支持 L7 策略,DNS 策略,可观测性极强 云原生高级用户,需要可观测性
Antrea OVS / eBPF VMware 主导,与 NSX 集成良好 虚拟化迁移场景
Flannel 不支持 NetworkPolicy 简单 Overlay 开发测试环境

建议:生产环境建议使用 Calico (eBPF模式) 或 Cilium。它们不仅支持 NetworkPolicy,还支持 GlobalNetworkPolicy(集群级别策略,不受命名空间限制),非常适合安全团队统一管控。


第六章:策略即代码 —— GitOps 与自动化审计

手动管理 YAML 容易出错且难以审计。应将 NetworkPolicy 纳入 GitOps 流程。

6.1 工具:np-viewer 与 Kubeshark

  • np-viewer:可视化命名空间内的策略关系。

    bash

    kubectl np-viewer --namespace production
  • Kubeshark:类似 TCPDump 的 K8s 流量抓包工具,用于验证策略是否符合预期。

6.2 工具:Cilium Hubble

如果使用 Cilium,Hubble 提供了强大的服务地图和流量监控功能,可以直观地看到哪些流量被允许,哪些被拒绝。

bash

hubble observe --from-pod default/nginx --to-pod default/backend --verdict DROPPED

6.3 策略冲突与默认策略

建议在集群初始化时,通过 Admission Controller(如 OPA Gatekeeper)强制执行以下规则:

  1. 所有命名空间必须至少有一个 default-deny-all 策略。

  2. 禁止使用 podSelector: {} 且无 namespaceSelector 的过于宽泛的策略(除非是监控组件)。

OPA 策略示例(Rego)

rego

package kubernetes.admission

deny[msg] {
    input.request.kind.kind == "NetworkPolicy"
    not input.request.object.spec.policyTypes[_] == "Ingress"
    msg := "NetworkPolicy must specify Ingress or Egress type"
}

第七章:故障排查与常见陷阱

7.1 策略未生效

  • 检查 CNIkubectl get pods -n kube-system | grep -E 'calico|cilium|weave'

  • 检查 CNI 配置:某些 CNI 默认不开启策略执行(如 Calico 需要启用 policy 资源)。

7.2 端口与协议

  • 陷阱:如果不指定 ports 字段,策略将匹配该规则下的 所有端口。这通常是危险的。

  • ICMP (ping):NetworkPolicy 默认不支持 ICMP 协议(除非 CNI 扩展)。如需允许 ping,通常需要添加 ipBlock 规则或特定 CNI 配置。

7.3 命名空间选择器的坑

很多用户混淆了 namespace 的 name 和 label

  • 错误namespaceSelector: { matchLabels: { name: kube-system } } 依赖于 Kubernetes 默认给 namespace 注入的 kubernetes.io/metadata.name 标签(v1.21+ GA)。在旧版集群中,可能需要手动给 namespace 打标签 kubectl label ns kube-system name=kube-system

7.4 双向策略

如果 Service A 需要访问 Service B,通常只需要在 Service B 上配置 Ingress 策略。但如果 Service B 需要回连 Service A(如回调),则需要在 Service A 上配置 Ingress 策略,或者确保连接是 TCP 长连接且策略是有状态的(CNI 都是 Stateful,允许响应流量通过)。


第八章:生产环境实战案例:3层防御体系

8.1 架构图简述

  • Layer 1 (全局):GlobalNetworkPolicy (Calico) 禁止所有跨节点 Pod 访问云厂商 Metadata IP (169.254.169.254)。

  • Layer 2 (租户):每个 Namespace 默认拒绝所有流量。

  • Layer 3 (应用):基于 Service Account 和 Label 的细粒度策略。

8.2 实战步骤

Step 1: 全局保护(禁止访问元数据服务)

yaml

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: block-metadata
spec:
  selector: all() # 匹配所有容器
  order: 10
  types:
  - Egress
  egress:
  - action: Deny
    destination:
      nets:
      - 169.254.169.254/32

Step 2: 命名空间初始化脚本
每次创建新命名空间时,自动应用 default-deny-all 和 allow-dns 策略。

bash

# 自动创建
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: $NAMESPACE
spec:
  podSelector: {}
  policyTypes:
  - Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: $NAMESPACE
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - port: 53
      protocol: UDP
EOF

Step 3: 应用级策略(电商示例)

  • Web Pod:允许 Ingress 来自 Ingress Controller(特定 namespace),允许 Egress 到 app=redis 和 app=db

  • DB Pod:仅允许 Ingress 来自 app=web,拒绝所有其他访问。


第九章:总结与最佳实践

9.1 核心原则

  1. 默认拒绝:在 Namespace 级别实施“默认全部拒绝”是零信任的基石。

  2. 显式允许:只开放业务必需的端口和来源。

  3. 分层防御:结合 Service Mesh(L7)与 CNI(L4)实现纵深防御。

  4. 策略即代码:所有策略必须存储在 Git 中,通过 CI/CD 自动同步,避免手动配置漂移。

9.2 未来趋势

  • eBPF 主导:Cilium 正在成为标准,它能够将网络、安全、可观测性统一到内核层。

  • 策略自动生成:利用 AI/ML 工具分析实际流量日志,自动生成最小权限策略建议(例如 Cilium 的 monitoring 和 policy-generator 特性)。


结束语

Kubernetes 的网络策略是实现云原生零信任架构最直接、最有效的工具。它改变了传统“先连接后认证”的模式,强制实施“先认证后连接”的微隔离机制。通过合理设计 CNI 选型、策略层级和自动化 CI/CD 流程,团队可以构建出具备强大弹性和安全性的云原生基础设施。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐