1.1 Pod调度
Pod 调度是 Kubernetes 中的一个核心概念,它涉及到 Kubernetes 集群中的一个或多个节点上调度运行 Pod 的过程。Pod 是 Kubernetes 中的最小部署单元,通常包含一个或多个容器。调度过程决定了哪个 Pod 应该在哪个节点上运行,以满足集群的资源需求和策略约束。
在Kubernetes中,Pod的调度是一个复杂的过程,涉及到多种因素和规则。为了控制Pod运行在特定的节点上,或者满足特定的亲和性要求,Kubernetes提供了以下几种调度方式:
-
自动调度:这是默认的调度方式,Scheduler会根据集群的资源状况和Pod的资源需求,自动选择最合适的节点来运行Pod。
-
定向调度:
-
NodeName:通过指定Pod应该运行在哪个节点上,可以强制Pod运行在特定的Node上。这可以通过在Pod的配置中设置
spec.nodeName
属性来实现。 -
NodeSelector:允许你根据节点的标签(Labels)来选择节点。通过在Pod的配置中设置
spec.nodeSelector
属性,可以指定Pod应该运行在带有特定标签的节点上。
-
-
亲和性调度:
-
NodeAffinity:这是一种更复杂的亲和性规则,它允许你根据节点的属性来选择节点。NodeAffinity可以指定必须满足的条件(requiredDuringSchedulingIgnoredDuringExecution)或者仅仅是偏好(preferredDuringSchedulingIgnoredDuringExecution)。
-
PodAffinity:允许你根据其他Pod的属性来选择节点,确保Pod被调度到与某些其他Pod在同一节点上或者在不同的节点上,这取决于你定义的是affinity还是anti-affinity规则。
-
PodAntiAffinity:与PodAffinity相反,它确保Pod不会被调度到已经运行了具有匹配标签的Pod的节点上。
-
-
污点(Taints)和容忍(Tolerations):
-
Taints:是附加到节点上的一种标记,可以阻止没有相应容忍的Pod被调度到该节点上。
-
Tolerations:是Pod的一个属性,它允许Pod容忍(忽略)节点上的污点,从而可以被调度到这些节点上。
-
1.1.1 定向调度
定向调度,指的是利用在Pod上声明NodeName或者nodeSelector,以此将Pod调度到期望的node节点上。注意,这里的调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已。
-
NodeName:当你在Pod的配置中指定了
nodeName
字段,你实际上是在告诉Kubernetes调度器,这个Pod必须被调度到具有该名称的特定节点上。如果该节点不存在,或者由于某种原因(如资源不足)无法在该节点上运行Pod,那么Pod将无法被调度,并且会保持在Pending状态。
[root@K8s-master ~]# vim pod-nodename.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: test spec: nodeName: k8s-node-01 #强制调度到node1 containers: - name: nginx image: nginx:1.17.1 [root@K8s-master ~]# kubectl apply -f pod-nodename.yaml pod/pod-nodename created [root@K8s-master ~]# kubectl get pod pod-nodename -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-nodename 1/1 Running 0 29s 10.244.1.8 k8s-node-01 <none> <none>
-
NodeSelector 指导调度:
nodeSelector
是一种标签选择器,它允许你指定一组标签,调度器会根据这些标签选择一个合适的节点来运行 Pod。如果存在多个带有匹配标签的节点,调度器会根据其他调度策略(如亲和性、反亲和性规则)来选择最佳节点。如果找不到任何匹配的节点,Pod 同样会处于 Pending 状态。
1、为node节点添加标签 [root@K8s-master ~]# kubectl label nodes k8s-node-01 nodeenv=dev node/k8s-node-01 labeled [root@K8s-master ~]# kubectl label nodes k8s-node-02 nodeenv=test node/k8s-node-02 labeled 2、创建Pod [root@K8s-master ~]# vim pod-nodeselector.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-nodeselector namespace: test spec: nodeSelector: nodeenv: dev containers: - name: nginx image: nginx:1.17.1 [root@K8s-master ~]# kubectl apply -f pod-nodeselector.yaml pod/pod-nodeselector created [root@K8s-master ~]# kubectl get pod pod-nodeselector -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-nodeselector 1/1 Running 0 6s 10.244.1.9 k8s-node-01 <none> <none>
-
如果到调度到一个没有的标签会调度失败
1.1.2 亲和性调度
亲和性调度是一种比硬性指定节点(使用 nodeName
或 nodeSelector
)更灵活的调度策略,它允许定义一组规则,根据这些规则,调度器会尝试将 Pod 调度到最合适的节点上,但如果找不到完全匹配的节点,它仍然可以调度到其他节点上。
下面是亲和性调度的三种主要类型及其使用场景:
亲和性类型 | 描述 | 调度规则示例 |
---|---|---|
Node Affinity | 定义 Pod 可以调度到哪些节点的规则。 | 基于节点的标签选择节点,如调度到具有特定硬件配置或特定区域的节点。 |
- requiredDuringSchedulingIgnoredDuringExecution | 必须满足所有规则才能调度。 | |
- nodeSelectorTerms | 节点选择列表。 | |
- matchFields | 按节点字段列出的节点选择器要求列表。 | |
- matchExpressions | 按节点标签列出的节点选择器要求列表(推荐)。 | |
- preferredDuringSchedulingIgnoredDuringExecution | 优先调度到满足规则的节点,如果没有,也可以调度到其他节点(软限制)。 | |
- preference | 节点选择器项,与权重相关联。 | |
- weight | 倾向权重,范围1-100。 | |
Pod Affinity | 定义 Pod 应该与哪些已存在的 Pod 调度到相同的拓扑域。 | 适用于需要频繁交互的应用,减少通信延迟。 |
- requiredDuringSchedulingIgnoredDuringExecution | 必须与指定的 Pod 调度到相同的拓扑域。 | |
- preferredDuringSchedulingIgnoredDuringExecution | 优先与指定的 Pod 调度到相同的拓扑域,如果没有,也可以调度到其他拓扑域(软限制)。 | |
Pod Anti-Affinity | 定义 Pod 不应该与哪些已存在的 Pod 调度到相同的拓扑域。 | 确保应用的多个实例分散在不同的拓扑域,提高可用性和容错性。 |
- requiredDuringSchedulingIgnoredDuringExecution | 必须不与指定的 Pod 调度到相同的拓扑域。 | |
- preferredDuringSchedulingIgnoredDuringExecution | 优先不与指定的 Pod 调度到相同的拓扑域,如果没有,也可以调度到其他拓扑域(软限制)。 |
每种亲和性都支持两种模式:
-
RequiredDuringSchedulingIgnoredDuringExecution&#x