Skip to content
共绩算力文档中心

如何发布 Job 任务类型

Job 任务类型适用于一次性执行的任务,如批处理、数据处理、机器学习训练等场景。任务完成后 Pod 会自动终止,不会持续运行。

Job 任务创建成功后具有以下特性:任务名称可以随时修改,支持任务暂停和重启功能,为用户提供了基本的任务管理能力。然而,Job 任务在创建后存在诸多不可修改的限制,包括高级设置、yaml 文件配置、共享内存设置、镜像地址、暴露端口配置以及节点数量等核心参数。这些限制的存在主要基于 Job 任务的一次性执行特性,确保任务执行的稳定性和一致性。用户如需修改这些参数,需要重新创建任务实例。

在弹性部署服务任务创建页面,您可以通过可视化界面配置和发布 Job 任务。首先进入弹性部署任务创建页面,点击 K8S YAML 导入在资源配置部分,选择需要的 GPU 类型和数量。

任务创建完成后,您可以在任务列表页面查看任务状态,在任务详情页面进行任务管理操作,支持任务暂停、重启等基本功能。如需修改资源配置,需要重新创建任务实例。

job 任务配置示例

---
apiVersion: batch/v1 # 指定 Kubernetes API 的版本,用于 Job 资源
kind: Job # 指定资源类型为 Job,用于运行一次性任务
metadata: # 元数据部分,定义 Job 的基本信息
name: gpu-job-pi # Job 的名称,必须是唯一的
spec: # Job 的具体配置
completions: 4 # 总共需要成功完成的 Pod 数量
parallelism: 2 # 同时运行的 Pod 数量
backoffLimit: 4 # Pod 失败后的重试次数
ttlSecondsAfterFinished: 86400 # Job 完成后保留的时间(秒),之后自动清理
template: # Pod 模板,定义每个 Pod 的配置
metadata: # Pod 元数据
labels: # Pod 的标签,用于标识和选择
app: gpu-job-pi
spec: # Pod 的具体配置
restartPolicy: Never # Pod 的重启策略,设置为 Never 表示失败后不重启
containers: # 定义 Pod 中的容器
- name: pi # 主容器名称
image: harbor.suanleme.cn/huang5876/jupyter-tf1.15-gpu:v3.0 # 主容器的镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略,如果本地存在则不拉取
env: # 环境变量
- name: DEBUG_MODE # 调试模式开关
value: "true" # 设置为 "true" 进入调试模式,"false" 运行实际任务
command: # 容器启动命令
- /bin/bash
- -c
args: # 容器启动参数
- |
if [[ $DEBUG_MODE == true ]]; then
echo "==== DEBUG: sleep 8h ===="
sleep 28800 # 调试模式下睡眠 8 小时
else
echo "==== 真正脚本写这里 ===="
# python /mnt/data/train.py # 替换为实际的启动命令
fi
resources: # 资源限制和请求
limits:
cpu: "14" # 最大 CPU 使用量
nvidia.com/gpu: "1" # 使用 1 块 GPU
memory: 50Gi # 最大内存使用量
requests:
cpu: 1166m # 最小 CPU 请求量
nvidia.com/gpu: "1" # 请求 1 块 GPU
memory: 2133Mi # 最小内存请求量
volumeMounts: # 挂载卷
- name: data
mountPath: /mnt/data # 数据卷挂载路径
- name: out
mountPath: /mnt/output # 输出卷挂载路径
- name: pi2 # 辅助调试容器
image: harbor.suanleme.cn/library/cuda:debugv4 # 调试容器的镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略
command: # 调试容器启动命令
- sleep
- infinity # 无限睡眠,方便调试
resources: # 资源限制和请求
limits:
cpu: "9"
nvidia.com/gpu: "1"
memory: 4Gi
requests:
cpu: 2333m
nvidia.com/gpu: "1"
memory: 10Gi
volumes: # 定义卷
- name: data
persistentVolumeClaim: # 数据卷 PVC
claimName: gpu-job-data-pvc # PVC 名称
- name: out
persistentVolumeClaim: # 输出卷 PVC
claimName: gpu-job-output-pvc # PVC 名称
nodeSelector: # 节点选择器
accelerator: nvidia # 选择带有 GPU 的节点
tolerations: # 容忍度
- key: nvidia.com/gpu
operator: Exists # 允许调度到带有 GPU 污点的节点
effect: NoSchedule

3 通过 API 形式发布 Job 任务类型

Section titled “3 通过 API 形式发布 Job 任务类型”

任务创建接口是系统核心功能之一,用于通过 API 方式创建和管理 Job 任务。接口参数文档位于:https://s.apifox.cn/6aa360d3-d8f2-471e-b841-3a35c33a7b7c/api-296881505

通过 API 创建 Job 任务需要按照 Kubernetes Job 资源格式配置 YAML,以下是一个多容器 Job 任务的完整配置示例:

---
apiVersion: batch/v1 # 指定 Kubernetes API 的版本,用于 Job 资源
kind: Job # 指定资源类型为 Job,用于运行一次性任务
metadata: # 元数据部分,定义 Job 的基本信息
name: gpu-job-pi # Job 的名称,必须是唯一的
spec: # Job 的具体配置
completions: 4 # 总共需要成功完成的 Pod 数量
parallelism: 2 # 同时运行的 Pod 数量
backoffLimit: 4 # Pod 失败后的重试次数
ttlSecondsAfterFinished: 86400 # Job 完成后保留的时间(秒),之后自动清理
template: # Pod 模板,定义每个 Pod 的配置
metadata: # Pod 元数据
labels: # Pod 的标签,用于标识和选择
app: gpu-job-pi
spec: # Pod 的具体配置
restartPolicy: Never # Pod 的重启策略,设置为 Never 表示失败后不重启
containers: # 定义 Pod 中的容器
- name: pi # 主容器名称
image: harbor.suanleme.cn/huang5876/jupyter-tf1.15-gpu:v3.0 # 主容器的镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略,如果本地存在则不拉取
env: # 环境变量
- name: DEBUG_MODE # 调试模式开关
value: "true" # 设置为 "true" 进入调试模式,"false" 运行实际任务
command: # 容器启动命令
- /bin/bash
- -c
args: # 容器启动参数
- |
if [[ $DEBUG_MODE == true ]]; then
echo "==== DEBUG: sleep 8h ===="
sleep 28800 # 调试模式下睡眠 8 小时
else
echo "==== 真正脚本写这里 ===="
# python /mnt/data/train.py # 替换为实际的启动命令
fi
resources: # 资源限制和请求
limits:
cpu: "14" # 最大 CPU 使用量
nvidia.com/gpu: "1" # 使用 1 块 GPU
memory: 50Gi # 最大内存使用量
requests:
cpu: 1166m # 最小 CPU 请求量
nvidia.com/gpu: "1" # 请求 1 块 GPU
memory: 2133Mi # 最小内存请求量
volumeMounts: # 挂载卷
- name: data
mountPath: /mnt/data # 数据卷挂载路径
- name: out
mountPath: /mnt/output # 输出卷挂载路径
- name: pi2 # 辅助调试容器
image: harbor.suanleme.cn/library/cuda:debugv4 # 调试容器的镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略
command: # 调试容器启动命令
- sleep
- infinity # 无限睡眠,方便调试
resources: # 资源限制和请求
limits:
cpu: "9"
nvidia.com/gpu: "1"
memory: 4Gi
requests:
cpu: 2333m
nvidia.com/gpu: "1"
memory: 10Gi
volumes: # 定义卷
- name: data
persistentVolumeClaim: # 数据卷 PVC
claimName: gpu-job-data-pvc # PVC 名称
- name: out
persistentVolumeClaim: # 输出卷 PVC
claimName: gpu-job-output-pvc # PVC 名称
nodeSelector: # 节点选择器
accelerator: nvidia # 选择带有 GPU 的节点
tolerations: # 容忍度
- key: nvidia.com/gpu
operator: Exists # 允许调度到带有 GPU 污点的节点
effect: NoSchedule

1️⃣ 改参数(5 个高频开关)

用任何编辑器打开 gpu-job.yaml——只动下面 5 处,别的别动:

位置

示例值

说明

name: gpu-job-pi

my-experiment

一次提交一个 Job,名字不能重复

completions: 4

10

总共要成功的 Pod 数

parallelism: 2

5

同时跑几个 Pod

value: "true"

"false"

true 睡 8 h 调试;false 真正跑代码

nvidia.com/gpu: "1"

"2"

每 Pod 用几张卡

改完保存即可。

2️⃣ 提交到集群

Terminal window
kubectl apply --dry-run=client -f gpu-job.yaml
kubectl apply -f gpu-job.yaml

成功提示

job.batch/my-experiment created

3️⃣ 实时看 Pod 状态

Terminal window
watch -n 1 kubectl get po -l app=gpu-job-pi

输出示例

NAME READY STATUS RESTARTS AGE
my-experiment-5shk9 2/2 Running 0 14s
my-experiment-7v4kp 2/2 Running 0 14s
my-experiment-h6abc 0/2 Pending 0 2s # 还没调度

STATUS 列常见值

Pending → 正在找 GPU 节点 / 拉镜像

ContainerCreating → 创建中

Running → 可以 exec 进去了

Completed → 正常退出

Error / CrashLoopBackOff → 出错了看日志

4️⃣ 进终端调试(两种容器)

a) 进主容器(pi)——里面有 GPU、训练环境

Terminal window
kubectl exec -it my-experiment-5shk9 -c pi -- bash
[root@5shk9 /]# nvidia-smi # 看 GPU
[root@5shk9 /]# ls /mnt/data # 看数据卷
[root@5shk9 /]# python /mnt/data/train.py # 手动跑脚本

退出 exit

b) 进辅助容器(pi-debug)——纯净 CUDA 环境,调驱动、看卡

Terminal window
kubectl exec -it my-experiment-5shk9 -c pi-debug -- bash
[root@5shk9 /]# nvcc --version
[root@5shk9 /]# nvidia-smi -q # 详细显卡信息

退出 exit

5️⃣ 看日志(排错必用)

Terminal window
kubectl logs my-experiment-5shk9 -c pi
kubectl logs my-experiment-5shk9 -c pi-debug

6️⃣ 清理 Job(跑完及时删)

Terminal window
kubectl delete job my-experiment

因为模板里写了 ttlSecondsAfterFinished: 86400,集群也会在 1 天后自动清掉。

当使用多容器配置时,系统采用智能的资源分配算法来确保每个容器获得合理的资源分配。

CPU 资源分配机制:在 Job 任务的多容器场景中,系统采用加权平均算法进行 CPU 资源分配。该算法确保每个容器按照其配置比例获得相应的 CPU 资源。算法实现过程如下:首先计算所有容器的 CPU 配置总和,然后根据每个容器的配置占比,将实际机器的 CPU 核心数按比例分配给各个容器。例如,当第一个容器配置 14,000 微核,第二个容器配置 9,333 微核时,总和为 23,333 微核。在实际分配过程中,假设选择 4090 卡(20 核)作为目标机器,系统会计算第一个容器的分配比例:14,000 ÷ 23,333 ≈ 60%,因此第一个容器将获得 20 核 × 60% = 12 核的 CPU 资源。

内存资源分配机制:内存分配采用总量计算和比例分配相结合的策略。系统首先汇总所有容器的内存配置需求,然后按照各容器的内存配置比例进行资源分配。具体分配流程如下:以第一个容器内存配置 51,200 兆,第二个容器配置 4,200 兆为例,系统计算出总内存需求为 55,400 兆。随后,系统根据第一个容器的内存配置占比(51,200 ÷ 55,400 ≈ 92%)将目标机器的内存资源进行分配,假设目标机器内存为 101 G,则第一个容器将获得 101 G × 92% ≈ 93 G 的内存资源。

GPU 资源分配策略:GPU 资源分配采用优先级分配策略,确保关键任务能够优先获得 GPU 资源支持。分配规则如下:当选择单 GPU 配置时,系统优先将 GPU 资源分配给第一个容器;当选择多 GPU 配置时,系统会为所有容器分配 GPU 资源。这种策略确保了资源分配的公平性和效率。在资源请求计算方面,系统采用统一的规则:计算完 limit 值后,request 值设置为 limit 除以 4,这种配置方式既保证了资源的有效利用,又避免了资源过度预留。