Docker与K8S中Pod的调度策略有哪些具体应用和不同场景下的选择?

2026-04-18 01:301阅读0评论SEO基础
  • 内容介绍
  • 相关推荐

本文共计1333个文字,预计阅读时间需要6分钟。

Docker与K8S中Pod的调度策略有哪些具体应用和不同场景下的选择?

上一篇,我们学习了各种工作负载的使用,工作负载会自动帮我们完成Pod的调度和部署。但有时我们需要自定义Pod的调度策略,这时该怎么办呢?今天我们就来探讨一下如何定义自定义的调度策略。

上一篇,我们学习了各种工作负载的使用,工作负载它会自动帮我们完成Pod的调度和部署,但有时我们需要自己定义Pod的调度策略,这个时候该怎么办呢?今天我们就来看一下如何定义Pod调度策略。

一、NodeSelector:节点定向调度

Kubernetes的Scheduler服务在调度Pod的时候会通过一系列复杂的算法自动计算出每一个Pod的最佳目标节点,但有的时候,我们需要将Pod指定的到一些Node上,比如我们有的Node安装了SSD,磁盘读写高,可以部署一些IO密集型应用,这个时候,我们就需要给这些Node打标签,然后在Pod中定义NodeSelector就可以实现。接下来我们来看一些如何实现:

1、我们通过kubectl label命令给集群中kubevm2打标签:disk=ssd,标示我们kubevm2的磁盘使用SSD。

