Kubernetes调度之Pod亲和性
Kubernetes调度中的Pod亲和性

abstract.png
Pod亲和性
节点亲和性,是基于节点的标签对Pod进行调度。而Pod亲和性则可以实现基于已经在节点上运行Pod的标签来约束新Pod可以调度到的节点。具体地,如果X上已经运行了一个或多个满足规则Y的Pod,则这个新Pod也应该运行在X上。其中,X可以是节点、机架、可用性区域、地理区域等。可通过topologyKey字段定义拓扑域X,其取值是节点标签的键名Key;而Y则是Kubernetes尝试满足的规则。可以通过标签选择器的形式来定义。此外,Pod亲和性使用podAffinity字段,其下支持两种亲和性:
「requiredDuringSchedulingIgnoredDuringExecution」:requiredDuringScheduling表明其是一个强制性的调度,调度器只有在规则被满足的时候才能执行调度;而IgnoredDuringExecution则表明其不会影响已在节点上运行的Pod
「preferredDuringSchedulingIgnoredDuringExecution」:preferredDuringScheduling表明其是一个偏好性的调度,调度器会根据偏好优先选择满足对应规则的节点来调度Pod。但如果找不到满足规则的节点,调度器则会选择其他节点来调度Pod。而IgnoredDuringExecution则表明其不会影响已在节点上运行的Pod
强制性调度
这里提供了一个存在5个工作节点的K8s集群,然后我们使用Deployment部署了应用的前端服务
# 应用的前端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-frontendspec: # Pod副本数量 replicas: 2 selector: matchLabels: app: frontend # Pod模板 template: metadata: # 标签信息: 应用的前端服务 labels: app: frontend spec: # 容器信息 containers: - name: my-app-frontend image: jocatalin/kubernetes-bootcamp:v1效果如下所示,可以看到前端服务运行了2个Pod。分别在my-k8s-cluster-multi-node-worker2、my-k8s-cluster-multi-node-worker3节点上

figure 1.jpeg
现在我们来部署应用的后端服务,这里我们期望后端服务的Pod能够运行在前端服务的Pod所在的节点上。这时就可以通过节点亲和性实现。具体地:
首先,使用podAffinity来定义Pod亲和性规则,使用requiredDuringSchedulingIgnoredDuringExecution定义强制性的调度规则
然后,使用标签选择器来确定Pod的范围,这里我们显然选择的是前端服务的Pod
最后,使用topologyKey来定义拓扑域信息,这里我们使用的是节点主机名。对于 此时即将被调度的新Pod 与 标签选择器所确定的Pod 来说,它们各自运行节点的主机名是相同的。即,后端服务的Pod 必须被调度到 与前端服务的Pod所在节点拥有相同主机名 的节点上
这样即可实现后端服务的Pod所在的节点上,一定存在前端服务的Pod
# 应用的后端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-backendspec: # Pod副本数量 replicas: 4 selector: matchLabels: app: backend # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: backend spec: # 亲和性 affinity: # Pod亲和性规则 podAffinity: # 强制性的调度规则, 但不会影响已在节点上运行的Pod requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: kubernetes.io/hostname # 标签选择器 labelSelector: matchLabels: app: frontend # 容器信息 containers: - name: my-app-backend image: tutum/dnsutils command: - sleep - infinity效果如下所示。后端服务的5个Pod均运行在my-k8s-cluster-multi-node-worker2、my-k8s-cluster-multi-node-worker3节点上

figure 2.jpeg
偏好性调度
这里提供了一个存在5个工作节点的K8s集群,然后我们使用Deployment部署了应用的前端服务
# 应用的后端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-backendspec: # Pod副本数量 replicas: 2 selector: matchLabels: app: backend # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: backend spec: # 容器信息 containers: - name: my-app-backend image: tutum/dnsutils command: - sleep - infinity效果如下所示,可以看到后端服务运行了2个Pod。分别在my-k8s-cluster-multi-node-worker、my-k8s-cluster-multi-node-worker3节点上。而通过标签信息可知,这两个节点都位于上海

