自定义Kubernetes调度程序来编排高可用性应用程序

只要愿意遵守规则,在Kubernetes上进行部署和乘飞机旅行就可以很愉快。通常,事情会“正常工作”。但是,如果有兴趣与必须生存的鳄鱼一起旅行,或对必须保持可用状态的数据库进行扩展,则情况可能会变得更加复杂。为此,甚至可能更容易构建自己的飞机或数据库。除了爬行动物之外,扩展高可用性的有状态系统也不是一件容易的事。

扩展任何系统都有两个主要组成部分:

  1. 添加或删除系统将在其上运行的基础结构,以及
  2. 确保系统知道如何处理自己添加和删除的其它实例。

大多数无状态系统(例如Web服务器),在创建时不需要知道对等对象的。有状态的系统(包括CockroachDB之类的数据库)必须与对等实例进行协调,并在数据周围进行重新整理。幸运的是,CockroachDB能处理数据的重新分发和复制。棘手的部分是通过确保数据和实例分布在许多故障域(可用性区域)中,能够容忍这些操作中的故障。

Kubernetes的职责之一是将“资源”(例如磁盘或容器)放入群集中,并满足所要求的约束。例如:“必须在可用区域A”,或“不能将我与另一个Pod放置在同一节点上”。

除了这些约束之外,Kubernetes还提供Statefulsets(状态集),该状态集为Pod提供身份,以及“跟随”这些已标识Pod的持久性存储。StatefulSet中的身份由Pod名称末尾的递增整数处理。该整数必须始终是连续的:在StatefulSet中,如果容器1和3存在,则容器2也必须存在。

CockroachCloud将CockroachDB的每个区域作为StatefulSet,部署在其Kubernetes集群中。在本文中,将研究一个单独的区域,一个StatefulSet和一个Kubernetes集群,该集群分布在至少三个可用性区域中。

一个三节点的CockroachCloud集群如下所示:

向集群添加资源时,将它们分布在区域之间。为了获得最快的用户体验,同时添加了所有Kubernetes节点,然后扩展了StatefulSet。

无论Pod分配给Kubernetes节点的顺序如何,都满足反亲和性anti-affinity。此示例中,分别将Pod 0、1和2分配给区域A,B和C,分别以不同的顺序将Pod 3和4分配给区域B和A。由于吊舱仍放置在不同的区域中,因此仍然可以满足抗亲和力anti-affinity要求。

从集群中删除资源,逆序执行这些操作。

首先缩小StatefulSet,然后从群集中删除缺少CockroachDB pod的所有节点。

小为n的StatefulSet中的pod的id必须在range内[0,n)。将StatefulSet按m缩小,Kubernetes会从最高序数开始,向最低序数移动m吊舱,倒序添加。考虑下面的群集拓扑:

当从该群集中删除序号5到3时,状态集statefulset将在所有3个可用性区域中继续存在。

Kubernetes的调度程序并不能像最初预期的那样,保证上面的位置。

以下方面的综合了解,导致这种错误的原因。

考虑以下拓扑:

这些窗格是按顺序创建的,分布在集群中的所有可用性区域中。当序数5到3终止时,此群集将失去在C区的存在!

自动化将删除节点A-2,B-2和C-2。使CRDB-1处于非计划状态,持久卷积仅在最初创建区域中可用。

为了更正后一个问题,现在采用“狩猎和啄食hunt and peck”的方法从群集中删除计算机。不会从群集中盲目删除Kubernetes节点,而只会删除没有CockroachDB pod的节点。更艰巨的任务是纠缠Kubernetes调度程序。

头脑风暴会议为我们提供了3个选择:

1.升级到kubernetes 1.18并利用Pod拓扑扩展约束

虽然这似乎是一个完美的解决方案,公共云中的两个最常见的托管Kubernetes服务(EKS和GKE)尚无法使用Kubernetes 1.18。此外,pod拓扑扩展约束仍然是1.18中beta功能,这意味着即使v1.18可用,也不能保证在托管群集中也可以使用它。整个过程让人想起了Internet Explorer 8仍然存在时检查caniuse.com的过程

2.为每个区域部署一个有状态集。

与其在所有可用区域上分布一个StatefulSet,不如在每个区域具有节点亲和力的单个StatefulSet,将允许对区域拓扑进行手动控制。一直认为这是一种选择,这使其特别具有吸引力。最终,决定放弃此选项,因为这将需要对代码库进行大修,在现有客户集群上执行迁移,将是一项同样艰巨的任务。

3.编写一个自定义的Kubernetes调度程序。

编写自己的自定义Kubernetes调度程序。部署并运行了概念验证后, Kubernetes的调度程序,负责将持久卷映射到其调度的Pod。输出kubectl get events,还有另一个系统在起作用。在寻找负责存储声明映射的组件的过程中,发现了kube-scheduler插件系统。下一个POC是一个Filter插件,按Pod顺序确定合适的可用性区域,并且可以完美地工作!

自定义调度程序插件是开源的,可在所有CockroachCloud集群中运行。控制StatefulSet Pod的调度方式,充满信心地进行扩展。一旦GKE和EKS中提供了Pod拓扑扩展约束,可能会考虑淘汰插件,但是维护开销却出乎意料的低。更妙的是:该插件的实现与业务逻辑正交。部署或撤消它,就像更改schedulerName的StatefulSet定义中的字段一样简单。

最新文章

  1. 测试docker不同主机间容器互相访问
  2. .net 4.0 ValidateRequest="false" 无效
  3. JS中对象排序
  4. windows下sublime2 clojure环境配置
  5. SharePoint 创建模版页
  6. 解决 git 中文路径显示 unicode 代码的问题
  7. 寻虫记:BOM头制造的冤案,无故多出空白行
  8. hadoop-初学者写map-reduce程序中容易出现的问题 3
  9. 关于android listview去掉分割线
  10. [搜片神器]服务器SQL2005查询分页语句你理解了么
  11. CSS之图片旋转
  12. 如何为Myeclipse手工添加dtd支持
  13. UVA 714 Copying Books 最大值最小化问题 (贪心 + 二分)
  14. go 冒泡排序
  15. js模拟jq获取id
  16. 第1阶段——u-boot分析之make指令(2)
  17. SpringBoot动态配置加载
  18. HTML5 常用标签整理
  19. 【CF833E】Caramel Clouds(线段树)
  20. c# 上传excel数据总结(一)线程的使用

热门文章

  1. CSS新特性contain,控制页面的重绘与重排
  2. wire shark 抓包过滤器
  3. 路由器逆向分析------firmware-mod-kit工具安装和使用说明
  4. 基于C++简单Windows API的socket编程(阻塞模式)
  5. LA3266田忌赛马
  6. Win64 驱动内核编程-9.系统调用、WOW64与兼容模式
  7. Python 爬虫之Scrapy框架
  8. (转)VMware中桥接模式与NAT模式的区别
  9. Day009 稀疏数组
  10. Mybatis-Plus02 CRUD