k8s-pod的亲和度调度

2023-10-27

前言:
由于Affinity对pod的调度更加精细,我们在使用中逐渐代替了NodeSelector。可以分为node亲和性调度和pod亲和性调度。
1)node亲和性调度:不仅有NodeSelector的硬限制,而且可以在软限制中定义权重。
2)pod亲和性调度:它可以使得pod根据在节点上正在运行的pod的标签(而不是节点的标签)进行调度,要求对节点和pod两个条件进行匹配。

1. Node Affinity

1.1 node节点的预制标签

有一些预置的标签,我们可以直接使用

  • 查看master上的标签
[root@DoM01 ~]# kubectl get node dom03 --show-labels
NAME    STATUS   ROLES    AGE   VERSION   LABELS
dom03   Ready    master   52d   v1.15.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=dom03,kubernetes.io/os=linux,node-role.kubernetes.io/master=
  • 格式不是很友好,我们用describe看一下
[root@DoM01 ~]# kubectl describe node dom01
Name:               dom01
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=dom01
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/master=
……

说明:
“beta.kubernetes.io/arch=amd64”,“beta.kubernetes.io/os=linux” 这两个在1.18中弃用。
看名字使用,也没什么解释的。

1.2 自定义标签

1.2.1 给node增加标签

  • 语法
# kubectl label node node名  键=值
  • 示例
[root@DoM01 ~]# kubectl label node don01 zone=east
node/don01 labeled
  • 验证
    如下可见 don01 设置了标签 zone=east
[root@DoM01 ~]# kubectl describe node don01
Name:               don01
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=don01
                    kubernetes.io/os=linux
                    zone=east

1.2.2 修改label

说明:加 --overwrite参数

# kubectl label node don01 zone=south --overwrite

1.2.3 修改label

说明:删除一个key为zone的标签,只需把key的后边加一个减号即会删除该key

# kubectl label node don01 zone-

1.3 Require

  • 概述:
    equiredDuringSchedulingIgnoredDuringExecution是硬限制,必须满足此条件才可以调度pod到该node上(功能和nodeSelector很像)

  • 示例

apiVersion: v1
kind: Pod
metadata:
  name: nginxtest
  namespace: test
spec:
  affinity:
     # 说明是"节点亲和性调度"
    nodeAffinity:
      # 说明是"节点亲和性调度"
      requiredDuringSchedulingIgnoredDuringExecution:
        #说明要选择节点了
        nodeSelectorTerms:
        - matchExpressions:
          - key: zone
            operator: In
            values:
            - "east"
  containers:
    - name: nginxtest
      image: harbocto.boe.com.cn/public/nginx
  • 创建并查看结果
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginxtest   1/1     Running   0          91s   10.244.5.166   don03   <none>           <none>

说明:可以看到,pod被调度到了一个zone=east的节点don01上

  • 更改调度
    将yml文件修改成调度到zone=south的节点,然后更新pod如下
[root@DoM01 test]# kubectl apply -f nginx.yml
The Pod "nginxtest" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations)
  core.PodSpec{
        ……

说明:以上报错为了引出下边两个重要规则。

  • 规则
    1)亲和度的值是不能直接修改的。
    2)如果此时修改了node标签,使得节点不满足要求,这个改变也将被系统忽略。(即pod仍会在该节点上运行)

1.4 Perferred

  • 概述
    preferredDuringSchedulingIgnoredDuringExecution 是软限制,强调优先满足制定规则,多个优先级可以设置权重。

  • 示例

apiVersion: v1
kind: Pod
metadata:
  name: nginxtest
  namespace: test
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 60
          preference:
            matchExpressions:
            - key: zone
              operator: In
              values:
              - "east"
        - weight: 80
          preference:
            matchExpressions:
            - key: zone
              operator: In
              values:
              - "south"
  containers:
    - name: nginxtest
      image: harbocto.boe.com.cn/public/nginx  
  • 创建并查看结果
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test  -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginxtest   1/1     Running   0          23s   10.244.7.190   don05   <none>           <none>

说明:虽然 zone=east的权重是60,但是仍可以调度到上边

  • 修改east的权重为20,删除pod再启动一下
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 ~]# kubectl get pod -n test  -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginxtest   1/1     Running   0          18m   10.244.3.33   don01   <none>           <none>
[root@DoM01 ~]#

说明:可以看到此时该pod被调度到zone=south的节点上了,权重的作用可见一斑。

1.3 注意事项

  • 如果设置了nodeSelector和nodeAffinity,则需同时满足。
  • 如果设置多个nodeSelectorTerms,有一个满足即可。
  • 如果nodeSelectorTerms下有多个 matchExpressions,则必须满足所有条件才可以。

