Kubernetes中的亲和性与反亲和性
2021-01-19 19:48
465 查看
通常情况下,Pod分配到哪些Node是不需要管理员操心的,这个过程会由scheduler自动实现。但有时,我们需要指定一些调度的限制,例如某些应用应该跑在具有SSD存储的节点上,有些应用应该跑在同一个节点上等等。
nodeSelector:
首先我们为Node规划标签,然后在创建部署的时候,通过使用nodeSelector标签来指定Pod运行在哪些节点上。
亲和性(Affinity )与反亲和性(AntiAffinity):
- 亲和性:应用A与应用B两个应用频繁交互,所以有必要利用亲和性让两个应用的尽可能的靠近,甚至在一个node上,以减少因网络通信而带来的性能损耗。
- 反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,以提高HA。
包含:nodeAffinity(主机亲和性),podAffinity(POD亲和性)以及podAntiAffinity(POD反亲和性)
策略名称 | 匹配目标 | 支持的操作符 | 支持拓扑域 | 设计目标 |
---|---|---|---|---|
nodeAffinity | 主机标签 | In,NotIn,Exists,DoesNotExist,Gt,Lt | 不支持 | 决定Pod可以部署在哪些主机上 |
podAffinity | Pod标签 | In,NotIn,Exists,DoesNotExist | 支持 | 决定Pod可以和哪些Pod部署在同一拓扑域 |
PodAntiAffinity | Pod标签 | In,NotIn,Exists,DoesNotExist | 支持 | 决定Pod不可以和哪些Pod部署在同一拓 |
nodeAffinity使用场景 :
- 将S1服务的所有Pod部署到指定的符合标签规则的主机上。
- 将S1服务的所有Pod部署到除部分主机外的其他主机上。
podAffinity使用场景 : - 将某一特定服务的pod部署在同一拓扑域中,不用指定具体的拓扑域。
-
如果S1服务使用S2服务,为了减少它们之间的网络延迟(或其它原因),把S1服务的POD和S2服务的pod部署在同一拓扑域中。
podAntiAffinity使用场景: - 将一个服务的POD分散在不同的主机或者拓扑域中,提高服务本身的稳定性。
- 给POD对于一个节点的独占访问权限来保证资源隔离,保证不会有其它pod来分享节点资源。
- 把可能会相互影响的服务的POD分散在不同的主机上。
运算符关系:
- In:label的值在某个列表中
- NotIn:label的值不在某个列表中
- Gt:label的值大于某个值
- Lt:label的值小于某个值
- Exists:某个label存在
- DoesNotExist:某个label不存在
nodeSelector的调度方式略显简单,通过亲和和反亲和配置,能够为调度提供更灵活的策略,主要有以下几点增强:
- 更多的表达式支持,不仅仅是ADD和精确匹配了
- 可以设置soft/preference的调度策略,而不是刚性的要求
- 可以通过Pod的标签进行调度约束,不仅仅是Node的标签
亲和性特性包含两种方式:
- requiredDuringSchedulingIgnoredDuringExecution: hard,严格执行,满足规则调度,否则不调度,在预选阶段执行,所以违反hard约定一定不会调度到
- preferredDuringSchedulingIgnoredDuringExecution:soft,尽力执行,优先满足规则调度,在优选阶段执行
- requiredDuringSchedulingRequiredDuringExecution,类似 requiredDuringSchedulingIgnoredDuringExecution。不同之处就是pod运行过程中如果节点不再满足pod的亲和性,则pod会在该节点中逐出。
IgnoreDuringExecution表示如果在Pod运行期间Node的标签发生变化,导致亲和性策略不能满足,则继续运行当前的Pod。
限制
topologyKey:
- 对于亲和性和软反亲和性,不允许空topologyKey;
- 对于硬反亲和性,LimitPodHardAntiAffinityTopology控制器用于限制topologyKey只能是kubernetes.io/hostname;
- 对于软反亲和性,空topologyKey被解读成kubernetes.io/hostname, failure-domain.beta.kubernetes.io/zone and failure-domain.beta.kubernetes.io/region的组合;
例子:
apiVersion: apps/v1 kind: Deployment metadata: name: redis-cache spec: selector: matchLabels: app: redis replicas: 3 template: metadata: labels: app: redis spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - redis topologyKey: "kubernetes.io/hostname" containers: - name: redis-server image: redis:latest
上面的例子中,创建了一个具有三个实例的部署,采用了Pod间的反亲和策略,限制创建的实例的时候,如果节点上已经存在具有相同标签的实例,则不进行部署,避免了一个节点上部署多个相同的实例。
基于上面的例子:
再创建3个Web服务的实例,同上面Redis的配置,首先确保两个Web不会部署到相同的节点,然后在应用Pod间亲和策略,优先在有Redis服务的节点上部署Web。
apiVersion: apps/v1 kind: Deployment metadata: name: web-server spec: selector: matchLabels: app: web-store replicas: 3 template: metadata: labels: app: web-store spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - web-store topologyKey: "kubernetes.io/hostname" podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - redis topologyKey: "kubernetes.io/hostname" containers: - name: web-app image: nginx:latest
⚠️注意事项:
- Pod间的亲和性策略要求可观的计算量可能显著降低集群的性能,不建议在超过100台节点的范围内使用。
- Pod间的反亲和策略要求所有的Node都有一致的标签,例如集群中所有节点都应有匹配topologyKey的标签,如果一些节点缺失这些标签可能导致异常行为。
- 如果同时指定nodeSelector和nodeAffinity,则必须满足两个条件,才能将Pod调度到候选节点上。
- 如果pod已经调度在该节点,当我们删除或修该节点的标签时,pod不会被移除。换句话说,亲和性选择只有在pod调度期间有效。
- 在key下的values只要有一个满足条件,那么当前的key就满足条件
- 如果在matchExpressions下有多个key列表,那么只有当所有key满足时,才能将pod调度到某个节点【针对硬亲和】。
相关文章推荐
- Kubernetes中的亲和性
- Kubernetes中的亲和性与反亲和性
- Kubernetes源码阅读
- Kubernetes1.3:POD生命周期管理
- 关于Docker&kubernetes的一些问题
- 使用 kind 快速搭建 kubernetes 环境
- 基于 CentOS7 的 Kubernetes 集群
- Kubernetes 是一个“数据库”吗?
- Kubernetes高级实践:Master高可用方案设计和踩过的那些坑
- centos7 安装kubernetes1.4(kubeadm版)
- 云服务器-异地部署集群服务-Kubernetes(K8S)-Kubeadm安装方式-完整篇
- kubernetes1.4新特性:支持两种新的卷插件
- 【K8S】如何进入kubernetes的一个pod
- Kubernetes 1.4 基础篇:kubeadm方式安装
- 【K8S】 基于Kubernetes部署Kafka集群
- 在centos7上部署kubernetes
- 【华为云技术分享】跟唐老师学习云网络 : Kubernetes网络实现
- kubernetes学习1--centOS7.2使用yum安装kubernetes
- 视频教程-prometheus(kubernetes)企业监控2018视频-Docker/K8S
- Kubernetes总体架构和应用创建流程