配置集群网络政策

借助 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 设置来定位一系列端口(例如 8000 到 9000)。
  • 命名端口:使用 destinationNamedPort 设置定位 Pod 规范中定义的符号名称。

政策评估层次结构

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

  • 层级:管理员规则优先执行,然后依次是 NetworkPolicy 和 Baseline。
  • CNP 优先级:在同一层级内,系统会根据政策的明确数值优先级来评估政策。
  • CNP 规则顺序:在单个政策中,规则会像访问权限控制列表 (ACL) 一样从上到下进行处理。

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

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

  1. 管理员层级:系统会先根据 Admin 层级中的 ClusterNetworkPolicy 规则评估流量。如果存在“允许”或“拒绝”匹配,评估就会停止。如果没有匹配项或执行了“通过”操作,流量将进入 NetworkPolicy 层级。
  2. NetworkPolicy 层级:系统会根据标准命名空间政策评估流量。如果匹配,则允许流量通过。如果没有匹配项,流量将进入 Baseline 层级。
  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. 将以下 Deployment 清单保存为 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 可观测性。

后续步骤