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

本文档介绍了如何在 Google Distributed Cloud (GDC) air-gapped 中通过在专用节点池内隔离容器工作负载来增强 Kubernetes 集群的安全性和管理能力。隔离工作负载可让您更好地控制 Pod,并降低 Kubernetes 集群中发生提权攻击的风险。如需详细了解专用节点池的优势和限制,请参阅节点隔离概览

隔离容器工作负载涉及多个工作流程,包括:

  • 为节点池添加污点和标签:为节点池添加污点和标签,以便将 pod 排斥在该节点池之外,除非这些 pod 专门标记为在该节点池中运行。

  • 添加容忍和节点亲和性规则:将容忍和规则应用于您的 pod,以强制它们仅在指定的节点池池上运行。

  • 验证分离是否有效:确认带有污点的节点池仅运行您标记为在该节点池中运行的 pod。

这些工作流适用于平台管理员群组中的 IT 管理员(负责管理 Kubernetes 集群的节点池)和应用运营者群组中的应用开发者(负责管理容器工作负载)等受众群体。如需了解详情,请参阅 GDC 气隙环境文档的受众群体

准备工作

在开始之前,请确保您已执行以下任务:

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

  • 如有必要,请让组织 IAM 管理员为您授予未绑定到命名空间的 User Cluster Developer 角色 (user-cluster-developer)。

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

向新节点池应用污点或标签时,所有节点(包括稍后添加的任何节点)都将自动获取指定的污点和标签。

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

  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 路径。如果您尚未为目标可用区中的 API 服务器生成 kubeconfig 文件,请参阅可用区级管理 API 服务器资源了解详情。

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

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

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

  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 部分:

      # Several lines of code are omitted here.
        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"
            # Several lines of code are omitted here.
    

    替换以下内容:

    • 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
    

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

后续步骤