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 亲和与互斥的条件设置也是 requiredDuringSchedulingIgnoredDuringExecution
和preferredDuringSchedulingIgnoredDuringExecution
。
- 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等一系列知识点的讲解,并且最后总