K8s影响Pod调度相关

调度方式

  • 定向调度
  • 亲和性调度
  • 污点与容忍

1. 定向调度

1.1 nodeName

nodeName 用于强制约束将Pod调度到指定Name的Node节点上。这种方式,其实是跳过Scheduler的调度逻辑,直接将Pod调度到指定名称的节点上。

1.2 nodeSelector

nodeSelector 用于将Pod调度到指定标签的Node节点上。它是通过k8s的label-selector机制实现的,在Pod创建之前,会由Scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node。然后将Pod调度到目标节点,该匹配是强制约束

apiVersion: v1
kind: Pod
metadata:
  name: podsc
  namespace: dev
spec:
  #nodeName: 192.168.0.30
  # nodeSelector:
  #   nodename: node20
  containers:
    - image:  192.168.0.200/public/nginx:v1
      imagePullPolicy: Always
      name:  podsc

2.亲和性调度

2.1 nodeAffinity node亲和性

nodeAffinity 是以node为目标,解决Pod可以调度到那些node的问题。
注意:
a. 如果同时设置了nodeSelector和nodeAffinity那么必须要满足这两个条件才能调度到节点上。
b. 如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要满足一个能够匹配成功即可调度。
c. 如果一个nodeSelectorTerms中有多个matchExpressions,则同一个节点必须要满足所有的才能匹配成功。
d. 如果一个pod所在的Node在Pod运行期间标签发生了改变,不再符合Pod的节点亲和性需求,则系统忽略此变化。因为已经经过scheduler调度。只有重新部署触发scheduler才能重新调度。
应用场景:

  1. 特殊资源使用:例如磁盘ssd,pod需要高IO性能。
  2. 特殊场景:重点业务需要部署在常年没有出现过故障的机器上等。
2.1.1 requiredDuringSchedulingIgnoredDuringExecution 硬限制,必须要node满足这些条件才能调度,否则就调度不上去, 不经过scheduler 这个也属于定向调度
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
            - key: nodename
              operator: In
              values: ["node20", "node21"]
2.1.2 preferredDuringSchedulingIgnoredDuringExecution 软限制,非必要满足这些条件,需要经过scheduler,当不满足这些条件时则选择其他节点。
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 10
          preference: 
            matchExpressions:
            - key: nodename
              operator: In
              values: ["node24", "node23"] //没有这些标签的
2.2 podAffinity pod亲和性

podAffinity 是以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题。
应用场景:

  1. Pod之间需要频繁交互,有必要使用亲和性让两个应用尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。
  2. 高可用场景下,将同一个业务的pod将其自动放到部署了相同应用pod的机器上。
2.2.1 preferredDuringSchedulingIgnoredDuringExecution 软限制即不满足也可调度
# pod亲和度参照Pod
apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: dev
  labels:
    kk: vv
spec:
  containers:
  - name: test
    image:  192.168.0.200/public/nginx:v1

# Pod亲和度使用软限制
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution: #硬限制
        - weight: 10
          podAffinityTerm:
            namespaces: #指定参照Pod的名称空间[]
            - "dev"
            topologyKey: kubernetes.io/hostname #指定匹配后的调度作用域
            labelSelector:
              matchExpressions:
              - key: kk
                operator: In
                values: 
                  - "vv"
                  - "bb"
2.2.2 requiredDuringSchedulingIgnoredDuringExecution 硬限制不满足则无法调度直接报错
# pod亲和度参照Pod
apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: dev
  labels:
    kk: vv
spec:
  containers:
  - name: test
    image:  192.168.0.200/public/nginx:v1
# Pod亲和度使用硬限制
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: "kk"
            operator: In
            values:
            - "yy"
            - "xx"
        namespaces:
        - "dev"
        topologyKey: kubernetes.io/hostname
2.3 podAntiAffinity pod反亲性

podAntiAffinity 是以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题

  1. 当应用采用多副本部署时,有必要采用反亲和性进行打散,可以有效提高服务的高可用性。
    注意:反亲和硬限制情况下,如果没有 匹配到指定标签的pod 那么就会按照其他算法来进行分配。一般还会搭配其他调度算法进行调度。
2.3.1 Pod反亲和性requiredDuringSchedulingIgnoredDuringExecution硬限制
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    podAntiAffinity: #Pod反亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #硬限制
      - labelSelector:
          matchExpressions: #匹配kk的值在yy 或者 xx 中的标签
          - key: "kk"
            operator: In
            values:
            - "yy"
            - "vv"
        namespaces:
        - "dev"
        topologyKey: kubernetes.io/hostname #作用域主机打散
2.3.1 Pod反亲和性preferredDuringSchedulingIgnoredDuringExecution软限制
apiVersion: v1
kind: Pod
metadata:
  name: affinitytest
  namespace: dev
