ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Kubernetes——Pod资源亲和调度

2022-07-06 17:02:15  阅读:158  来源: 互联网

标签:亲和性 Kubernetes app 调度 myapp Pod 节点


Pod资源亲和调度

  出于高效通信的需求,偶尔需要把一些 Pod 对象组织在相似的位置(同一节点、机架、区域或地区等),如某业务的前端 Pod 和后端 Pod 等,此时可以将这些 Pod 对象间的关系称为亲和性。

  偶尔,出于安全或分布式等原因也有可能需要将一些 Pod 对象在其运行的位置上隔离开来,如在每个区域运行一个应用代理 Pod 对象等,此时可把这些 Pod 对象间的关系称为反亲和性(anti-affinity)。

  Kubernetes 调度器通过内建的 MatchInterPodAffinity 预选策略为这种调度方式完成节点预选,并基于 InterPodAffinityPriority 优选函数进行各节点的优先级评估。

一、位置拓扑

  Pod亲和性调度需要各相关的 Pod 对象运行于“同一位置”,而反亲和性调度则要求它们不能运行于“同一位置”。何谓同一位置?事实上,它们取决于节点的位置拓扑,拓扑的方式不同。

  如果以基于各节点的 kubernetes.io/hostname 标签作为评判标准,那么很显然,“同一位置” 意味着同一个节点,不同节点即不同的位置,如图所示:

   在定义 Pod 对象的亲和性与反亲和性时,需要借助于标签选择器来选择被依赖的 Pod 对象,并根据选出的 Pod 对象所在的节点的标签来判定 "同一位置" 的具体意义。

二、Pod硬亲和调度

  Pod 强制约束的亲和性调度也使用 requiredDuringSchedulinglgnoredDuringExecution 属性进行定义。Pod 亲和性用于描述一个 Pod 对象与具有某特征的现存 Pod 对象运行位置的依赖关系,因此,测试使用 Pod 亲和性约束,需要事先存在被依赖的Pod对象,它们具有特别的识别标签。例如创建一个有着标签 app=tomcat 的 Deployment 资源部署一个 Pod 对象:

kubectl run tomcat -l app=tomcat --image tomcat:alpine

  下面的资源配置清单(required-podAffinity-pod1.yaml)中定义了一个 Pod 对象,它通过 labelSelector 定义的标签选择器挑选感兴趣的现存 Pod 对象,而后根据挑选出的 Pod 对象所在节点的标签 "kubernetes.io/hostname" 来判断同一位置的具体含义,并将当前 Pod 对象调度至这一位置的某节点之上:

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity-1
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["tomcat"]}
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx

  事实上,kubernetes.io/hostname 标签是 Kubernetes 集群节点的内建标签,它的值为当前节点的节点主机名称标识,对于各个节点来说,各有不同。因此,新建的 Pod 象将被部署至被依赖的Pod 对象的同一节点上,requiredDuringSchedulingIgnoredDuringExecution 表示这种亲和性为强制约束。

kubectl apply -f required-podAffinity-pod1.yaml
kubectl get pods -o wide

  基于单一节点的 Pod 亲和性只在极个别的情况下才有可能会用到,较为常用的通常是基于同一地区 region、区域 zone 或机架 rack 的拓扑位置约束。例如部署应用程序服务 myapp 与数据库 db 服务相关的 Pod 时,db Pod 可能会部署于如上图所示的 foo 或 bar 这两个区域中的某节点之上,依赖于数据服务的 myapp Pod 对象可部署于 db Pod 所在区域内的节点上。当然,如果 db Pod 在两个区域 foo 和 bar 中各有副本运行,那么 myapp Pod 将可以运行于这两个区域的任何节点之上。

  例如,创建具有两个拥有标签为 "app=db" 的副本 Pod 作为被依赖的资源,它们可能运行类似下图所示的三个节点中的任何一个或两个节点上,本示例中它们凑巧运行于两个 zone 标签值不同的节点上:

kubectl  run  db -l app=db --image=redis:alpin --replicas=2
kubectl get pods -l app=db -o wide -w

  于是,依赖于亲和于这两个 Pod 的其他 Pod 对象可运行于 zone 标签值为 foo 和 bar 的区域内的所有节点之上。下面的资源清单(deploy-with-required-podAffinity.yaml)中正是定义了这样一些 Pod 资源,它们由 Deployment 控制器所创建:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-pod-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - {key: app, operator: In, values: ["db"]}
            topologyKey: zone
      containers:
      - name: nginx
        image: nginx

  在调度示例中的 Deployment 控制器创建的 Pod资 源时,调度器首先会基于标签选择器查询拥有标签 "app=db" 的所有 Pod 资源,接着获取到它们分别所属的节点的 zone 标签值,接下来再查询拥有匹配这些标签值的所有节点,从而完成节点预选。而后根据优选函数计算这些节点的优先级,从而挑选出运行新建 Pod 对象的节点。

  需要注意的是,如果节点上的标签在运行时发生了更改,以致它不再满足 Pod 上的亲和性规则,但该 Pod 还将继续在该节点上运行,因此它仅会影响新建的 Pod 资源;另外,labelSelector 属性仅匹配与被调度器的 Pod 在同一名称空间中的 Pod 资源,不过也可以通过为其添加 namespace 字段以指定其他名称空间 。

三、Pod 软亲和调度

  类似于节点亲和性机制,Pod 也支持使用 preferredDuringSchedulinglgnoredDuringExecution 属性定义柔性亲和机制,调度器会尽力确保满足亲和约束的调度逻辑,然而在约束条件不能得到满足时,它也允许将 Pod 对象调度至其他节点运行。下面是一个使用了 Pod 软亲和性调度机制的资源配置清单示例(deploy-with-preferred-podAffinity.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-preferred-pod-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 80
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["cache"]}
              topologyKey: zone
          - weight: 20
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["db"]}
              topologyKey: zone
      containers:
      - name: nginx
        image: nginx

  它定义了两组亲和性判定机制,一个是选择 cache Pod 所在节点的 zone 标签,并赋予了较高的权重 80,另一个是选择 db Pod 所在节点的 zone 标签,它有着略低的权重 20。于是,调度器会将目标节点分为四类 :cache Pod 和 db Pod 同时所属的 zone、cache Pod 单独所属的 zone、db Pod 单独所属的 zone,以及其他所有的 zone。

四、Pod反亲和调度

  podAffinity 用于定义 Pod 对象的亲和约束,对应地,将其替换为 podAntiAffinty 即可用于定义Pod对象的反亲和约束。不过,反亲和性调度一般用于分散同一类应用的 Pod 对象等,也包括将不同安全级别的 Pod 对象调度至不同的区域、机架或节点等。下面的资源配置清单中定义了由同一 Deployment 创建但彼此基于节点位置互斥的 Pod 对象:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-pod-anti-affinity
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - {key: app, operator: In, values: ["myapp"]}
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx

  由于定义的强制性反亲和和约束,因此,创建的 4 个 Pod 副本必须运行于不同的节点中。不过,本集群中一共只存在 3 个节点,因此,必然地会有一个 Pod 对象处于 Pending 状态。

  Pod 反亲和调度也支持使用柔性约束机制,在调度时,它将尽量不把位置相斥的 Pod 对象调度于同一位置,但是,当约束关系无法得到满足时,也可以违反约束而调度。 

标签:亲和性,Kubernetes,app,调度,myapp,Pod,节点
来源: https://www.cnblogs.com/zuoyang/p/16451414.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有