figure 3.jpeg
现在我们来部署应用的缓存服务,这里我们期望 缓存服务Pod所在的节点 能够尽可能与 前端服务Pod所在的节点 在通过一个地理区域,以减少网络通讯的延迟。
首先,使用podAffinity来定义Pod亲和性规则,使用preferredDuringSchedulingIgnoredDuringExecution定义偏好性的调度规则。可通过权重值来定义对节点偏好,权重值越大优先级越高。其中,权重范围: 1~100
然后,使用标签选择器来确定Pod的范围,这里我们显然选择的是前端服务的Pod
最后,使用topologyKey来定义拓扑域信息,这里我们使用的是节点的Region标签地理位置。此时即将被调度的新Pod 将会更倾向于调度到 与标签选择器所确定的Pod的所在节点 具有相同Region标签值的节点当中。即,缓存服务的Pod的所在节点 与 后端服务的Pod的所在节点 将会尽可能得位于同一个地理区域(具有相同Region标签值)
# 应用的缓存服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-redisspec: # Pod副本数量 replicas: 4 selector: matchLabels: app: redis # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: redis spec: # 亲和性 affinity: # Pod亲和性规则 podAffinity: # 偏好性的调度规则, 但不会影响已在节点上运行的Pod preferredDuringSchedulingIgnoredDuringExecution: - weight: 70 # 权重范围: 1~100, 权重值越大, 优先级越高 podAffinityTerm: topologyKey: Region # 标签选择器 labelSelector: matchLabels: app: backend # 容器信息 containers: - name: my-app-redis image: redis:3.2-alpine效果如下所示。缓存服务的4个Pod均运行同样位于上海的节点上。需要注意的是,由于这里是偏好性调度。故如果当上海的节点由于某种原因导致无法调度Pod到其上运行,调度器选择其他地域的节点进行调度也是合法的、允许的。比如这里位于广州的节点

figure 4.jpeg
Pod反亲和性
而Pod反亲和性,同样也是基于已经在节点上运行Pod的标签来约束新Pod可以调度到的节点。只不过其与Pod亲和性恰恰相反。即,如果X上已经运行了一个或多个满足规则Y的Pod,则这个新Pod不应该运行在X上。此外,Pod反亲和性使用podAntiAffinity字段,其下同样支持两种反亲和性:requiredDuringSchedulingIgnoredDuringExecution 强制性调度、preferredDuringSchedulingIgnoredDuringExecution 偏好性调度
强制性调度
这里提供了一个存在5个工作节点的K8s集群,然后我们使用Deployment部署了应用的后端服务。这里为了便于后续演示,我们规定后端服务的Pod只允许运行在上海的节点上
# 应用的后端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-backendspec: # Pod副本数量 replicas: 5 selector: matchLabels: app: backend # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: backend spec: # 配置节点选择器, 要求K8s只将该Pod部署到包含标签Region=ShangHai的节点上 nodeSelector: Region: ShangHai # 容器信息 containers: - name: my-app-backend image: tutum/dnsutils command: - sleep - infinity效果如下所示,可以看到后端服务运行了5个Pod。分别运行在位于上海的my-k8s-cluster-multi-node-worker、my-k8s-cluster-multi-node-worker3、my-k8s-cluster-multi-node-worker5节点上

figure 5.jpeg
现在我们来部署应用的前端服务,同时基于某种特殊原因的考量,我们期望该应用的前、后端服务的Pod分别运行在不同区域。即前端服务的Pod的运行在位于上海的节点,则我们希望后端服务的Pod运行在除上海之外的节点当中。这时就可以通过节点反亲和性实现。具体地:
首先,使用podAntiAffinity来定义Pod反亲和性规则,使用requiredDuringSchedulingIgnoredDuringExecution定义强制性的调度规则
然后,使用标签选择器来确定Pod的范围,这里我们显然选择的是后端服务的Pod
最后,使用topologyKey来定义拓扑域信息,这里我们使用的是节点的Region标签地理位置。对于 此时即将被调度的新Pod 与 标签选择器所确定的Pod 来说,它们各自运行节点的地理位置是不同的。即,后端服务的Pod 必须被调度到 与前端服务的Pod所在节点拥有不同地理位置 的节点上
# 应用的前端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-frontendspec: # Pod副本数量 replicas: 5 selector: matchLabels: app: frontend # Pod模板 template: metadata: # 标签信息: 应用的前端服务 labels: app: frontend spec: # 亲和性 affinity: # Pod反亲和性规则 podAntiAffinity: # 强制性的调度规则, 但不会影响已在节点上运行的Pod requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: Region # 标签选择器 labelSelector: matchLabels: app: backend # 容器信息 containers: - name: my-app-frontend image: jocatalin/kubernetes-bootcamp:v1效果如下所示。前端服务的5个Pod均运行在位于广州的my-k8s-cluster-multi-node-worker2、my-k8s-cluster-multi-node-worker4节点上

