k8s调度管理之调度策略

网友投稿 302 2022-09-09

k8s调度管理之调度策略

我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的节点,应该怎么办呢?下面介绍k8s中的调度策略,主要有以下调度策略:

节点选择器调度 节点亲和调度 pod亲和调度 pod反亲和调度 污点-容忍度调度

节点选择器

nodeName

通过指定节点名称,把pod调度到指定节点,下面的pod将会被调度到k8s-node01节点。

apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: default labels: app: nginx spec: nodeName: k8s-node01 containers: - name: nginx image: nginx:1.21.5 imagePullPolicy: IfNotPresent

pod创建成功后,通过kubectl get pod -o wide发现被调度到了k8s-node01节点。

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-nodename 1/1 Running 0 5s 10.81.85.226 k8s-node01

nodeSelector

首先给k8s-node02节点添加一个标签type=nginx

#给节点添加标签 kubectl label node k8s-node02 type=nginx #查看节点-显示标签 kubectl get node --show-labels

创建pod并将该pod调度到标签为type=nginx的节点上

apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: default labels: app: nginx spec: nodeSelector: type: nginx containers: - name: nginx image: nginx:1.21.5 imagePullPolicy: IfNotPresent

pod创建成功后,通过kubectl get pod -o wide查看pod状态,如下所示pod被成功调度到k8s-node02节点。

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-nodename 1/1 Running 0 9s 10.81.58.214 k8s-node02

节点亲和性

节点亲和性属性定义可以通过kubectl explain pods.spec.affinity.nodeAffinity查看,如下所示:

nodeAffinity # POD 对 node 节点的亲和性 preferredDuringSchedulingIgnoredDuringExecution <[]Object> # 软亲和性要求,尽量满足亲和性 preference # 亲和的节点对象 matchExpressions <[]Object> # 查找表达式 key # 标签 operator # 操作:比较 values <[]string> # 值 matchFields <[]Object> # 查找字段 key # 标签 operator # 操作:比较 values <[]string> # 值 weight # 权重 1 - 100 requiredDuringSchedulingIgnoredDuringExecution # 硬亲和性要求,不满足则 Pending nodeSelectorTerms <[]Object> # 选择器对象列表 matchExpressions <[]Object> # 选择器对象列表 key # 标签 operator # 操作:比较 values <[]string> # 值 matchFields <[]Object> # 查找字段 key # 标签 operator # 操作:比较 values <[]string> # 值

preferredDuringSchedulingIgnoredDuringExecution表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,也叫软亲和性

requiredDuringSchedulingIgnoredDuringExecution表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,也叫硬亲和性

软亲和性

apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity1 namespace: default labels: app: nginx spec: containers: - name: nginx image: nginx:1.21.5 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: # 软亲和性要求,不满足也可以 - preference: matchExpressions: - key: type: operator: In values: - tomcat weight: 50

上面的pod在调度时,尽管找不到标签为type=tomcat的节点,任然可以调度成功,这是软亲和性的特点。

硬亲和性

apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity2 namespace: default labels: app: nginx spec: containers: - name: nginx image: nginx:1.21.5 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性要求,不满足就Pending nodeSelectorTerms: - matchExpressions: - key: type operator: In values: - tomcat

pod创建成功后,我们查看pod状态如下:

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-nodeaffinity2 0/1 Pending 0 6s

上面的pod在调度时,因为找不到标签为type=tomcat的节点,所以调度不成功,一直显示Pending状态,这是硬亲和性的特点。

pod亲和性

pod亲和性属性定义可以通过kubectl explain pods.spec.affinity.podAffinity查看,如下所示:

podAffinity # POD 对其他 POD 的亲和性 preferredDuringSchedulingIgnoredDuringExecution <[]Object> # 软性亲和性,尽量满足亲和性 podAffinityTerm # 亲和的 POD 对象 labelSelector # 标签选择器对象列表 matchExpressions <[]Object> # 标签选择器对象,选 POD 标签 key # 标签 operator # 操作:比较 values <[]string> # 值 matchLabels # 集合标签选择器 namespaces <[]string> # 名称空间的列表 topologyKey # 亲和判断条件 weight # 权重 1 - 100 requiredDuringSchedulingIgnoredDuringExecution <[]Object> # 硬性亲和性,不满足则 Pending labelSelector # 标签选择器对象列表 matchExpressions <[]Object> # 标签选择器对象,选 POD 标签 key # 标签 operator # 操作:比较 values <[]string> # 值 matchLabels # 集合标签选择器 namespaces <[]string> # 名称空间的列表 topologyKey # 亲和判断条件

