kubernetes资源调度

nodeSelector

nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。
Pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,而后调度 Pod 到目标节点,该匹配规则属于强制约束

作用:

  • 约束Pod到特定的节点运行
  • 完全匹配节点标签# nodeAffinity

应用场景:

  • 专用节点:根据业务线将Node分组管理
  • 配备特殊硬件:部分Node配有SSD硬盘、GPU
    默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node。不过有些情况我们希望将 Pod 部署到指定的 Node,比如将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Node,或者 Pod 需要 GPU,需要运行在配置了 GPU 的节点上。
    Kubernetes 是通过 label 来实现这个功能的。

添加标签到节点
执行 kubectl get nodes 命令获取集群的节点名称。 选择一个你要增加标签的节点,然后执行 kubectl label nodes = 命令将标签添加到你所选择的节点上。 例如,如果你的节点名称为 ‘kubernetes-foo-node-1.c.a-robinson.internal’ 并且想要的标签是 ‘disktype=ssd’,则可以执行 kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd 命令。

你可以通过重新运行 kubectl get nodes --show-labels, 查看节点当前具有了所指定的标签来验证它是否有效。 你也可以使用 kubectl describe node “nodename” 命令查看指定节点的标签完整列表。

添加 nodeSelector 字段到 Pod 配置中
选择任何一个你想运行的 Pod 的配置文件,并且在其中添加一个 nodeSelector 部分。

[root@master ~]# vi pod.yml 

---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

# 创建pod
[root@master ~]# kubectl apply -f pod.yml
pod/nginx created

# pod nginx被调度到预期节点运行
[root@master ~]# kubectl get pod nginx -o  wide
NAME    READY   STATUS              RESTARTS   AGE   IP       NODE                NOMINATED NODE   READINESS GATES
nginx   0/1     ContainerCreating   0          12s   <none>   node1.example.com   <none>           <none>

nodeAffinity

目前支持两种类型的node affinity,requiredDuringSchedulingIgnoredDuringExecution 和preferredDuringSchedulingIgnoredDuringExecution,可以他们看作“hard(强制)”和“soft(非强制)”。某种意义上,前者指定了要将pod调度到节点上必须满足的规则(像nodeSelector,但使用了更具表现力的语法),而后者试图调度到特定的节点但不能保证一定会调度到该节点。其中,“IgnoredDuringExecution”表示如果在pod运行时节点的标签发生改变导致无法满足pods创建时使用的调度规则,pod会继续在该节点上运行,这点与nodeSelector相似。将来会提供requiredDuringSchedulingRequiredDuringExecution,与requiredDuringSchedulingIgnoredDuringExecution一样,但是会迁移节点上的pod以满足其node affinity 的规则。

# 设置节点label
[root@master ~]# kubectl label nodes node1.example.com  cpu=high
node/node1.example.com labeled

[root@master ~]# kubectl  label node node1.example.com disktype=ssd
node/node1.example.com labeled

[root@master ~]# kubectl label nodes node2.example.com  cpu=low
node/node2.example.com labeled
部署pod的预期是到ssd类型硬盘(disktype=ssd)、且CPU高配的机器上(cpu=high)。

# 查看满足条件节点
[root@master ~]# kubectl get nodes -l 'cpu=high, disktype=ssd'
NAME                STATUS   ROLES    AGE    VERSION
node1.example.com   Ready    <none>   2d3h   v1.23.1

# pod.yaml文件内容如下
[root@master ~]# cat pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: cpu
            operator: In
            values:
            - high
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    
# pod nginx成功部署到ssd类型硬盘且CPU高配的机器上。
[root@master ~]# kubectl  get pod nginx -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE                NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          27s   10.244.1.33   node1.example.com   <none>           <none>

taint and tolratins

节点亲和性 是 Pod 的一种属性,它使 Pod 被吸引到一类特定的节点 (这可能出于一种偏好,也可能是硬性要求)。 污点(Taint)则相反——它使节点能够排斥一类特定的 Pod。

容忍度(Toleration)是应用于 Pod 上的,允许(但并不要求)Pod 调度到带有与之匹配的污点的节点上。

污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod,是不会被该节点接受的。

# kubectl taint 给节点增加一个污点
kubectl taint nodes node1 key1=value1:NoSchedule

给节点 node1 增加一个污点,它的键名是 key1,键值是 value1,效果是 NoSchedule。 这表示只有拥有和这个污点相匹配的容忍度的 Pod 才能够被分配到 node1 这个节点。

#移除上述命令所添加的污点
kubectl taint nodes node1 key1=value1:NoSchedule-

在 PodSpec 中定义 Pod 的容忍度。 下面两个容忍度均与上面例子中使用 kubectl taint 命令创建的污点相匹配, 因此如果一个 Pod 拥有其中的任何一个容忍度都能够被分配到 node1 :

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
tolerations:
- key: "key1"
  operator: "Exists"
  effect: "NoSchedule"

注:
存在两种特殊情况:

  • 如果一个容忍度的 key 为空且 operator 为 Exists, 表示这个容忍度与任意的 key 、value 和 effect 都匹配,即这个容忍度能容忍任意 taint。
  • 如果 effect 为空,则可以与所有键名 key1 的效果相匹配。

上述例子中 effect 使用的值为 NoSchedule,您也可以使用另外一个值 PreferNoSchedule。 这是“优化”或“软”版本的 NoSchedule —— 系统会 尽量 避免将 Pod 调度到存在其不能容忍污点的节点上, 但这不是强制的。effect 的值还可以设置为 NoExecute,下文会详细描述这个值。

您可以给一个节点添加多个污点,也可以给一个 Pod 添加多个容忍度设置。 Kubernetes 处理多个污点和容忍度的过程就像一个过滤器:从一个节点的所有污点开始遍历, 过滤掉那些 Pod 中存在与之相匹配的容忍度的污点。余下未被过滤的污点的 effect 值决定了 Pod 是否会被分配到该节点,特别是以下情况:

  • 如果未被过滤的污点中存在至少一个 effect 值为 NoSchedule 的污点, 则 Kubernetes 不会将 Pod 分配到该节点。
  • 如果未被过滤的污点中不存在 effect 值为 NoSchedule 的污点, 但是存在 effect 值为 PreferNoSchedule 的污点, 则 Kubernetes 会 尝试不将 Pod 分配到该节点。
  • 如果未被过滤的污点中存在至少一个 effect 值为 NoExecute 的污点, 则 Kubernetes 不会将 Pod 分配到该节点(如果 Pod 还未在节点上运行), 或者将 Pod 从该节点驱逐(如果 Pod 已经在节点上运行)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值