figure 6.jpeg
偏好性调度
这里提供了一个存在5个工作节点的K8s集群,然后我们使用Deployment部署了应用的后端服务
# 应用的后端服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-backendspec: # Pod副本数量 replicas: 2 selector: matchLabels: app: backend # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: backend spec: # 容器信息 containers: - name: my-app-backend image: tutum/dnsutils command: - sleep - infinity效果如下所示,可以看到前端服务运行了2个Pod。分别在my-k8s-cluster-multi-node-worker、my-k8s-cluster-multi-node-worker4节点上
figure 7.jpeg
现在我们来部署应用的缓存服务,这里由于后端服务、缓存服务都非常占用资源。故我们提出下述调度要求
缓存服务Pod所在的节点 能够尽可能与 前端服务Pod所在的节点 不是同一个节点
缓存服务Pod所在的节点 能够尽可能与 前端服务Pod所在的节点 不在同一个地理区域
上诉2点均为偏好性要求,且第1点优先级是最高的
首先,使用podAntiAffinity来定义Pod反亲和性规则,使用preferredDuringSchedulingIgnoredDuringExecution定义偏好性的调度规则。可通过权重值来定义偏好,权重值越大优先级越高。其中,权重范围: 1~100
然后,使用标签选择器来确定Pod的范围,这里我们显然选择的是前端服务的Pod
最后,使用topologyKey来定义拓扑域信息。这里我们分别使用了节点主机名、地理位置。以此实现即将被调度的新Pod 将会更倾向于调度到 与标签选择器所确定的Pod的所在节点 具有不同节点 或 不同地理区域的节点上
# 应用的缓存服务apiVersion: apps/v1kind: Deploymentmetadata: name: my-app-redisspec: # Pod副本数量 replicas: 4 selector: matchLabels: app: redis # Pod模板 template: metadata: # 标签信息: 应用的后端服务 labels: app: redis spec: # 亲和性 affinity: # Pod反亲和性规则 podAntiAffinity: # 偏好性的调度规则, 但不会影响已在节点上运行的Pod preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 # 权重范围: 1~100, 权重值越大, 优先级越高 podAffinityTerm: topologyKey: kubernetes.io/hostname # 标签选择器 labelSelector: matchLabels: app: backend - weight: 1 # 权重范围: 1~100, 权重值越大, 优先级越高 podAffinityTerm: topologyKey: Region # 标签选择器 labelSelector: matchLabels: app: backend # 容器信息 containers: - name: my-app-redis image: redis:3.2-alpine效果如下所示。缓存服务的4个Pod均运行在与后端服务Pod所在节点不同的节点上。但这里由于是偏好性调度,当最终结果未满足两个服务运行在不同的地理位置时,即调度器选择相同地理位置的节点进行调度也是合法的、允许的

