Kubernetes APIServer,Etcd,controller manager,scheduler 高可用原理

2023-11-20

高可用背后的原理


这两个月和博云合作的项目是要用于客户生产环境的,这个和我以前做的东西有很大的不同,所有基础架构必须给出高可用的解决方案。在这之前我只做过一些流量较小的用户产品或者一些原型项目,一开始基础架构都只给出了单节点的解决方案,结果被大师兄喷这个在生产环境根本不可用。不过事实确实是在一个真实的分布式系统中硬件损坏、进程崩溃、网络不通都可能直接导致系统不可用,所以后来花了很大的精力将项目的基础架构层面改造成完全高可用的,这个过程对一个之前完全没做过这方面东西的人来说确实会感觉比较困难,不过在这个过程中也确实实践了不少分布式系统的理论,了解了各种各样的高可用解决方案,也对Kubernetes的架构运行原理有了更加深刻的认识。下面我会从我调研的高可用解决方案的各个细节来给大家介绍一下高可用的Kubernetes集群背后的原理。

ETCD高可用


Kubernetes使用ETCD持久化存储集群状态信息。ETCD是CoreOS开源的一个强一致性的分布式键值存储服务,ETCD使用raft算法将一组主机组成集群,集群中的每个节点都可以根据集群运行的情况在三种状态间切换:follower, candidate 与 leader。leader 和 follower 之间保持心跳。如果follower在一段时间内没有收到来自leader的心跳,就会转为candidate,发出新的选主请求。

集群初始化的时候内部的节点都是follower节点,之后会有一个节点因为没有收到leader的心跳转为candidate节点,发起选主请求。当这个节点获得了大于一半节点的投票后会转为leader节点。

正在上传…重新上传取消

当leader节点服务异常后,其中的某个follower节点因为没有收到leader的心跳转为candidate节点,发起选主请求。只要集群中剩余的正常节点数目大于集群内主机数目的一半,ETCD集群就可以正常对外提供服务。

当集群内部的网络出现故障集群可能会出现“脑裂”问题,这个时候集群会分为一大一小两个集群(奇数节点的集群),较小的集群会处于异常状态,较大的集群可以正常对外提供服务。

ETCD的作用是用来存储,其高可用的很大一个作用是用来备份存储的数据,因此它基于Raft的高可用解决方案会使每个节点都在工作。还有一个值得注意的一点,ETCD 2个节点是不能实现高可用的,最少需要3个节点,这个是Raft协议的特性使之的,大家感兴趣可以去读一下Raft的论文。

控制器高可用保证


Kubernetes 提供了Leader 选举机制,用以确保多个控制器的实例同时运行,并且只有Leader 实例提供真正的服务。其他实例处于准备就绪状态,如果Leader 出现故障,则取代Leader 以保证Pod 能被及时调度。此机制以占用更多资源为代价,提升了Kubernetes控制器的可用性。

Leader 选举的核心是利用 Configmap Endpoints Lease 对象实现分布式资源锁。当多个实例同时启动后,在运行任何业务逻辑之前,都会尝试读取该资源锁。
Lease 对象为例,在首次抢占过程中,该对象无任何 Leader 信息,第一个尝试占有锁的实例会更新该对象的acquireTime holderIdentity ,并以 leaseDurationSeconds 为周期不断更新renewTime
控制器的判断逻辑是:只有当 holderIdentity 与当前实例的 Pod 名称完全匹配时,控制器的程序执行才继续,否则等待获取锁。如果Leader 能保证在固定周期内及时更新renewTime ,则该锁始终被 Leader 占有,任何其他实例周期性地尝试更新 holderIdentity 以成为新的 Leader 。该机制保证 Leader 实例出现故障或网络断开时,其 Leader租约会到期,其他实例可抢占资源锁迅速成为新Leader Lease 对象的示例代码如下:

资源锁可保存在ConfigmapEndpoints Lease 三种对象中。推荐使用Lease,因为Lease 对象本身就是用来协调租约对象的,其Spec 定义与Leader 选举机制需要操控的属性是一致的。使用Configmap Endpoints 对象更多是为了向后兼容,伴随着一定的负面影响。

以Endpoints 为例,Leader 每隔固定周期就要续约,这使得Endpoints 对象处于不断的变化中。Endpoints 对象会被每个节点的kube-proxy 等监听,任何Endpoints 对象的变更都会推送给所有节点的kube-proxy,这为集群引入了不必要的网络流量。

任何集群控制器均可基于 Leader 选举机制进行开发部署。调度器是一个 特殊 的控
制器,它基于 Leader 选举机制,用于保证服务高可用。

 

 

controller manager和scheduler的高可用


kube-controller-mansger和kube-scheduler,其中kube-controller-mansger和kube-scheduler组件

自身通过选择机制已经实现了高可用,就是说,如果集群里配置了多个kube-controller-manager和