[root@kubevm1 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubevm1 Ready master 33d v1.19.16 192.168.56.120 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 kubevm2 Ready <none> 33d v1.19.16 192.168.56.121 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 kubevm3 Ready <none> 33d v1.19.16 192.168.56.122 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 [root@kubevm1 ~]# kubectl label nodes kubevm2 disk=ssd

2、我们在之前deployment的例子中的Pod定义中增加nodeSelector设置:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 nodeSelector: disk: ssd

3、创建此Deployment,查看pod部署位置:我们发现三个副本都部署在kubevm2上。

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-758754644-d2qg5 1/1 Running 0 101s 10.244.1.26 kubevm2 <none> <none> nginx-deployment-758754644-tsf9f 1/1 Running 0 101s 10.244.1.27 kubevm2 <none> <none> nginx-deployment-758754644-vxdkm 1/1 Running 0 101s 10.244.1.25 kubevm2 <none> <none>

如果我们给多个Node都定义了相同的标签,则Scheduler会从这组Node中挑选一个可用的Node。我们可以看到通过给Node打标签的方式,我们可以描述集群中具有不同特点的Node,在部署应用时通过结合应用的需求设置NodeSelector进行指定Node范围的调度。这里要注意,如果我们指定了NodeSelector条件,但集群中不存在包含相应标签的Node,即使集群中还有其他可供使用的node,这个Pod也无法被成功调度,就那上面的例子来说,我们希望应用部署在SSD节点上,但如果集群中没有SSD的节点了,使用机械硬盘的节点也能部署,这样的话,使用NodeSelector就无法满足这一需求了。这个时候我们就需要使用节点亲和性调度了。

Docker与K8S中Pod的调度策略有哪些具体应用和不同场景下的选择?

二、NodeAffinity:节点亲和性调度

NodeAffinity是用于替换NodeSelector的全新调度策略,目前该策略有两种表达方式:

  • RequiredDuringSchedulingIgnoredDuringExecution:调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector,但其语法表达能力更强

  • PreferredDuringSchedulingIgnoredDuringExecution:调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。

我们可以看到RequiredDuringSchedulingIgnoredDuringExecution 的特性跟NodeSelector很像,而PreferredDuringSchedulingIgnoredDuringExecution更加灵活一些,我们接下来看一下二者的用法:

1、RequiredDuringSchedulingIgnoredDuringExecution使用

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disk operator: In values: - ssd

我们创建此Deployment,可以看到Pod豆部署在kubevm2上:

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-6ff7bf994d-9dhl2 1/1 Running 0 63s 10.244.1.28 kubevm2 <none> <none> nginx-deployment-6ff7bf994d-c8xzh 1/1 Running 0 63s 10.244.1.29 kubevm2 <none> <none> nginx-deployment-6ff7bf994d-xlpg8 1/1 Running 0 63s 10.244.1.30 kubevm2 <none> <none>

2、PreferredDuringSchedulingIgnoredDuringExecution的使用

我们将kubevm2、kubevm3打标签:disk=sata:

[root@kubevm1 workspace] kubectl label nodes kubevm2 disk=sata node/kubevm2 labeled [root@kubevm1 workspace] kubectl label nodes kubevm3 disk=sata node/kubevm3 labeled

修改deployment配置:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disk operator: In values: - ssd - key: disk operator: In values: - ssd

我们创建此Deployment可以看到,即使当前集群中没有ssd的node,Pod仍然可以部署:

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-cff9b7cf7-26hww 1/1 Running 0 81s 10.244.2.15 kubevm3 <none> <none> nginx-deployment-cff9b7cf7-k9x47 1/1 Running 0 81s 10.244.1.31 kubevm2 <none> <none> nginx-deployment-cff9b7cf7-xtrq4 1/1 Running 0 81s 10.244.1.32 kubevm2 <none> <none>

在上面的例子中,我们使用到了In操作符,NodeAffinity支持的操作符包括In、NotIn、Exists、DoesNotExist、Gt、Lt等。

OK,以上就是今天的内容了,后面我们继续学习Pod的其他调度策略。

本文共计1333个文字,预计阅读时间需要6分钟。

Docker与K8S中Pod的调度策略有哪些具体应用和不同场景下的选择?

上一篇,我们学习了各种工作负载的使用,工作负载会自动帮我们完成Pod的调度和部署。但有时我们需要自定义Pod的调度策略,这时该怎么办呢?今天我们就来探讨一下如何定义自定义的调度策略。

上一篇,我们学习了各种工作负载的使用,工作负载它会自动帮我们完成Pod的调度和部署,但有时我们需要自己定义Pod的调度策略,这个时候该怎么办呢?今天我们就来看一下如何定义Pod调度策略。

一、NodeSelector:节点定向调度

Kubernetes的Scheduler服务在调度Pod的时候会通过一系列复杂的算法自动计算出每一个Pod的最佳目标节点,但有的时候,我们需要将Pod指定的到一些Node上,比如我们有的Node安装了SSD,磁盘读写高,可以部署一些IO密集型应用,这个时候,我们就需要给这些Node打标签,然后在Pod中定义NodeSelector就可以实现。接下来我们来看一些如何实现:

1、我们通过kubectl label命令给集群中kubevm2打标签:disk=ssd,标示我们kubevm2的磁盘使用SSD。

[root@kubevm1 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubevm1 Ready master 33d v1.19.16 192.168.56.120 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 kubevm2 Ready <none> 33d v1.19.16 192.168.56.121 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 kubevm3 Ready <none> 33d v1.19.16 192.168.56.122 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://1.13.1 [root@kubevm1 ~]# kubectl label nodes kubevm2 disk=ssd

2、我们在之前deployment的例子中的Pod定义中增加nodeSelector设置:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 nodeSelector: disk: ssd

3、创建此Deployment,查看pod部署位置:我们发现三个副本都部署在kubevm2上。

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-758754644-d2qg5 1/1 Running 0 101s 10.244.1.26 kubevm2 <none> <none> nginx-deployment-758754644-tsf9f 1/1 Running 0 101s 10.244.1.27 kubevm2 <none> <none> nginx-deployment-758754644-vxdkm 1/1 Running 0 101s 10.244.1.25 kubevm2 <none> <none>

如果我们给多个Node都定义了相同的标签,则Scheduler会从这组Node中挑选一个可用的Node。我们可以看到通过给Node打标签的方式,我们可以描述集群中具有不同特点的Node,在部署应用时通过结合应用的需求设置NodeSelector进行指定Node范围的调度。这里要注意,如果我们指定了NodeSelector条件,但集群中不存在包含相应标签的Node,即使集群中还有其他可供使用的node,这个Pod也无法被成功调度,就那上面的例子来说,我们希望应用部署在SSD节点上,但如果集群中没有SSD的节点了,使用机械硬盘的节点也能部署,这样的话,使用NodeSelector就无法满足这一需求了。这个时候我们就需要使用节点亲和性调度了。

Docker与K8S中Pod的调度策略有哪些具体应用和不同场景下的选择?

二、NodeAffinity:节点亲和性调度

NodeAffinity是用于替换NodeSelector的全新调度策略,目前该策略有两种表达方式:

  • RequiredDuringSchedulingIgnoredDuringExecution:调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector,但其语法表达能力更强

  • PreferredDuringSchedulingIgnoredDuringExecution:调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。

我们可以看到RequiredDuringSchedulingIgnoredDuringExecution 的特性跟NodeSelector很像,而PreferredDuringSchedulingIgnoredDuringExecution更加灵活一些,我们接下来看一下二者的用法:

1、RequiredDuringSchedulingIgnoredDuringExecution使用

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disk operator: In values: - ssd

我们创建此Deployment,可以看到Pod豆部署在kubevm2上:

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-6ff7bf994d-9dhl2 1/1 Running 0 63s 10.244.1.28 kubevm2 <none> <none> nginx-deployment-6ff7bf994d-c8xzh 1/1 Running 0 63s 10.244.1.29 kubevm2 <none> <none> nginx-deployment-6ff7bf994d-xlpg8 1/1 Running 0 63s 10.244.1.30 kubevm2 <none> <none>

2、PreferredDuringSchedulingIgnoredDuringExecution的使用

我们将kubevm2、kubevm3打标签:disk=sata:

[root@kubevm1 workspace] kubectl label nodes kubevm2 disk=sata node/kubevm2 labeled [root@kubevm1 workspace] kubectl label nodes kubevm3 disk=sata node/kubevm3 labeled

修改deployment配置:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disk operator: In values: - ssd - key: disk operator: In values: - ssd

我们创建此Deployment可以看到,即使当前集群中没有ssd的node,Pod仍然可以部署:

[root@kubevm1 workspace]# kubectl create -f demo_deployment.yml deployment.apps/nginx-deployment created [root@kubevm1 workspace]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-cff9b7cf7-26hww 1/1 Running 0 81s 10.244.2.15 kubevm3 <none> <none> nginx-deployment-cff9b7cf7-k9x47 1/1 Running 0 81s 10.244.1.31 kubevm2 <none> <none> nginx-deployment-cff9b7cf7-xtrq4 1/1 Running 0 81s 10.244.1.32 kubevm2 <none> <none>

在上面的例子中,我们使用到了In操作符,NodeAffinity支持的操作符包括In、NotIn、Exists、DoesNotExist、Gt、Lt等。

OK,以上就是今天的内容了,后面我们继续学习Pod的其他调度策略。