2. Pod Affinity

说明:
根据pod1的标签选是否在某一组(或一个)node节点上部署pod2。
这一组node上用来限制亲和度的标签的key 称为 topologyKey。
因此pod2需要两个标签来确定亲和度:
(1)限制在那个范围内(topologyKey)。( 2)和哪个pod亲和(相应pod的标签)。
关于topologyKey,我们不需要指明值,因为只要同一个值的一组node下亲和就可以了。

2.1 Pod Affinity

说明:
同样分为
“requiredDuringSchedulingIgnoredDuringExecution”
“preferredDuringSchedulingIgnoredDuringExecution”
两种

2.1.1 required

  • 参照目标pod
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag
  namespace: test
labels:
  security: "S1"
  app: "nginx-flag"
spec:       
  containers:
    - name: nginx-flag
      image: nginx
  • pod的亲和度调度
apiVersion: v1
kind: Pod
metadata:
  name: nginxtest
  namespace: test
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - "S1"
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginxtest
    image: harbocto.boe.com.cn/public/nginx

  • 启动并查看结果
[root@DoM01 test]# kubectl create -f nginx-flag.yml
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-flag   1/1     Running   1          14m   10.244.7.191   don05   <none>           <none>
nginxtest    1/1     Running   0          58s   10.244.7.192   don05   <none>           <none>

说明:可见nginxtest调度到了nginx-flag上

  • 找不到合适节点
    如果没有启动nginx-flag而直接启动nginxtest,系统找不到合适的节点调度,会一直处于pending状态。
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test
NAME        READY   STATUS    RESTARTS   AGE
nginxtest   0/1     Pending   0          3s

如下可见,nginx-flag启动之后,nginxtest被调度到了有nginx-flag的节点上。

[root@DoM01 test]# kubectl create -f nginx-flag.yml
pod/nginx-flag created
NAME         READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
nginx-flag   1/1     Running   0          17s     10.244.5.169   don03   <none>           <none>
nginxtest    1/1     Running   0          2m33s   10.244.5.168   don03   <none>           <none>

2.1.2 preferred

  • 参照目标pod
    同上
  • pod的亲和度调度
    创建nginx.yml文件如下:
apiVersion: v1
kind: Pod
metadata:
  name: nginxtest
  namespace: test
spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 20
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - "S1"
          topologyKey: kubernetes.io/hostname
      - weight: 80
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - "S2"
          topologyKey: kubernetes.io/hostname
  containers:
    - name: nginxtest
      image: harbocto.boe.com.cn/public/nginx
  • 启动和查看
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test  -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx-flag   1/1     Running   0          56s   10.244.3.34   don01   <none>           <none>
nginxtest    1/1     Running   0          8s    10.244.3.35   don01   <none>           <none>

如上,可见nginxtest被调度到了nginx-flag所在的节点上

  • 亲和度是相互的

测试:
再启动一个nginx-flag-02,lable设置为security=S2。由前边可知,nginxtest和它的亲和度是80,但是它会主动选择nginxtest。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag-02
  namespace: test
  labels:
    security: "S2"
    app: "nginx-flag"
spec:
  containers:
    - name: nginx-flag-02
      image: harbocto.boe.com.cn/public/nginx

删除nginxtest,在重新启动

[root@DoM01 test]# kubectl create -f nginx-flag02.yml
pod/nginx-flag-02 created
[root@DoM01 test]# kubectl get pod -n test  -o wide
NAME            READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
nginx-flag      1/1     Running   0          3m18s   10.244.3.34   don01   <none>           <none>
nginx-flag-02   1/1     Running   0          6s      10.244.3.36   don01   <none>           <none>
nginxtest       1/1     Running   0          2m30s   10.244.3.35   don01   <none>           <none>

如上:
发现它们竟然会粘在一起,nginx-flag-02居然也会启动在(看了一下node资源,如果没有亲和度的话nginx-flag-02应该启动在don03上。)

  • 删除ngintest,在删除nginx-flag-02。再启动nginx-flag-02,果然如上边预期被调度到了don03上。
[root@DoM01 test]# kubectl delete -n test pod nginxtest
pod "nginxtest" deleted
[root@DoM01 test]# kubectl delete -n test pod nginx-flag-02
pod "nginx-flag-02" deleted
[root@DoM01 test]# kubectl create -f nginx-flag02.yml
pod/nginx-flag-02 created
[root@DoM01 test]# kubectl get pod -n test  -o wide
NAME            READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
nginx-flag      1/1     Running   0          5m36s   10.244.3.34    don01   <none>           <none>
nginx-flag-02   1/1     Running   0          2s      10.244.5.191   don03   <none>           <none>
  • 测试亲和度权重
