运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • Devops笔记

  • Kubernetes

    • k8s 使用YAML配置文件管理资源
    • k8s 调度约束
      • 1. 调度器的工作机制
        • 1.1 预备工作
        • 1.2 调度过程
        • 1.2.1 过滤阶段
        • 1.2.2 打分阶段
      • 2. 调度方式
      • 3. 调度策略
        • 3.1 nodeSelector:node标签选择器
        • 3.2 affinity 和 anti-affinity:亲和性和反亲和性
        • 3.2.1 nodeAffinity node亲和性
        • 3.2.2 podAffinity pod亲和性
        • 3.2.3 podAntiAffinity pod反亲和性
        • 3.3 nodeAffinity示例
        • 3.4 podAffinity pod亲和性 和 podAntiAffinity pod反亲和性示例
        • 3.5 软限制
        • 3.6 硬限制
        • 3.7 taint 和 toleration:污点和容忍
        • 3.7.1 taint 污点
        • 3.7.2 toleration 容忍
        • 3.7.3 硬规则
        • 3.7.4 软规则
    • k8s 资源约束
    • k8s 健康检测
    • k8s 重启策略
    • k8s pod管理
    • k8s DaemonSet典型应用
    • k8s Job任务
    • k8s service服务
  • 运维监控系统

  • go分布式爬虫

  • Linux性能优化

  • 夜莺(nightingale)开源观测平台

  • kubernetes-network-policy-recipes

  • 专栏
  • Kubernetes
lyndon
2022-10-05
目录

k8s 调度约束

kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群控制面的一部分。

# 1. 调度器的工作机制

# 1.1 预备工作

  • 1、缓存所有的node节点,记录他们的规格:cpu、内存、磁盘空间、gpu显卡数等;
  • 2、缓存所有运行中的pod,按照pod所在的node进行区分,统计每个node上的pod request了多少资源。request是pod的QoS配置
  • 3、list & watch pod资源,当检查到有新的Pending状态的pod出现,就将它加入到调度队列中
  • 4、调度器的worker组件从队列中取出pod进行调度

# 1.2 调度过程

# 1.2.1 过滤阶段

  • 1、先将当前所有的node放入队列

  • 2、执行predicates算法,对队列中的node进行筛选。

    这里算法检查了一些pod运行的必要条件,包括port不冲突、cpu和内存资源QoS(如果有的话)必须满足、挂载volume(如果有的话)类型必须匹配、nodeSelector规则必须匹配、硬性的affinity规则必须匹配、node的状态(condition)必须正常,taint_toleration硬规则等等。

# 1.2.2 打分阶段

  • 3、执行priorities算法,对队列中剩余的node进行评分。

    这里有许多评分项,各个项目有各自的权重:整体cpu,内存资源的平衡性、node上是否有存在要求的镜像、同rs的pod是否有调度、node affinity的软规则、taint_toleration软规则等等。

  • 4、最终评分最高的node会被选出。

    即代码中suggestedHost, err := sched.schedule(pod) 依据(plugin/pkg/scheduler/scheduler.go)的返回值。如果存在多个得分最高的 Node,kube-scheduler 会从中随机选取一个。

  • 5、调度器执行assume方法。

    该方法在pod调度到node之前,就以“该pod运行在目标node上” 为场景更新调度器缓存中的node 信息,也即预备工作中的1、2两点。这么做是为了让pod在真正调度到node上时,调度器也可以同时做后续其他pod的调度工作。

  • 6、调度器执行bind方法,该方法创建一个Binding资源,apiserver检查到创建该资源时,会主动更新pod的nodeName字段。完成调度。

