k8s晋级之亲和性与反亲和性

nodeSelector 提供了一个非常简单的方式,将 Pod 限定到包含特定标签的节点上。亲和性与反亲和性(affinity / anti-affinity)特性则极大地扩展了限定的表达方式。主要的增强点在于:

  1. 表达方式更加有效(不仅仅是多个精确匹配表达式的“和”关系)
  2. 可以标识该规则为“soft” / “preference” (软性的、偏好的)而不是 hard requirement(必须的),此时,如果调度器发现该规则不能被满足,Pod 仍然可以被调度
  3. 可以对比节点上(或其他拓扑域 topological domain)已运行的其他 Pod 的标签,而不仅仅是节点自己的标签,此时,可以定义类似这样的规则:某两类 Pod 不能在同一个节点(或拓扑域)上共存

节点亲和性

节点亲和性(node affinity)的概念与 nodeSelector 相似,可以基于节点的标签来限定 Pod 可以被调度到哪些节点上。

当前支持两种类型的节点亲和性, requiredDuringSchedulingIgnoredDuringExecution (hard,目标节点必须满足此条件) 以及 preferredDuringSchedulingIgnoredDuringExecution (soft,目标节点最好能满足此条件)。名字中 IgnoredDuringExecution 意味着:如果 Pod 已经调度到节点上以后,节点的标签发生改变,使得节点已经不再匹配该亲和性规则了,Pod 仍将继续在节点上执行(这一点与 nodeSelector 相似)。将来,Kubernetes 将会提供 requiredDuringSchedulingRequiredDuringExecution 这个选项,该选项与 requiredDuringSchedulingIgnoredDuringExecution 相似,不同的是,当节点的标签不在匹配亲和性规则之后,Pod 将被从节点上驱逐。

requiredDuringSchedulingIgnoredDuringExecution 的一个例子是,只在 Intel CPU 上运行该 PodpreferredDuringSchedulingIgnoredDuringExecution 的一个例子是,尽量在高可用区 XYZ 中运行这个 Pod,但是如果做不到,也可以在其他地方运行该 Pod

PodSpec 中通过 affinity.nodeAffinity 字段来定义节点亲和性

apiVersion: v1
kind: Pod
metadata:name: with-node-affinity
spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/e2e-az-nameoperator: Invalues:- e2e-az1- e2e-az2preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: another-node-label-keyoperator: Invalues:- another-node-label-valuecontainers:- name: with-node-affinityimage: k8s.gcr.io/pause:2.0

此处的亲和性规则表明,该 Pod 只能被调度到包含 key 为 kubernetes.io/e2e-az-name 且 value 为 e2e-az1e2e-az2 的标签的节点上。此外,如果节点已经满足了前述条件,将优先选择包含 key 为 another-node-label-key 且 value 为 another-node-label-value 的标签的节点。