pod亲和性跟节点亲和性一样,也有软亲和性和硬亲和性,它的特点跟节点亲和性里的软亲和性和硬亲和性一样。下面用硬亲和性举个例子,软亲和性大家自己动手写写。

apiVersion: v1 kind: Pod metadata: name: pod1 namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: nginx:1.21.5 imagePullPolicy: IfNotPresent --- apiVersion: v1 kind: Pod metadata: name: pod2 namespace: default labels: app: db spec: containers: - name: nginx image: nginx:1.21.5 imagePullPolicy: IfNotPresent affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性要求,不满足的 Pending - labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname # 亲和性的依据为同一个主机名则亲和

上面有两个pod,第一个pod设置了标签app=myapp,第二个pod通过硬亲和性去匹配标签为app=myapp的pod,所以两个pod会被调度到同一个节点。查看pod状态如下(可以删除后重新创建,多运行几次,观察两个pod总是调度相同的节点上):

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod1 1/1 Running 0 9s 10.81.85.230 k8s-node01 pod2 1/1 Running 0 9s 10.81.85.231 k8s-node01

pod反亲和性

节点亲和性属性定义可以通过kubectl explain pods.spec.affinity.podAntiAffinity查看,如下所示:

podAntiAffinity # POD 对其他 POD 的反亲和性 preferredDuringSchedulingIgnoredDuringExecution <[]Object> # 软性反亲和性,尽量满足亲和性 podAffinityTerm # 反亲和的 POD 对象 labelSelector # 标签选择器对象列表 matchExpressions <[]Object> # 标签选择器对象,选 POD 标签 key # 标签 operator # 操作:比较 values <[]string> # 值 matchLabels # 集合标签选择器 namespaces <[]string> # 名称空间的列表 topologyKey # 亲和判断条件 weight # 权重 1 - 100 requiredDuringSchedulingIgnoredDuringExecution <[]Object> # 硬性反亲和性,不满足则 Pending labelSelector # 标签选择器对象列表 matchExpressions <[]Object> # 标签选择器对象,选 POD 标签 key # 标签 operator # 操作:比较 values <[]string> # 值 matchLabels # 集合标签选择器 namespaces <[]string> # 名称空间的列表 topologyKey # 亲和判断条件

反亲和性跟亲和性刚好相反,看下下面的例子,第一个pod定义了标签app=myapp,第二个pod通过反亲和性规则app=myapp,因此第二个pod不会调度到第一个pod相同的节点上。

apiVersion: v1 kind: Pod metadata: name: pod3 namespace: default labels: app: myapp spec: containers: - name: myapp image: nginx:1.21.5 --- apiVersion: v1 kind: Pod metadata: name: pod4 namespace: default labels: app: db spec: containers: - name: busybox image: nginx:1.21.5 imagePullPolicy: IfNotPresent affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性要求,不满足的 Pending - labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname # 反亲和性的依据为同一个主机名

查看两个pod的状态如下所示,分别被调度到了两个不同的节点

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod3 1/1 Running 0 5s 10.81.85.232 k8s-node01 pod4 1/1 Running 0 5s 10.81.58.215 k8s-node02

pod亲和性就是pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率; pod反亲和性就是pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。

污点-容忍度

node污点

污点只用在node上的键值属性nodes.spec.taints,它的作用是拒绝不能容忍这些污点的pod运行的,因此需要在pod上定义容忍度pods.spec.tolerations,它也是键值数据,是一个列表,表示pod可以容忍的污点列表。一个pod能不能运行在一个节点上,就是pods.spec.tolerations列表中是否包括了nodes.spec.taints中的数据。

node污点的属性格式详见kubectl explain node.spec.taints,如下所示:

taints <[]Object> # 污点对象列表 effect # 当 POD 不能容忍这个污点的时候,要采取的行为,也就是排斥不容忍污点的 POD NoSchedule # 影响调度过程,但是已经调度完成 POD 无影响 PreferNoSchedule # 影响调度过程,尝试驱逐调度已经完成的但不容忍新污点的 POD NoExecute # 新增的污点,影响新的调度过程,且强力驱逐调度已经完成的但不容忍新污点的 POD key # 键 timeAdded # value # 值

#给节点1打上污点,键为 node-type 值为 production,污点动作NoSchedule kubectl taint node k8s-node01 node-type=production:NoSchedule #删除污点 kubectl taint node k8s-node01 node-type-