[root@DoM01 test]# kubectl create -f nginx.yml
pod/nginxtest created
[root@DoM01 test]# kubectl get pod -n test -o wide
NAME            READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
nginx-flag      1/1     Running   0          4h24m   10.244.3.34    don01   <none>           <none>
nginx-flag-02   1/1     Running   0          4h19m   10.244.5.191   don03   <none>           <none>
nginxtest       1/1     Running   0          14s     10.244.5.194   don03   <none>           <none>

说明:如上可见,nginxtest被调度到权重更高的nginx-flag-02的节点上了。

2.2 Pod Anti Affinity

  • 参照pod
    复制一下刚才的参照pod,把五个节点的四个都占了
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag-01
  namespace: test
  labels:
    security: "S1"
    app: "nginx-flag"
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - "don01"
  containers:
    - name: nginx-flag-01
      image: harbocto.boe.com.cn/public/nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag-02
  namespace: test
  labels:
    security: "S2"
    app: "nginx-flag"
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - "don02"
  containers:
    - name: nginx-flag-02
      image: harbocto.boe.com.cn/public/nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag-03
  namespace: test
  labels:
    security: "S3"
    app: "nginx-flag"
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - "don03"
  containers:
    - name: nginx-flag-03
      image: harbocto.boe.com.cn/public/nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flag-04
  namespace: test
  labels:
    security: "S4"
    app: "nginx-flag"
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - "don04"
  containers:
    - name: nginx-flag-04
      image: harbocto.boe.com.cn/public/nginx
  • pod的反亲和调度
apiVersion: v1
kind: Pod
metadata:
  name: nginxtest-02
  namespace: test
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - "nginx-flag"
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginxtest-02
    image: harbocto.boe.com.cn/public/nginx
  • 创建和查看
[root@DoM01 test]# kubectl get pod -n test -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-flag-01   1/1     Running   0          15m   10.244.3.38    don01   <none>           <none>
nginx-flag-02   1/1     Running   0          15m   10.244.4.35    don02   <none>           <none>
nginx-flag-03   1/1     Running   0          15m   10.244.5.201   don03   <none>           <none>
nginx-flag-04   1/1     Running   0          15m   10.244.6.27    don04   <none>           <none>
nginxtest-02    1/1     Running   0          14m   10.244.7.210   don05   <none>           <none>

如上可见,nginxtest-02被调度到最后剩下的一个节点上了

2.3 注意事项

  • topology
    1)反亲和性 requiredDuringScheduling 中topologyKey 不能为空
    2)反亲和性 preferredDuringScheduling 中topologyKey 为空,则被认为是如下的组合:
    kubernetes.io/hostname
    failure-domain.beta.kubernetes.io/zone
    failure-domain.beta.kubernetes.io/region
    3)如果admission controller 设置了LimitPodHardAntiAffinityTopology ,则互斥性被限制在 kubernetes.io/hostname

  • namespace限制
    1)位置:和topologyKey同级
    2)未定义namespace:表示和参照目标的pod相同
    3)设置为空:表示所有namespace


在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s-pod的亲和度调度 的相关文章

