×

节点选择器指定一个键/值对映射,这些键/值对是使用节点上的自定义标签和Pod中指定的选择器定义的。

为了使Pod能够在节点上运行,Pod必须与节点上的标签具有相同的键/值节点选择器。

关于节点选择器

您可以使用Pod上的节点选择器和节点上的标签来控制Pod的调度位置。使用节点选择器,Red Hat OpenShift Service on AWS 将Pod调度到包含匹配标签的节点上。

您可以使用节点选择器将特定Pod放置在特定节点上,使用集群范围的节点选择器将新Pod放置在集群中任何位置的特定节点上,以及使用项目节点选择器将项目中的新Pod放置在特定节点上。

例如,作为集群管理员,您可以创建一个基础架构,让应用程序开发人员只能将Pod部署到最靠近其地理位置的节点上,方法是在他们创建的每个Pod中包含一个节点选择器。在此示例中,集群由分布在两个区域的五个数据中心组成。在美国,将节点标记为us-eastus-centralus-west。在亚太地区(APAC),将节点标记为apac-eastapac-west。开发人员可以向他们创建的Pod添加节点选择器,以确保Pod被调度到这些节点上。

如果Pod对象包含节点选择器,但没有节点具有匹配的标签,则不会调度Pod。

如果您在同一个Pod配置中同时使用节点选择器和节点亲和性,则以下规则控制Pod放置到节点上

  • 如果您同时配置了nodeSelectornodeAffinity,则必须满足这两个条件才能将Pod调度到候选节点上。

  • 如果您指定了与nodeAffinity类型关联的多个nodeSelectorTerms,则如果满足其中一个nodeSelectorTerms,则可以将Pod调度到节点上。

  • 如果您指定了与nodeSelectorTerms关联的多个matchExpressions,则只有在满足所有matchExpressions时,才能将Pod调度到节点上。

特定Pod和节点上的节点选择器

您可以使用节点选择器和标签来控制特定Pod的调度节点。

要使用节点选择器和标签,首先标记节点以避免Pod被取消调度,然后将节点选择器添加到Pod。

您不能直接将节点选择器添加到已调度的现有Pod。您必须标记控制Pod的对象,例如部署配置。

例如,以下Node对象具有region: east标签

带有标签的示例Node对象
kind: Node
apiVersion: v1
metadata:
  name: ip-10-0-131-14.ec2.internal
  selfLink: /api/v1/nodes/ip-10-0-131-14.ec2.internal
  uid: 7bc2580a-8b8e-11e9-8e01-021ab4174c74
  resourceVersion: '478704'
  creationTimestamp: '2019-06-10T14:46:08Z'
  labels:
    kubernetes.io/os: linux
    topology.kubernetes.io/zone: us-east-1a
    node.openshift.io/os_version: '4.5'
    node-role.kubernetes.io/worker: ''
    topology.kubernetes.io/region: us-east-1
    node.openshift.io/os_id: rhcos
    node.kubernetes.io/instance-type: m4.large
    kubernetes.io/hostname: ip-10-0-131-14
    kubernetes.io/arch: amd64
    region: east (1)
    type: user-node
#...
1 匹配Pod节点选择器的标签。

一个Pod具有type: user-node,region: east节点选择器

带有节点选择器的示例Pod对象
apiVersion: v1
kind: Pod
metadata:
  name: s1
#...
spec:
  nodeSelector: (1)
    region: east
    type: user-node
#...
1 匹配节点标签的节点选择器。节点必须具有每个节点选择器的标签。

使用示例Pod规范创建Pod时,它可以调度到示例节点上。

默认集群范围节点选择器

使用默认集群范围节点选择器时,在该集群中创建Pod时,Red Hat OpenShift Service on AWS 会将默认节点选择器添加到Pod,并将Pod调度到具有匹配标签的节点上。

例如,以下Scheduler对象具有默认的集群范围region=easttype=user-node节点选择器

示例调度程序操作员自定义资源
apiVersion: config.openshift.io/v1
kind: Scheduler
metadata:
  name: cluster
#...
spec:
  defaultNodeSelector: type=user-node,region=east
#...

该集群中的一个节点具有type=user-node,region=east标签

示例Node对象
apiVersion: v1
kind: Node
metadata:
  name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4
#...
  labels:
    region: east
    type: user-node
#...
带有节点选择器的示例Pod对象
apiVersion: v1
kind: Pod
metadata:
  name: s1
#...
spec:
  nodeSelector:
    region: east
#...

在示例集群中使用示例Pod规范创建Pod时,Pod将使用集群范围的节点选择器创建,并调度到已标记的节点上

已标记节点上Pod的示例Pod列表
NAME     READY   STATUS    RESTARTS   AGE   IP           NODE                                       NOMINATED NODE   READINESS GATES
pod-s1   1/1     Running   0          20s   10.131.2.6   ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4   <none>           <none>

