默认情况下pod被分配到哪个node都是随机的,但是很多情况下这不太符合预期。例如有多台node,有的属于cpu密集型适合逻辑运算,有的属于gpu密集型适合机器学习。这时候就需要对pod调度的node有所规划,这一节学习第一种方式,根据亲和性进行调度。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

文章目录

  • 一些概念
    • Affinity和Anti-affinity
    • NodeAffinity和PodAffinity
    • 软策略和硬策略
  • 实际操作
    • NodeAffinity实际操作
      • 硬策略
      • 软策略
    • PodAffinity实际操作
      • 硬策略
      • 软策略
  • 总结

一些概念

Affinity对应pod的pod.spec.affinity字段,下面有多种组合配置,需要先明白一些概念

Affinity和Anti-affinity

亲和性分为正向的Affinity,表示愿意被分配至目标node,和反向的Anti-affinity,表示不愿意被分配至目标node。

NodeAffinity和PodAffinity

两个不同维度的亲和性策略,NodeAffinity是根据node的标签去决定是否分配。而PodAffinity是根据pod的标签去决定要不要和别的pod分配到一个node。

软策略和硬策略

软策略字段以preferred开头,表示尽量达到,没满足也没关系,多个软策略之间会有各自权重。硬策略字段以required开头,表示必须满足。

实际操作

因为本节的概念理解起来相对容易,所以直接上手操作。不过因为字段组合较多,建议多利用kubectl explain pod.spec.affinity查看各个字段的含义。

以下所有yaml文件托管在我的Github仓库

NodeAffinity实际操作

硬策略

通过下面的yaml文件test-nodeaffinity-hard.yaml来验证下node亲和性的硬策略

apiVersion: v1
kind: Pod
metadata:name: test-nodeaffinity-hardlabels:app: app1
spec:containers:- name: mynginximage: mynginx:v2affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- k8s-node3

这里的matchExpressions是比配node的labels,底下的三个字段如下

字段 类型 说明
key string node的标签的key
operator string 判断符号,可以选In/NotIn/Exists/DoesNotExist/Gt/Lt
values list 一组值,结合上面的运算符号进行判断

node的labels可以用如下方式查看

[root@k8s-master affinity]# kubectl get node --show-labels
NAME         STATUS   ROLES    AGE   VERSION    LABELS
k8s-master   Ready    master   14d   v1.15.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8s-node1    Ready    <none>   14d   v1.15.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux

我这里有两个node,它们的hostname都不是k8s-nodes,在这种硬策略下该pod没有node可以分配

[root@k8s-master affinity]# kubectl apply -f test-nodeaffinity-hard.yaml
pod/test-nodeaffinity-hard created
[root@k8s-master affinity]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
test-nodeaffinity-hard   0/1     Pending   0          6s    <none>   <none>   <none>           <none>

这是修改下pod的信息

apiVersion: v1
kind: Pod
metadata:name: test-nodeaffinity-hardlabels:app: app1
spec:containers:- name: mynginximage: mynginx:v2affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- k8s-master

再启动,无论启动多少次都只会在master节点

[root@k8s-master affinity]# kubectl apply -f test-nodeaffinity-hard.yaml
pod/test-nodeaffinity-hard created
[root@k8s-master affinity]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-nodeaffinity-hard   1/1     Running   0          5s    10.244.0.19   k8s-master   <none>           <none>

我这里没有足够节点所以选择master节点,一般master节点是不会分配pod的

软策略

将上面的yaml文件稍微修改成如下的test-nodeaffinity-soft.yaml

apiVersion: v1
kind: Pod
metadata:name: test-nodeaffinity-softlabels:app: app1
spec:containers:- name: mynginximage: mynginx:v2affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- k8s-node3

这里虽然还是希望能被调度到node3,但是没有这么一个node存在的时候,还是能被成功调度的

[root@k8s-master affinity]# kubectl apply -f test-nodeaffinity-soft.yaml
pod/test-nodeaffinity-soft created
[root@k8s-master affinity]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
test-nodeaffinity-hard   1/1     Running   0          9m40s   10.244.0.19    k8s-master   <none>           <none>
test-nodeaffinity-soft   1/1     Running   0          5s      10.244.1.133   k8s-node1    <none>           <none>

因为有权重的存在,所以可以设置多条策略,按照权重高低进行选择。权重可配置1-100。

当然硬策略和软策略可以一起配置,优先考虑硬策略。

PodAffinity实际操作

