【重识云原生】第六章容器基础6.4.9.5节——端点切片(Endpoint Slices)

news2024/11/15 17:46:01

1 EndpointSlice特性 

Kubernetes v1.21 [stable]

        端点切片(EndpointSlices) 是一个新 API,它提供了 Endpoint API 可伸缩和可拓展的替代方案。EndpointSlice 会跟踪 Service Pod 的 IP 地址、端口、readiness 和拓扑信息。

        在 Kubernetes v1.19 中,此功能将默认启用:从 EndpointSlice (不是 Endpoint)中读取 kube-proxy。尽管这个更改看起来并不起眼,但实际上它能让大型集群的可伸缩性得到显着提高。另外,它还与 Kubernetes 未来版本中的重要新功能有关,例如 Topology Aware Routing。

1.1 诞生背景--Endpoint API 可伸缩性限制

        如果使用 Endpoint API,Service 只有一个 Endpoint 资源。这意味着它需要为 Service 的每个 Pod 都存储好 IP 地址和端口(网络端点),这需要大量的 API 资源。另外,kube-proxy 会在每个节点上运行,并监控 Endpoint 资源的任何更新。如果 Endpoint 资源中有一个端口发生更改,那么整个对象都会分发到 kube-proxy 的每个实例。

        Endpoint API 另一个局限是,它会限制跟踪 Service 的网络端点数量。一般存储在 etcd 中的对象默认大小限制为 1.5MB。在某些情况下,它会将 Endpoint 资源限制为 5000 个 Pod IP。对于大多数用户而言,这没什么关系,但是对于接近这个大小的 Service 而言,就有大问题了。

        为了说明这些问题的严重程度,这里举一个简单的例子。如果一个 Service 有 5000 个 Pod,它如果有 1.5MB 的 Endpoint 资源。当该列表中的某个网络端点发生了变化,那么就要将完整的 Endpoint 资源分发给集群中的每个节点。在具有 3000 个节点的大型集群中,这会是个很大的问题。每次更新将跨集群发送 4.5GB 的数据(1.5MB*3000,即 Endpoint 大小 * 节点个数),并且每次端点更新都要发送这么多数据。想象一下,如果进行一次滚动更新,共有 5000 个 Pod 全部被替换,那么传输的数据量将超过 22 TB。

1.2 EndpointSlice API 拆分 Endpoint

        EndpointSlice API 旨在通过类似于分片的方法来解决该问题。我们不跟踪 Service Pod IP 的单个 Endpoint 资源,而是将它们拆分为多个较小的 EndpointSlice。

        举个例子,现在有 15 个 Pod 在支持一个 Service,那么就有跟踪这些的一个 Endpoint 资源。如果将 EndpointSlice 配置为每个 EndpointSlice 存储 5 个端点,就得到了 3 个不同的 EndpointSlice:

        默认情况下,EndpointSlice 每个存储能多达 100 个端点,我们可以使用 kube-controller-manager 的 --max-endpoints-per-slice 标签进行配置。

1.3 EndpointSlice 提升 10 倍可伸缩性

        EndpointSlice API 大大提高了网络的可伸缩性,因为现在添加或删除 Pod 时,只需更新 1 个小的 EndpointSlice。尤其是成百上千个 Pod 支持单个 Service 时,差异将非常明显。

        更重要的是,既然 Service 的所有 Pod IP 都不需要存储在单个资源中,那么我们就不必担心 etcd 中存储对象的大小限制。EndpointSlice 可以用于扩展到超过 10 万个网络端点的 Service。

        当这些与 kube-proxy 的一些重大性能改进结合在一起后,再大规模地使用 EndpointSlice 时,用于端点更新的数据将大大减少,kube-proxy 还可以更快更新 iptables 和 ipvs 规则。这样,Service 现在的可伸缩性能达到以前的至少 10 倍。

1.4 EndpointSlice 有关新功能

        作为 Kubernetes v1.16 中的 alpha 功能引入的 EndpointSlice 在 Kubernetes 未来版本中,会和一些令人兴奋的新功能有关,例如 dual-stack Service、topology aware routing 和 endpoint subsetting。

  • Dual-stack Service 是一项与 EndpointSlice 一起开发的新功能。它们利用 IPv4 和 IPv6 地址提供 Service,并依靠 EndpointSlice 上的 addressType 字段按 IP 系列跟踪这些地址。
  • Topology aware routing 会更新 kube-proxy 以 prefer 同一区域或区域内的路由请求。这使用了为 EndpointSlice 端点存储的拓扑字段。另外,目前还在探索 endpoint subsetting 的潜力,未来 kube-proxy 将只允许观察 EndpointSlice 的子集。这可以与 topology aware routing 结合使用,这样 kube-proxy 只需要监控包含同一区域内端点的 EndpointSlice,这将提供另一个非常显着的可伸缩性改进。

