在专用节点池中隔离工作负载

借助 Google Distributed Cloud (GDC) 网闸隔离配置中的专用节点池,您可以隔离容器工作负载,以加强 Kubernetes 集群安全性并控制 Pod 放置。这种分离有助于降低提权攻击的风险。如需设置专用池,您需要应用污点和标签,将其与工作负载容忍和节点亲和性规则进行匹配,并验证调度。

本文档适用于管理 Kubernetes 集群的平台管理员组中的 IT 管理员,以及运行容器的应用运维人员组中的开发者。如需了解详情,请参阅节点隔离概览和 GDC 网闸隔离配置文档的受众群体。

准备工作

如需完成本文档中的任务,您必须请求必要的权限并准备环境。

申请 IAM 角色

您必须拥有特定角色,才能获得在 Kubernetes 集群中隔离容器工作负载所需的权限。您所需的角色取决于您是在组织级共享集群还是项目级标准集群中工作。如需了解详情,请参阅 Kubernetes 集群配置。

共享集群角色

请与您的 IAM 组织管理员联系,请求获取以下角色,以便在共享集群中对节点池进行污点设置和添加标签:

  • 用户集群管理员 (user-cluster-admin):创建、删除、修改或查看托管在 Management API 服务器上的共享集群的资源。此角色提供对共享集群的节点池的访问权限。

  • 用户集群开发者 (user-cluster-developer):创建、删除、修改或查看共享集群。此角色提供对托管在共享集群中的数据平面 API 的访问权限。

这些角色不绑定到命名空间。

标准集群角色

请与您的 IAM 项目管理员联系,请求获取以下角色,以便在标准集群中为节点池添加污点和标签:

  • Cluster Admin (cluster-admin):在标准集群中创建、删除、修改或查看所有资源。此角色提供对标准集群中托管的数据平面 API 的访问权限,这些 API 用于管理集群的资源。

  • Cluster Developer (cluster-developer):创建、删除、修改或查看标准集群。此角色提供对标准集群中托管的数据平面 API 的访问权限,这些 API 用于管理集群。

  • Standard Cluster Admin (standard-cluster-admin):创建、删除、修改或查看托管在 Management API 服务器上的 Standard 集群的资源。此角色提供对标准集群的节点池的访问权限。

这些角色会绑定到您的项目命名空间。

准备环境

如需使用 API 对 Kubernetes 集群运行命令,请确保您拥有以下资源:

  • 登录并生成 Kubernetes 集群的 kubeconfig 文件。

  • 使用 Kubernetes 集群的 kubeconfig 路径替换这些说明中的 KUBERNETES_CLUSTER_KUBECONFIG。

  • 登录并生成管理 API 服务器的 kubeconfig 文件。

  • 在这些说明中,请使用 Management API 服务器的 kubeconfig 路径替换 MANAGEMENT_API_SERVER。

  • 为您想要用于专用节点池的节点污点和节点标签选择特定名称。例如 workloadType=untrusted。

为新节点池添加污点和标签

在向新节点池应用污点或标签时,所有节点(包括之后添加的所有节点)都将自动获取指定的污点和标签。污点或标签应用后,您无法将其从节点池中移除。

如需向新节点池添加污点和标签,请完成以下步骤:

  1. 创建节点池时,直接修改 Cluster 自定义资源的 nodePools 部分:

    nodePools:
      # Several lines of code are omitted here.
      - machineTypeName: n2-standard-2-gdc
        name: nodepool-1
        nodeCount: 3
        taints:
        - key: "TAINT_KEY"
          value: "TAINT_VALUE"
          effect: "TAINT_EFFECT"
        labels:
          LABEL_KEY: LABEL_VALUE
    

    替换以下内容:

    • TAINT_KEY:与调度 TAINT_EFFECT 关联的键值对的污点键部分。例如 workloadType。
    • TAINT_VALUE:与调度 TAINT_EFFECT 关联的键值对的污点值部分。例如 untrusted。
    • TAINT_EFFECT:以下效果值之一:
      • NoSchedule:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。
      • PreferNoSchedule:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到该节点上。
      • NoExecute:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
    • LABEL_KEY: LABEL_VALUE:节点标签的键值对,与您在工作负载清单中指定的选择器对应。
  2. 应用 Cluster 资源以创建新的节点池:

    kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVER
    

    将 MANAGEMENT_API_SERVER 替换为托管 Kubernetes 集群的可用区级 API 服务器的 kubeconfig 路径。