pod与pod之间就开始出现Affinity和Anti-Affinity了

硬策略

目前已存在的两个pod如下,用作参照

[root@k8s-master affinity]# kubectl get pod --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   LABELS
test-nodeaffinity-hard   1/1     Running   0          49m   app=app1
test-nodeaffinity-soft   1/1     Running   0          39m   app=app1

用如下的yaml文件test-podaffinity-hard.yaml去创建一个pod

apiVersion: v1
kind: Pod
metadata:name: test-podaffinity-hardlabels:app: app2
spec:containers:- name: mynginximage: mynginx:v2affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- app1topologyKey: kubernetes.io/hostname

注意,这里用的是Anti-Affinity,所以是不想和目标pod在一起。然后这里还有个topologyKey字段,表示node的一个label,表示要被创建的pod所在的node的这个label值和被比较pod所在的node这个label值要不一致才行。这个逻辑关系有点绕,就是先选出目标pod,然后根据目标pod所在node的label来决定去哪个node。

这里选出的pod是满足app: app1的pod,上面两个pod都满足,然后是查看node的hostname,上述两个pod已经把集群内的两个node都占据了,所以新的pod没有node可以被分配

[root@k8s-master affinity]# kubectl apply -f test-podaffinity-hard.yaml
pod/test-podaffinity-hard created
[root@k8s-master affinity]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
test-nodeaffinity-hard   1/1     Running   0          53m   10.244.0.19    k8s-master   <none>           <none>
test-nodeaffinity-soft   1/1     Running   0          43m   10.244.1.133   k8s-node1    <none>           <none>
test-podaffinity-hard    0/1     Pending   0          8s    <none>         <none>       <none>           <none>

修改其中一个pod的label为app:test

[root@k8s-master affinity]# kubectl edit pod test-nodeaffinity-hard
pod/test-nodeaffinity-hard edited
[root@k8s-master affinity]# kubectl get pod --show-labels -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES   LABELS
test-nodeaffinity-hard   1/1     Running   0          63m   10.244.0.19    k8s-master   <none>           <none>            app=test
test-nodeaffinity-soft   1/1     Running   0          54m   10.244.1.133   k8s-node1    <none>           <none>            app=app1
test-podaffinity-hard    1/1     Running   0          10m   10.244.0.20    k8s-master   <none>           <none>            app=app2

可以看到新的pod被创建了,而且是分配在master

软策略

再通过下面的yaml文件test-podaffinity-soft演示一下正向的Affinity

apiVersion: v1
kind: Pod
metadata:name: test-podaffinity-softlabels:app: app2
spec:containers:- name: mynginximage: mynginx:v2affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- testtopologyKey: kubernetes.io/hostname

这里新的pod想和app:test的pod分配在同一个hostname的node上,也就是master

apiVersion: v1
kind: Pod
metadata:name: test-podaffinity-softlabels:app: app2
spec:containers:- name: mynginximage: mynginx:v2affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- testtopologyKey: kubernetes.io/hostname

注意这里权重是1,新建以后发现新pod并不在master上

[root@k8s-master affinity]# kubectl get pod -o wide --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES   LABELS
test-nodeaffinity-hard   1/1     Running   0          71m   10.244.0.19    k8s-master   <none>           <none>            app=test
test-nodeaffinity-soft   1/1     Running   0          61m   10.244.1.133   k8s-node1    <none>           <none>            app=app1
test-podaffinity-hard    1/1     Running   0          17m   10.244.0.20    k8s-master   <none>           <none>            app=app2
test-podaffinity-soft    1/1     Running   0          23s   10.244.1.134   k8s-node1    <none>           <none>            app=app2

总结

总结下这一节的知识点

  • Affinity分为节点型的NodeAffinity和pod型的PodAffinity,不过到了最后都是看node的标签决定分配位置,前者是直接查看,后者是根据符合条件的pod去查看
  • PodAffinity分为正向的Affinity和反向的Anti-Affinity
  • 硬策略是一定要满足的,而软连接有权重,按照权重大小去依次尽量满足

这一节讲的只是k8s中调度限制的一种方法,下一节来看第二种方法:污点和容忍。

