配置集群网络政策

借助 ClusterNetworkPolicy,您可以为整个集群定义全局 GKE 安全态势。本文档面向需要强制执行强制性安全措施或建立零信任基准的集群管理员。

此资源依赖于严格的评估层次结构,该层次结构比标准命名空间范围的 NetworkPolicy 资源具有更高的优先级。您可以使用 ClusterNetworkPolicy资源实现显式拒绝接受通过操作。借助这些操作,您可以配置全局允许或拒绝政策,将流量控制委托给特定命名空间,并将出站流量限制为 CIDR 块。

准备工作

在配置集群网络政策之前,请确保满足以下要求:

  1. 确保您的 GKE 集群运行的是 1.36.0-gke.4447000 或更高版本。
  2. 确保您的集群使用 GKE Dataplane V2。

支持的协议和端口

ClusterNetworkPolicy 规则可以根据 TCP、UDP 或 SCTP 协议匹配流量。 您可以通过以下方式指定目标端口:

  • 特定端口号:使用 destinationPort.number 设置来指定 单个端口(例如 80)。
  • 端口范围:使用 destinationPort.range 设置来指定一系列 端口(例如 80009000)。
  • 已命名端口:使用 destinationNamedPort 设置来指定 Pod 规范中定义的符号 名称。

政策评估层次结构

与标准的附加式 NetworkPolicy 不同,ClusterNetworkPolicy (CNP) 依赖于严格的评估层次结构,其中第一个匹配的规则获胜。流量按顺序流经三层流水线:

  • 层级:管理员规则首先执行,然后级联到 NetworkPolicy, 最后到基准。
  • CNP 优先级:在层级内,政策根据其 显式数字优先级进行评估。
  • CNP 规则顺序:在单个政策内,规则像访问权限控制列表 (ACL) 一样 从上到下处理。

显示 GKE 网络政策评估层次结构的示意图

上图说明了 CNP 评估层次结构的决策流程:

  1. 管理员层级:首先根据 ClusterNetworkPolicy规则评估Admin层级中的流量。如果存在“允许”或“拒绝”匹配项,则评估停止。如果没有匹配项或“通过”操作,则流量将进入 NetworkPolicy 层级。
  2. NetworkPolicy 层级:根据标准命名空间 政策评估流量。如果存在匹配项,则允许流量。如果没有匹配项,则流量将进入基准层级。
  3. 基准层级:根据基准层级中的 ClusterNetworkPolicy 规则评估流量。如果存在“允许”或“拒绝”匹配项,则评估停止。如果没有匹配项,则流量将进入默认行为。
  4. 默认 GKE 行为:如果任何层级中都没有匹配的政策, 则流量将受到隐式允许行为的约束。

判定操作:“允许”“拒绝”和“通过”

匹配数据包后,每条规则都会触发以下三个严格操作之一:

  • 拒绝:立即阻止流量。
  • 接受:允许流量。这两个操作都会立即使流水线短路,从而忽略所有剩余的政策。
  • 通过:将控制权转移到下一层级,使平台 工程师能够将特定流量决策委托给标准命名空间级 政策,而无需放弃总体管理控制权。

配置全局拒绝政策

如需将敏感命名空间与所有其他集群内部流量隔离开,请应用不可替换的拒绝规则。此默认拒绝政策有助于确保在管理层级阻止进出敏感命名空间的任何流量。 此政策充当保护性基准,不会被命名空间级规则意外绕过。

  1. 将以下清单保存为 global-deny.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: cluster-wide-deny-sensitive
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            kubernetes.io/metadata.name: sensitive-ns
      ingress:
      - action: Deny
        name: deny-all-ingress
        from:
        - namespaces:
            matchLabels: {}
      egress:
      - action: Deny
        name: deny-all-egress
        to:
        - namespaces:
            matchLabels: {}
    
  2. 将清单应用到您的集群:

    kubectl apply -f global-deny.yaml
    

配置全局允许政策

全局允许政策有助于确保所有 Pod 都可以访问集群 DNS 服务,而不管开发者创建了哪些网络政策。

  1. 将以下清单保存为 global-allow-dns.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-kube-dns-admin
    spec:
      tier: Admin
      priority: 20
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-dns-egress
        to:
        - pods:
            namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: kube-system
            podSelector:
              matchLabels:
                k8s-app: kube-dns
        protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    
  2. 将清单应用到您的集群:

    kubectl apply -f global-allow-dns.yaml
    

