theboyaply

学,就硬学!

  • Home
  • Archives
  • Java
  • Maven
  • Docker
  • Kubernetes
  • JavaScript
  • ES6
  • Vue
  • 踩坑记录
  • noted

  • 搜索
element ui vue wsimport webservice npm mysql redis node nginx nfs ftp es6 开发工具 vscode 前端 javascript springboot 常见问题 tomcat oracle jenkins maven k8s Linux gitlab docker java

k8s 调度流程介绍

发表于 2020-04-02 | 分类于 Kubernetes | 0 | 阅读次数 1178
  • k8s 调度过程介绍
  • 亲和性
    • 节点亲和性
    • Pod 亲和性
    • operator 及调度目标
  • 污点和容忍
    • 污点(taint)
    • 容忍(toleration)
  • 指定调度节点

k8s 调度过程介绍

Scheduler 是 k8s 中的调度器,主要的让你无是把定义的 Pod 分配到集群的节点上。听起来很简单,但有很多要考虑的问题:

  • 公平:如何保证每个节点都能被分配资源。
  • 资源利用率高:集群所有资源最大化被使用。
  • 效率:调度的性能要好,能够尽快的对大批量的 Pod 完成调度工作。
  • 灵活:允许用户根据自己的需求控制调度逻辑。

Scheduler 是作为一个单独的程序运行的,启动之后会一直监听 apiserver。

调度过程

调度过程分为几个部分:

  1. 首先是过滤掉不满足条件的节点,这个过程称为 predicate 。
  2. 然后对满足条件的节点按照优先级排序,这个是 priority。
  3. 最后从中选择优先级最高的节点。

上面步骤中任何步骤有错误,就直接返回错误。

predicate 有一系列的算法可以使用:

  • PodFitsResources:节点上剩余的资源是否大于 Pod 请求的资源。
  • PodFitsHost:如果 Pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配。
  • PodFitsHostPorts:节点上已经使用的 port 是否和 Pod 申请的 port 冲突。
  • PodSelectorMatches:过滤掉和 Pod 指定的 labels 不匹配的节点。
  • NoDiskConflict:已经 mount 的 volume 和 Pod 指定的 volume 不冲突,除非他们都是只读。

如果在 predicate 过程中没有适合的节点,Pod 会一直处于 pending 状态,不断重试调度,直到有节点满足条件。

经过 predicate 后,如果有多个节点满足条件,就继续 priority 过程:按照优先级大小对节点排序。

优先级由一系列键值对组成,键是该优先级的名称,值是它的权重。这些优先级包括:

  • LeastRequestedPriority:通过计算 CPU 和 Memory 的使用率来决定权重,使用率越低权重越高。
  • BalancedResourceAllocation:节点上 CPU 和 Memory 使用率越接近,权重越高。这个应该和 BalancedResourceAllocation 一起使用。
  • ImageLocalityPriority:如果 Pod 要使用的镜像节点中已经有了,并且 镜像总大小值越大,权重越高。

亲和性

亲和性策略,可以设置 Pod 在创建时更倾向创建在哪个节点上。其有两个维度可设置:

  • 节点亲和性:设置节点的相关信息,在创建 Pod 的时候与节点信息进行匹配。
  • Pod 亲和性:设置 Pod 的相关信息,在创建 Pod 的时候与已存在的 Pod 信息进行匹配。

不管是节点亲和性还是 Pod 亲和性,其设置策略中都有 软策略 和 硬策略 两种方案。

  • 软策略:Pod 倾向于创建在某个节点上,如果条件不符合,可以创建在其它节点上。
  • 硬策略:Pod 必须被创建某个节点上,如果条件不符合,那么 Pod 会一直处于 pending 状态。

节点亲和性

pod.spec.affinity.nodeAffinity

  • preferredDuringSchedulingIgnoredDuringExecution:软策略
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略

软策略示例

apiVersion: v1
kind: Pod
metadata:
  name: node-pre-pod