1.5 与 Endpoints 的比较

        原来的 Endpoints API 提供了在 Kubernetes 中跟踪网络端点的一种简单而直接的方法。随着 Kubernetes 集群和服务逐渐开始为更多的后端 Pod 处理和发送请求, 原来的 API 的局限性变得越来越明显。最明显的是那些因为要处理大量网络端点而带来的挑战。

        由于任一 Service 的所有网络端点都保存在同一个 Endpoints 对象中,这些 Endpoints 对象可能变得非常巨大。对于保持稳定的服务(长时间使用同一组端点),影响不太明显; 即便如此,Kubernetes 的一些使用场景也没有得到很好的服务。

        当某 Service 存在很多后端端点并且该工作负载频繁扩缩或上线新更改时,对该 Service 的单个 Endpoints 对象的每次更新都意味着(在控制平面内以及在节点和 API 服务器之间)Kubernetes 集群组件之间会出现大量流量。 这种额外的流量在 CPU 使用方面也有开销。

        使用 EndpointSlices 时,添加或移除单个 Pod 对于正监视变更的客户端会触发相同数量的更新, 但这些更新消息的大小在大规模场景下要小得多。

        EndpointSlices 还支持围绕双栈网络和拓扑感知路由等新功能的创新。

2 EndpointSlice API

        在 Kubernetes 中,EndpointSlice 包含对一组网络端点的引用。 控制面会自动为设置了选择算符的 Kubernetes Service 创建 EndpointSlice。 这些 EndpointSlice 将包含对与 Service 选择算符匹配的所有 Pod 的引用。 EndpointSlice 通过唯一的协议、端口号和 Service 名称将网络端点组织在一起。 EndpointSlice 的名称必须是合法的 DNS 子域名。

        例如,下面是 Kubernetes Service example 所拥有的 EndpointSlice 对象示例。

apiVersion: discovery.k8s.io/v1 
kind: EndpointSlice 
metadata: 
  name: example-abc 
  labels: 
    kubernetes.io/service-name: example 
addressType: IPv4 
ports: 
  - name: http 
    protocol: TCP 
    port: 80 
endpoints: 
  - addresses: 
    - "10.1.2.3" 
  conditions: 
    ready: true 
  hostname: pod-1 
  nodeName: node-1 
  zone: us-west2-a

        默认情况下,控制面创建和管理的 EndpointSlice 将包含不超过 100 个端点。 你可以使用 kube-controller-manager 的 --max-endpoints-per-slice 标志设置此值,最大值为 1000。

        当涉及如何路由内部流量时,EndpointSlice 可以充当 kube-proxy 的决策依据。

2.1 地址类型

        EndpointSlice 支持三种地址类型:

  • IPv4
  • IPv6
  • FQDN (完全合格的域名)

        每个 EndpointSlice 对象代表一个特定的 IP 地址类型。如果你有一个支持 IPv4 和 IPv6 的 Service, 那么将至少有两个 EndpointSlice 对象(一个用于 IPv4,一个用于 IPv6)。

2.2 状态

        EndpointSlice API 存储了可能对使用者有用的、有关端点的状态。 这三个状态分别是 ready、serving 和 terminating。

2.2.1 Ready(就绪)状态

        ready 状态是映射 Pod 的 Ready 状态的。 对于处于运行中的 Pod,它的 Ready 状态被设置为 True,应该将此 EndpointSlice 状态也设置为 true。 出于兼容性原因,当 Pod 处于终止过程中,ready 永远不会为 true。 消费者应参考 serving 状态来检查处于终止中的 Pod 的就绪情况。 该规则的唯一例外是将spec.publishNotReadyAddresses设置为 true 的 Service。 这些 Service 的端点将始终将 ready 状况设置为 true。

2.2.2 Serving(服务中)状态 

Kubernetes v1.22 [beta]

        serving 状态与 ready 状态相同,不同之处在于它不考虑终止状态。 如果 EndpointSlice API 的使用者关心 Pod 终止时的就绪情况,就应检查此状态。

