当前位置: 代码迷 >> 综合 >> OpenShift 4 - Pod的亲和性/反亲和性
  详细解决方案

OpenShift 4 - Pod的亲和性/反亲和性

热度:11   发布时间:2024-02-24 13:55:53.0

文章目录

  • Pod的亲和性/反亲和性
    • 方法1:直接指定Pod运行Node
    • 方法2:通过设置Pod的nodeselector实现
    • 方法3:通过设置Pod的Affinity策略实现
  • 参考

Pod的亲和性/反亲和性

亲和性/反亲和性可以用来让用户指定一个pod是运行在哪个Node上(或不能运行在哪个节点上)- 即,或者一个Pod和哪个Pod一起运行(或不一起运行)。在实现过程中可以通过多种方法实现亲和性/反亲和性,有些方法可以基于Node实现Pod亲和性,有些方法可基于Pod实现Pod亲和性。

方法1:直接指定Pod运行Node

这种方法是最简单的方法,可直接在Pod对象中指定其运行的Node节点名称。

  1. 执行命令查看worker节点,以下OpenShift集群中有2个worker节点。
$ oc get node -l node-role.kubernetes.io/worker
NAME                                              STATUS   ROLES    AGE     VERSION
ip-10-0-141-34.ap-southeast-1.compute.internal    Ready    worker   5h24m   v1.18.3+47c0e71
ip-10-0-171-148.ap-southeast-1.compute.internal   Ready    worker   5h24m   v1.18.3+47c0e71
  1. 创建内容如下的nginx-node.yaml文件,其中直接使用了“nodeName”指定将Pod运行在“ip-10-0-141-34.ap-southeast-1.compute.internal”节点。
apiVersion: v1
kind: Pod
metadata:name: nginx-node
spec:containers:3. name: nginximage: nginxnodeName: ip-10-0-141-34.ap-southeast-1.compute.internal
  1. 执行命令创建pod,然后查看nginx-node是运行在指定的Node上。
$ oc apply -f nginx-node.yaml
$ oc get pod nginx-node -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE                                              NOMINATED NODE   READINESS GATES
nginx-node           1/1     Running   0          31s   10.128.2.49   ip-10-0-141-34.ap-southeast-1.compute.internal    <none>           <none>

方法2:通过设置Pod的nodeselector实现

此方法是通过Node的标签和Pod使用的Selector来选择出对应的运行节点。

  1. 执行命令,对集群中的一个节点打标签“disktype=hdd”。
$ HDD_NODE=ip-10-0-141-34.ap-southeast-1.compute.internal
$ oc label nodes $HDD_NODE disktype=hdd
node/ip-10-0-141-34.ap-southeast-1.compute.internal labeled
$ oc get nodes --show-labels | grep hdd
ip-10-0-141-34.ap-southeast-1.compute.internal   Ready    worker   3h23m   v1.18.3+47c0e71   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.4xlarge,beta.kubernetes.io/os=linux,disktype=hdd,failure-domain.beta.kubernetes.io/region=ap-southeast-1,failure-domain.beta.kubernetes.io/zone=ap-southeast-1b,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-10-0-141-34,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,node.kubernetes.io/instance-type=m5.4xlarge,node.openshift.io/os_id=rhcos,topology.kubernetes.io/region=ap-southeast-1,topology.kubernetes.io/zone=ap-southeast-1b
  1. 创建内容如下的nginx-nodeselector.yaml文件。其中使用了‘nodeSelector’指定将pod运行在满足“disktype: hdd”的节点上。
apiVersion: v1
kind: Pod
metadata:name: nginx-nodeselector
spec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentnodeSelector:disktype: hdd
  1. 运行命令创建poc,然后确认nginx-nodeselector运行在“ip-10-0-141-34.ap-southeast-1.compute.internal”节点上了。
$ oc apply -f nginx-nodeselector.yaml
$ oc get pods nginx-nodeselector --output=wide
NAME                 READY   STATUS    RESTARTS   AGE     IP           NODE                                              NOMINATED NODE   READINESS GATES
nginx-nodeselector   1/1     Running   0          3m29s   10.128.2.49   ip-10-0-141-34.ap-southeast-1.compute.internal   <none>           <none>

方法3:通过设置Pod的Affinity策略实现

此方法类似方法2,不过它可以实现比方法2更复杂的选择节点的条件。另外此种方法既可以实现基于Node实现Pod亲和性,还可实现基于Pod实现Pod亲和性。
在Pod对象中可以设置affinity策略(affinity进一步包括nodeAffinity或podAffinity/podAntiAffinity属性)来约定Pod在哪个Node运行。在描述nodeAffinity或podAffinity/podAntiAffinity的时候可以使用requiredDuringSchedulingIgnoredDuringExecution(硬条件,即必须满足该条件亲和或反亲和策略才有效)和preferredDuringSchedulingIgnoredDuringExecution(软条件,即如能满足该条件则该亲和或反亲和策略生效;如果条件不能满足将服从Kubernetes调度运行Pod)。

  1. 执行命令,对集群中的一个节点打标签“disktype=ssd”。
$ SSD_NODE=ip-10-0-171-148.ap-southeast-1.compute.internal
$ oc label nodes $SSD_NODE disktype=ssd
node/ip-10-0-171-148.ap-southeast-1.compute.internal labeled
$ oc get nodes --show-labels | grep ssd
ip-10-0-171-148.ap-southeast-1.compute.internal   Ready    worker   3h23m   v1.18.3+47c0e71   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.4xlarge,beta.kubernetes.io/os=linux,disktype=ssd,failure-domain.beta.kubernetes.io/region=ap-southeast-1,failure-domain.beta.kubernetes.io/zone=ap-southeast-1b,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-10-0-171-148,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,node.kubernetes.io/instance-type=m5.4xlarge,node.openshift.io/os_id=rhcos,topology.kubernetes.io/region=ap-southeast-1,topology.kubernetes.io/zone=ap-southeast-1b
  1. 创建如下的nginx-node-affinity.yaml文件。其中Pod使用了“affinity”配置和相关策略“preferredDuringSchedulingIgnoredDuringExecution”,然后在“preference”中利用标签选择运行节点。
apiVersion: v1
kind: Pod
metadata:name: nginx-node-affinity
spec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: disktypeoperator: Invalues:- ssd          containers:-- name: nginximage: nginximagePullPolicy: IfNotPresent
  1. 执行命令创建的pod,然后确认nginx-node-affinity运行在“SSD_NODE”类型的Node上。
$ oc apply -f nginx-node-affinity.yaml
$ oc get pods nginx-node-affinity --output=wide
NAME                  READY   STATUS    RESTARTS   AGE     IP           NODE                                              NOMINATED NODE   READINESS GATES
nginx-node-affinity   1/1     Running   0          3m29s   10.131.0.7   ip-10-0-171-148.ap-southeast-1.compute.internal   <none>           <none>
  1. 创建内容如下的nginx-pod-affinity.xml文件。其中我们希望将名为nginx-pod-affinity的pod和带有“team=nginx-team”标签的pod运行在相同的Node上。
apiVersion: v1
kind: Pod
metadata:name: nginx-pod-affinity
spec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: teamoperator: Invalues:- nginx-teamtopologyKey: kubernetes.io/hostnamecontainers:-- name: nginximage: nginximagePullPolicy: IfNotPresent
  1. 执行命令创建名为nginx-poc-affinity的pod。不过由于podAffnity的策略是requiredDuringSchedulingIgnoredDuringExecution硬条件,且此时还没有含有“team=nginx-team”标签的pod,因此一直是“Pending”状态。
$ oc apply -f nginx-pod-affinity.yaml
$ oc get pod nginx-pod-affinity -o wide
NAME                 READY   STATUS    RESTARTS   AGE     IP            NODE                                              NOMINATED NODE   READINESS GATES
nginx-pod-affinity   0/1     Pending   0          3m44s   <none>        <none>                                            <none>           <none>
  1. 执行命令对前面创建的nginx-node-affinity打标签“team=nginx-team”。
$ oc label pod nginx-node-affinity team=nginx-team
pod/nginx-pod-affinit labeled
$ oc get pod nginx-node-affinity -o wide --show-labels
NAME                   READY   STATUS    RESTARTS   AGE   IP            NODE                                             NOMINATED NODE   READINESS GATES   LABELS
nginx-node-affinity    1/1     Running   0          19h   10.128.2.49   ip-10-0-141-34.ap-southeast-1.compute.internal   <none>           <none>            team=nginx-team
  1. 然后在查看nginx-pod-affinity的状态,确认nginx-pod-affinity和nginx-node-affinity运行在相同的Node上了。
$ oc get pod nginx-pod-affinity -o wide
NAME                 READY   STATUS    RESTARTS   AGE    IP            NODE                                             NOMINATED NODE   READINESS GATES
nginx-pod-affinity   1/1     Running   0          7m4s   10.128.2.59   ip-10-0-141-34.ap-southeast-1.compute.internal   <none>           <none>
  1. 创建内容如下的nginx-pod-anti-affinity.yaml文件,它使用“podAntiAffinity”的策略,不会和含有“team=nginx-team”标签的pod一起运行的同一个Node。
apiVersion: v1
kind: Pod
metadata:name: nginx-pod-anti-affinity
spec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: teamoperator: Invalues:- "nginx-team"topologyKey: kubernetes.io/hostnamecontainers:-- name: nginximage: nginximagePullPolicy: IfNotPresent
  1. 确认nginx-pod-anti-affinity和nginx-node-affinity运行在不同的Node上了。
$ oc get pod nginx-pod-anti-affinity -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE                                              NOMINATED NODE   READINESS GATES
nginx-pod-anti-affinity   1/1     Running   0          50s   10.131.0.23   ip-10-0-171-148.ap-southeast-1.compute.internal   <none>           <none>

参考

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node
https://docs.openshift.com/container-platform/4.5/nodes/scheduling/nodes-scheduler-pod-affinity.html