Kubernetes中的亲和性与反亲和性

一般状况下,Pod分配到哪些Node是不须要管理员操心的,这个过程会由scheduler自动实现。但有时,咱们须要指定一些调度的限制,例如某些应用应该跑在具备SSD存储的节点上,有些应用应该跑在同一个节点上等等。 node

nodeSelector
首先咱们为Node规划标签,而后在建立部署的时候,经过使用nodeSelector标签来指定Pod运行在哪些节点上。nginx

亲和性(Affinity )与反亲和性(AntiAffinity):
web

  • 亲和性:应用A与应用B两个应用频繁交互,因此有必要利用亲和性让两个应用的尽量的靠近,甚至在一个node上,以减小因网络通讯而带来的性能损耗。
  • 反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,以提升HA。

包含:nodeAffinity(主机亲和性),podAffinity(POD亲和性)以及podAntiAffinity(POD反亲和性)redis

策略名称 匹配目标 支持的操做符 支持拓扑域 设计目标
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使用场景 api

  • 将S1服务的全部Pod部署到指定的符合标签规则的主机上。
  • 将S1服务的全部Pod部署到除部分主机外的其余主机上。
    podAffinity使用场景 :
  • 将某一特定服务的pod部署在同一拓扑域中,不用指定具体的拓扑域。
  • 若是S1服务使用S2服务,为了减小它们之间的网络延迟(或其它缘由),把S1服务的POD和S2服务的pod部署在同一拓扑域中。
    podAntiAffinity使用场景:网络

  • 将一个服务的POD分散在不一样的主机或者拓扑域中,提升服务自己的稳定性。
  • 给POD对于一个节点的独占访问权限来保证资源隔离,保证不会有其它pod来分享节点资源。
  • 把可能会相互影响的服务的POD分散在不一样的主机上。

运算符关系:app

  • In:label的值在某个列表中
  • NotIn:label的值不在某个列表中
  • Gt:label的值大于某个值
  • Lt:label的值小于某个值
  • Exists:某个label存在
  • DoesNotExist:某个label不存在

nodeSelector的调度方式略显简单,经过亲和和反亲和配置,可以为调度提供更灵活的策略,主要有如下几点加强:dom

  • 更多的表达式支持,不单单是ADD和精确匹配了
  • 能够设置soft/preference的调度策略,而不是刚性的要求
  • 能够经过Pod的标签进行调度约束,不单单是Node的标签

亲和性特性包含两种方式:
ide

  • 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调度到某个节点【针对硬亲和】。
相关文章
相关标签/搜索