figure 8.jpeg
相关文章:
Kubernetes调度之Pod亲和性
Kubernetes调度中的Pod亲和性abstract.pngPod亲和性节点亲和性,是基于节点的标签对Pod进行调度。而Pod亲和性则可以实现基于已经在节点上运行Pod的标签来约束新Pod可以调度到的节点。具体地,如果X上已经运行了一个或多个满足规则Y的Pod,则这个…...
建立相关在线社群的3个简单步骤
在线社群管理和社交媒体营销通常被视为一回事。虽然社群管理确实是社交媒体营销的一个关键部分,但它的意义超越了社交媒体的内容发布。因此,在线社群对于企业的数字营销十分重要。创建、维护和发展社群不是一件容易的工作,也不是一个快速的过…...
安全运营的新模式
安全运营的新模式是传统安全运维的扩展和升级,其实现落地需要管理和技术两斱面同时支撑、相互衎接和配合,缺夰仸何一个都是行不通的。管理斱面,在顶层设计时,网络安全运营要根据国家信息安全等级保护 2.0 的相关要求,参…...
Day10-网页布局实战CSS3
一 补充 1 画三角形 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…...
代码规范(C/C++规范)
文章目录前言个人编写的代码规范链接请求合作大体章节END前言 什么是代码规范 一套用于统一代码开发的准则 为什么需要代码规范 提升代码可读性,提升团队效率 个人编写的代码规范 近期本人编写了一份以C/C为主的代码规范。 其他语言开发者也可以阅读参考。 本…...
春招冲刺(九):计算属性和监视属性总结
计算属性和监视属性总结 Q1:计算属性 姓:<input type"text" v-model"firstName"><br><br> 名:<input type"text" v-model"lastName"><br><br> 姓名ÿ…...
数据挖掘(作业1)
实验开始前先配置环境 以实验室2023安装的版本为例: 1、安装anaconda:(anaconda自带Python,安装了anaconda就不用再安装Python了) 下载并安装 Anaconda3-2022.10-Windows-x86_64.exe 自己选择安装路径,其他使用默认…...
【UE4 RTS游戏】01-项目准备
步骤新建一个工程,选择俯视角游戏模板我命名工程如下:删除场景内的所有cube再删除Floor和Wall删除TopDownCharacter删除“NavgationMeshBoundVolume”删除“TamplateLabel”和“RecastNavMesh-Default”删除LightmassImportanceVolume、PostProcessVolum…...
登录系统账号检测--课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)
实例8:登录系统账号检测 登录系统一般具有账号密码检测功能,即检测用户输入的账号密码是否正确。若用户输入的账号或密码不正确,提示 “用户名或密码错误”和“您还有*次机会”; 若用户输入的账号和密码正确,提示“登…...
CentOS8基础篇12:使用RPM管理telnet-server软件包
一、RPM包管理工具简介 RedHat软件包管理工具(RedHat Package Manager,RPM) RPM软件包工具常用于软件包的安装、查询、更新升级、校验、卸载以及生成.rpm格式的软件包等操作。 RPM软件包工具只能管理后缀是.rpm的软件包。软件包的命名格式: 软件名称…...
IT女神文章记录之自己
匆匆时光,一转眼自己已经从一个学生转变成一个职场工作者了刚出校园的时候,对职场充满了憧憬,觉得自己可以大展身手然后其实在我毕业后2年内,踏入码农阶段的时候,是一段非常压抑的工作,不知道谁能体会到那种…...
Compose 动画 (四) : AnimatedVisibility 各种入场和出场动画效果
AnimatedVisibility中的EnterTransition 和 ExitTransition ,用来配置入场/出场时候的动画效果。 默认的入场效果是 fadeIn() expandVertically() 默认的出场效果是 fadeOut() shrinkVertically() 1. EnterTransition和ExitTransition支持的动画 enter的参数类…...
notepad++学习小技巧
不要小瞧了notepadd 这个可是我们的cv好帮手。。。 实战1背景,我找一个同事要表结构 结果他给我了一个xml。顿时一懵,我也不知道为啥好像是从前端扣下来的。 建表我只需要 columnName, displayName当作是comment, dataTypeNamecolumnType借鉴…...
Android supports-screens 屏幕适配
基本概念 supports-screens用于设置屏幕相关,处于Manifest的子标签中。 使您能够指定应用支持的屏幕尺寸,并为比应用支持的最大屏幕还大的屏幕启用屏幕兼容性模式。请务必始终在应用中使用此元素指定应用支持的屏幕尺寸。 注意:建议不要在屏…...
操作系统基础知识介绍之Mixed CriticalitySystems——混合关键系统
一、发展背景 在嵌入式场景中,虽然Linux已经得到了广泛应用,但并不能覆盖所有需求,例如高实时、高可靠、高安全的场合。这些场合往往是实时操作系统 的用武之地。有些应用场景既需要Linux的管理能力、丰富的生态又需要实时操作系统的高实时、…...
【数据结构初阶】详解链表OJ题
目录一.删除链表中等于给定值的节点二.合并有序链表并返回三.链表的回文结构1.反转单链表2.返回非空链表的中间节点四.输出链表倒数第K个节点五.基于给定值x分割单链表六.返回两个链表的第一个中间节点一.删除链表中等于给定值的节点 我们先来看第一题(题目链接): 因为我们需…...
Java基本数据类型变量自动提升、强制类型转换、String基本类型使用
文章目录基本数据类型变量自动提升特殊情况强制类型转换String基本类型使用基本数据类型变量自动提升 规则: 将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型 。 byte、short、char-->int-->…...
Redis锁与幂等性不得不说的故事
前言: 相信很多小伙伴对缓存锁都不陌生,但是简单的缓存锁想要用好还是需要一些功力。本文总结了笔者多年使用缓存所的一些心得,欢迎交流探讨~ 幂等模型: 幂等场景一般由查重写入两步操作组成,两步操作组成一个最小完…...
Spark 应用调优
Spark 应用调优人数统计优化摇号次数分布优化Shuffle 常规优化数据分区合并加 Cache优化中签率的变化趋势中签率局部洞察优化倍率分析优化表信息 : apply : 申请者 : 事实表lucky : 中签者表 : 维度表两张表的 Schema ( batchNum,carNum ) : ( 摇号批次,…...
synchronized 与 volatile 关键字
目录1.前言1.synchronized 关键字1. 互斥2.保证内存可见性3.可重入2. volatile 关键字1.保证内存可见性2.无法保证原子性3.synchronized 与 volatile 的区别1.前言 synchronized关键字和volatile是大家在Java多线程学习时接触的两个关键字,很多同学可能学习完就忘记…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