# 2. 调度方式

  • 全自动调度:运行在哪个节点上完全由master的scheduler经过一系列的算法计算得出, 用户无法进行干预。

  • nodeselector定向调度: 指定pod调度到一些node上, 通过设置node的标签和deployment的nodeSelctor属性相匹配。

    • 多个node有相同标签, scheduler 会选择一个可用的node进行调度;
    • nodeselector定义的标签匹配不上任何node上的标签, 这个pod是无法调度;
    • k8s给 node 预定义了一些标签, 通过kubectl describe node xxxx进行查看用户可以使用k8s给node预定义的标签。
  • NodeAffinity: node节点亲和性

    • 硬限制 : 必须满足指定的规则才可以调度pod到node上。
    • 软限制 : 优先满足指定规则,调度器会尝试调度pod到node上, 但不强求。
  • PodAffinity: pod亲和与互斥调度, 根据在节点上正在运行的pod标签而不是节点的标签进行判断和调度

    • 亲和: 匹配标签两个pod调度到同一个node上;
    • 互斥: 匹配标签两个pod不能运行在同一个node上。

# 3. 调度策略

# 3.1 nodeSelector:node标签选择器

常规情况下,会直接使用nodeSelector这种调度策略。

labels(标签) 是k8s里面用来编标记资源的一种常用的方式,我们可以给node标记特殊的标签,然后nodeSelector会将pod调度到带有指定labels的node上

#增加标签
kubectl label nodes node01 test=test

#在spec.template.spec段添加:
nodeSelector:
  test: test
1
2
3
4
5
6

# 3.2 affinity 和 anti-affinity:亲和性和反亲和性

亲和性可以分为具体可以细分为 硬亲和性 和 软亲和性。

  • 软亲和性:如果调度的时候,没有满足要求,也可以继续调度,即能满足最好,不能也无所谓。

    软策略: preferredDuringSchedulingIgnoredDuringExecution;

  • 硬亲和性:是指调度的时候必须满足特定的要求,如果不满足,那么pod将不会被调度到当前node。

    硬策略: requiredDuringSchedulingIgnoredDuringExecution;

# 3.2.1 nodeAffinity node亲和性

主要是用来控制 pod 能部署在哪些节点上,以及不能部署在哪些节点上的。它可以进行一些简单的逻辑组合,不只是简单的相等匹配。

# 3.2.2 podAffinity pod亲和性

pod的亲和性主要用来解决pod可以和哪些pod部署在同一个集群里面,即拓扑域(由node组成的集群)里面。

# 3.2.3 podAntiAffinity pod反亲和性

pod的反亲和性是为了解决pod不能和哪些pod部署在一起的问题。

二者都是为了解决pod之间部署问题。

需要注意的是,Pod 间亲和与反亲和需要大量的处理,这可能会显著减慢大规模集群中的调度,不建议在具有几百个节点的集群中使用,而且Pod 反亲和需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配 topologyKey。如果某些或所有节点缺少指定的 topologyKey 标签,可能会导致意外行为。

topologyKey的值一般是kubernetes的内置标签:

  • ​ 对于亲和性和软反亲和性,不允许空topologyKey;
  • ​ 对于硬反亲和性,LimitPodHardAntiAffinityTopology控制器用于限制topologyKey只能是kubernetes.io/hostname;
  • ​ 对于软反亲和性,空topologyKey被解读成kubernetes.io/hostname, failure-domain.beta.kubernetes.io/zone and failure-domain.beta.kubernetes.io/region的组合;

kubernetes.io/hostname标签是Kubernetes集群节点的内建标签,它的值为当前节点的主机名,对于各个节点来说都是不同的

查看kubernetes内置标签:

kubectl -get nodes --show-labels
    ○ kubernetes.io/hostname
    ○ failure-domain.beta.kubernetes.io/zone
    ○ failure-domain.beta.kubernetes.io/region
    ○ beta.kubernetes.io/instance-type
    ○ beta.kubernetes.io/os
    ○ beta.kubernetes.io/arch
1
2
3
4
5
6
7

# 3.3 nodeAffinity示例

在spec段:

affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
   - matchExpressions:
     - key: kubernetes.io/e2e-az-name
       operator: In
       values:
       - e2e-az1
       - e2e-az2
         preferredDuringSchedulingIgnoredDuringExecution:
         - weight: 1
           preference:
           matchExpressions:
           - key: another-node-label-key
             operator: In
             values:
             - another-node-label-value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