为现有节点池添加污点和标签

如需将污点或标签应用于现有节点池,您必须将更改应用于每个现有节点。您无法动态更新节点池配置。

污点或标签应用后,您无法将其从节点池中移除。

如需向现有节点池添加污点和标签,请完成以下步骤:

  1. 列出专用节点池中的节点:

    kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \
        -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
    

    执行以下变量替换操作:

    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 集群的 kubeconfig 路径。
    • NODE_POOL_NAME:专用节点池的名称。

    从输出中记下节点池中所有节点的每个节点 ID。

  2. 对于节点池中的每个节点,应用以下污点:

    kubectl taint nodes NODE_ID \
        TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    执行以下变量替换操作:

    • NODE_ID:专用节点池中工作器节点的 ID。
    • TAINT_KEY=TAINT_VALUE:与调度 TAINT_EFFECT 关联的键值对。例如 workloadType=untrusted。
    • TAINT_EFFECT:以下效果值之一:
      • NoSchedule:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。
      • PreferNoSchedule:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到该节点上。
      • NoExecute:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 集群的 kubeconfig 路径。
  3. 对于节点池中的每个节点,应用与您将在容器工作负载中定义的选择器相对应的标签:

    kubectl label NODE_ID \
        LABEL_KEY:LABEL_VALUE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    执行以下变量替换操作:

    • NODE_ID:专用节点池中工作器节点的 ID。
    • LABEL_KEY:LABEL_VALUE:节点标签的键值对,与您在工作负载清单中指定的选择器对应。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 集群的 kubeconfig 路径。

添加容忍和节点亲和性规则

污染专用节点池后,任何工作负载都无法在其上调度,除非它们具有与您添加的污染相对应的容忍度。将容忍度添加到您的工作负载规范中,让这些 Pod 在您的受污染节点池调度。

如果您已为专用节点池添加标签,则还可以添加节点亲和性规则,以指示 GDC 仅在该节点池上调度工作负载。

如需将容器工作负载配置为在专用节点池中运行,请完成以下步骤:

  1. 将以下部分添加到容器工作负载清单文件(例如 Deployment 自定义资源)的 .spec.template.spec 部分:

    tolerations:
    - key: TAINT_KEY
      operator: Equal
      value: TAINT_VALUE
      effect: TAINT_EFFECT
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: LABEL_KEY
              operator: In
              values:
              - "LABEL_VALUE"
    

    替换以下内容:

    • TAINT_KEY:您应用于专用节点池的污点键。
    • TAINT_VALUE:您应用于专用节点池的污点值。
    • TAINT_EFFECT:以下效果值之一:
      • NoSchedule:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。
      • PreferNoSchedule:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到该节点上。
      • NoExecute:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
    • LABEL_KEY:您应用于专用节点池的节点标签键。
    • LABEL_VALUE:您应用于专用节点池的节点标签值。

    例如,以下 Deployment 资源为 workloadType=untrusted:NoExecute 污点添加容忍设置,并为 workloadType=untrusted 节点标签添加节点亲和性规则:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: my-app
      namespace: default
      labels:
        app: my-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          tolerations:
          - key: workloadType
            operator: Equal
            value: untrusted
            effect: NoExecute
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: workloadType
                    operator: In
                    values:
                    - "untrusted"
          containers:
          - name: my-app
            image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: SECRET
    
  2. 更新容器工作负载:

    kubectl apply -f deployment.yaml -n NAMESPACE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    执行以下变量替换操作:

    • NAMESPACE:容器工作负载的命名空间。对于共享集群,此命名空间必须是项目命名空间。对于标准集群,它可以是任何命名空间。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 集群的 kubeconfig 路径。

GDC 会重新创建受影响的 Pod。节点亲和性规则强制 Pod 推送到您创建的专用节点池。容忍设置仅允许将这些 Pod 放置在节点上。

验证分离是否有效

验证您指定的 Pod 是否在带标签的节点池池上运行。

  • 列出给定命名空间中的 Pod:

    kubectl get pods -o=wide -n NAMESPACE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    执行以下变量替换操作:

    • NAMESPACE:容器工作负载的命名空间。对于共享集群,此命名空间必须是项目命名空间。对于标准集群,它可以是任何命名空间。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 集群的 kubeconfig 路径。

    输出类似于以下内容:

    pod/kube-abc-12tyuj
    pod/kube-abc-39oplef
    pod/kube-abc-95rzkap
    

    确认您的工作负载是否在专用节点池中运行。

后续步骤