将Pod调度到指定节点
将pod调度到指定节点的方法
你可以约束一个 Pod 以便 限制 其只能在特定的节点上运行, 或优先在特定的节点上运行。有几种方法可以实现这点,推荐的方法都是用 标签选择算符来进行选择。 通常这样的约束不是必须的,因为调度器将自动进行合理的放置(比如,将 Pod 分散到节点上, 而不是将 Pod 放置在可用资源不足的节点上等等)。但在某些情况下,你可能需要进一步控制 Pod 被部署到哪个节点。例如,确保 Pod 最终落在连接了 SSD 的机器上, 或者将来自两个不同的服务且有大量通信的 Pod 被放置在同一个可用区。
你可以使用下列方法中的任何一种来选择 Kubernetes 对特定 Pod 的调度:
- 与节点标签匹配的 nodeSelector
- 亲和性与反亲和性
- nodeName 字段
- Pod 拓扑分布约束
节点标签
与很多其他 Kubernetes 对象类似,节点也有标签。 你可以手动地添加标签。 Kubernetes 也会为集群中所有节点添加一些标准的标签。 参见常用的标签、注解和污点以了解常见的节点标签。
给节点添加标签
1.列出你的集群中的节点, 包括这些节点上的标签:
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ops-control-plane Ready control-plane 19h v1.27.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ops-control-plane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=
ops-worker Ready <none> 19h v1.27.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ops-worker,kubernetes.io/os=linux
ops-worker2 Ready <none> 19h v1.27.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ops-worker2,kubernetes.io/os=linux
ops-worker3 Ready <none> 19h v1.27.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=ops-worker3,kubernetes.io/os=linux
2.从你的节点中选择一个,为它添加标签:
$ kubectl label nodes ops-worker disktype=ssd
node/ops-worker labeled
3.验证你选择的节点确实带有 disktype=ssd
标签:
$ kubectl get node ops-worker --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ops-worker Ready <none> 19h v1.27.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=ops-worker,kubernetes.io/os=linux
如果要取消标签可以执行 kubectl label nodes <节点名称> <标签键>-
$ kubectl label nodes ops-worker disktype-
node/ops-worker unlabeled
创建一个将被调度到你选择的节点的pod
因为指定了 nodeSelector
,因此pod会被调度到有 disktype=ssd
标签的node节点上
cat > pod-nginx.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
EOF
创建一个会被调度到特定节点上的pod
因为指定了 nodeName
,因此pod会被调度到指定的node节点上
cat > pod-nginx-specific-node.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: ops-worker2 # 调度Pod到名为ops-worker2的node节点
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
EOF
亲和性与反亲和性
nodeSelector
提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:
- 亲和性、反亲和性语言的表达能力更强。
nodeSelector
只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。 - 你可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时仍然调度该 Pod。
- 你可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束, 而不是只能使用节点本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。
亲和性功能由两种类型的亲和性组成:
- 节点亲和性功能类似于
nodeSelector
字段,但它的表达能力更强,并且允许你指定软规则。 - Pod 间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod。
节点亲和性
节点亲和性概念上类似于 nodeSelector
, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:
requiredDuringSchedulingIgnoredDuringExecution
: 调度器只有在规则被满足的时候才能执行调度。此功能类似于nodeSelector
, 但其语法表达能力更强。preferredDuringSchedulingIgnoredDuringExecution