用节点污点控制调度


本页面简要介绍了 Google Kubernetes Engine (GKE) 上的节点污点。当您安排工作负载以在集群上进行部署时,可使用节点污点来控制允许工作负载在哪些节点上运行。

概览

当您提交要在集群中运行的工作负载时,调度程序会确定要在何处放置与工作负载关联的 Pod。调度程序可以在任何满足 Pod 的 CPU、内存和自定义资源要求的节点上自由放置 Pod。

如果您的集群运行各种工作负载,您可能希望对特定节点池上可以运行哪些工作负载进行一些控制。

利用节点污点,您可以标记节点,以使调度程序避免或阻止将其用于某些 Pod。利用补充功能“容忍”,您可以指定能在“有污点的”节点上使用的 Pod

节点污点是与“效果”相关联的键值对。以下是可用的效果:

  • NoSchedule:不能容忍此污点的 Pod 不会被调度到节点上;现有 Pod 不会从节点中逐出。
  • PreferNoSchedule:Kubernetes 会避免将不能容忍此污点的 Pod 安排到节点上。
  • NoExecute:如果 Pod 已在节点上运行,则会将该 Pod 从节点中逐出;如果尚未在节点上运行,则不会将其安排到节点上。

请注意,某些系统 Pod(例如 kube-proxy 和 fluentd)可以容忍所有 NoExecuteNoSchedule 污点,因此不会被逐出。

准备工作

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

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

使用节点污点创建集群

创建集群时,您可以将节点污点分配给集群。此操作会将污点分配给使用集群创建的所有节点。

gcloud

如需创建具有节点污点的集群,请运行以下命令:

gcloud container clusters create cluster-name \
  --node-taints key=value:effect

替换以下内容:

  • cluster-name 是要创建的集群的名称。
  • effectPreferNoScheduleNoScheduleNoExecute
  • keyvalue 构成了与 effect 关联的键值对。

例如,以下命令会应用具有键 dedicated、值 experimental 和效果 PreferNoSchedule 的污点:

gcloud container clusters create example-cluster \
  --node-taints dedicated=experimental:PreferNoSchedule

控制台

如需创建具有节点污点的集群,请执行以下操作:

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 点击 创建

  3. 根据需要配置集群。

  4. 在导航窗格的节点池下,展开要修改的节点池,然后点击元数据

  5. 节点污点部分中,点击 添加污点

  6. 效果下拉列表中,选择所需的效果。

  7. 字段中输入所需的键值对。

  8. 点击创建

API

当您使用 API 创建集群时,请在 nodeConfig 下方添加 nodeTaints 字段。示例如下:

POST https://container.googleapis.com/v1/projects/project-id/zones/compute-zone/clusters

{
  'cluster': {
    'name': 'example-cluster',
    'nodeConfig': {
      'nodeTaints': [
        {
          'key': 'special',
          'Value': 'gpu',
          'effect': 'PreferNoSchedule'
        }
      ]
      ...
    }
    ...
  }
}

使用节点污点创建节点池

将污点应用于节点时,只允许容忍污点的 Pod 在节点上运行。在 GKE 集群中,您可以将污点应用于节点池,这会将污点应用于池中的所有节点。

如需使用节点污点创建节点池,您可以使用 gcloud 命令行工具、Cloud Console 或 GKE API。

gcloud

如需创建具有节点污点的节点池,请运行以下命令:

gcloud container node-pools create pool-name \
  --cluster cluster-name \
  --node-taints key=value:effect

替换以下内容:

  • pool-name 是要创建的节点池的名称。
  • cluster-name 是在其中创建节点池的集群的名称。
  • effectPreferNoScheduleNoScheduleNoExecute
  • keyvalue 构成了与 effect 关联的键值对。

例如,以下命令会应用具有键 dedicated、值 experimental 和效果 NoSchedule 的污点:

gcloud container node-pools create example-pool --cluster example-cluster \
  --node-taints dedicated=experimental:NoSchedule

此命令会应用具有键 special、值 gpu 和效果 NoExecute 的污点:

gcloud container node-pools create example-pool-2 --cluster example-cluster \
  --node-taints special=gpu:NoExecute

控制台

如需创建具有节点污点的节点池,请执行以下步骤:

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 在集群列表中,点击您要修改的集群的名称。

  3. 集群详情页面上,点击 添加节点池

  4. 在导航窗格中,点击元数据

  5. 节点污点下,点击 添加污点

  6. 效果下拉列表中选择所需的效果。

  7. 字段中输入所需的键值对。

  8. 点击创建

API

当您使用 API 创建节点池时,请在 nodeConfig 下方添加 nodeTaints 字段。示例如下:

POST https://container.googleapis.com/v1/projects/project-id/zones/compute-zone/clusters/cluster-id/nodePools

{
  'nodePool': {
    'name': 'example-pool',
    'nodeConfig': {
      'nodeTaints': [
        {
          'key': 'dedicated',
          'Value': 'experimental',
          'effect': 'NoSchedule'
        }
      ]
      ...
    }
    ...
  }
}

配置 Pod 以容忍污点

要配置 Pod 以容忍污点,您可以在 Pod 的规范中加入 tolerations 字段。以下是 Pod 规范的一部分。

此 Pod 可以安排在具有污点 dedicated=experimental:NoSchedule 的节点上:

tolerations:
- key: dedicated
  operator: Equal
  value: experimental
  effect: NoSchedule

向现有节点添加污点

您可以使用 kubectl taint 命令将污点添加到现有节点:

kubectl taint nodes node-name key=value:effect

例如:

kubectl taint nodes node1 key=value:NoSchedule

您还可以向具有特定标签的节点添加污点:

kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule

如需了解详情,请参阅 Kubernetes 文档中的污点和容忍

检查节点的污点

如需查看节点的污点,您可以使用 kubectl 命令行工具。

  1. 通过运行以下命令获取集群中所有节点的列表:

    kubectl get nodes
    
  2. 通过运行以下命令检查节点:

    kubectl describe node node-name
    
  3. 在返回的节点说明中,查找 Taints 字段:

    Taints: key=value:effect
    

从节点中移除污点

您可以使用 kubectl taint 移除污点。也可以通过键、键值对或键效果对移除污点。

例如,以下命令可使用键 dedicated 从节点 foo 中移除所有污点:

kubectl taint nodes foo dedicated-

使用 GKE 节点污点功能的优点

将 GKE 节点污点功能用于集群和节点池,较之使用 kubectl 手动设置污点有几个优点:

  • 重启或替换节点时会保留污点。
  • 将节点添加到节点池或集群时会自动创建污点。
  • 在集群自动扩缩期间会自动创建污点。

后续步骤