【Kubernetes 015】pod调度之Affinity亲和性相关推荐

  1. Kubernetes之Pod调度

    本文讲的是Kubernetes之Pod调度[编者的话]Kubernetes调度器根据特定的算法与策略将pod调度到工作节点上.在默认情况下,Kubernetes调度器可以满足绝大多数需求,例如调度po ...

  2. 二十、Kubernetes中Pod调度第二篇NodeAffinity详解、实例

    1.概述 在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的.但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制 ...

  3. Kubernetes对Pod调度指定Node以及Node的Taint 和 Toleration

    1.指定pod到指定的node上 #1.1查看节点的lebel kubectl get nodes --show-labels#1.2获取到该节点的label信息 ip-10-100-2-80 Rea ...

  4. k8s学习笔记-调度之Affinity

    Kubernetes中的调度策略可以大致分为两种 一种是全局的调度策略,要在启动调度器时配置,包括kubernetes调度器自带的各种predicates和priorities算法,具体可以参看上一篇 ...

  5. kubernetes 简介:调度器和调度算法((Affinity/Anti-Affinity, Taints and Tolerations, 自定义调度器 )

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 简介 scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: ...

  6. kubernetes Affinity亲和性

    kubernetes Affinity 亲和性 亲和性/反亲和性调度策略 键值运算关系 affinity.nodeAffinity.nodeSelectorTerms.operator 一. 节点亲和 ...

  7. 关于K8s中Pod调度[选择器,指定节点,主机亲和性]方式和节点[coedon,drain,taint]标记的Demo

    写在前面 嗯,整理K8s中pod调度相关笔记,这里分享给小伙伴 博文内容涉及: kube-scheduler组件的简述 Pod的调度(选择器.指定节点.主机亲和性)方式 节点的coedon与drain ...

  8. Kubernetes Pod调度进阶:Taints(污点)和Tolerations(容忍)

    [注意]最后更新于 2 years ago,文中内容可能已过时,请谨慎使用. 污点(Taint)和容忍(Toleration)是从Kubernetes 1.6开始提供的高级调度功能. 在Kuberne ...

  9. 【项目实战23】k8s(9)—k8s调度(节点亲和性,Taint污点,pod容忍性)

    k8s调度 一.k8s调度背景介绍 二.nodeName方式调度 三.nodeSelector方式调度 (1).使用方式 (2).节点亲和性 四.Taints污点 (1).介绍 (2).使用 五.to ...

  10. k8s的list-watch机制和 pod调度约束

    文章目录 一: k8s的list-watch 机制 1.1 k8s通过list-watch 机制进行每个组件的写作 1.2 Pod 的典型启动过程 1.3 调度过程 1.3.1 预算策略(predic ...

最新文章

  1. libACE-6.3.3.so: cannot open shared object file: No such file or directory
  2. python生成有条件的列表_python复杂列表生成式教程
  3. 1.1 内存的四个分区
  4. java邮件附件默认路径_JavaMail - 文件夹管理( Folder Management)
  5. Eclipse项目部署到Tomcat中路径
  6. Java8 Stream 函数式接口
  7. 【Windows工具】BBDown.exe B站视频下载工具详细使用说明(https://github.com/nilaoda/BBDown)
  8. python全景图像拼接_Python+OpenCV实现图像的全景拼接
  9. ABBYY FineReader 12扫描对页的步骤有哪些
  10. 需要重新格式化NameNode
  11. 在CNDS博客中插入Latex公式
  12. java生成32位id,java中生成32位随机ID
  13. 二阶rc无源低通滤波器matlab,二阶rc无源低通滤波电路
  14. dell最新计算机如何U盘引导,详解戴尔台式电脑如何bios设置U盘启动
  15. Strut2的工作流程
  16. 计算请假时间(不算节假日)
  17. kali 更新后出现乱码的解决方案
  18. 如何在浏览器中打开windows应用程序
  19. 一文读懂 Linux 下单机实现百万并发的内核黑科技:连接跟踪(Conntrack)
  20. Windows静默安装

热门文章

  1. [LuoguP3503]「BZOJ2086」[POI2010] Blocks
  2. Spring Boot 2020 官方基础68课程第十七个 Hypermedia-Driven RESTful Web Service 超媒体
  3. 解决word中Mathtype按钮灰色问题(亲测有效)
  4. 简单解析一下,实施MES管理系统后有哪些效益
  5. leaflet保存pm绘图geojson数据
  6. 网站如何被百度蜘蛛快速抓取?
  7. 08系统装iss_安全信息系统| ISS | 第1部分
  8. 使用 crictl 对 Kubernetes 节点进行调试
  9. android系统已停止运用,安卓系统平板电脑启动器停止运行处理方法(文/明)
  10. 简单的python爬虫爬豆瓣图书TOP250