用节点污点控制调度


本页面简要介绍了 Google Kubernetes Engine (GKE) 上的节点污点。节点污点可帮助您指定工作负载应在其中运行的节点。

Autopilot 集群仅支持使用节点污点进行工作负载分离。如需了解相关说明,请参阅在 GKE 中配置工作负载分离

概览

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

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

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

污点和容忍协同工作,确保 Pod 不会被调度到不当的节点上。

污点是与“效果”相关联的键值对。下表列出了可用的变量效果:

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

在 GKE 中设置节点污点的优势

您可以将节点污点添加到 GKE 中的集群和节点,也可以使用 kubectl taint 命令。与在 GKE 中指定节点污点相比,具有以下优势:kubectl

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

准备工作

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

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

创建具有节点污点的集群

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

如果您创建具有 NoSchedule 效果或 NoExecute 效果的节点污点的标准集群,则 GKE 无法在当您创建群集时 GKE 创建的默认节点池上安排某些 GKE 管理的组件,例如 kube-dnsmetrics-server。GKE 无法安排这些组件,因为它们没有相应的节点污点容忍机制。您必须添加满足以下条件之一的新节点池:

  • 无污点
  • 具有 PreferNoSchedule 效果的污点
  • components.gke.io/gke-managed-components=true:NoSchedule 个污点

满足上述任何条件后,GKE 便可在新节点池中安排 GKE 管理的组件。

如需了解相关说明,请参阅在专用节点上隔离工作负载

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. 转到 Google Cloud 控制台中的 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 集群中,您可以将污点应用于节点池,这会将污点应用于池中的所有节点。

如需创建具有节点污点的节点池,您可以使用 Google Cloud CLI、Google Cloud 控制台或 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. 转到 Google Cloud 控制台中的 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

例如,以下命令会将键值对为 dedicated=experimental 且具有 NoSchedule 效果的污点应用于 mynode 节点:

kubectl taint nodes mynode dedicated=experimental:NoSchedule

您还可以通过使用 -l 选择器以及指定的标签和值,将污点添加到具有特定标签的节点:

kubectl taint nodes -l LABEL=LABEL_VALUE KEY=VALUE:EFFECT

例如,以下命令会向 my_pool 节点池中的 GKE 节点添加具有键 dedicated-pool 的污点:

kubectl taint nodes -l cloud.google.com/gke-nodepool=my_pool dedicated-pool=my_pool:NoSchedule

检查节点的污点

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

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

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

    kubectl describe node NODE_NAME
    
  3. 在返回的输出中,查找 Taints 字段。输出内容类似如下:

    Taints:  dedicated-pool=mypool:NoSchedule
    

从节点中移除污点

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

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

kubectl taint nodes mynode dedicated-

从节点池中移除所有污点

如需从节点池移除所有污点,请运行以下命令:

gcloud beta container node-pools update POOL_NAME \
--node-taints="" \
--cluster=CLUSTER_NAME

替换以下内容:

  • POOL_NAME:要更改的节点池的名称。
  • CLUSTER_NAME:在其中创建节点池的集群的名称。

后续步骤