21. 资源的调度——PodAffinity:亲和与互斥

本章讲解知识点

  • 前言
  • PodAffinity 概念
  • 实验

<br>

1. 前言

在实际的生产环境中有一类特殊的 Pod 调度需求:存在某些相互依赖、频繁调用的 Pod,它们需要被尽可能地部署在同一个 Node 节点、机架、机房、网段内,这就是 Pod 之间的亲和性;反之,出于避免竞争或者容错的需求,我们也可能使某些 Pod 尽可能地远离某些特定的 Pod,这就是 Pod 之间的反亲和性和互斥性

<br>

2. PodAffinity 概念

PodAffinity 和 Pod Anti Affinity 是 Kubernetes 中用于定义拓扑关系的机制。简单来说,PodAffinity 用于确定哪些相关联的 Pod 可以在同一个拓扑域中共存,而 Pod Anti Affinity 则用于确定哪些相关联的 Pod 在同一个拓扑域中应该互斥。拓扑域由一些 Node 节点组成,这些节点通常有相同的地理空间坐标,比如在同一个机架、机房或地区。我们一般用 region 表示机架、机房这样的拓扑区域,用 Zone 表示地区这样更大的拓扑区域。在极端情况下,我们也可以认为一个 Node 就是一个拓扑区域。Kubernetes 中默认的一些拓扑域包括:

  • kubernetes.io/hostname;
  • topology.kubernetes.io/region;
  • topology.kubernetes.io/zone

需要注意的是以上拓扑域是 Kubernetes 自身维护的,在 Node 节点初始化时,controller-manager 会为 Node 打上许多标签,比如 kubernetes.io/hostname 这个标签的值就会被设置为 Node 节点的 hostname。

因此 PodAffinity 可以用于多个场景,例如:

  • 希望将一组相关的 Pod 调度到同一个节点上,以获得更好的性能或更低的延迟。
  • 希望将不同的 Pod 调度到不同的节点上,以减少节点之间的资源竞争和单点故障的风险。
  • 希望将不同的 Pod 调度到同一个节点上,以便它们可以共享资源(例如,共享同一个 Volume)。

Pod 亲和与互斥的调度的具体做法,就是通过在 Pod 的定义上增加 topologyKey 属性,来声明对应的目标拓扑区域内几种相关联的 Pod 要“在一起或不在一起”。与节点亲和相同,Pod 亲和与互斥的条件设置也是 requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution

  • RequiredDuringSchedulingIgnoredDuringExecution:表示 Pod 必须与指定的一组 Pod 具有亲和关系才能被调度。如果无法找到符合要求的节点,则 Pod 调度失败。
  • PreferredDuringSchedulingIgnoredDuringExecution:表示尽量将 Pod 调度到与指定的一组 Pod 具有亲和关系的节点上。如果无法找到符合要求的节点,则 Pod 仍会被调度到其他节点上。

3. 实验

我们先将节点标签去掉:

[root@master mtuser]# kubectl label node node1 app-
node/node1 labeled
[root@master mtuser]# kubectl get node -l app=my-first-deploy
No resources found.

然后定义一个简单 deployment,命名为 my-first-deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-first-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-first-deploy
  template:
    metadata:
      labels:
        app: my-first-deploy
    spec:
      containers:
      - name: my-first-container
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoSchedule
        key: node-role.kubernetes.io/master

创建其应用:

[root@master mtuser]# kubectl create -f my-first-deploy.yaml
deployment.apps/my-first-deploy created
[root@master mtuser]# kubectl get pod -owide
NAME                               READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
my-first-deploy-84ffb59778-7pkjd   1/1     Running   0          6s    10.244.0.16   master   <none>           <none>

同时我们可以看到 Pod 默认调度到了 master 节点上。接下来我们创建第二个 deployment,包含有 Pod 的亲和性相关定义,命名为 my-second-deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-second-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-second-deploy
  template:
    metadata:
      labels:
        app: my-second-deploy
    spec:
      containers:
      - name: my-second-container
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - my-first-deploy
            topologyKey: kubernetes.io/hostname

上面定义了 Pod 亲和性,m

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

云计算面试题全解析 文章被收录于专栏

本专刊适合于立志转行云计算的小白,有一定的编程、操作系统、计算机网络、数据结构、算法基础。 本专刊同时也适合于面向云计算(Docker + Kubernetes)求职的从业者。 本专刊囊括了云计算、VMWare、Docker、Kubernetes、Containerd等一系列知识点的讲解,并且最后总

全部评论

相关推荐

2024-11-18 10:36
内蒙古民族大学 Java
白菜小丑呜呜:Radis写错了兄弟
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务