说明:

尽管 serving 与 ready 几乎相同,但是它是为防止破坏 ready 的现有含义而增加的。 如果对于处于终止中的端点,ready 可能是 true,那么对于现有的客户端来说可能是有些意外的, 因为从始至终,Endpoints 或 EndpointSlice API 从未包含处于终止中的端点。 出于这个原因,ready 对于处于终止中的端点 总是 false, 并且在 v1.20 中添加了新的状态 serving,以便客户端可以独立于 ready 的现有语义来跟踪处于终止中的 Pod 的就绪情况。

2.2.3 Terminating(终止中)状态 

Kubernetes v1.22 [beta]

        Terminating 是表示端点是否处于终止中的状态。 对于 Pod 来说,这是设置了删除时间戳的 Pod。

2.3 拓扑信息

        EndpointSlice 中的每个端点都可以包含一定的拓扑信息。 拓扑信息包括端点的位置,对应节点、可用区的信息。 这些信息体现为 EndpointSlices 的如下端点字段:

  • nodeName - 端点所在的 Node 名称;
  • zone - 端点所处的可用区。说明:

        在 v1 API 中,逐个端点设置的 topology 实际上被去除, 以鼓励使用专用的字段nodeName和zone。

        对 EndpointSlice 对象的 endpoint 字段设置任意的拓扑结构信息这一操作已被废弃, 不再被 v1 API 所支持。取而代之的是 v1 API 所支持的 nodeName 和 zone 这些独立的字段。这些字段可以在不同的 API 版本之间自动完成转译。 例如,v1beta1 API 中 topology 字段的topology.kubernetes.io/zone 取值可以在 v1 API 中通过 zone 字段访问。

2.4 管理

        通常,控制面(尤其是端点切片的控制器) 会创建和管理 EndpointSlice 对象。EndpointSlice 对象还有一些其他使用场景, 例如作为服务网格(Service Mesh)的实现。 这些场景都会导致有其他实体或者控制器负责管理额外的 EndpointSlice 集合。

        为了确保多个实体可以管理 EndpointSlice 而且不会相互产生干扰, Kubernetes 定义了标签 endpointslice.kubernetes.io/managed-by,用来标明哪个实体在管理某个 EndpointSlice。 端点切片控制器会在自己所管理的所有 EndpointSlice 上将该标签值设置为 endpointslice-controller.k8s.io。 管理 EndpointSlice 的其他实体也应该为此标签设置一个唯一值。

2.5 属主关系

        在大多数场合下,EndpointSlice 都由某个 Service 所有, (因为)该端点切片正是为该服务跟踪记录其端点。这一属主关系是通过为每个 EndpointSlice 设置一个属主(owner)引用,同时设置 kubernetes.io/service-name 标签来标明的, 目的是方便查找隶属于某 Service 的所有 EndpointSlice。

2.6 EndpointSlice 镜像

        在某些场合,应用会创建定制的 Endpoints 资源。为了保证这些应用不需要并发的更改 Endpoints 和 EndpointSlice 资源,集群的控制面将大多数 Endpoints 映射到对应的 EndpointSlice 之上。

        控制面对 Endpoints 资源进行映射的例外情况有:

  • Endpoints 资源上标签 endpointslice.kubernetes.io/skip-mirror 值为 true。
  • Endpoints 资源包含标签 control-plane.alpha.kubernetes.io/leader。
  • 对应的 Service 资源不存在。
  • 对应的 Service 的选择算符不为空。

        每个 Endpoints 资源可能会被转译到多个 EndpointSlices 中去。 当 Endpoints 资源中包含多个子网或者包含多个 IP 协议族(IPv4 和 IPv6)的端点时, 就有可能发生这种状况。 每个子网最多有 1000 个地址会被镜像到 EndpointSlice 中。

