Kubernetes Node Affinity

Assigning Pods to Nodes

可以限制Pods在特定节点上运行,也可以优先调度到特定节点。有几种方式可以实现这个功能,它们都使用选择标签的方式完成。通常情况下这些限制是没必要的,k8s会自动实现合理的调度(例如,pods在集群中调度时,不会被调度到资源不足的节点上)。但是,有些场景下,希望对运行pod的节点进行限制,如需要将pod调度到磁盘为SSD的节点上,或将两个不同的服务但需要经常通信的pod调度到同一个zone。

1.nodeSelector

nodeSelector是最简单的一种实现方式,是podSpec的一个字段,它指定了一个key-value的键值对。为了使pods能够在该节点上运行,该节点必须有所有需要的键值对作为标签(节点也可以有其它的标签)。

第一步:节点打标签

#语法
kubectl label nodes <node-name> <label-key>=<label-value>

#示例,如果节点名称是harmonycloud,需要添加‘disktype=ssd’标签
kubectl lable nodes harmonycloud disktype=ssd

# 验证,使用如下命令查看是否成功给node添加标签
kubectl get nodes --show-labels

第二步:配置文件中添加nodeSelector 字段

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:  #Add this field
    disktype: ssd

第三步:验证

#运行以下命令,创建pod
kubectl create -f pod.yaml

#查看pod运行节点
kubectl get pods -o wide 

2. Affinity and anti-affinity

nodeSelector 提供了一种简单的方式将pods调度到具有特定标签的节点上。

Affinity and anti-affinity 现在是beta版,大大拓展了可以表达的约束类型。相对于nodeSelector主要有以下几个优点:

  1. 语法更具表现力(不仅仅支持“与(AND)”完全匹配)
  2. 可以指明规则是“soft/preference”而不是强制要求,所以如果不满足调度条件,pods依然可以被调度。
  3. 可以将规则限制在运行在一个节点上的pods(或其他拓扑域),而不仅仅是节点本身,这将允许pods是否可以调度到同一个节点。

Affinity特征有两种类型,“node affinit” 和 “inter-pod affinity/anti-affinity”。 Node affinity跟nodeSelector很像,但有以上两个优点。inter-pod affinity/anti-affinity是对pod的标签进行限制,具有以上三条特性。

nodeSelector可以正常工作,最终将会被弃用,因为node affinity可以表示它可以表示的所有内容。

2.1 Node affinity(beta)

Kubernetes 1.2中,node affinity是alpha版。 Node affinity概念上与nodeSelector相似,通过选择标签的方式,可以限制pod被调度到特定的节点上。

目前支持两种类型的node affinity,requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution,可以他们看作“hard(强制)”和“soft(非强制)”。某种意义上,前者指定了要将pod调度到节点上必须满足的规则(像nodeSelector,但使用了更具表现力的语法),而后者试图调度到特定的节点但不能保证一定会调度到该节点。其中,“IgnoredDuringExecution”表示如果在pod运行时节点的标签发生改变导致无法满足pods创建时使用的调度规则,pod会继续在该节点上运行,这点与nodeSelector相似。将来会提供requiredDuringSchedulingRequiredDuringExecution,与requiredDuringSchedulingIgnoredDuringExecution一样,但是会迁移节点上的pod以满足其node affinity 的规则。

下面有一个使用node affinity的例子:

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

这条规则表示,pod可以被调度到key为“kubernetes.io/e2e-az-name”,值为“e2e-az1”或“e2e-az2”的节点。另外,在满足该条件的节点中,优先使用具有“another-node-label-key”标签,且至为“another-node-label-value”的节点。

上面的例子使用了“In”操作符,node affinity语法支持以下集中操作符:In, NotIn, Exists, DoesNotExist,Gt,Lt。没有明确的“node anti-affinity”概念,但是NotIn和DoesNotExist可以表示该含义。

如果同时指定了nodeSelectornodeAffinity,要调度的节点必须同时满足这两点规则。

