k8s资源调度

默认的情况下,一个pod在哪个node节点上运行,是由scheduler组件采取对应的算法计算出来的,这个过程是不受人工控制的,在实际的使用过程中,这不能够满足客观的场景,针对这样的情况,k8s 提供了四大类调度方式:

  1. 自动调度: 运行在哪个node节点上完全由scheduler 经过一些里的算法计算出来
  2. 定向调度:NodeName、NodeSelector
  3. 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
  4. 污点(容忍)调度:taints、Toleration
  • 定向调度

定向调度,指的是利用在 Pod 上声明的 nodeName 或 nodeSelector ,以此将 Pod 调度到期望的 Node 节点上。这里的调度是强制的,这就意味着即使要调度的目标 Node 不存在,也会向上面进行调度,只不过 Pod 运行失败而已。

NodeName方式调度

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  nodeName: k8s-node1 # 指定调度到k8s-node1节点上
  containers:
  - name: nginx
    image: nginx:1.20.2
    resources:
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    ports:
    - containerPort:  80
      name:  http
    volumeMounts:
    - name: localtime
      mountPath: /etc/localtime
  volumes:
    - name: localtime
      hostPath:
        path: /usr/share/zoneinfo/Asia/Shanghai
  restartPolicy: Always

NodeSelector方式调度

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  nodeSelector:
    nodeevn: pro # 指定调度到 nodeevn = pro 标签的 Node 节点上
  containers:
  - name: nginx
    image: nginx:1.20.2
    resources:
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    ports:
    - containerPort: 80
      name:  http
    volumeMounts:
    - name: localtime
      mountPath: /etc/localtime
  volumes:
    - name: localtime
      hostPath:
        path: /usr/share/zoneinfo/Asia/Shanghai
  restartPolicy: Always
  • 亲和性调度

虽然定向调度的两种方式,使用起来非常方便,但是也有一定的问题,那就是如果没有满足条件的 Node,那么 Pod 将不会被运行,即使在集群中还有可用的 Node 列表也不行,这就限制了它的使用场景。基于上面的问题,Kubernetes 还提供了一种亲和性调度(Affinity)。它在 nodeSelector 的基础之上进行了扩展,可以通过配置的形式,实现优先选择满足条件的 Node 进行调度,如果没有,也可以调度到不满足条件的节点上,使得调度更加灵活。

● Affinity 主要分为三类:

○ nodeAffinity(node亲和性):以 Node 为目标,解决 Pod可 以调度到那些 Node 的问题。

○ podAffinity(pod亲和性):以 Pod 为目标,解决 Pod 可以和那些已存在的 Pod 部署在同一个拓扑域中的问题。

○ podAntiAffinity(pod反亲和性):以 Pod 为目标,解决 Pod 不能和那些已经存在的 Pod 部署在同一拓扑域中的问题。

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

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

● 反亲和性:当应用采用多副本部署的时候,那么就有必要利用反亲和性让各个应用实例打散分布在各个 Node 上,这样可以提高服务的高可用性。

yaml 复制代码
pod.spec.affinity.nodeAffinity
  requiredDuringSchedulingIgnoredDuringExecution  # Node节点必须满足指定的所有规则才可以,硬性过滤
    nodeSelectorTerms  # 节点选择列表
      matchFields   # 按节点字段列出的节点选择器要求列表  
      matchExpressions   # 按节点标签列出的节点选择器要求列表(推荐)
        key    # 键
        values # 值
        operator # 关系符 支持Exists, DoesNotExist, In, NotIn, Gt, Lt
  preferredDuringSchedulingIgnoredDuringExecution # 优先调度到满足指定的规则的Node,软性评分 (倾向)   
    preference   # 一个节点选择器项,与相应的权重相关联
      matchFields # 按节点字段列出的节点选择器要求列表
      matchExpressions   # 按节点标签列出的节点选择器要求列表(推荐)
        key # 键
        values # 值
        operator # 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt  
    weight # 倾向权重,在范围1-100。

● podAffinity 主要实现以运行的 Pod 为参照,实现让新创建的 Pod 和参照的 Pod 在一个区域的功能。

● podAntiAffinity 主要实现以运行的 Pod 为参照,让新创建的 Pod 和参照的 Pod 不在一个区域的功能。

● PodAffinity 的可选配置项:

