在K8S中,网络策略有哪些?

在 Kubernetes 中,网络策略(NetworkPolicy) 本身是一个具体的 API 对象(kind: NetworkPolicy),用于定义访问控制规则。严格来说,“有哪些”指的是不同类型的 NetworkPolicy 规则配置方式,而非多个独立策略类型。这些规则通过组合以下关键元素实现不同场景的流量管控:


一、核心策略规则类型(按流量方向)

  1. 入站规则 (ingress)
    控制哪些来源可以访问目标 Pod(白名单)。
    核心字段 from

    • podSelector:允许同一 Namespace 内匹配标签的 Pod 访问。
      ingress:
        - from:
            - podSelector:
                matchLabels:
                  app: frontend
      
    • namespaceSelector:允许指定 Namespace(匹配标签)中所有 Pod 访问(可跨 Namespace)。
      ingress:
        - from:
            - namespaceSelector:
                matchLabels:
                  env: prod
      
    • ipBlock:允许特定 IP 段(如外部服务或集群外 IP)访问。
      ingress:
        - from:
            - ipBlock:
                cidr: 192.168.1.0/24
      
    • 组合使用:允许多种来源(例如同时允许来自 frontend Pod 和 prod Namespace 的流量)。

    端口限制 (ports)

    • 指定允许访问的端口(如 TCP 80),不指定则允许所有端口。
  2. 出站规则 (egress)
    控制目标 Pod 可以访问哪些外部资源(白名单)。
    核心字段 to

    • podSelector / namespaceSelector / ipBlock:与 ingress 类似,定义可访问的目标
      端口限制 (ports)
    • 限制目标端口(如仅允许访问 DNS 的 UDP 53)。
    egress:
      - to:
          - ipBlock:
              cidr: 8.8.8.8/32
        ports:
          - protocol: UDP
            port: 53
    

二、常见策略场景示例

1. 完全隔离 Namespace

拒绝所有入站流量,仅允许同 Namespace 内 Pod 通信:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}  # 作用于当前 Namespace 所有 Pod
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - podSelector: {}  # 仅允许同 Namespace 内的 Pod 访问

2. 仅允许特定 Pod 访问数据库

db Pod 仅允许来自 app=backend 的 Pod 访问 3306 端口:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-db-access
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: backend
      ports:
        - protocol: TCP
          port: 3306

3. 禁止 Pod 访问公网

限制 app: internal 的 Pod 禁止所有出站流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector:
    matchLabels:
      app: internal
  policyTypes: ["Egress"]
  egress: []  # 无规则表示禁止所有出站流量

4. 仅允许访问特定外部服务

仅允许 monitoring Pod 访问 Prometheus 服务(如 1.2.3.4:9090):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus
spec:
  podSelector:
    matchLabels:
      app: monitoring
  egress:
    - to:
        - ipBlock:
            cidr: 1.2.3.4/32
      ports:
        - protocol: TCP
          port: 9090

三、高级策略能力(依赖 CNI 插件)

⚠️ 以下功能需特定 CNI 插件支持(如 Calico、Cilium)

  1. 基于 DNS 的出站规则
    允许按域名(而非 IP)控制访问(如仅允许访问 *.example.com):

    # 示例:Calico 扩展策略
    egress:
      - to:
          - domains: ["*.example.com"]
    
  2. 策略层级继承
    在命名空间级别设置默认策略(如 Namespace 级默认拒绝规则)。

  3. 服务账户(ServiceAccount)匹配
    允许基于 Pod 关联的 ServiceAccount 定义规则:

    ingress:
      - from:
          - serviceAccountSelector:
              matchLabels:
                name: api-service-account
    
  4. 协议级控制(如 ICMP)
    允许/禁止特定网络层协议(需插件支持):

    ingress:
      - protocols: ["ICMP"]
    

四、关键使用原则

  1. 默认拒绝(Zero Trust)

    • 未匹配任何策略的 Pod 允许所有流量(传统模式)。
    • 一旦 Pod 被策略选中,则遵循 “默认拒绝,显式允许” 规则。
  2. 策略叠加(Additive)
    多个策略同时作用于同一 Pod 时,规则取 并集(OR 关系)。

  3. 依赖 CNI 插件

    • 必须使用支持 NetworkPolicy 的 CNI(如 Calico、Cilium、Weave Net)。
    • 基础网络插件(如 Flannel)不支持策略功能

总结

Kubernetes 网络策略的本质是通过 ingress(入站)和 egress(出站)规则,基于 标签选择器(podSelector/namespaceSelector)和 IP 段(ipBlock 实现流量管控。核心场景包括:

  1. 隔离 Namespace/Pod
  2. 保护敏感服务(如数据库)
  3. 限制出站流量(如禁止公网访问)
  4. 精细化外部服务访问控制

实际策略能力取决于底层 CNI 插件,生产环境中建议选择 CalicoCilium 等高级插件以支持复杂场景(如 DNS 规则、服务账户匹配等)。

posted @ 2025-08-16 20:13  天道酬勤zjh  阅读(12)  评论(0)    收藏  举报