kube-scheduler组件,他们会根据自己的竞争机制选出主用组件。

Kubernetes使用scheduler、controller manager来实现pod的调度和rc、deployment等的副本控制。Kubernetes也是通过controller manager和应用健康检查机制实现了它上面部署应用的高可用。

而scheduler、controller manager的高可用原理和上面又是不一样的,为了保证集群运行正常,scheduler、controller manager同一时刻只允许一个服务处以具体的任务。Kubernetes中实现了一套简单的类似于分布式锁的方案,依赖ETCD实现scheduler和controller-manager的选主功能。

如果scheduler和controller manager在启动的时候设置了 --leader-elect 参数,它们在启动后会先尝试获取leader节点身份,只有在获取leader节点身份后才可以执行具体的业务逻辑。

它们分别会在ETCD中创建scheduler和controller manager的endpoint,endpoint的信息中记录了当前的leader节点信息,以及记录的上次更新时间。leader节点会定期更新endpoint的信息,维护自己的leader身份。每个从节点的服务都会定期检查endpoint的信息,如果endpoint的信息在时间范围内没有更新,它们会尝试更新自己为leader节点。

scheduler服务以及controller manager服务之间不会进行通信,利用ETCD的强一致性,能够保证在分布式高并发情况下leader节点的全局唯一性。

当集群中的leader节点服务异常后,其它节点的服务会尝试更新自身为leader节点,当有多个节点同时更新endpoint时,由Etcd保证只有一个服务的更新请求能够成功。

通过这种机制sheduler和controller manager可以保证在leader节点宕机后其它的节点可以顺利选主,保证服务故障后快速恢复。

etcd使用场景

  • 可以用于键值对存储,应用程序可以读取和写入etcd 中的数据
  • etcd 比较多的应用场景是用于服务注册与发现

它有lease的机制,续约机制一般用在什么场景下?用于服务发现的场景,比如spring cloud,跑一个应用实例,有一个注册中心,当应用实例运行完之后就要去注册中心把自己注册上,但是注册的时间是有时效性的比如30s,作为客户端如何保证自己是活着的,这就需要不停的去续约,一旦续约没有完成,比如中间网络中断,那么之前的键值就失效了,所以它很自然的就落在了服务发现的场景,我写一个键值对注册自己,并且不停的续约,如果续约不成功,那么键值对失效。

通过这种机制就可以发现整个集群里面的service。

服务注册与发现

 有一个服务注册中心,这里都有服务提供者和服务消费者,服务提供者比如说提供了web服务,我将自己的ip和服务名称写到etcd里面,通过续约的机制写进去,通过lease的机制写进去,通过心跳来保持这个续约有效,如果中间链路或者自身出现了问题,那么租约就失败了。

另外一边服务消费者,他就去服务注册中心发现服务,服务有哪些endpoint,只要在服务注册中心里面服务发现这个查询能够发现的这些endpoint,那就说明它是当前的有效的服务提供者,那么就可以产生绑定关系。

消费者要相信etcd会将失效的服务提供者,也就是没有及时续约的,那些提供者的ip都会自动拿掉,通过这种场景就可以做服务注册和发现。

apiserver的高可用


Kubernetes的接入层服务主要是kube-apiserver,官方文档上说apiserver是Kubernetes资源的唯一入口。其实后来根据我对Kubernetes的使用和对其源码的阅读,可以看作apiserver实现了Kubernetes对象的model存到ETCD里面,然后自己作为一个RESTful的HTTP server和外界交互作CRUD操作。apiserver是无状态的,无状态的意思是在哪个apiserver上面接收请求都会得到相同的结果,我们可以同时开多个apiserver处理外部请求,这一点是和scheduler和controller manager不同的。因此apiserver的高可用没必要像scheduler、controller manager一样通过分布式锁强一致性实现同一时间只有一个leader在工作。

而使用多活apiserver的最大难点是如何实现能保证高可用的负载均衡,为了解决这个问题主要使用了keepalived和Nginx。可以使用keepalived配置节点的优先级和检测失活脚本,然后可以给外部一个同一的VIP,并且保证机器肯定能接收到请求,然后配置Nginx可以将请求负载到可用的apiserver上。

使用keepalived、Nginx这种IP漂移、负载均衡的方式比分布式锁服务保持单个leader这种方式可以保持多个实例、性能更高。

除了这个三个主要的之外,我还做了一些例如kube-DNS、CNI插件Calico、Docker镜像仓库的高可用。但是这些都可以是可以基于Kubernetes的副本控制去做的,这里我就只说明一下Kubernetes自身高可用的解决方案,其他就不赘述了。

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