spec:
  containers:
  - name: nginx-container
    image: hub.xixihaha.com/library/mynginx:v1
    ports:
    - containerPort: 80
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - k8s-node01

说明:

  • weight:权重值。一个 Pod 可能会有多个软策略,按照权重值从大到小选择。
  • preference:固定格式。
  • matchExpressions:固定格式。
  • key:节点的标签名称。可使用 kubectl get node --show-labels 查看。
  • values:标签的值。
  • operator:键值运算关系符。

以上资源清单创建的 Pod,会优先在节点标签中含有 kubernetes.io/hostname=k8s-node01 的节点上创建。如果在整个 k8s 集群找不到符合条件的节点,那么 scheduler 会根据一些其它条件自动分配到某一节点中。

硬策略示例

apiVersion: v1
kind: Pod
metadata:
  name: node-req-pod
spec:
  containers:
  - name: nginx-container
    image: hub.xixihaha.com/library/mynginx:v1
    ports:
    - containerPort: 80
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - k8s-node01

以上资源清单创建的 Pod,不会在节点标签中有 kubernetes.io/hostname=k8s-node01 的节点上创建,如果集群中没有符合的节点,那么该 Pod 会一直处于 pending 状态。

当然我们也可以将这两个策略放在一起:

apiVersion: v1
kind: Pod
metadata:
  name: node-pod
spec:
  containers:
  - name: nginx-container
    image: hub.xixihaha.com/library/mynginx:v1
    ports:
    - containerPort: 80
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - k8s-node01
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - k8s-node02

这样的 Pod 会先匹配符合硬策略的节点,然后再匹配符合软策略的节点。

Pod 亲和性

pod.spec.affinity.podAffinity/podAntiAffinity

  • preferredDuringSchedulingIgnoredDuringExecution:软策略
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略

其中的软策略和硬策略与节点亲和性是一个意思。

你可能会注意到,上面的两个可选项:

  • podAffinity:Pod 与指定的 Pod 在同一拓扑域。
  • podAntiAffinity:Pod 与指定的 Pod 不在同一拓扑域。

拓扑域:使用 topologyKey 属性(下方示例中有)定义的值,通俗来讲就是节点的标签。

如果使用的是 podAffinity,那么在 Pod 创建时,如果寻找到了符合条件的 Pod(假设该 Pod 所在的节点标签为 node-x),那么我们要创建的 Pod 就可以在任一含有 node-x 标签的节点中创建。

podAntiAffinity 则反之。

因为软策略与硬策略上面已经介绍过了,这里直接一起放入示例中:

apiVersion: v1
kind: Pod
metadata:
  name: pod-aff-pod
spec:
  containers:
  - name: nginx-container
    image: hub.xixihaha.com/library/mynginx:v1
    ports:
    - containerPort: 80
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: pod-name
            operator: In
            values:
            - nginx-pod
        topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: pod-name
              operator: In
              valuses:
              - nginx-pod
        topologyKey: kubernetes.io/hostname

operator 及调度目标

调度策略匹配标签操作符拓扑域支持调度目标
nodeAffinity主机In、NotIn、Exists、DoesNotExist、Gt、Lt否指定主机
podAffinityPodIn、NotIn、Exists、DoesNotExist是Pod 与指定 Pod 在同一拓扑域
podAnitAffinityPodIn、NotIn、Exists、DoesNotExist是Pod 与指定 Pod 不在同一拓扑域

污点和容忍

上面介绍的 亲和性,是 Pod 的一种属性(偏好或者硬性要求),它使 Pod 被吸引到一类特点的节点。污点(taint)则相反,它使 Pod 排斥一类特点的节点。

污点(taint)和容忍(toleration)相互相互配合,可以用来避免 Pod 被分配到不适合的节点上。每个节点可以有0个或者多个 taint,这表示对于那些不能容忍这些 taint 的 Pod,是不会被创建在这些节点上的。如果将 toleration 应用于 Pod 上,则表示这些 Pod 可以被调度到具有匹配 taint 的节点上。