如果指定了与多条与nodeSelector相关的表达式,pod将会被调度到同时满足这几条表达式的节点。

2.2 Inter-pod affinity and anti-affinity(beat)

Kubernetes 1.4中提出了inter-pod和anti-affinity的概念。inter-pod affinity和anti-affinity允许根据已在节点上运行的pod上的标签来限制pod可以调度到哪些节点,而不是基于节点上的标签。

规则的形式是,pod应该(anti-affinity表示不应该)运行在X中,如果X已经运行了一个或多个满足规则Y的pod。Y表示为LabelSelector具有相关namespace的列表(或所有namespace)。与节点不同,pod是属于不同namespace的(因此pod上的标签是隐含的namespace),pod 标签上的label selector必须制定该selector应用到哪个namespace。从概念上来说,X是一个拓扑域,如节点,机架,云提供商域等。

如node affinity,目前支持两种类型的pod affinity和anti-affinity:requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecutionrequiredDuringSchedulingIgnoredDuringExecution会将service A和service B的pod调度到同一个zone,因为他们彼此通信很多;preferredDuringSchedulingIgnoredDuringExecution,anti-affinity会把同一个service的pods调度到不同的zone(强制要求是没有意义的,因为pod的数量要大于zone)。

下面有一个使用pod affinity的例子:

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

这个例子中定义了affinity和anti-affinity规则。podAffinity是requiredDuringSchedulingIgnoredDuringExecution,podAntiaffinity是preferredDuringSchedulingIgnoredDuringExecution。pod affinity 规则表示,该pod只能运行在集群中的特定节点上,这些节点已经至少运行一个具有”security=S1“标签的pod,并且和这些节点在同一个zone(更确切的说,这个pod可以运行在节点N上,如果节点N有key为failure-domain.beta.kubernetes.io/zone和值为V的标签,同时该节点上运行着一个具有“security=S1”标签的pod)。pod anti-affinity规则表示,如果该节点已经运行着具有“security=S2”标签的pod,将不会优先调度到该节点。(如果topologyKeyfailure-domain.beta.kubernetes.io/zone,该pod也不会被优先调度到具有“security=S2”标签的节点所在的zone)。

和node affinity 一样,pod affinity 合法的操作符有In, NotIn, Exists, DoesNotExist, Gt, Lt。

原则上,topologyKey可以是任意标签,为了性能考虑只允许一些有限的topologyKey,默认情况下,有以下几个:

  • kubernetes.io/hostname
  • failure-domain.beta.kubernetes.io/zone
  • failure-domain.beta.kubernetes.io/region

除了labelSelectortopologyKey,也可以选择性的指定一些labelSelector需要匹配的namespace。如果忽略namespace,默认匹配affinity/anti-affinity定义的规则指定的namespace。如果定义了namespace,意味着所有namespace都可以。

必须满足所有与requiredDuringSchedulingIgnoredDuringExecution 相关的表达式才能将pod调度到某个节点。

3. 设计文档

node affinity/anti-affinity 设计文档
inter-pod affinity/anti-affinity设计文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • •Kubernetes介绍1.背景介绍云计算飞速发展- IaaS- PaaS- SaaSDocker技术突飞猛进-...
    Zero___阅读 14,734评论 0 21
  • 环境规划 手里的环境是四台安装了CentOS 7的主机。环境规划如下: Kubernetes Master 节点:...
    负二贷阅读 3,256评论 6 26
  • 1.1 Kubernetes是什么 首先,它是一个全新的基于容器技术的分布式架构领先方案; 其次,Kubernet...
    c84f3109853b阅读 80,582评论 1 117
  • 我要面临离婚了吗?没有感情,没有欣赏,只是为了结婚而结婚。 现在分床是不是等于我们的交点要过...
    乙烯烃阅读 372评论 0 0
  • 简介 Git Git是开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Linus Torvald...
    啤酒找尿布阅读 470评论 0 0