01 引言
声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记
我们可以将Pod
的各种常规调度策略认为是将整个集群视为一个整体,然后进行 “打散或聚合” 的调度。
当我们的集群是为了容灾而建设的跨区域的多中心(多个Zone
)集群,即集群中的节点位于不同区域的机房时,比如:
北京、上海、广 州、武汉,要求每个中心的应用相互容灾备份,又能同时提供服务,此时最好的调度策略就是将需要容灾的应用均匀调度到各个中心,当某个中心出现问题时, 又自动调度到其他中心均匀分布,
Pod
的多中心均匀分布调度效果图如下所示(不管每个中心的Nod节点数量如何):
02 如何实现?
用普通的基于Node
标签选择的调度方式也可以实现上述效果,比如为每个
Zone都建立一个Deployment,Pod的副本总数除以Zone的数量就是每个分区的
Pod副本数量。但这样做有个问题:如果某个Zone失效,那么这个Zone的Pod就无法迁移到其他Zone。
另外,topology.kubernetes.io/zone就是Kubernetes默认支持的重要拓扑域之
一,那是否可以用Pod的亲和性调度来解决这个问题呢?不能,因为Pod的亲和性 调度用于解决相关联的Pod的调度问题,不能保证被依赖的Pod被均匀调度到多个Zone。
为了满足这种容灾场景下的特殊调度需求,在Kubernetes1.16版本中首次引入Even Pod Spreading特性,用于通过topologyKey
属性识别Zone,并通过设置新 的参数topologySpreadConstraints来将Pod均匀调度到不同的Zone。
03 举例
举个例子, 假如我们的集群被划分为多个Zone
,我们有一个应用(对应的Pod
标签为 app=foo
)需要在每个Zone
均匀调度以实现容灾,则可以定义YAML
文件如下:
spec: topologySpreadConstraints: - maxSkew: 1 whenUnsatisfiable: DoNotSchedule topologyKey: topology.kubernetes.io/zone selector: matchLabels: app: foo
在以上YAML定义中,关键的参数是maxSkew
,用于指定Pod
在各个Zone
上调度时能容忍的最大不均衡数:
- 值越大,表示能接受的不均衡调度越大;
- 值越小,表示各个Zone的Pod数量分布越均匀。
为了理解maxSkew
,我们需要先理解skew
参数的计算公式:
skew[topo]=count[topo]-min(count[topo])
即每个拓扑区域的skew值都为该区域包括的目标Pod数量与整个拓扑区域最少Pod数量的差,而naxSkew就是最大的skew值。
假如在上面的例子中有3个拓扑区域,分别为Zone A、Zone B及Zone C,有3个目标Pod需要调度到这些拓扑区域,那么前两个毫无疑问会被调度到Zone A和Zone B,Even Pod Spreading调度效果如图所示:
那么,第3个Pod
会被调度到哪里呢?我们可以手动计算每个Zone的skew:
- 首先计算出
min(count[topo])
是0,对应Zone C; - 于是
Zone A
的skew=1-0=1,Zone B
的skew=1-0=0,Zone C
的skew=0-0=0,于是第3个Pod应该被放在Zone C
,此时min(count[topo])的值就变成了1,而实际的maxSkew的值为0,符合预期设置; - 如果我们把maxSkew设置为2,则在这种情况下,第3个Pod被放在
Zone A
或Zone B
都是符合要求的。
有了新的Even Pod Spreading调度特性的加持,再加上之前就已成熟的Pod亲和性调度,Kubernetes就可以完美实现特定应用的容灾部署目标了。
具体做法也很简单:将一个应用中需要部署在一起的几个Pod用亲和性调度声明捆绑,然后选 择其中一个Pod,加持Even Pod Spreading调度规则即可。最终的部署效果图如下:
04 文末
本文主要讲解pod的容灾调度的一些概念及例子,希望能帮助到大家,谢谢大家的阅读,本文完!