yaml 复制代码
pod.spec.affinity.podAffinity
  requiredDuringSchedulingIgnoredDuringExecution  硬限制
    namespaces 指定参照pod的namespace
    topologyKey 指定调度作用域
    labelSelector 标签选择器
      matchExpressions  按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values 值
        operator 关系符 支持In, NotIn, Exists, DoesNotExist.
      matchLabels    指多个matchExpressions映射的内容  
  preferredDuringSchedulingIgnoredDuringExecution 软限制    
    podAffinityTerm  选项
      namespaces
      topologyKey
      labelSelector
         matchExpressions 
            key    键  
            values 值  
            operator
         matchLabels 
    weight 倾向权重,在范围1-1
  • 污点和容忍

● 前面的调度方式都是站在 Pod 的角度上,通过在 Pod 上添加属性,来确定 Pod 是否要调度到指定的 Node 上,其实我们也可以站在 Node 的角度上,通过在 Node 上添加污点属性,来决定是否运行 Pod 调度过来。

● Node 被设置了污点之后就和 Pod 之间存在了一种相斥的关系,进而拒绝 Pod 调度进来,甚至可以将已经存在的 Pod 驱逐出去。

污点的格式为:

key=value:effect

key 和 value 是污点的标签及对应的值

effect 描述污点的作用

● effect 支持如下的三个选项:

○ PreferNoSchedule:Kubernetes 将尽量避免把 Pod 调度到具有该污点的 Node 上,除非没有其他节点可以调度;换言之,尽量不要来,除非没办法。

○ NoSchedule:Kubernets 将不会把 Pod 调度到具有该污点的 Node 上,但是不会影响当前 Node 上已经存在的 Pod ;换言之,新的不要来,在这的就不要动。

○ NoExecute:Kubernets 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐;换言之,新的不要来,这这里的赶紧走。

  1. 新增污点

kubectl taint node xxx key=value:effect

  1. 去除污点

kubectl taint node xxx key:effect-

  1. 去除所有污点

kubectl taint node xxx key-

  1. 查看污点

kubectl describe node xxx | grep -i taints


容忍:

● 上面介绍了污点的作用,我们可以在 Node上 添加污点用来拒绝 Pod 调度上来,但是如果就是想让一个 Pod 调度到一个有污点的 Node 上去,这时候应该怎么做?这就需要使用到容忍。

污点就是拒绝,容忍就是忽略,Node 通过污点拒绝 Pod 调度上去,Pod 通过容忍忽略拒绝。

kubectl explain pod.spec.tolerations

...

FIELDS:

key # 对应着要容忍的污点的键,空意味着匹配所有的键

value # 对应着要容忍的污点的值

operator # key-value的运算符,支持Equal和Exists(默认)

effect # 对应污点的effect,空意味着匹配所有影响

tolerationSeconds # 容忍时间, 当effect为NoExecute时生效,表示pod在Node上的停留时间

● 污点和容忍的匹配:

○ 当满足如下条件的时候,Kubernetes 认为污点和容忍匹配:

■ 键(key)相同。

■ 效果(effect)相同。

■ 污点的 operator 为:

● Exists ,此时污点中不应该指定 value 。

● Equal,此时容忍的 value 应该和污点的 value 相同。

○ 如果不指定 operator ,默认为 Equal 。

● 特殊情况:

○ 容忍中没有定义 key ,但是定义了 operator 为 Exists ,Kubernetes 则认为此容忍匹配所有的污点,如:

yaml 复制代码
tolerations:
- operator: Exists
# 最终,所有有污点的机器我们都能容忍,Pod 都可以调度。
yaml 复制代码
  tolerations: # 容忍
    - key: "tag" # 要容忍的污点的key
      operator: Exists # 操作符
# 最终,有这个污点的机器我们可以容忍,Pod 都可以调度。
相关推荐
CSH0562 小时前
haproxy程序崩溃问题处理
docker·kubernetes
misakivv5 小时前
Centos7.9 使用 Kubeadm 自动化部署 K8S 集群(一个脚本)
运维·云原生·容器·kubernetes·自动化
周湘zx8 小时前
k8s下的网络通信与调度
linux·运维·云原生·容器·kubernetes
是芽芽哩!16 小时前
【Kubernetes】常见面试题汇总(三十)
云原生·容器·kubernetes
是芽芽哩!1 天前
【Kubernetes】常见面试题汇总(二十三)
云原生·容器·kubernetes
Hai9902181 天前
PromQl语句
kubernetes·prometheus
赵渝强老师1 天前
【赵渝强老师】K8s的DaemonSets控制器
linux·docker·云原生·容器·kubernetes
福大大架构师每日一题1 天前
16.3 k8s容器cpu内存告警指标与资源request和limit
容器·贪心算法·kubernetes·prometheus
莫得等待1 天前
kubernetes架构
容器·架构·kubernetes
是小赵鸭.2 天前
云计算实训50——Kubernetes基础命令、常用指令
linux·深度学习·容器·kubernetes·云计算·学习方法