节点k8s-node01被打上污点后,创建一个pod不设置容忍度,看它的调度情况是怎么样的。

apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 4 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: nginx:1.21.5 ports: - name: http containerPort: 80

pod创建成功后,如下所示,发现pod都被调度到k8s-node02节点上,符合预期,因为k8s-node01节点设置了污点,如果pod不添加容忍度是不会被调度到该节点的。

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy-5c75f74dc5-2z7hg 1/1 Running 0 7s 10.81.58.216 k8s-node02 myapp-deploy-5c75f74dc5-4sww5 1/1 Running 0 6s 10.81.58.217 k8s-node02 myapp-deploy-5c75f74dc5-fsdwh 1/1 Running 0 6s 10.81.58.219 k8s-node02 myapp-deploy-5c75f74dc5-w9w82 1/1 Running 0 6s 10.81.58.218 k8s-node02

此时给k8s-node02节点也打上污点,如下所示:

kubectl taint node k8s-node02 node-type=dev:NoExecute

通过kubectl get pods -o wide命令查看pod状态如下所示,发现k8s-node02节点新增的污点驱逐了不能容忍污点的pod ,所以所有pod都被挂起。

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy-5c75f74dc5-4dfzl 0/1 Pending 0 20s myapp-deploy-5c75f74dc5-654bx 0/1 Pending 0 20s myapp-deploy-5c75f74dc5-b5bl4 0/1 Pending 0 20s myapp-deploy-5c75f74dc5-wnz2r 0/1 Pending 0 20s

pod容忍度

pod容忍度的属性格式详见kubectl explain node.spec.tolerations,如下所示:

tolerations <[]Object> # 容忍度对象 effect # 能否容忍 node 上的污点驱逐策略,为空表示容忍任何驱逐策略 NoSchedule # 能容忍 node 污点的 NoSchedule PreferNoSchedule # 能容忍 node 污点的 PreferNoSchedule NoExecute # 能容忍 node 污点的 NoExecute key # 污点的键 operator # Exists 污点存在不管什么值,Equal 污点的值必须等值 tolerationSeconds # 容忍时间,即如果被驱逐,可以等多久再走,默认 0 秒,NoExecute 使用 value # 污点的值

上面分别给k8s-node01节点和k8s-node02节点都设置了污点,下面创建pod并添加容忍度,值为dev污点动作为NoExecute。

apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 4 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: nginx:1.21.5 ports: - name: http containerPort: 80 tolerations: - key: node-type operator: Equal value: dev effect: NoExecute

运行上面的pod,可以发现pod成功调度到了k8s-node02节点,因为pod设置了node-type=dev:NoExecute的容忍度。

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy-667785b946-4kxml 1/1 Running 0 6s 10.81.58.222 k8s-node02 myapp-deploy-667785b946-9dqgn 1/1 Running 0 6s 10.81.58.220 k8s-node02 myapp-deploy-667785b946-cp7db 1/1 Running 0 6s 10.81.58.221 k8s-node02 myapp-deploy-667785b946-xf5b5 1/1 Running 0 6s 10.81.58.223 k8s-node02

字段选择器

上面介绍亲和性时,示例中的匹配规则都是用的表达式匹配,匹配规则有两种:表达式匹配-matchExpressions和字段匹配-matchFields。

表达式匹配通过节点、pod的标签进行匹配,字段匹配根据字段选择器进行匹配,在k8s中不同的资源类型支持不同的字段选择器。 所有资源类型都支持metadata.name 和metadata.namespace字段。下面是一些使用字段选择器查询的例子:

metadata.name=my-service metadata.namespace!=default status.phase=Pending

使用不被支持的字段选择器会产生错误,例如:

kubectl get ingress --field-selector foo.bar=baz

下面这个命令将筛选出status.phase字段值为Running的所有pod

kubectl get pods --field-selector status.phase=Running

链式选择器

kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

匹配亲和性

下面创建pod,通过字段选择器进行匹配,匹配条件为metadata.name=k8s-node02,该pod将会被调度到k8s-node02节点(前提是不考虑污点和容忍度)。

apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity2 namespace: default labels: app: nginx spec: containers: - name: nginx image: nginx:1.21.5 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性要求,不满足就Pending nodeSelectorTerms: - matchFields: - key: metadata.name operator: In values: - k8s-node02

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Kubernetes----安装部署NFS服务器
下一篇:中国足协:全力解决叙利亚等4队参赛签证问题!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~