Kubernetes APIServer,Etcd,controller manager,scheduler 高可用原理 的相关文章

  • 在 selenium webdriver 中打开一个新窗口而不是新选项卡

    当在我的应用程序中手动单击链接时 它会在 Chrome 和 IE 中的新选项卡中打开 但是 当我的脚本运行时 该链接会在 IE 中的新窗口而不是新选项卡中打开 相同的脚本在 Chrome 中按预期运行 知道如何摆脱这个吗 更改 IE 的默认
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过
  • 正则表达式 - 匹配不包含字符串的模式

    我对正则表达式很陌生 并且一直在寻找方法来做到这一点 但没有成功 给定一个字符串 我想删除以 abc 开头 以 abc 结尾且中间不包含 abc 的任何模式 如果我做 abc abc abc 它将匹配以 b 开头 以 abc 结尾并且中间包
  • Javascript/jQuery 外部高度()

    Does idOfLememt outerHeight 对所有浏览器产生相同的结果 IE7 有什么不同吗 只要去http api jquery com outerHeight http api jquery com outerHeight
  • 我如何用 javascript/jquery 进行两指拖动?

    我正在尝试创建当有两个手指放在 div 上时拖动 div 的功能 我已将 div 绑定到 touchstart 和 touchmove 事件 我只是不确定如何编写这些函数 就像是if event originalEvent targetTo
  • Maven 构建错误 TOOLS.JAR NOT FOUND IN JRE

    我在构建 Maven 项目时遇到这个问题 请帮我解决 ERROR Failed to execute goal org apache maven plugins maven compiler plugin 2 5 1 compile def
  • Android 的代码覆盖率[重复]

    这个问题在这里已经有答案了 可能的重复 Android测试代码覆盖率 Eclipse https stackoverflow com questions 3282702 android test code coverage eclipse
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ
  • Angular 2:使用正则表达式进行数字验证

    我正在尝试验证 IE 11 中的数字字段
  • Swift 中的 quitFirstResponder

    我怎样才能用Apple的新语言实现它 Objective C 代码 void touchesBegan NSSet touches withEvent UIEvent event for UIView view in self view s
  • Maven2继承

    如果我有一个父 pom 并且想将其继承到多个项目 我通常通过添加到项目顶部来做到这一点
  • 文本处理问题:删除其中一列不包含特定值的行

    我有一个制表符分隔的文件 如下所示 input sequence match sequence score receptor group epitope antigen organism ASRPPGGVNEQF ASRPPGGVNEQF
  • 用 Beautiful Soup 进行抓取:为什么 get_text 方法不返回该元素的文本?

    最近我一直在用 python 开发一个项目 其中涉及抓取一些网站的一些代理 我遇到的问题是 当我尝试抓取某个知名代理站点时 当我要求 Beautiful Soup 查找 IP 在代理表中的位置时 它并没有按照我的预期执行操作 我将尝试查找每
  • 使用并非为 IOC 设计的遗留应用程序避免服务定位器反模式

    我经常读到IOC 中的服务定位器是一种反模式 http blog ploeh dk 2010 02 03 ServiceLocatorIsAnAntiPattern aspx 去年 我们在工作中的应用程序中引入了 IOC 具体来说是 Nin
  • JavaScript 中“键”的类型是什么?

    当我失去焦点并开始思考一个愚蠢的问题时 我遇到了这样的时刻 var a b value b 的类型是什么 我的意思不是 值 的类型 而是标记为 b 的实际键 背景 当我必须创建一个字符串键时 我开始想知道这一点 var a b value
  • 从 Teradata sql Assistant 将结果导出到 Excel 工作表

    我想通过在 Teradata SQL Assistant 中运行查询将结果导出到 Excel 工作表中 我使用了复制粘贴 但没有用 提前致谢 如果您将答案返回到 SQL Assistant 您应该能够从 文件 菜单中选择 保存答案集 然后
  • 如何在 Symfony 4 中为测试环境设置数据库

    我对如何在 symfony 4 中为测试环境设置数据库感到困惑 我曾经在配置测试 ymlsymfony 3 及以下版本中的文件 最佳做法是什么 我应该重新创建一个学说 yaml文件输入配置 包 测试 该文档提到如何通过编辑 phpunit
  • 尝试了解天蓝色云服务中的负载平衡

    我正在维护一个天蓝色的云服务 它有 1 个 Web 角色和几个辅助角色 该网络角色有多个实例 当我从资源中打开云服务时 我可以看到服务端点和公共IP地址 我想了解这个蔚蓝云服务中的流量负载是如何平衡的 我搜索了负载均衡器 但在订阅中找不到它
  • 将 read.csv 与符号链接文件一起使用

    我正在尝试做什么 我的源文件非常大 我想避免将其复制到其他文件夹中 我决定创建一个指向大文件的符号链接并想使用read csv读取文件 文件夹结构 项目1 数据 源文件 csv 项目2 数据 别名到源文件 csv 什么地方出了错 读取源文件
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