2.7 EndpointSlices 的分布问题

        每个 EndpointSlice 都有一组端口值,适用于资源内的所有端点。 当为 Service 使用命名端口时,Pod 可能会就同一命名端口获得不同的端口号, 因而需要不同的 EndpointSlice。这有点像 Endpoints 用来对子网进行分组的逻辑。

        控制面尝试尽量将 EndpointSlice 填满,不过不会主动地在若干 EndpointSlice 之间执行再平衡操作。这里的逻辑也是相对直接的:

  1. 列举所有现有的 EndpointSlices,移除那些不再需要的端点并更新那些已经变化的端点。
  2. 列举所有在第一步中被更改过的 EndpointSlices,用新增加的端点将其填满。
  3. 如果还有新的端点未被添加进去,尝试将这些端点添加到之前未更改的切片中, 或者创建新切片。

        这里比较重要的是,与在 EndpointSlice 之间完成最佳的分布相比,第三步中更看重限制 EndpointSlice 更新的操作次数。例如,如果有 10 个端点待添加,有两个 EndpointSlice 中各有 5 个空位,上述方法会创建一个新的 EndpointSlice 而不是将现有的两个 EndpointSlice 都填满。换言之,与执行多个 EndpointSlice 更新操作相比较, 方法会优先考虑执行一个 EndpointSlice 创建操作。

        由于 kube-proxy 在每个节点上运行并监视 EndpointSlice 状态,EndpointSlice 的每次变更都变得相对代价较高,因为这些状态变化要传递到集群中每个节点上。 这一方法尝试限制要发送到所有节点上的变更消息个数,即使这样做可能会导致有多个 EndpointSlice 没有被填满。

        在实践中,上面这种并非最理想的分布是很少出现的。大多数被 EndpointSlice 控制器处理的变更都是足够小的,可以添加到某已有 EndpointSlice 中去的。 并且,假使无法添加到已有的切片中,不管怎样都很快就会创建一个新的 EndpointSlice 对象。Deployment 的滚动更新为重新为 EndpointSlice 打包提供了一个自然的机会,所有 Pod 及其对应的端点在这一期间都会被替换掉。

2.8 重复的端点

        由于 EndpointSlice 变化的自身特点,端点可能会同时出现在不止一个 EndpointSlice 中。鉴于不同的 EndpointSlice 对象在不同时刻到达 Kubernetes 的监视/缓存中, 这种情况的出现是很自然的。

说明:

EndpointSlice API 的客户端必须能够处理特定端点地址出现在多个 EndpointSlice 中的情况。

        你可以在 kube-proxy 中的 EndpointSliceCache 代码中找到有关如何执行这个端点去重的参考实现。

参考链接

利用EndpointSlices扩展Kubernetes网络,提供更强的可伸缩性和功能 - alauda - 博客园

EndpointSlice | Kubernetes

【K8s概念】端点切片(Endpoint Slices) - Varden - 博客园

使用 EndpointSlice 扩展 Kubernetes 网络_K8sMeetup 社区的博客-CSDN博客_endpoint slice

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

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

相关文章

一文看懂页面置换算法

页面置换算法分为两类 1、局部页面置换算法 最优页面置换算法(OPT、optimal)先进先出算法(FIFO)最近最久未使用算法(LRU,Least Recently Used)时钟页面置换算法(Clock)最不常用算法…

【算法 | 实验18】在字符矩阵中查找给定字符串的所有匹配项

文章目录题目描述思路分析bug记录:"error: >> should be > > within a nested template argument list"代码题目描述 题目 在字符矩阵中查找给定字符串的所有匹配项 给定一个MN字符矩阵,以及一个字符串S,找到在矩阵中所…

给Git仓库添加.gitignore:清理、删除、排除被Git误添加的临时文件

文章目录一、前言二、发现提交的临时文件三、去掉临时文件的方法3.1 添加.gitignore3.2 删除临时文件缓存3.3 添加后的效果一、前言 最近维护代码过程中,发现某APP代码库里被提交了许多临时文件,而这些临时文件每次都会变化,所以导致每次修改…

为什么要写单测

一、什么是单元测试 “在计算机编程中,单元测试又称为模块测试,是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最…

大屏经典组件:“无限滚动” 从分析到开发

📖阅读本文,你将 理解大屏 “无限滚动组件” 的开发思路跟随作者,一步步完成一个高性能 “无限滚动组件” 的开发收获一份该实现的粗糙源码。 一、无限滚动:事件/告警 的有力帮手 1.1 为什么需要滚动列表 大屏之所以 “炫酷” …

稳压二极管稳压电路如何设计

在一些电流不大的地方,一般毫安级别,有时候我们可以利用稳压二极管去设计一个我们需要的电压。 大家可以看下稳压二极管的伏安曲线 在反向电压下,尽管电流在很大的范围内变化,而稳压二极管两端的电压却基本上稳定在击穿电压附近&a…