随机推荐

  • 网络编程之IO复用机制(多路IO转接)之select实现IO复用的思路02

    1 select实现IO复用的思路02 下面的都是伪代码 主要讲究思路 1 lfd socket 2 bind 3 listen 4 将lfd添加到select的读集合用于传入 借助内核帮我们监听事件 而不直接调用accept函数监听 为了
  • jmeter生成接口测试报告

    一 安装Ant配置 1 下载地址 https ant apache org bindownload cgi 2 安装Ant 下载解压 3 配置环境变量 新建变量ANT HOME 值为D ant apache ant 1 10 12 系统变量
  • 机器学习、深度学习、图像检索 的一些优秀博客

    机器学习 深度学习 图像检索 的一些优秀博客 1 http www cnblogs com ooon 2 http yongyuan name blog
  • 怎么向OpenHarmony的Git仓推送代码

    1 Git设置 git config global user name yourname 随意 git config global user email your email address DCO验证的邮箱 设置记住密码 git conf
  • React Hooks 在使用上有哪些限制?

    React Hooks 的限制主要有两条 不要在循环 条件或嵌套函数中调用 Hook 在 React 的函数组件中调用 Hook 那为什么会有这样的限制呢 就得从 Hooks 的设计说起 Hooks 的设计初衷是为了改进 React 组件的
  • 【docker-compose】从构建镜像到一键运行Java项目

    先来思考个问题 新机器跑一个常规springboot项目要几步 1 下载并配置java环境 mysql环境 redis环境 6步 2 初始化mysql数据库 导入sql文件 2步 3 下载jar包 启动 2步 大概分为零零碎碎的十多步 每块
  • EasyExcel使用教程-实现页面中批量导入导出数据-详解

    EasyExcel介绍 EasyExcel是阿里巴巴开源的一个excel处理框架 以使用简单 节省内存著称 EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中 而是从磁盘上一行行读取数据
  • PhpStorm 部署web到apache 教程

    1 Edit Configrations 进去之后点server 因为是本地部署 所以写localhost就可以 其他不用动 之后下面有一个start Url 意思就是你点击运行时浏览器要打开的那个界面 我们写项目名称就可以 2 Tool
  • iframe跨域没有权限_浅谈跨域威胁与安全

    WEB前端中最常见的两种安全风险 XSS与CSRF XSS 即跨站脚本攻击 CSRF即跨站请求伪造 两者属于跨域安全攻击 对于常见的XSS以及CSRF在此不多谈论 仅谈论一些不太常见的跨域技术以及安全威胁 一 域 域 即域名对应的网站 不同
  • 阿里云服务器和轻量云服务器对比有什么区别?

    阿里云轻量应用服务器和云服务器ECS有什么区别 ECS是专业级云服务器 轻量应用服务器是轻量级服务器 轻量服务器使用门槛更低 适合个人开发者或中小企业新手使用 可视化运维 云服务器ECS适合集群类 高可用 高容灾企业级架构 使用相对于轻量更
  • 详细解析STM32的时钟系统

    STM32的时钟系统 一 时钟系统框图 1 1 STM32F10x 1 2 STM32F40x 二 时钟系统 2 1 STM32F10x时钟源 HSI RC振荡器 频率8MHz 精度不高HSE 外接石英 陶瓷晶振 4MHz 16MHz LS
  • java的作用域

    文章目录 作用域 细节 注意 作用域 在java中 主要变量就是成员变量和局部变量 一般局部变量指的是成员方法中定义的变量 作用域的分为全局变量和局部变量 全局变量的作用域在整个类体 除了属性之外的都是局部变量 作用域只能用于某块 全局变量
  • 软件测试质量度量指标

    软件测试质量度量指标 度量模块 度量指标 统计方法 度量说明 产品完成度 1 需求通过率 已通过需求 已计划需求 体现需求的完成度 也常可以统计为 测试用例通过数 计划的测试用例总数 即默认用例覆盖是完全的 2 功能点通过率 已通过功能点
  • 安装驱动时出现“INF中的服务安装段落无效”

    今天安装ti开发板的驱动 在安装虚拟串口时出现 INF中的服务安装段落无效 以致驱动未安装成功 接下来我就说说我的解决过程 因为提示的是 inf中的 了解驱动的就知道有个扩展名为inf的文件 于是准备 打开驱动目录中的inf文件 如下图 有
  • 【延期至12月】2022年网络安全国际研讨会(CSW2022)

    延期至12月 2022年网络安全国际研讨会 CSW2022 重要信息 会议网址 www cybersecurityworkshop org 会议时间 2022年12月16 18日 召开地点 杭州 截稿时间 2022年10月20日 录用通知
  • 商业不是战争

    我在一个大客户那里工作的时候经常想这样一件事 他们 以及国内很多 IT或者非IT 企业 讲军事化管理 讲服从命令 为什么我总觉得这事不对 到底不对在什么地方 我想出来的结论是 商业不是战争 第一 商业的特点是negotiatable 战争是
  • 单链表中间值(经典案例,5分钟解决)

    一 题目描述 给定一个单链表 但不知该表的大小 现要求只遍历一次 找出位于单链表中间的值 输入 1 8 7 6 4 5 3 1 输出 6 样例输入 Copy 1 2 4 8 9 6 3 1 0 样例输出 Copy 9 二 实现方法 普通方法
  • 创新零售,京东重新答题?

    继新一轮组织架构调整后 京东从低价到下沉动作不断 新成立的创新零售部在京东老将闫小兵的带领下悄然完成了整合 近日 京喜拼拼已改名为京东拼拼 与七鲜 前置仓等业务共同承载起京东线上线下加速融合的梦想 同时 拼拼的更名 也被外界解读为京东重新点
  • 关于jdbc常见错误

    版本问题 如果运行时控制台报错 Exception in thread main com mysql jdbc exceptions jdbc4 MySQLNonTransientConnectionException Could not
  • k8s-pod的亲和度调度

    文章目录 1 Node Affinity 1 1 node节点的预制标签 1 2 自定义标签 1 2 1 给node增加标签 1 2 2 修改label 1 2 3 修改label 1 3 Require 1 4 Perferred 1 3