例子中使用了操作符 In。节点亲和性支持如下操作符:InNotInExistsDoesNotExistGtLt。使用 NotInDoesNotExist 可以实现节点反亲和性(node anti-affinity)的效果,或者也可以使用 [污点 为节点排斥某类 Pod。

如果某个 Pod 同时指定了 nodeSelectornodeAffinity,则目标节点必须同时满足两个条件,才能将 Pod 调度到该节点上。

如果为 nodeAffinity 指定多个 nodeSelectorTerms,则目标节点只需要满足任意一个 nodeSelectorTerms 的要求,就可以将 Pod 调度到该节点上。

如果为 nodeSelectorTerms 指定多个 matchExpressions,则目标节点必须满足所有的 matchExpressions 的要求,才能将 Pod 调度到该节点上。

当 Pod 被调度到某节点上之后,如果移除或者修改节点的标签,Pod 将仍然继续在节点上运行。换句话说,节点亲和性规则只在调度该 Pod 时发生作用。

preferredDuringSchedulingIgnoredDuringExecution 中的 weight 字段取值范围为 1-100。对于每一个满足调度要求的节点(资源请求、亲和性/反亲和性规则,等),调度器将遍历该节点匹配的 preferredDuringSchedulingIgnoredDuringExecution 中所有的weight 并求和。此求和结果将与节点的其他优先级计算的得分合并。得分最高的节点被优先选择。

Pod亲和性与反亲和性

Pod之间的亲和性与反亲和性(inter-pod affinity and anti-affinity)可以基于已经运行在节点上的 Pod 的标签(而不是节点的标签)来限定 Pod 可以被调度到哪个节点上。此类规则的表现形式是:

  • 当 X 已经运行了一个或者多个满足规则 Y 的 Pod 时,待调度的 Pod 应该(或者不应该 - 反亲和性)在 X 上运行

    • 规则 Y 以 LabelSelector 的形式表述,附带一个可选的名称空间列表

      与节点不一样,Pod 是在名称空间中的(因此,Pod的标签是在名称空间中的),针对 Pod 的 LabelSelector 必须同时指定对应的名称空间

    • X 是一个拓扑域的概念,例如节点、机柜、云供应商可用区、云供应商地域,等。X 以 topologyKey 的形式表达,该 Key代表了节点上代表拓扑域(topology domain)的一个标签。

pod affinity 的一个例子

apiVersion: v1
kind: Pod
metadata:name: with-pod-affinity
spec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: securityoperator: Invalues:- S1topologyKey: failure-domain.beta.kubernetes.io/zonepodAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: securityoperator: Invalues:- S2topologyKey: failure-domain.beta.kubernetes.io/zonecontainers:- name: with-pod-affinityimage: k8s.gcr.io/pause:2.0

该 Pod 的 affinity 定义了一个 Pod 亲和性规则和一个 Pod 反亲和性规则,例子中, podAffinityrequiredDuringSchedulingIgnoredDuringExecution,而 podAntiAffinity 则是 preferredDuringSchedulingIgnoredDuringExecution

  • Pod 亲和性规则要求,该 Pod 可以被调度到的节点所在的可用区 zone 必须已经有一个已经运行的 Pod 包含标签 key=security,value=S1,或者更准确地说,节点必须满足如下条件:

    • 节点包含 key 为 failure-domain.beta.kubernetes.io/zone 的标签,假设该标签的值为 V
    • 至少有一个包含 key 为 failure-domain.beta.kubernetes.io/zone 且 value 为 V 的标签的节点已经运行了一个包含标签 key 为 security 且 value 为 S1 的 Pod
  • Pod 反亲和性规则要求,该 Pod 最好不要被调度到已经运行了包含 key 为 security 且 value 为 S2 的标签的 Pod 的节点上,或者更准确地说,必须满足如下条件:

    • 如果 topologyKeyfailure-domain.beta.kubernetes.io/zone,则,Pod不能被调度到同一个 zone 中的已经运行了包含标签 security: S2 的节点上

原则上, topologyKey 可以是任何合法的标签 key。然而,处于性能和安全的考虑,仍然对 topologyKey 有如下限制:

  1. 对亲和性以及 requiredDuringSchedulingIgnoredDuringExecution Pod 反亲和性,topologyKey 不能为空
  2. requiredDuringSchedulingIgnoredDuringExecution Pod 反亲和性,管理控制器 LimitPodHardAntiAffinityTopology 被用来限制 topologyKey 必须为 kubernetes.io/hostname。如果想要使用其他的自定义 topology,必须修改该管理控制器,或者将其禁用
  3. preferredDuringSchedulingIgnoredDuringExecution Pod 反亲和性,如果 topologyKey 为空,则代表所有的 topology (此时,不局限于 kubernetes.io/hostnamefailure-domain.beta.kubernetes.io/zonefailure-domain.beta.kubernetes.io/region 的组合)
  4. 除了上述的情形以外,topologyKey 可以是任何合法的标签 Key

除了 labelSelectortopologyKey 以外,还可以指定一个 namespaces 的列表,用作 labelSelector 的作用范围(与 labelSelectortopologyKey 的定义为同一个级别)。如果不定义或者该字段为空,默认为 Pod 所在的名称空间。

所有与 requiredDuringSchedulingIgnoredDuringExecution 亲和性和反亲和性关联的 matchExpressions 必须被满足,Pod 才能被调度到目标节点。

更多实用的例子

Pod 亲和性与反亲和性结合高级别控制器(例如 ReplicaSet、StatefulSet、Deployment 等)一起使用时,可以非常实用。此时可以很容易的将一组工作复杂调度到同一个 topology,例如,同一个节点。

始终在同一个节点

在一个三节点的集群中,部署一个使用 redis 的 web 应用程序,并期望 web-server 尽可能与 redis 在同一个节点上。

下面是 redis deployment 的 yaml 片段,包含三个副本以及 app=store 标签选择器。Deployment 中配置了 PodAntiAffinity,确保调度器不会将三个副本调度到一个节点上:

apiVersion: apps/v1
kind: Deployment
metadata:name: redis-cache
spec:selector:matchLabels:app: storereplicas: 3template:metadata:labels:app: storespec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- storetopologyKey: "kubernetes.io/hostname"containers:- name: redis-serverimage: redis:3.2-alpine

配置详解:

这个YAML文件描述了一个Kubernetes的Deployment对象,用于部署一个名为 “redis-cache” 的应用程序。以下是文件的详细解读:

  1. apiVersion: apps/v1: 这个字段指定了使用的Kubernetes API版本,这里是apps/v1,表示我们正在定义一个Deployment对象。
  2. kind: Deployment: 这个字段指定了我们要创建的Kubernetes资源的类型,这是一个Deployment资源,用于部署和管理应用程序的副本。
  3. metadata: 这个字段包含有关Deployment对象的元数据信息,例如名称和标签。
    • name: redis-cache: 这个字段指定了Deployment对象的名称,它将被用来标识和引用这个Deployment。
  4. spec: 这个字段包含了Deployment的规范,定义了如何创建和运行Pod的规则。
    • selector: 这 个部分定义了哪些Pod将被包括在Deployment中。
      • matchLabels: 这里指定了一个标签选择器,要求匹配具有 “app: store” 标签的Pod将包括在Deployment中。
    • replicas: 3: 这个字段指定了要创建的Pod副本数量,这里是3个。
    • template: 这个部分定义了要创建的Pod的模板。
      • metadata: 这里指定了Pod模板的标签,这些标签与Deployment的标签选择器匹配。
        • labels: 这里定义了一个标签 “app: store”。
      • spec: 这个部分定义了Pod的规范。
        • affinity: 这里定义了Pod的亲和性规则,以确保Pod在节点上的分布。
          • podAntiAffinity: 这个字段定义了Pod的反亲和性规则,要求具有相同标签 “app: store” 的Pod不会被调度到相同的节点上。
            • requiredDuringSchedulingIgnoredDuringExecution: 这个字段指定了在调度时必须满足的反亲和性规则。
              • labelSelector: 这里定义了一个标签选择器,要求匹配具有 “app: store” 标签的Pod。
              • topologyKey: "kubernetes.io/hostname": 这个字段指定了拓扑域的键,表示Pod的反亲和性规则将基于节点的主机名来执行。
        • containers: 这里定义了要在Pod中运行的容器列表。
          • name: redis-server: 这个字段指定了容器的名称,这个容器运行一个名为 “redis-server” 的服务。
          • image: redis:3.2-alpine: 这个字段指定了要使用的容器镜像,这里使用的是Redis 3.2版本的Alpine Linux基础镜像。

作用是创建一个名为 “redis-cache” 的Deployment,该Deployment包含3个副本,每个副本运行一个名为 “redis-server” 的Redis容器,并且确保这些Pod在不同的节点上运行,以提高可用性和容错性。这个Deployment使用标签选择器来选择要管理的Pod,并定义了Pod的亲和性规则以确保它们在节点上的分布。

下面是 webserver deployment 的 yaml 片段,配置了 podAntiAffinity 以及 podAffinity。要求将其副本与 包含 app=store 标签的 Pod 放在同一个节点上;同时也要求 web-server 的副本不被调度到同一个节点上。

apiVersion: apps/v1
kind: Deployment
metadata:name: web-server
spec:selector:matchLabels:app: web-storereplicas: 3template:metadata:labels:app: web-storespec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- web-storetopologyKey: "kubernetes.io/hostname"podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- storetopologyKey: "kubernetes.io/hostname"containers:- name: web-appimage: nginx:1.12-alpine

如果创建上述两个 deployment,集群将如下所示:

Node-1Node-2Node-3
web-server-1webserver-2webserver-3
cache-1cache-2cache-3

web-server 的三个副本都自动与 cach 的副本运行在相同的节点上。

kubectl get pods -o wide已复制到剪贴板!

1

输出结果如下所示

NAME                           READY     STATUS    RESTARTS   AGE       IP           NODE
redis-cache-1450370735-6dzlj   1/1       Running   0          8m        10.192.4.2   kube-node-3
redis-cache-1450370735-j2j96   1/1       Running   0          8m        10.192.2.2   kube-node-1
redis-cache-1450370735-z73mh   1/1       Running   0          8m        10.192.3.1   kube-node-2
web-server-1287567482-5d4dz    1/1       Running   0          7m        10.192.2.3   kube-node-1
web-server-1287567482-6f7v5    1/1       Running   0          7m        10.192.4.3   kube-node-3
web-server-1287567482-s330j    1/1       Running   0          7m        10.192.3.2   kube-node-2
始终不在相同的节点上

上面的例子使用了 PodAntiAffinity 规则与 topologyKey: "kubernetes.io/hostname" 来部署 redis 集群,因此没有任何两个副本被调度到同一个节点上。参考 ZooKeeper tutorial 了解如何使用相同的方式为 StatefulSet 配置反亲和性以实现高可用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149670.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】微服务——Ribbon负载均衡(跟进源码分析原理)

添加LoadBalanced注解,即可实现负载均衡功能,这是什么原理 1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。 2.源码跟踪 为什么我们只输入了service名称就可以访问了呢?之前还要获取…

论文阅读——Pyramid Grafting Network for One-Stage High Resolution Saliency Detection

目录 基本信息标题目前存在的问题改进网络结构CMGM模块解答为什么要用这两个编码器进行编码 另一个写的好的参考 基本信息 期刊CVPR年份2022论文地址https://arxiv.org/pdf/2204.05041.pdf代码地址https://github.com/iCVTEAM/PGNet 标题 金字塔嫁接网络的一级高分辨率显著性…

java做个qq机器人

前置的条件 机器人是基于mirai框架实现的。根据官方的文档&#xff0c;建议使用openjdk11。 我这里使用的编辑工具是idea2023 在idea中新建一个maven项目&#xff0c;虽然可以使用gradle进行构建&#xff0c;不过我这里由于网络问题没有跑通。 pom.xml <dependency>&l…

克服网络安全压力:如何掌控无限的云数据

管理云中的数字风险比以往任何时候都更加重要。数字化转型引发的云数据呈指数级增长&#xff0c;为安全分析师创造了一个更大的威胁环境。随着威胁行为者继续危害组织最敏感的数据&#xff0c;这一挑战将会加剧。 预计未来五年全球网络犯罪成本将激增&#xff0c;从 2022 年的…

数值分析学习笔记——误差【华科B站教程版本】

误差 误差&#xff1a;一个物理量的真实值与计算值之间的误差 误差来源与分类 模型误差&#xff1a;对问题所抽象出来的数学/物理模型是误差的&#xff0c;比如要有一些假设条件才进行理论的推导观测误差&#xff1a;测量得到的模型的参数的值的误差方法误差&#xff08;截断…

【网络安全---sql注入(2)】如何通过SQL注入getshell?如何通过SQL注入读取文件或者数据库数据?一篇文章告诉你过程和原理。

前言 本篇博客主要是通过piakchu靶场来讲解如何通过SQL注入漏洞来写入文件&#xff0c;读取文件。通过SQL输入来注入木马来getshell等&#xff0c;讲解了比较详细的过程&#xff1b; 如果想要学习SQL注入原理以及如何进行SQL注入&#xff0c;我也写了一篇详细的SQL注入方法及…

JMeter性能测试

性能测试前言 老师开局一句话&#xff1a;性能测试和你会不会JMeter一点关系没有…… 作者坚持技多不压身的原则&#xff0c;还是多学一点JMeter吧&#xff0c;看老师到底要怎么讲下去&#xff0c;什么并发量、吞吐量啥的…… 性能测试的核心思想&#xff1a;在于创造大量并发去…

[NSSRound#1 Basic]sql_by_sql - 二次注入+布尔盲注||sqlmap

进入注册界面后   假设sql&#xff1a;update user set password ‘’ where username ‘’ and password ‘’     此时如果我们注册的用户名是admin’–、admin’#、admin’–的话   update user set password ‘123’ where username ‘admin’#’ and passwor…

Hive SQL初级练习(30题)

前言 Hive 的重要性不必多说&#xff0c;离线批处理的王者&#xff0c;Hive 用来做数据分析&#xff0c;SQL 基础必须十分牢固。 环境准备 建表语句 这里建4张表&#xff0c;下面的练习题都用这些数据。 -- 创建学生表 create table if not exists student_info(stu_id st…

第七章 查找 八、B树

目录 一、定义 二、B树的核心特性 1、B树各个结点的子树数和关键字数 2、子树高度 3、关键字的值 4、B树高度 三、B树的插入 四、B树的删除 一、定义 B树&#xff0c;又称多路平衡查找树&#xff0c;B树中所有结点的孩子个数的最大值称为B树的阶&#xff0c;通常用m表示…

Gorsonpy的计算器

Gorsonpy的计算器 0.页面及功能展示1. PSP表格2.解题思路描述3.设计实现过程4.程序性能改进5.异常处理6.单元测试展示7.心路历程和收获 这个作业属于哪个课程https://bbs.csdn.net/forums/ssynkqtd-05这个作业要求在哪里https://bbs.csdn.net/topics/617294583这个作业的目标完…

基于JavaWeb技术的在线考试系统设计与实现

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 考试统计管理 专业列表管理 忘记密码人员登记管理 修改密码 试卷信息 考试信息管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理…

卷积神经网络-卷积层

卷积神经网络 卷积神经网络&#xff08;convolutional neural network&#xff0c;CNN&#xff09;是一类包含卷积计算且具有深度结构的前馈神经网络&#xff0c;是深度学习的代表算法之一。卷积神经网络具有表征学习能力&#xff0c;能够按其阶层结构对输入信息进行平移不变分…

Folium笔记:HeatMap

在地图上生成热力图 0 举例 import folium from folium.plugins import HeatMap# 创建一个地图对象 m folium.Map(location(1.34084, 103.83637), zoom_start13)# 创建一个坐标点的数据集 data [(1.431656, 103.827896),(1.424789, 103.789902),(1.325781, 103.860446),(1.…

Java编程技巧:swagger2、knif4j集成SpringBoot或者SpringCloud项目

目录 1、springbootswagger2knif4j2、springbootswagger3knif4j3、springcloudswagger2knif4j 1、springbootswagger2knif4j 2、springbootswagger3knif4j 3、springcloudswagger2knif4j 注意点&#xff1a; Api注解&#xff1a;Controller类上的Api注解需要添加tags属性&a…

NEFU数字图像处理(1)绪论

一、简介 1.1什么是数字图像 图像是三维场景在二维平面上的影像。根据其存储方式和表现形式&#xff0c;可以将图像分为模拟图像和数字图像两大类 图像处理方法&#xff1a;光学方法、电子学方法 模拟图像&#xff1a;连续的图像数字图像&#xff1a;通过对时间上和数值上连续…

Hive【Hive(六)窗口函数】

窗口函数&#xff08;window functions&#xff09; 概述 定义 窗口函数能够为每行数据划分 一个窗口&#xff0c;然后对窗口范围内的数据进行计算&#xff0c;最后将计算结果返回给该行数据。 语法 窗口函数的语法主要包括 窗口 和 函数 两个部分。其中窗口用于定义计算范围…

Seata 源码篇之AT模式启动流程 - 下 - 04

Seata 源码篇之AT模式启动流程 - 下 - 04 全局事务提交分支事务全局提交全局事务回滚分支事务全局回滚小结 本系列文章: Seata 源码篇之核心思想 - 01Seata 源码篇之AT模式启动流程 - 上 - 02Seata 源码篇之AT模式启动流程 - 中 - 03 上一篇文章&#xff0c;我们看了Seata AT…

maven 初学

1. maven 安装 配置安装 路径 maven 下载位置: D:\software\apache-maven-3.8.6 默认仓库位置: C:\Users\star-dream\.m2\repository 【已更改】 本地仓库设置为&#xff1a;D:\software\apache-maven-3.8.6\.m2\repository 镜像已更改为阿里云中央镜像仓库 <mirrors>…

数据结构与算法(一):概述与复杂度分析

参考引用 Hello 算法 Github 仓库&#xff1a;hello-algo 1. 初识算法 1.1 算法无处不在 1.1.1 二分查找&#xff1a;查阅字典 在字典里&#xff0c;每个汉字都对应一个拼音&#xff0c;而字典是按照拼音字母顺序排列的。假设我们需要查找一个拼音首字母为 r 的字&#xff0…