通俗来讲,就是节点上可以设置污点(taint),如果创建 Pod 时不设置 Pod 的容忍(toleration)的话,那么该 Pod 就不可能被创建在有污点的节点上。

master 节点默认有一个污点,这也就是为什么前面我们创建的 Pod 一直没有被创建在 master 节点上的原因。

[root@k8s-master01 ~]# kubectl get node
NAME           STATUS   ROLES    AGE   VERSION
k8s-master01   Ready    master   15d   v1.15.1
k8s-node01     Ready    <none>   15d   v1.15.1
k8s-node02     Ready    <none>   15d   v1.15.1

[root@k8s-master01 ~]# kubectl describe node k8s-master01
......
Taints:             node-role.kubernetes.io/master:NoSchedule
......

污点(taint)

污点的组成

key=value:effect
  • key=value:每一个污点都有一个 key 和 value 作为 污点的标签,其中 value 可以为空,即 key:effect。我们上面列出的 master 默认污点就是这种格式。

  • effect:描述污点的作用,支持以下三种选项:

    • NoSchedule:k8s 不会将 Pod 调度到具有该污点的 Node 上。
    • PreferNoSchedule:k8s 尽量避免将 Pod 调度到具有该污点的 Node 上。
    • NoExecute:k8s 不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已存在的 Pod 驱逐出去。

    注意:上面描述的前提是所有 Pod 是没有设置容忍的。

设置、去除污点

# 设置污点
kubectl taint nodes k8s-node01 check=test:NoSchedule

# 去除污点,只需要在最后加一个 '-'
kubectl taint nodes k8s-node01 check=test:NoSchedule-

# 查看某个node的污点,其结果中的 Taints 字段便是污点
kubectl describe node k8s-node01

容忍(toleration)

设置了污点的 node 将根据污点的作用(effect)与 Pod 之间产生互斥的关系。但是我们可以在创建 Pod 时为 Pod 设置容忍,意味着 Pod 在创建时可以容忍污点的存在,可以被调度到存在污点的 node 上。

污点的格式如下:

spec:
  tolerations:
  - effect: "NoSchedule"
    key: "key"
    operator: "Exists"
    tolerationSeconds: 3600
    value: "value"

说明:

  • key、value、effect:需要与 node 上的污点标签信息一致。

  • operator:表示 key 与 value 的关系。

    • Exists:忽略 value 的值,只要 key 匹配上即可。
    • Equal:默认为 Equal。
  • tolerationSeconds:如果 effect 的值为 Noexecute,那么 tolerationSeconds 表示 Pod 在被驱逐之前还可以保留运行的时间。

注意:

当不指定 key 时,表示容忍所有的污点 key:

spec:
  tolerations:
  - operator: "Exists"

当不指定 effect 时,表示容忍所有的污点作用:

spec:
  tolerations:
  - key: "key"
    operator: "Exists"

有多个 master 存在时,防止资源浪费,可以如下设置:

kubectl taint nodes node-name node-role.kubernetes.io/master=:PreferNoSchedule

指定调度节点

如果你想要指定 Pod 被调度到具体的 node 上,那么你可以这样做:

kind: Pod
spec:
  nodeName: k8s-node01
# 或者
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node01

nodeName:将 Pod 直接调度到指定的 node 节点上,会跳过 Scheduler 的调度策略,是强制匹配。

nodeSelector:通过 k8s 的 label-selector 机制选择节点,由调度器策略匹配 label,而后调度 Pod 到目标节点上,该匹配规则属于强制约束。

-- end --

# k8s
2-maven 安装及运行过程详解
xshell连接CentOS使用命令上传下载
  • 文章目录
  • 站点概览
theboyaply

theboyaply

好记性不如烂笔头

184 日志
13 分类
27 标签
Github E-mail
Creative Commons
0%
© 2019 — 2023 theboyaply
由 Halo 强力驱动
|
主题 - NexT.Gemini
湘ICP备19009291号

湘公网安备 43312402001034号