用节点污点控制调度

本页面简要介绍了 Google Kubernetes Engine 上的节点污点。当您调度工作负载以在集群上进行部署时,可借助节点污点来控制允许工作负载在哪些节点上运行。

概览

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

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

您可以利用节点污点对节点进行标记,以使调度器避免或阻止将其用于特定 Pod;还可以利用一项补充功能(即“容忍”)指定能在“有污点的”节点上使用的 Pod

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

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

准备工作

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

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

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

使用 gcloud init

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

    gcloud init

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

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

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project project-id
  • 如果您使用的是地区级集群,请设置默认计算地区
    gcloud config set compute/zone compute-zone
  • 如果您使用的是区域级集群,请设置默认计算区域
    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] 是要创建的集群的名称。
  • [EFFECT]PreferNoScheduleNoScheduleNoExecute
  • [KEY][VALUE] 构成了与 [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. 如果需要,添加其他节点污点。

  9. 点击创建

API

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

POST https://container.googleapis.com/v1/projects/[PROJECT_ID]/zones/[ZONE]/clusters

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

创建具有节点污点的节点池

如果为节点设置污点,那么只有能容忍此污点的 Pod 才可在节点上运行。在 GKE 集群中,您可以为节点池设置污点,从而为池中的所有节点设置污点。

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

gcloud

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

gcloud container node-pools create [POOL_NAME] --cluster [CLUSTER_NAME] \
    --node-taints [KEY]=[VALUE]:[EFFECT]

其中:

  • [POOL_NAME] 是要创建的节点池的名称。
  • [CLUSTER_NAME] 是在其中创建节点池的集群的名称。
  • [EFFECT]PreferNoScheduleNoScheduleNoExecute
  • [KEY][VALUE] 构成了与 [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. 点击保存以退出节点池修改叠加层。

  9. 点击创建

API

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

POST https://container.googleapis.com/v1/projects/[PROJECT_ID]/zones/[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 命令行工具。

首先,要获取集群中所有节点的列表,请运行以下命令:

kubectl get nodes

然后,要检查一个节点,请运行以下命令:

kubectl describe node [NODE_NAME]

在返回的节点说明中,查找 Taints 字段:

Taints: [KEY]=[VALUE]:[EFFECT]

从节点中移除污点

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

例如,以下命令会从节点 foo 中移除所有键为 dedicated 的污点:

kubectl taint nodes foo dedicated-

使用节点污点的优势

与使用 kubectl 手动设置污点相比,使用节点污点具有多项优势:

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

后续步骤