在处理AI/ML训练、高性能计算(HPC)等场景时,我们经常需要确保特定的工作负载只能运行在具备特定硬件(如GPU、高性能SSD或特殊网络接口)的机器上。Kubernetes的节点亲和性(Node Affinity)就是解决这一问题的核心机制。
本文将聚焦如何使用硬性亲和性规则,确保计算任务精准地落在贴有GPU标签的工作节点上。
1. 节点亲和性概述
节点亲和性是Kubernetes提供的一种更灵活、更富有表现力的Pod调度机制,用于取代早期的 nodeSelector。它允许你基于节点的标签来定义Pod的调度偏好或硬性要求。
亲和性主要分为两种类型:
- 硬性亲和(Required): requiredDuringSchedulingIgnoredDuringExecution。Pod必须满足这些条件才能被调度。如果集群中没有符合条件的节点,Pod将保持Pending状态。
- 软性亲和(Preferred): preferredDuringSchedulingIgnoredDuringExecution。调度器会尽量满足这些条件,但不保证。如果找不到满足条件的节点,Pod仍会调度到其他节点上。
2. 准备工作:为GPU节点打标签
要使用节点亲和性,首先需要识别并标记出具备GPU的节点。假设你的一个节点名为 k8s-worker-03,并且它安装了NVIDIA设备插件。
使用 kubectl label 命令为其添加一个描述性标签:
# 语法: kubectl label node <node-name> <key>=<value>
kubectl label node k8s-worker-03 feature=gpu
# 验证标签是否添加成功
kubectl get nodes --show-labels
你现在应该能看到 k8s-worker-03 节点上带有 feature=gpu 标签。
3. 配置硬性节点亲和性(Required Node Affinity)
我们将创建一个Pod,它不仅请求一个GPU资源(通过 nvidia.com/gpu),更重要的是,它通过 nodeAffinity 规则强制要求该Pod只能调度到标签为 feature=gpu 的节点上。
以下是使用硬性亲和性规则的Pod YAML示例:
apiVersion: v1
kind: Pod
metadata:
name: required-gpu-task
spec:
# 1. 定义亲和性规则
affinity:
nodeAffinity:
# 2. 硬性要求:调度时必须满足,执行后忽略(即标签改变不影响已运行的Pod)
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
# 3. 至少一个nodeSelectorTerm满足条件即可
- matchExpressions:
# 定义匹配表达式
- key: feature
# 操作符:In (在值列表中), NotIn, Exists, DoesNotExist, Gt (大于), Lt (小于)
operator: In
values:
- gpu # 匹配 feature 标签的值为 'gpu' 的节点
containers:
- name: cuda-test-container
image: nvidia/cuda:11.7.1-base-ubuntu20.04
command: ["/bin/bash", "-c", "echo 'Task running on GPU node' && sleep 3600"]
resources:
# 4. 同时请求GPU资源(前提是节点上安装了NVIDIA设备插件)
limits:
nvidia.com/gpu: "1"
4. 部署与验证
- 应用配置:
kubectl apply -f required-gpu-task.yaml - 验证调度结果:
查看Pod的状态和它被调度到的节点:kubectl get pod required-gpu-task -o wide如果一切正常,该Pod的 NODE 字段将显示你贴有 feature=gpu 标签的节点名称(例如 k8s-worker-03)。
5. 应对无匹配节点的情况
如果你尝试运行这个Pod,但集群中没有节点带有 feature=gpu 标签,或者匹配的GPU节点资源不足,Pod将保持在 Pending 状态。你可以通过查看Pod事件来确认原因:
kubectl describe pod required-gpu-task
在事件(Events)列表中,你将看到类似以下的警告信息,明确指出调度失败是因为硬性亲和性规则没有得到满足。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 5s default-scheduler 0/3 nodes are available: 3 node(s) didn't match Pod's node affinity/selector.
总结
通过结合使用Kubernetes的节点标签和 requiredDuringSchedulingIgnoredDuringExecution 节点亲和性规则,我们可以有效地实现对计算任务的精准定位调度。这对于优化资源利用率、确保高优先级任务运行在高性能硬件上至关重要,是现代容器化AI/ML工作流中不可或缺的技术手段。
汤不热吧