这个pod只允许被调度到带有kubernetes.io/e2e-az-name=e2e-az1或e2e-az2的label的node上,也即只允许被调度到e2e-az1或者e2e-az2两个可用域中;

另外,pod要尽量调度到包含another-node-label-key的值为another-node-label-value的node上

matchExpressions 结构记录各种表达式,一个表达式包含key、operator、values,分别表示关键字、关键字匹配关系、关键字匹配值。

operator 匹配关系包括:

  • In:label 的值在某个标签中
  • NotIn:label 的值不在某个标签中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

NotIn和DoesNotExist是node anti-affinity的一种表现。

  • 如果一个pod的描述信息中同时包含了 nodeSelector 和 nodeAffinity,那么调度时两个规则都要满足;
  • 如果一个 nodeAffinity 中包含了多条 nodeSelectorTerms , 调度器只需要满足其中一条;
  • 如果一个 nodeSelectorTerms中记录了多条matchExpressions,那么调度器要满足所有的matchExpressions。

# 3.4 podAffinity pod亲和性 和 podAntiAffinity pod反亲和性示例

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: kubernetes.io/hostname
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

podAffinity 规则中 topologyKey 是zone,也就是可用域,说明这条规则可以规划出调度到的域。

首先,node上必须至少有一个running状态的pod包含key为security,value为S1的label。只要满足这个条件,那么这个node和其同一个域(拥有相同的failure-domain.beta.kubernetes.io/zone 为key,且值相同的label)的node均会被调度。

podAntiAffinity规则中topologyKey是hostname,表明该规则约定了某种node尽量不会被调度到,这种node上已经运行了包含key为security,value为S2的label的pod。

假如现在有node a,b,c,其中a和b拥有相同的zone,且b上运行了一个pod,这个pod有一个label,key为security,value为S1。那么我们创建如上的一个亲和性规则的3副本时,三个副本都会被调度到a或者b上。假如b上同时运行了一个pod,这个pod有一个label,key为security,value为S2,那么所有的副本都会调度到node a上。

# 3.5 软限制

      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - bluwhale-application
                topologyKey: kubernetes.io/hostname
              weight: 100
1
2
3
4
5
6
7
8
9
10
11
12

# 3.6 硬限制

      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - bluwhale-application
              topologyKey: kubernetes.io/hostname
1
2
3
4
5
6
7
8
9
10

# 3.7 taint 和 toleration:污点和容忍

node 可以被打上污点标记,并配置污点容忍策略。而pod的描述信息中如果包含了相同的污点容忍策略,就可以被调度到这个node上,反之则不可、或尽量不允许。

# 3.7.1 taint 污点

给node a 打上污点 name=huang, 策略为不可调度:

kubectl taint nodes a name=huang:NoSchedule
1

# 3.7.2 toleration 容忍

若pod中有以下描述则可以调度:

tolerations:
- key: "role"
  operator: "Equal"
  value: "messi"
  effect: "NoSchedule"

或者:
tolerations:
- key: "name"
  operator: "Exist"
  effect: "NoSchedule"
1
2
3
4
5
6
7
8
9
10
11

# 3.7.3 硬规则

类似的硬性规则体现在effect字段中,还有NoExecute,它比NoSchedule更严格,不止pod不能调度上去,node上原有的pod如果不能容忍污点,就会被驱逐(eviction),配合字段 tolerationSeconds 可以规定这些会被驱逐的pod能在node上呆多久。

# 3.7.4 软规则

除了NoExecute,NoSchedule,还有一条软规则:PreferNoSchedule。

配置effect=PreferNoSchedule后,没有相关污点策略的pod会尽量避免调度到该node上。

上次更新: 2022/10/05, 02:02:36
k8s 使用YAML配置文件管理资源
k8s 资源约束

← k8s 使用YAML配置文件管理资源 k8s 资源约束→

最近更新
01
ctr和crictl显示镜像不一致
03-13
02
alpine镜像集成常用数据库客户端
03-13
03
create-cluster
02-26
更多文章>
Theme by Vdoing | Copyright © 2015-2024 op81.com
苏ICP备18041258号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式