diff --git a/kubernetes-MD/kubernetes调度粘性.md b/kubernetes-MD/kubernetes调度粘性.md index b3c781e..8c66f5c 100644 --- a/kubernetes-MD/kubernetes调度粘性.md +++ b/kubernetes-MD/kubernetes调度粘性.md @@ -1,288 +1,287 @@ -

kubernetes调度粘性

- -著作:行癫 <盗版必究> - ------- - -## 一:调度粘性 - -#### 1.三种调度粘性 - -​ NodeSelector(定向调度) - -​ NodeAffinity(Node亲和性) - -​ PodAffinity(Pod亲和性) - -​ 通常情况下,使用的都是k8s默认的调度调度方式,但是在有些情况下,我们需要将pod运行在具有特点的标签的node上才能都运行,这个时候,pod的调度策略就不能使用k8s默认的调度策略了,这个时候,就需要指定调度策略,告诉k8s需要将pod调度到那些node上。 - -#### 2.nodeSelector - -​ 常规情况下,会直接使用nodeSelector这种调度策略。labels(标签) 是k8s里面用来编标记资源的一种常用的方式,我们可以给node标记特殊的标签,然后nodeSelector会将pod调度到带有指定labels的node上的;提供简单的pod部署限制,pod选择一个或多个node的label部署 - -给node添加label: - -```shell -kubectl label nodes = -``` - -pod添加nodeSelector机制: - -```shell -apiVersion: v1 -kind: Pod -metadata: - name: nginx - labels: - env: test -spec: - containers: - - name: nginx - image: nginx - imagePullPolicy: IfNotPresent - nodeSelector: - disktype: ssd -``` - -部署pod: - -```shell -[root@master ~]# kubectl create -f test.yaml -pod/nginx created -``` - -查看结果: - -```shell -[root@master ~]# kubectl get pod -A -o wide -NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES -default nginx 0/1 ContainerCreating 0 37s node-1 -``` - -​ 从上面的执行结果可以看出,pod 通过默认的 default-scheduler 调度器到了node-1节点上。不过,这种调度方式属于强制性的。如果node02上的资源不足,那么pod的状态将会一直是pending状态。 - -#### 3.亲和性和反亲和性调度 - -​ k8s的默认调度流程实际上是经过了两个阶段predicates(判断),priorities(优先选择) 。使用默认的调度流程的话,k8s会将pod调度到资源充裕的节点上,使用nodeselector的调度方法,又会将pod调度具有指定标签的节点上。然后在实际生产环境中,我们需要将pod调度到具有些label的一组node才能满足实际需求,这个时候就需要nodeAffinity、podAffinity以及 podAntiAffinity(pod 反亲和性) - -亲和性可以分为具体可以细分为硬和软两种亲和性: - -​ 软亲和性:如果调度的时候,没有满足要求,也可以继续调度,即能满足最好,不能也无所谓 - -​ 硬亲和性:是指调度的时候必须满足特定的要求,如果不满足,那么pod将不会被调度到当前node - -​ requiredDuringSchedulingIgnoredDuringExecution #硬性强制 - -​ preferredDuringSchedulingIgnoredDuringExecution #软性配置 - -#### 4.nodeAffinity 节点亲和性 - -​ 节点亲和性主要是用来控制 pod 能部署在哪些节点上,以及不能部署在哪些节点上的;它可以进行一些简单的逻辑组合了,不只是简单的相等匹配(preferredDuringSchedulingIgnoredDuringExecution) - -​ 强调优先满足制定规则,调度器会尝试调度pod到Node上,但并不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义执行的先后顺序 - -nodeAffinity控制 pod 的调度: - -```shell -apiVersion: v1 -kind: Pod -metadata: - name: with-node-affinity -spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: beta.kubernetes.io/arch - operator: In - values: - - amd64 - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - preference: - matchExpressions: - - key: disk-type - operator: In - values: - - ssd - containers: - - name: with-node-affinity - image: nginx -``` - -设置label: - -```shell -[root@master ~]# kubectl label nodes node-2 disk-type=ssd -node/node-2 labeled -``` - -创建pod并查看运行结果: - -```shell -[root@master yaml]# kubectl get pod -o wide -NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES -with-node-affinity 0/1 ContainerCreating 0 4m node-2 -``` - -NodeAffinity规则设置的注意事项如下: - -​ 如果同时定义了nodeSelector和nodeAffinity,name必须两个条件都得到满足,pod才能最终运行在指定的node上 - -​ 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可 - -​ 如果在nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有matchExpressions才能运行该pod - -​ matchExpressions : 匹配表达式,这个标签可以指定一段,例如pod中定义的key为zone,operator为In(包含那些),values为 foo和bar;就是在node节点中包含foo和bar的标签中调度 - -kubernetes提供的操作符有下面的几种: - -​ In:label 的值在某个标签中 - -​ NotIn:label 的值不在某个标签中 - -​ Gt:label 的值大于某个值 - -​ Lt:label 的值小于某个值 - -​ Exists:某个 label 存在 - -​ DoesNotExist:某个 label 不存在 - -#### 5.podAffinity pod亲和性 - -​ Pod的亲和性主要用来解决pod可以和哪些pod部署在同一个集群里面,即拓扑域(由node组成的集群)里面;而pod的反亲和性是为了解决pod不能和哪些pod部署在一起的问题,二者都是为了解决pod之间部署问题。需要注意的是,Pod 间亲和与反亲和需要大量的处理,这可能会显著减慢大规模集群中的调度,不建议在具有几百个节点的集群中使用,而且Pod 反亲和需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配topologyKey。如果某些或所有节点缺少指定的topologyKey标签,可能会导致意外行为 - -​ Pod亲和性场景,我们的k8s集群的节点分布在不同的区域或者不同的机房,当服务A和服务B要求部署在同一个区域或者同一机房的时候,我们就需要亲和性调度了 - -​ labelSelector : 选择跟那组Pod亲和 - -​ namespaces : 选择哪个命名空间 - -​ topologyKey : 指定节点上的哪个键 - -​ pod亲和性调度需要各个相关的pod对象运行于"同一位置", 而反亲和性调度则要求他们不能运行于"同一位置" - -​ 这里指定“同一位置” 是通过 topologyKey 来定义的,topologyKey 对应的值是 node 上的一个标签名称,比如各别节点zone=A标签,各别节点有zone=B标签,pod affinity topologyKey定义为zone,那么调度pod的时候就会围绕着A拓扑,B拓扑来调度,而相同拓扑下的node就为“同一位置”;如果基于各个节点kubernetes.io/hostname标签作为评判标准,那么很明显“同一位置”意味着同一节点,不同节点既为不同位置 - -pod亲和性: - -```shell -apiVersion: v1 -kind: Pod -metadata: - name: pod-first - labels: - app: myapp - tier: frontend -spec: - containers: - - name: myapp - image: daocloud.io/library/nginx:latest ---- -apiVersion: v1 -kind: Pod -metadata: - name: pod-second - labels: - app: db - tier: db -spec: - containers: - - name: busybox - image: daocloud.io/library/busybox - imagePullPolicy: IfNotPresent - command: ["sh","-c","sleep 3600"] - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - {key: app, operator: In, values: ["myapp"]} - topologyKey: kubernetes.io/hostname -``` - -查看结果: - -```shell -[root@master yaml]# kubectl get pod -o wide -NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES -pod-first 1/1 Running 0 10m 10.244.1.6 node-1 -pod-second 1/1 Running 0 10m 10.244.1.7 node-1 -``` - -pod反亲和性: - -​ Pod反亲和性场景,当应用服务A和数据库服务B要求尽量不要在同一台节点上的时候 - -```shell -apiVersion: v1 -kind: Pod -metadata: - name: pod-first-1 - labels: - app: myapp - tier: frontend -spec: - containers: - - name: myapp - image: daocloud.io/library/nginx:latest ---- -apiVersion: v1 -kind: Pod -metadata: - name: pod-second-2 - labels: - app: backend - tier: db -spec: - containers: - - name: busybox - image: daocloud.io/library/busybox:latest - imagePullPolicy: IfNotPresent - command: ["sh","-c","sleep 3600"] - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - {key: app, operator: In, values: ["myapp"]} - topologyKey: kubernetes.io/hostname -``` - -查看结果: - -```shell -[root@master yaml]# kubectl get pod -o wide -NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES -pod-first-1 1/1 Running 0 7m28s 10.244.1.8 node-1 -pod-second-2 1/1 Running 0 7m28s 10.244.2.6 node-2 -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - +

kubernetes调度粘性

+ + +------ + +## 一:调度粘性 + +#### 1.三种调度粘性 + +​ NodeSelector(定向调度) + +​ NodeAffinity(Node亲和性) + +​ PodAffinity(Pod亲和性) + +​ 通常情况下,使用的都是k8s默认的调度调度方式,但是在有些情况下,我们需要将pod运行在具有特点的标签的node上才能都运行,这个时候,pod的调度策略就不能使用k8s默认的调度策略了,这个时候,就需要指定调度策略,告诉k8s需要将pod调度到那些node上。 + +#### 2.nodeSelector + +​ 常规情况下,会直接使用nodeSelector这种调度策略。labels(标签) 是k8s里面用来编标记资源的一种常用的方式,我们可以给node标记特殊的标签,然后nodeSelector会将pod调度到带有指定labels的node上的;提供简单的pod部署限制,pod选择一个或多个node的label部署 + +给node添加label: + +```shell +kubectl label nodes = +``` + +pod添加nodeSelector机制: + +```shell +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + nodeSelector: + disktype: ssd +``` + +部署pod: + +```shell +[root@master ~]# kubectl create -f test.yaml +pod/nginx created +``` + +查看结果: + +```shell +[root@master ~]# kubectl get pod -A -o wide +NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +default nginx 0/1 ContainerCreating 0 37s node-1 +``` + +​ 从上面的执行结果可以看出,pod 通过默认的 default-scheduler 调度器到了node-1节点上。不过,这种调度方式属于强制性的。如果node02上的资源不足,那么pod的状态将会一直是pending状态。 + +#### 3.亲和性和反亲和性调度 + +​ k8s的默认调度流程实际上是经过了两个阶段predicates(判断),priorities(优先选择) 。使用默认的调度流程的话,k8s会将pod调度到资源充裕的节点上,使用nodeselector的调度方法,又会将pod调度具有指定标签的节点上。然后在实际生产环境中,我们需要将pod调度到具有些label的一组node才能满足实际需求,这个时候就需要nodeAffinity、podAffinity以及 podAntiAffinity(pod 反亲和性) + +亲和性可以分为具体可以细分为硬和软两种亲和性: + +​ 软亲和性:如果调度的时候,没有满足要求,也可以继续调度,即能满足最好,不能也无所谓 + +​ 硬亲和性:是指调度的时候必须满足特定的要求,如果不满足,那么pod将不会被调度到当前node + +​ requiredDuringSchedulingIgnoredDuringExecution #硬性强制 + +​ preferredDuringSchedulingIgnoredDuringExecution #软性配置 + +#### 4.nodeAffinity 节点亲和性 + +​ 节点亲和性主要是用来控制 pod 能部署在哪些节点上,以及不能部署在哪些节点上的;它可以进行一些简单的逻辑组合了,不只是简单的相等匹配(preferredDuringSchedulingIgnoredDuringExecution) + +​ 强调优先满足制定规则,调度器会尝试调度pod到Node上,但并不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义执行的先后顺序 + +nodeAffinity控制 pod 的调度: + +```shell +apiVersion: v1 +kind: Pod +metadata: + name: with-node-affinity +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - amd64 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: disk-type + operator: In + values: + - ssd + containers: + - name: with-node-affinity + image: nginx +``` + +设置label: + +```shell +[root@master ~]# kubectl label nodes node-2 disk-type=ssd +node/node-2 labeled +``` + +创建pod并查看运行结果: + +```shell +[root@master yaml]# kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +with-node-affinity 0/1 ContainerCreating 0 4m node-2 +``` + +NodeAffinity规则设置的注意事项如下: + +​ 如果同时定义了nodeSelector和nodeAffinity,name必须两个条件都得到满足,pod才能最终运行在指定的node上 + +​ 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可 + +​ 如果在nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有matchExpressions才能运行该pod + +​ matchExpressions : 匹配表达式,这个标签可以指定一段,例如pod中定义的key为zone,operator为In(包含那些),values为 foo和bar;就是在node节点中包含foo和bar的标签中调度 + +kubernetes提供的操作符有下面的几种: + +​ In:label 的值在某个标签中 + +​ NotIn:label 的值不在某个标签中 + +​ Gt:label 的值大于某个值 + +​ Lt:label 的值小于某个值 + +​ Exists:某个 label 存在 + +​ DoesNotExist:某个 label 不存在 + +#### 5.podAffinity pod亲和性 + +​ Pod的亲和性主要用来解决pod可以和哪些pod部署在同一个集群里面,即拓扑域(由node组成的集群)里面;而pod的反亲和性是为了解决pod不能和哪些pod部署在一起的问题,二者都是为了解决pod之间部署问题。需要注意的是,Pod 间亲和与反亲和需要大量的处理,这可能会显著减慢大规模集群中的调度,不建议在具有几百个节点的集群中使用,而且Pod 反亲和需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配topologyKey。如果某些或所有节点缺少指定的topologyKey标签,可能会导致意外行为 + +​ Pod亲和性场景,我们的k8s集群的节点分布在不同的区域或者不同的机房,当服务A和服务B要求部署在同一个区域或者同一机房的时候,我们就需要亲和性调度了 + +​ labelSelector : 选择跟那组Pod亲和 + +​ namespaces : 选择哪个命名空间 + +​ topologyKey : 指定节点上的哪个键 + +​ pod亲和性调度需要各个相关的pod对象运行于"同一位置", 而反亲和性调度则要求他们不能运行于"同一位置" + +​ 这里指定“同一位置” 是通过 topologyKey 来定义的,topologyKey 对应的值是 node 上的一个标签名称,比如各别节点zone=A标签,各别节点有zone=B标签,pod affinity topologyKey定义为zone,那么调度pod的时候就会围绕着A拓扑,B拓扑来调度,而相同拓扑下的node就为“同一位置”;如果基于各个节点kubernetes.io/hostname标签作为评判标准,那么很明显“同一位置”意味着同一节点,不同节点既为不同位置 + +pod亲和性: + +```shell +apiVersion: v1 +kind: Pod +metadata: + name: pod-first + labels: + app: myapp + tier: frontend +spec: + containers: + - name: myapp + image: daocloud.io/library/nginx:latest +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod-second + labels: + app: db + tier: db +spec: + containers: + - name: busybox + image: daocloud.io/library/busybox + imagePullPolicy: IfNotPresent + command: ["sh","-c","sleep 3600"] + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - {key: app, operator: In, values: ["myapp"]} + topologyKey: kubernetes.io/hostname +``` + +查看结果: + +```shell +[root@master yaml]# kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +pod-first 1/1 Running 0 10m 10.244.1.6 node-1 +pod-second 1/1 Running 0 10m 10.244.1.7 node-1 +``` + +pod反亲和性: + +​ Pod反亲和性场景,当应用服务A和数据库服务B要求尽量不要在同一台节点上的时候 + +```shell +apiVersion: v1 +kind: Pod +metadata: + name: pod-first-1 + labels: + app: myapp + tier: frontend +spec: + containers: + - name: myapp + image: daocloud.io/library/nginx:latest +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod-second-2 + labels: + app: backend + tier: db +spec: + containers: + - name: busybox + image: daocloud.io/library/busybox:latest + imagePullPolicy: IfNotPresent + command: ["sh","-c","sleep 3600"] + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - {key: app, operator: In, values: ["myapp"]} + topologyKey: kubernetes.io/hostname +``` + +查看结果: + +```shell +[root@master yaml]# kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +pod-first-1 1/1 Running 0 7m28s 10.244.1.8 node-1 +pod-second-2 1/1 Running 0 7m28s 10.244.2.6 node-2 +``` + + + + + + + + + + + + + + + + + + + + + + + + + + +