[附源码]java毕业设计旅游产品销售管理

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

CISCN 2022 初赛 web 复现

[CISCN 2022 初赛]ezpop 可以看到版本&#xff0c;那么直接上网找链子打 www.zip 查看路由&#xff0c;是 Index/test&#xff0c;然后 post 传参 a <?php // 保证命名空间的一致 namespace think {// Model需要是抽象类abstract class Model {// 需要用到的关键字priv…

【vue】vuex中modules的基本用法

1&#xff0c;什么时候用modules 由于使用单一状态树&#xff0c;应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时&#xff0c;store 对象就有可能变得相当臃肿。 为了解决以上问题&#xff0c;Vuex 允许我们将 store 分割成模块&#xff08;module&#xff09…

NFT交易平台开发 创建NFT数字藏品平台

为什么需要 NFT 市场&#xff1f; NFT Marketplace 允许用户购买、出售、交易、查看或创建自己的 NFT&#xff0c;就像他们需要一个市场来购买物理或数字世界中的大多数产品一样。几乎每个人都可以进入 NFT 市场&#xff0c;但要做到这一点&#xff0c;用户必须满足以下要求&a…

第3关:节点状态检查、数据查看和更新

首先&#xff0c;需要启动服务器&#xff0c;并使用zkCli.sh连接服务器&#xff0c;进入客户端命令行界面&#xff08;如第一关所述&#xff09;。 节点状态包含以下信息&#xff1a; czxid: 节点创建时的时间戳。mzxid: 节点最新一次更新发生时的时间。ctime&#xff1a; 节…

[附源码]java毕业设计篮球装备商城系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务中的服务发现是什么?

作者&#xff1a;罗泽轩 摘要&#xff1a;本文通过服务发现的相关背景和 APISIX 对于服务发现的应用与实践&#xff0c;来介绍微服务中的服务发现内容。 在互联网刚开始出现的年代&#xff0c;人们要想访问某个在线服务&#xff0c;需要输入一长串的 IP 地址。IP 地址虽然不长&…

PDF怎么编辑修改文字?

PDF怎么编辑修改文字&#xff1f;PDF大家都不陌生&#xff0c;我们经常会接触到各种类型的PDF文档&#xff0c;尽管大多数人对PDF的需求仅仅是阅读&#xff0c;但是也有很多人会需要去编辑和修改PDF文件&#xff0c;那你们知道如何编辑和修改PDF文件吗&#xff1f;金闪PDF编辑器…

提取图像直方图(图像处理)

继直方图规定化后的研究 由于直方图规定化是根据两张图片的累计直方图进行图像的处理。对于这个处理过程&#xff0c;我尝试了很图像进行替换色系&#xff0c;但是没有找到一个相对合适案例&#xff0c;来体现直方图规定化这个算法的精妙之处。在多次尝试中&#xff0c;我发现…

低代码核心:代码生成还是模型解释?

2020年第一届低代码研讨会上&#xff0c; Jordi Cabot发表了一篇文章&#xff08;或者说观点&#xff09;&#xff0c;对比了低代码和模型驱动开发的关系&#xff0c;认为低代码等于模型驱动开发。但实际上&#xff0c;不少低代码系统并不是使用模型驱动的&#xff0c;而是采用…

node的express模块

express的概述: express是一个提供web服务的框架&#xff08;内置http模块&#xff09;&#xff0c;他简化了http的相关内容&#xff0c;将对应的内容封装为了特定的方法 安装: npm i express -S 导入以及代码: //导入express 是一个函数 const expressrequire(express) //cre…

做机器人开发,你一定绕不开的模块!

Allspark 机载电脑 Allspark 是阿木实验室为广大AI智能硬件开发者打造的一款微型边缘计算机。在设计之初就定义了尺寸小巧、重量轻、算力强、可靠、扩展性高的特点。Allspark机身采用铝合金新材料外壳设计&#xff0c;内置静音散热风扇&#xff0c;尺寸94mm*59mm*37mm&#xff…

[附源码]java毕业设计警院学生学习交流系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux进程常见通信方式

文章目录1、管道<1>匿名管道<2> 命名管道2、共享内存3、信号量为什么要进程要进行通信呢&#xff1f; 进程间可能存在特定的协同工作的场景&#xff0c;这个时候就需要一个进程把自己的数据交付给另一个进程&#xff0c;让其进行处理。 进程通信的本质 因为进程具有…