Pod调度(定向调度NodeName/NodeSelector亲和性调度NodeAffinity/PodAffinity/PodAntiAffinity污点Taints和容忍调度Toleration)

本文介绍了Kubernetes中Pod的调度方式,包括定向调度的nodeName和nodeSelector,亲和性调度的NodeAffinity、PodAffinity和PodAntiAffinity,以及污点Taints和容忍Toleration机制。定向调度通过指定NodeName或NodeSelector将Pod约束到特定节点,亲和性调度提供更灵活的选择。污点和容忍则允许Node拒绝或接受带有特定污点的Pod调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、pod调度概述

在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制某些Pod到达某些节点上,那么应该怎么做呢?这就要求了解kubernetes对Pod的调度规则。

kubernetes提供了四大类调度方式:

  • 自动调度:运行在哪个节点上完全由Scheduler经过一系列的算法计算得出
  • 定向调度:NodeName、NodeSelector
  • 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
  • 污点(容忍)调度:Taints、Toleration

二、定向调度

定向调度,指的是利用在pod上声明 nodeName 或者 nodeSelector ,以此将Pod调度到期望的node节点上。

注意,这里的调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已。

(一)nodeName

NodeName用于强制约束将Pod调度到指定的Name的Node节点上。

这种方式,其实是直接跳过Scheduler的调度逻辑,直接将Pod调度到指定名称的节点。

[root@k8s-master ~]# vim pod-nodename.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx-port
      containerPort: 801
  nodeName: k8s-node01  # 指定将该pod调度到k8s-node01节点上。nodeName键所指定的值必须是 kubectl get node 命令所查出来的,nodeName是固定写法

[root@k8s-master ~]# kubectl get node
NAME         STATUS   ROLES    AGE     VERSION
k8s-master   Ready    master   5d20h   v1.17.4
k8s-node01   Ready    <none>   5d20h   v1.17.4
k8s-node02   Ready    <none>   5d20h   v1.17.4

[root@k8s-master ~]# kubectl create -f pod-nodename.yaml 
pod/pod-nodename created

[root@k8s-master ~]# kubectl get pod pod-nodename -n test -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
pod-nodename   1/1     Running   0          17s   10.244.1.36   k8s-node01   <none>           <none>

[root@k8s-master ~]# kubectl delete -f pod-nodename.yaml 
pod "pod-nodename" deleted

# 指定将pod运行在一个不属于集群中的某节点上
[root@k8s-master ~]# vim pod-nodename.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx-port
      containerPort: 80
  nodeName: node100

[root@k8s-master ~]# kubectl create -f pod-nodename.yaml 
pod/pod-nodename created

[root@k8s-master ~]# kubectl get pod pod-nodename -n test -o wide -w
NAME           READY   STATUS    RESTARTS   AGE   IP       NODE      NOMINATED NODE   READINESS GATES
pod-nodename   0/1     Pending   0          29s   <none>   node100   <none>           <none>
pod-nodename   0/1     Terminating   0          56s   <none>   node100   <none>           <none>
pod-nodename   0/1     Terminating   0          56s   <none>   node100   <none>           <none>
# 因为没有该节点,所以无法调度到,过一会就会自动删除该pod

(二)nodeSelector

NodeSelector用于将pod调度到添加了指定标签的node节点上。

它是通过kubernetes的label-selector机制实现的,也就是说,在pod创建之前,会由sceduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束,没有则失败。

首先为node节点添加标签:

[root@k8s-master ~]# kubectl label node k8s-node01 nodeenv=pro
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl label node k8s-node02 nodeenv=test
node/k8s-node02 labeled

# 查看
[root@k8s-master ~]# kubectl get node --show-labels
NAME         STATUS   ROLES    AGE     VERSION   LABELS
k8s-master   Ready    master   5d20h   v1.17.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8s-node01   Ready    <none>   5d20h   v1.17.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,nodeenv=pro
k8s-node02   Ready    <none>   5d20h   v1.17.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02,kubernetes.io/os=linux,nodeenv=test

创建使用nodeSelector调度pod的配置文件:

[root@k8s-master ~]# vim pod-nodeselector.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
  nodeSelector:
    nodeenv: pro   # 指定调度到具有 nodeenv=pro 标签的节点上。键值对必须存在,不存在调度会失败

# 创建
[root@k8s-master ~]# kubectl create -f pod-nodeselector.yaml
pod/pod-nodeselector created

# 调度到指定节点上
[root@k8s-master ~]# kubectl get pod pod-nodeselector -n test -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
pod-nodeselector   1/1     Running   0          16s   10.244.1.37   k8s-node01   <none>           <none>

# 删除
[root@k8s-master ~]# kubectl delete -f pod-nodeselector.yaml 
pod "pod-nodeselector" deleted

# 指定pod调度带到在不存在的节点标签上
[root@k8s-master ~]# vim pod-nodeselector.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
  nodeSelector:
    nodeenv: pro100   # 不存在的节点标签

[root@k8s-master ~]# kubectl create -f pod-nodeselector.yaml
pod/pod-nodeselector created

# 找不带此node节点,调度失败
[root@k8s-master ~]# kubectl get pod pod-nodeselector -n test -o wide -w
NAME               READY   STATUS    RESTARTS   AGE    IP       NODE     NOMINATED NODE   READINESS GATES
pod-nodeselector   0/1     Pending   0          2m3s   <none>   <none>   <none>           <none>

[root@k8s-master ~]# kubectl describe pod pod-nodeselector -n test
……省略……
Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.  # 在3个节点(1个master,2个node)上无法找到具有该标签的节点

# 虽然调度失败,但不会自动删除该pod,需手动删除
[root@k8s-master ~]# kubectl delete -f pod-nodeselector.yaml 
pod "pod-nodeselector" deleted

# 删除主机标签
[root@k8s-master ~]# kubectl label node k8s-node01 nodeenv-
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl label node k8s-node02 nodeenv-
node/k8s-node02 labeled

三、亲和性调度

上面基于 nodeName 和 nodeSelector 的两种定向调度的方式,使用比较方便,但是存在一定问题,那就是如果没有满足条件的node,那么pod将不会被调度和运行,即使在集群中还有可用node列表也不行,这就限制了它的使用场景。

基于此问题,kubernetes提供了一种亲和性调度(Affinity)。它在NodeSelector的基础之上的进行了扩展,可以通过配置的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使调度更加灵活。

Affinity主要分为三类:

  • nodeAffinity(node亲和性) ∶以node为目标,解决pod可以调度到哪些node的问题
  • podAffinitypod亲和性):以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
  • podAntiAffinity(pod反亲和性):以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题

关于亲和性(反亲和性)使用场景的说明:

亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。


反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值