k8s调度方式

2023-01-09  本文已影响0人  宏势

k8s 支持三大类调度方式:

一.节点亲和调度

用于约束一个 Pod以便 限制 其只能在特定的节点上运行, 或优先在特定的节点上运行。

1. nodeSelector

nodeSelector 是节点选择约束的最简单的方式,通过添加nodeSelector 字段添加到 Pod 的规约中设置你希望的目标节点所具有的标签,Kubernetes 只会将 Pod 调度到拥有你所指定的每个标签的节点上,常用于节点隔离。
例子:只能调度到具有type: test 标签的节点上

spec:
   nodeSelector:
        type: test

使用标签来实现节点隔离,建议选择节点上的 无法修改的标签键(NodeRestriction 准入插件防止 kubelet 使用 node-restriction.kubernetes.io/ 前缀设置或修改标签)。 这可以防止受感染的节点在自身上设置这些标签, 比如:example.com.node-restriction.kubernetes.io/pci-dss=true

2.通过NodeAffinity调度插件

利用NodeAffinity调度插件实现节点亲和性(.spec.affinity.nodeAffinity),具有更强的表达能力,且允许定义软规则。
节点亲和性有两种:

IgnoredDuringExecution 意味着如果节点标签在 Kubernetes 调度 Pod 后发生了变更,Pod 仍将继续运行

例子:只能运行在具有便签type=dev 或者 type=test的节点上,且优先选择具有便签键gpu节点上

···
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: type
            operator: In
            values:
            - dev
            - test
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: gpu
            operator: Exists
  containers:
···

1.operator 字段支持InNotInExistsDoesNotExistGtLt
2.nodeSelectorTerms指定多个条件是逻辑或的关系,单个matchExpressions多个表达式是逻辑与的关系

3.nodeName

nodeName 是比亲和性和nodeSelector 更为直接的形式。nodeName 是 Pod 规约中的一个字段。指定节点上的 kubelet 会尝试将 Pod 放到该节点上。 nodeName 规则的优先级会高于nodeSelector 或亲和性与非亲和性的规则(不建议使用)

直接运行在node-01节点上

spec:
  nodeName: node-01

二. Pod间亲和调度

Pod间亲和性和反亲和性调度(PodAffinity、PodUnAffinity)可以基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到的节点,而不是基于节点上的标签与节点亲和性类似, 常用于确保相关的Pod运行在“同一位置”,Pod 的亲和性与反亲和性也有两种类型:

例如Webapp 的Deployment , webapp 副本跟redis调度到同一位置 topologyKey:zone

···
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  
      - labelSelector:
          matchExpressions:
          - {key: app,  operator: In, values: ["redis"]}
        topologyKey: zone   #拓扑键,用于确定节点位置的节点标签,必须
  containers:
···

例如Redis的Deployment, redis 副本不要调度到同一节点上

···
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - {key: app,  operator: In, values: ["redis"]}
          topologyKey: "kubernetes.io/hostname"
  containers:
···

topologyKey 可以是任何合法的标签键。出于性能和安全原因,topologyKey 有一些限制:
对于 Pod 亲和性而言,在 requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution 中,topologyKey不允许为空。
对于 requiredDuringSchedulingIgnoredDuringExecution 要求的 Pod 反亲和性, 准入控制器 LimitPodHardAntiAffinityTopology 要求 topologyKey 只能是 kubernetes.io/hostname。如果你希望使用其他定制拓扑逻辑, 你可以更改准入控制器或者禁用之

可以通过与 labelSelector 和 topologyKey同层级 labelSelector 指定要匹配的命名空间列表, 如果 namespaces 被忽略或者为空,则默认为 Pod 亲和性/反亲和性的定义所在的命名空间

三.污点容忍调度

通过定义节点上Taints污点,用于让节点有能力主动拒绝调度器将pod调度到节点上,除非该pod具有接纳节点污点的容忍度, 简单说提供主动排斥Pod的能力。

1.定义污点(节点上)

kubectl taint nodes node1 key1=value1:NoSchedule #语法key=value:affective
kubectl taint nodes node1 key1=value1:NoSchedule- 

2.污点效用标识

3.定义容忍度(Pod)

通过spec.tolerations定义容忍度,一个容忍度和一个污点相“匹配”是指它们有一样的键名和效果
容忍污点key1=value1:NoSchedule

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

或者

...
spec:
    tolerations:
    - key: "key1"
      operator: "Exists" #此时容忍度不能指定value,代表容忍存在键值为key1 效果是NoSchedule的污点
      effect: "NoSchedule"
...

存在两种特殊情况:
如果一个容忍度的 key 为空且 operator 为 Exists, 表示这个容忍度与任意的 key、value 和 effect 都匹配,即这个容忍度能容忍任何污点。
如果 effect 为空,则可以与所有键名 key1 的效果相匹配

一个节点可以定义多个污点,Pod必须匹配节点上所有污点才算符合条件

延迟驱逐

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600  #当Pod不能容忍污点,Pod 还将继续在节点上运行 3600 秒,然后被驱逐

4.使用场景

上一篇 下一篇

猜你喜欢

热点阅读