将流量委托给命名空间政策

将特定流量模式委托给标准命名空间范围的 NetworkPolicy 对象。

  1. 将以下清单保存为 delegate-policy.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: delegate-to-netpol
    spec:
      tier: Admin
      priority: 30
      subject:
        namespaces: {}
      egress:
      - action: Pass
        name: delegate-web-traffic
        to:
        - namespaces:
            matchLabels:
              app: web-backend
        protocols:
        - tcp:
            destinationPort:
              number: 8080
    
  2. 将清单应用到您的集群:

    kubectl apply -f delegate-policy.yaml
    
  3. 如需允许目标命名空间内的委托流量,请将以下标准 NetworkPolicy 清单保存为 allow-web-backend.yaml

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-web-backend
      namespace: backend-ns
    spec:
      podSelector:
        matchLabels:
          app: web-backend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              app: web-frontend
        ports:
        - protocol: TCP
          port: 8080
    
  4. 将标准 NetworkPolicy 清单应用到您的集群:

    kubectl apply -f allow-web-backend.yaml
    

配置基准措施

建立默认 GKE 安全态势,命名空间管理员可以使用标准网络政策替换该态势。

  1. 将以下基准清单保存为 baseline-deny.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: default-deny-baseline
    spec:
      tier: Baseline
      priority: 100
      subject:
        namespaces: {}
      ingress:
      - action: Deny
        name: baseline-deny-all
        from:
        - namespaces: {}
    
  2. 将基准清单应用到您的集群:

    kubectl apply -f baseline-deny.yaml
    
  3. 将以下开发者替换清单保存为 developer-allow.yaml

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend-access
      namespace: my-app-ns
    spec:
      podSelector:
        matchLabels:
          app: frontend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
    
  4. 将替换清单应用到您的集群:

    kubectl apply -f developer-allow.yaml
    

使用已命名端口配置政策

如需从安全政策中抽象出端口号,请引用 Pod 规范中定义的已命名端口。

  1. 将以下部署清单保存为 app-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-webapp
    spec:
      template:
        spec:
          containers:
          - name: web-container
            image: nginx
            ports:
            - name: http-web
              containerPort: 8080
    
  2. 将部署清单应用到您的集群:

    kubectl apply -f app-deployment.yaml
    
  3. 将以下政策清单保存为 named-port-policy.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-web-named-port
    spec:
      tier: Admin
      priority: 40
      subject:
        namespaces: {}
      egress:
      - action: Accept
        to:
        - namespaces:
            matchLabels:
              app: my-webapp
        protocols:
        - tcp:
            destinationNamedPort: http-web
    
  4. 将政策清单应用到您的集群:

    kubectl apply -f named-port-policy.yaml
    

将出站流量限制为 CIDR 块

通过指定 CIDR 块来控制对外部资源或公司内网的访问。

  1. 将以下清单保存为 cidr-policy.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-egress-to-intranet
    spec:
      tier: Admin
      priority: 60
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-intranet
        to:
        - networks:
          - 10.0.0.0/8
          - 192.168.0.0/16
    
  2. 将清单应用到您的集群:

    kubectl apply -f cidr-policy.yaml
    

配置优先级

如需在多个政策应用于同一 Pod 时控制评估顺序,请指定优先级。优先级范围为 0 到 1000,其中数字越小表示优先级越高。单个 ClusterNetworkPolicy 对象最多可以包含 100 条入站规则和 100 条出站规则。

  1. 将以下清单保存为 priority-policies.yaml

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: deny-beta
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-beta-monitoring
        from:
        - pods:
            namespaceSelector:
              matchLabels:
                team: beta
            podSelector:
              matchLabels:
                app: monitoring
      - action: Deny
        name: deny-all-other-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    ---
    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-beta
    spec:
      tier: Admin
      priority: 50
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-all-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    
  2. 将清单应用到您的集群:

    kubectl apply -f priority-policies.yaml
    

问题排查

如需查找诊断和解决政策错误的方法,请使用以下命令。

列出集群中的所有集群网络政策:

kubectl get clusternetworkpolicies

描述特定政策以检查其状态和评估层级:

kubectl describe clusternetworkpolicy/<policy-name>

输出中的 status.conditions 字段提供有关集群的网络实现是否已成功协调政策的信息。

如需监控流量流和政策决策,请使用 GKE Dataplane V2 可观测性

后续步骤