spec:
  containers:
  - name: affinitytest
    image: 192.168.0.200/public/nginx:v1
    imagePullPolicy: Always
  affinity:
    podAntiAffinity: #Pod反亲和性
      preferredDuringSchedulingIgnoredDuringExecution: #硬限制
      - labelSelector:
          matchExpressions: #匹配kk的值在yy 或者 xx 中的标签
          - key: "kk"
            operator: In
            values:
            - "yy"
            - "vv"
        namespaces:
        - "dev"
        topologyKey: kubernetes.io/hostname #作用域主机打散

3.污点与容忍

3.1 污点

通过在Node上添加污点属性,决定是否允许Pod调度过来。
污点的格式为:key=value:effect
key和value是污点的标签,effect描述污点的作用,支持如下三个选项:

  • PreferNoSchedule: Scheduler尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度。
  • NoSchdule: Scheduler不会把Pod调度到具有该污点的Node上,但是不会影响当前Node上已经存在的Pod。
  • NoExecute: Scheduler不会把Pod调度到具有该污点的Node上,同时也会将Node上已经存在的Pod隔离,除非是容忍程度为NoExecute。
    注意:当节点打上污点设置为NoSchedule时通过指定节点(nodeName)任然可以设置运行到该节点,但是使用nodeSelector就不可以。
  • 设置污点:
kubectl taint node NODENAME KEY=VALUE:EFFECT
  • 去除污点
kubectl taint nodes NODENAME KEY:EFFECT-
  • 去除所有污点
kubectl taint nodes NODENAME KEY-
3.2 容忍污点

当节点设置了污点时,如果允许Pod调度到该污点上时需要在pod中设置容忍污点。 pod.spec.toleroations

apiVersion: v1
kind: Pod
metadata:
  name: test33
  namespace: dev
  labels:
    kk: vv
spec:
  nodeName: 192.168.0.21
  containers:
  - name: test33
    image:  192.168.0.200/public/nginx:v1
  tolerations: //容忍污点
  - key: "tag" // 对应污点KEY,若为空则意味着匹配所有的键
    operator: "Equal" // 匹配符,支持Equal和Exists(默认)
    value: "tagtaint" // 对应污点值
    effect: "NoExecute" // 对应污点的级别,空则匹配所有
    #tolerationSeconds: //容忍时间,当effect为NoExecute时生效,表示pod在Node上停留的时间,当时间到期时将会从此节点转移走,若永远没有设置则永远不会被剔除
[root@master10 yaml]# kgpoowiden dev
NAME     READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
test33   1/1     Running   0          9s    172.20.4.223   192.168.0.21   <none>           <none>
[root@master10 yaml]# kdno 192.168.0.21 | grep Ta
Taints:             tag=tagtaint:NoExecute

4.隔离与驱逐

    1. 通常在需要对Node进行停机维护时,一般需要进行对节点的隔离拒绝新的Pod调度到该节点上。
kubectl describe node NODENAME

程序也是通过对节点添加不可调度的污点来进行的隔离,使用的隔离程度为:NoSchedule,使用nodeName来进行指定调度,依然可以调度上去,可以避免资源不足导致新的Pod所有节点不可调度后导致节点Pending。

    1. 第二步即为对node节点上的Pod进行驱逐,drain会是一个平滑终止的过程,不会影响业务。
kubectl drain NODENAME --ignore-daemonsets --force

通常情况下需要忽略掉daemonset,此处还有一些没有被控制器控制的pod需要强制驱逐

    1. 查看当前节点上剩余的pod
[root@master10 yaml]# kgpoowideall | grep 0.20
default       daemon1-4w2ng                                1/1     Running            0          28m     172.20.3.156   192.168.0.20   <none>           <none>
kube-system   kube-flannel-ds-amd64-wngbj                  1/1     Running            0          28m     192.168.0.20   192.168.0.20   <none>           <none>
kube-system   node-local-dns-7frgs                         1/1     Running            8          41d     192.168.0.20   192.168.0.20   <none>           <none>
monitoring    node-exporter-52rqc                          2/2     Running            16         41d     192.168.0.20   192.168.0.20   <none>           <none>
    1. 确认没有后就可以进行维护或者将机器踢出集群后进行维护。维护完毕后取消隔离。
kubectl uncordon NODENAME
    1. 通过scalePod数量查看节点是否调度后完毕。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • nodeSelector pod只会运行在匹配nodeSelector的node上。 要使用这个功能需要先配置no...
    AlienPaul阅读 320评论 0 2
  • 前言 Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为kube-s...
    YP小站阅读 3,314评论 0 1
  • 一般情况下我们部署的 Pod 是通过集群的自动调度策略来选择节点的,默认情况下调度器考虑的是资源足够,并且负载尽量...
    祁恩达阅读 4,916评论 0 2
  • [toc] 一、HPA与弹性伸缩 1.1 scale scale命令可以使用命令行通过控制器调整副本数 1.2 H...
    Walker_7797阅读 1,724评论 0 0
  • 一、调度简介   一个容器平台的主要功能就是为容器分配运行时所需要的计算,存储和网络资源。容器调度系统负责选择在最...
    无剑_君阅读 757评论 0 1