照片由 Kaitlyn Chow 拍摄,来自 Unsplash
在 Kubernetes 中,有效的资源管理和工作负载调度对于优化性能和提高可靠性至关重要。Kubernetes 提供了多种工具来控制 Pod 的调度,确保工作负载运行在合适的节点上。在这样的背景下,三个重要的工具是 污点和容忍机制、节点选择器 和 节点亲和性。本文将探讨这些功能及其应用,解释它们是什么,它们是如何工作的,如何配置它们以及实际的应用场景。
Kubernetes调度器负责将Pod分配到集群中的各个节点上。它会考虑多种因素,如资源可用情况、亲和性、反亲和性策略等。三种重要的控制Pod运行位置的机制是污点和容忍度、节点选择器和节点亲和策略。这些机制有助于Pod被调度到符合特定要求的节点上,提高效率和可靠性。
污点标记应用于节点,使某些 pod 避免调度到这些节点上。它们是由键值对标签定义,附带一种效果(NoSchedule
、PreferNoSchedule
或 NoExecute
),防止 pod 被调度到带有污点标记的节点上,除非这些 pod 能够容忍该污点标记。
容忍应用于 Pod,允许 Pod 可以被调度到带有特定污点的节点上。容忍告诉 Kubernetes 调度器,这个 Pod 可以容忍这个节点的污点,因此可以在这个节点上运行。
Kubernetes调度器利用污点和容忍机制来决定pod是否可以调度到Node上:
了解污点的不同影响是有效利用其力量的关键。
污点标签可以使用 kubectl taint
命令应用到节点上。下面是如何使用命令给节点添加污点标签,使表达更加自然流畅。
kubectl taint nodes <node-name> key=value:effect
将节点标记为污点,其中<node-name>是节点名称,key=value是标记的键值对,effect是标记的效果。
例如,除非 Pod 具有匹配的容忍,否则不允许它们调度到节点上。
kubectl taint nodes node1 dedicated=workload:NoSchedule // 将节点node1标记为专用,不允许调度workload
这个命令给 node1
添加了一个带有键值对 dedicated
和 workload
,效果为 NoSchedule
的污点标签。
容许的设置指定在 pod 的 YAML 配置文件中。下面是一个示例:
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image tolerations: - key: "dedicated" operator: "Equal" value: "workload" effect: "NoSchedule"
此 pod 容忍污点标签 dedicated = workload : NoSchedule
,允许它被调度到带有该污点标签的节点。
为了使“污点”和“容忍度”的概念更易理解,可以想想医院里的例子。
节点选择指的是...
注意:这里的“节点选择”在技术讨论中更常用,而不是“节点选择器”。
节点选择器提供了一种更简单的方式来控制 pod 的调度位置,通过将 pod 与具有匹配标签的节点相匹配来实现。节点选择器是通过在 pod 配置中指定的一对键值对,用以限制 pod 只能在具有匹配标签的节点上运行。
节点选择器使用标签来匹配 pod 与节点。当一个 pod 指定节点选择器时,它只会调度到具有匹配标签的节点上。
第七章 配置节点选择器规则
你可以用 kubectl label
命令给节点打标签:例如:
kubectl label nodes <node-name> disktype=ssd // 给指定节点添加磁盘类型标签
这个命令用键为 disktype
和值为 ssd
标注节点。
节点选择器是在 pod 规范中定义的。比如使用节点选择器的方法如下:
apiVersion: API版本 kind: 类型 metadata: name: my-pod spec: 容器: - name: my-container image: my-image 节点选择器: 磁盘类型: ssd
这个 pod 只会被安排到具有 disktype=ssd
标签的节点上。
节点亲和性提供了比节点选择器更明确和灵活的方式来根据标签定义规则,从而更复杂地匹配和调度Pod。
节点亲和性允许我们通过 pod 规约来设定亲和性规则,这些规则由调度器会评估,以此来判断 pod 是否应该在节点上运行。节点亲和性有两种类型:
要配置 Pod 规范中的节点亲和性配置,可以这样做:
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd
在这个示例中,Pod只会被调度到带有disktype=ssd
标签的节点上。
专属节点:用污点来设置专属节点,用于特定工作负载,比如高优先级应用或专门任务(比如GPU任务)。
示例:比如这个污点 dedicated=high-priority:NoSchedule
确保只有高优先级任务会被安排到这些节点上。
节点维护:污点(taints)可以在维护期间暂时防止新 pod 被调度到节点上,同时允许现有 pod 正常运行。
示例:kubectl taint nodes node1 maintenance=true:NoSchedule
硬件需求:使用节点选择器将 Pod 放置在具有特定硬件(如 SSD 或 GPU)的节点上,以满足应用的性能需求。
示例:用 disktype=ssd
标记节点,并使用节点选择器将存储密集型应用程序部署到这些节点上。
区域感知:确保Pod被调度到特定的地理或可用性区域,以提高容错性和减少延迟。
示例:用 zone=us-west-1
标记节点,并为需要在美国西部运行的应用程序使用节点选择器。
更灵活的调度控制:使用节点亲和性根据节点标签应用更精细的调度策略,例如将pod调度到具有特定硬件能力或位于特定数据中心的节点上。
例如,需要高速存储的pod可以使用节点亲和性,优先调度到标记为支持高速存储的节点上。
软硬约束:节点亲和性允许你设置必需和优选的约束,提供灵活性以应对不同情况,例如更偏好具有某些硬件特性的节点,但不强制。
想象你有一个高性能应用,需要在配备了专用硬件(如GPU)的节点上运行,以进行高强度计算。这些节点也必须专用于这类任务,以避免与其他任务争夺资源。
挑战 2:仅使用节点亲和性进行挑战
gpu=true
)的节点上。然而,仅凭节点亲和性并不能阻止不使用 GPU 的工作负载被调度到 GPU 节点上,如果这些工作负载也恰好满足亲和性条件的话。这可能会导致资源争用,从而降低性能。通过结合污点容忍和节点亲和性策略,你可以实现这样的调度行为。
为GPU节点添加标记:
gpu=true:NoSchedule
标签,这样非 GPU Pod 将不会被调度到这些节点,除非它们能够容忍该污点。运行命令 kubectl taint nodes <gpu-node> gpu=true:NoSchedule
,将 <gpu-node> 节点的污点设置为 gpu=true:NoSchedule。
在Pod规格中配置节点亲和性:
gpu=true
标签。apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: containers: - name: gpu-container image: gpu-image tolerations: - key: gpu operator: Equal value: true effect: NoSchedule affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu operator: In values: - true
gpu=true
污点)的容器才能被调度到GPU节点上。其他非GPU任务会被这个污点排斥,从而不会占用GPU专用资源,这样既满足了硬件需求,也确保了GPU任务的专用资源。11. 最佳做法
污点(Taints)、容忍规则(Tolerations)、节点选择器(Node Selectors)和节点亲和性是 Kubernetes 中强大的工具,可让你更精细地调整 Pod 调度,有效管理和调度集群资源。通过理解并应用这些特性,你可以更优化地安排工作负载,确保可靠性并提升整体集群性能。试试这些工具,找到最适合你应用和基础设施需求的最佳策略。
感谢您一直读到最后,在您离开前: