文章目录
- Pod的亲和性/反亲和性
-
- 方法1:直接指定Pod运行Node
- 方法2:通过设置Pod的nodeselector实现
- 方法3:通过设置Pod的Affinity策略实现
- 参考
Pod的亲和性/反亲和性
亲和性/反亲和性可以用来让用户指定一个pod是运行在哪个Node上(或不能运行在哪个节点上)- 即,或者一个Pod和哪个Pod一起运行(或不一起运行)。在实现过程中可以通过多种方法实现亲和性/反亲和性,有些方法可以基于Node实现Pod亲和性,有些方法可基于Pod实现Pod亲和性。
方法1:直接指定Pod运行Node
这种方法是最简单的方法,可直接在Pod对象中指定其运行的Node节点名称。
- 执行命令查看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
- 创建内容如下的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
- 执行命令创建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来选择出对应的运行节点。
- 执行命令,对集群中的一个节点打标签“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
- 创建内容如下的nginx-nodeselector.yaml文件。其中使用了‘nodeSelector’指定将pod运行在满足“disktype: hdd”的节点上。
apiVersion: v1
kind: Pod
metadata:name: nginx-nodeselector
spec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentnodeSelector:disktype: hdd
- 运行命令创建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)。
- 执行命令,对集群中的一个节点打标签“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
- 创建如下的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
- 执行命令创建的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>
- 创建内容如下的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
- 执行命令创建名为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>
- 执行命令对前面创建的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
- 然后在查看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>
- 创建内容如下的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
- 确认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