如果您创建Pod的项目具有项目节点选择器,则该选择器优先于集群范围的节点选择器。如果Pod没有项目节点选择器,则不会创建或调度您的Pod。

项目节点选择器

使用项目节点选择器时,在此项目中创建Pod时,Red Hat OpenShift Service on AWS 会将节点选择器添加到Pod,并将Pod调度到具有匹配标签的节点上。如果存在集群范围的默认节点选择器,则项目节点选择器优先。

例如,以下项目具有region=east节点选择器

示例Namespace对象
apiVersion: v1
kind: Namespace
metadata:
  name: east-region
  annotations:
    openshift.io/node-selector: "region=east"
#...

以下节点具有type=user-node,region=east标签

示例Node对象
apiVersion: v1
kind: Node
metadata:
  name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4
#...
  labels:
    region: east
    type: user-node
#...

在此示例项目中使用示例Pod规范创建Pod时,Pod将使用项目节点选择器创建,并调度到已标记的节点上

示例Pod对象
apiVersion: v1
kind: Pod
metadata:
  namespace: east-region
#...
spec:
  nodeSelector:
    region: east
    type: user-node
#...
已标记节点上Pod的示例Pod列表
NAME     READY   STATUS    RESTARTS   AGE   IP           NODE                                       NOMINATED NODE   READINESS GATES
pod-s1   1/1     Running   0          20s   10.131.2.6   ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4   <none>           <none>

如果项目中的Pod包含不同的节点选择器,则不会创建或调度该Pod。例如,如果您将以下Pod部署到示例项目中,则不会创建它

带有无效节点选择器的示例Pod对象
apiVersion: v1
kind: Pod
metadata:
  name: west-region
#...
spec:
  nodeSelector:
    region: west
#...

使用节点选择器控制 Pod 部署位置

您可以使用Pod上的节点选择器和节点上的标签来控制Pod的调度位置。使用节点选择器,Red Hat OpenShift Service on AWS 将Pod调度到包含匹配标签的节点上。

您可以向节点、计算机器集或机器配置添加标签。将标签添加到计算机器集可确保如果节点或机器宕机,新节点也会具有该标签。如果节点或机器宕机,添加到节点或机器配置的标签将不会持久保存。

要向现有 Pod 添加节点选择器,请向该 Pod 的控制对象添加节点选择器,例如ReplicaSet对象、DaemonSet对象、StatefulSet对象、Deployment对象或DeploymentConfig对象。该控制对象下的任何现有 Pod 都将在具有匹配标签的节点上重新创建。如果您正在创建新的 Pod,可以直接将节点选择器添加到 Pod 规范中。如果 Pod 没有控制对象,则必须删除 Pod,编辑 Pod 规范,然后重新创建 Pod。

您无法直接向现有的已调度 Pod 添加节点选择器。

先决条件

要向现有 Pod 添加节点选择器,请确定该 Pod 的控制对象。例如,router-default-66d5cf9464-m2g75 Pod 由router-default-66d5cf9464副本集控制。

$ oc describe pod router-default-66d5cf9464-7pwkc
示例输出
kind: Pod
apiVersion: v1
metadata:
# ...
Name:               router-default-66d5cf9464-7pwkc
Namespace:          openshift-ingress
# ...
Controlled By:      ReplicaSet/router-default-66d5cf9464
# ...

Web 控制台在 Pod YAML 中的ownerReferences下列出控制对象。

apiVersion: v1
kind: Pod
metadata:
  name: router-default-66d5cf9464-7pwkc
# ...
  ownerReferences:
    - apiVersion: apps/v1
      kind: ReplicaSet
      name: router-default-66d5cf9464
      uid: d81dd094-da26-11e9-a48a-128e7edf0312
      controller: true
      blockOwnerDeletion: true
# ...
步骤
  • 向 Pod 添加匹配的节点选择器

    • 要向现有和未来的 Pod 添加节点选择器,请向 Pod 的控制对象添加节点选择器。

      带有标签的示例ReplicaSet对象
      kind: ReplicaSet
      apiVersion: apps/v1
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
      # ...
        template:
          metadata:
            creationTimestamp: null
            labels:
              ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
              pod-template-hash: 66d5cf9464
          spec:
            nodeSelector:
              kubernetes.io/os: linux
              node-role.kubernetes.io/worker: ''
              type: user-node (1)
      # ...
      1 添加节点选择器。
    • 要向特定的新 Pod 添加节点选择器,请直接将选择器添加到Pod对象。

      带有节点选择器的示例Pod对象
      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-node-6fbccf8d9
      # ...
      spec:
        nodeSelector:
          region: east
          type: user-node
      # ...

      您无法直接向现有的已调度 Pod 添加节点选择器。