Kubernetes
吾八哥学k8s(十一):kubernetes里Pod的调度机制
Pod的调度需求可以应用在非常多的场景里,举个简单的例子:某第三方接口服务器是在北京,那么就希望业务的Pod尽量调度到北京的节点上,以减少网络延时。kubernetes里提供了多种灵活调度的机制,可以根据实际情况来选择使用,下面简单的介绍下各种调度机制的用法。
全自动调度
全自动调度是指Pod运行在哪个节点上,由k8s集群的调度器经过一系列的调度算法来决定,用户无法干预调度策略,用户也不知道Pod会调度到哪个节点上。
定向调度
定向调度是指用户可以指定Pod调度到某些节点上,下面通过一些例子来说明。
根据节点名字来调度
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx-demo spec: replicas: 1 selector: matchLabels: app: nginx-demo template: metadata: labels: app: nginx-demo spec: nodeName: cn-zhangjiakou.node-1 #指定节点名 containers: - name: nginx-demo image: "nginx:1.20.0"
根据节点Label来调度
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx-demo spec: replicas: 1 selector: matchLabels: app: nginx-demo template: metadata: labels: app: nginx-demo spec: nodeSelector: lang: share #指定节点Label containers: - name: nginx-demo image: "nginx:1.20.0"
kubernetes内置的一些预定义的标签有:
kubernetes.io/hostname
kubernetes.io/os
kubernetes.io/arch
Node亲和性调度(NodeAffinity)
节点亲和性概念上类似于 nodeSelector,它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点。
目前有两种类型的节点亲和性,分别为 requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution。 你可以视它们为“硬需求”和“软需求”,意思是,前者指定了将 Pod 调度到一个节点上 必须满足的规则(就像 nodeSelector 但使用更具表现力的语法), 后者指定调度器将尝试执行但不能保证的偏好。 名称的“IgnoredDuringExecution”部分意味着,类似于 nodeSelector 的工作原理, 如果节点的标签在运行时发生变更,从而不再满足 Pod 上的亲和性规则,那么 Pod 将仍然继续在该节点上运行。
节点亲和性通过 PodSpec 的 affinity 字段下的 nodeAffinity 字段进行指定。例如下面的例子:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx-demo spec: replicas: 1 selector: matchLabels: app: nginx-demo template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-area operator: In values: - tencent - aliyun preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: node-cpu operator: In values: - max containers: - name: nginx-demo image: "nginx:1.20.0"
上面的亲和配置表示,Pod只允许调度到节点带标签为node-area=tencent或node-area=aliyun的节点上,在满足条件的节点中带有标签node-cpu=max的节点优先被使用。
Pod亲和与互斥调度
污点(Taints)和容忍(Tolerations)
节点的Taint基本操作
Taint能够使节点排斥一类特定的Pod,Taint和Toleration相互配合可以用来避免Pod被分配到不合适的节点。
节点增加一个Taint:
kubectl taint nodes k8s-node-001 key=value:NoSchedule
节点删除一个Taint:
kubectl taint nodes k8s-node-001 key:NoSchedule-
查看节点Taint:
kubectl describe node k8s-node-001 | grep Taint
pod容忍度配置
节点配置Taint后,只有和这个Taint相匹配的Toleration的Pod才能被分配到这个节点上,例如一个简单的容忍污点的yaml里的配置写法如下:
tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule"
如果yaml里没加上面的污点容忍度配置,则Pod是不会调度到k8s-node-001上的,只有加上才可能会调度上去。
Pod的Toleration声明中的key和effect需要与Taint的设置保持一致,并且满足如下条件之一:
operator的值为Exists(无须指定value) operator的值是Equal并且value相等
如果不指定operator,则默认值为Equal,有如下两个情况需要注意下:
空的key配合Exists操作符能够匹配所有的键和值 空的effect匹配所有的effect
effect的值相关的解释如下:
NoSchedule表示如果Pod没有容忍这些污点,Pod则不能被调度到包含这些污点的节点上 PreferNoSchedule是NoSchedule的一个宽松版本,表示尽量阻止Pod被调度到这个节点上,但是如果没有其他节点可调度,Pod依然会被调度到该节点 NoExecute不仅在调度期间起作用,也影响该节点上运行的Pod,节点上添加了NoExecute污点,则节点上没有容忍这个NoExecute污点的Pod都会被驱逐
配置节点失效后Pod重新调度最长等待时间的方法
可以配置一个容忍度,用于Pod运行所在节点变成unready或unreachable状态时,Kuberneters可以等待该pod被调度到其他节点的最长等待时间,例如:
tolerations: - key: "node.kubernetes.io/not-ready" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300 - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300
上面的配置表示,该Pod将容忍所在节点处于notready或unreachable状态维持300秒,超过300秒后将会被重新调度到其他节点上。
参考资料
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/
书籍《Kuberneters In Action》中文版
相关文章
- 在Kubernetes里使用openkruise实现服务原地升级功能
- 吾八哥学k8s(十):kubernetes里Service和Ingress
- kubernetes中服务自定义Prometheus的metrics的方法
- k8s集群安装Prometheus监控以及Grafana面板的方法
- kubernetes集群证书过期的解决方法
- kubelet启动失败报failed to find cgroups of kubelet的解决方法
- 吾八哥学k8s(九):kubernetes里持久化存储
- macOs和Linux环境下kubectl命令自动补齐的方法
- 吾八哥学k8s(八):kubernetes里Secret的用法
- apps/v1版本下使用client-go实现kubernetes回滚的方法