如何发布 Job 任务类型
1 Job 任务类型
Section titled “1 Job 任务类型”Job 任务类型适用于一次性执行的任务,如批处理、数据处理、机器学习训练等场景。任务完成后 Pod 会自动终止,不会持续运行。
Job 任务创建成功后具有以下特性:任务名称可以随时修改,支持任务暂停和重启功能,为用户提供了基本的任务管理能力。然而,Job 任务在创建后存在诸多不可修改的限制,包括高级设置、yaml 文件配置、共享内存设置、镜像地址、暴露端口配置以及节点数量等核心参数。这些限制的存在主要基于 Job 任务的一次性执行特性,确保任务执行的稳定性和一致性。用户如需修改这些参数,需要重新创建任务实例。
2 通过弹性部署发布
Section titled “2 通过弹性部署发布”在弹性部署服务任务创建页面,您可以通过可视化界面配置和发布 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: NoSchedule3 通过 API 形式发布 Job 任务类型
Section titled “3 通过 API 形式发布 Job 任务类型”3.1 接口概述
Section titled “3.1 接口概述”任务创建接口是系统核心功能之一,用于通过 API 方式创建和管理 Job 任务。接口参数文档位于:https://s.apifox.cn/6aa360d3-d8f2-471e-b841-3a35c33a7b7c/api-296881505
3.2 Job 任务配置示例
Section titled “3.2 Job 任务配置示例”通过 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: NoSchedule4.改参 - 提交 - 看状态 - 进终端
Section titled “4.改参 - 提交 - 看状态 - 进终端”1️⃣ 改参数(5 个高频开关)
用任何编辑器打开 gpu-job.yaml——只动下面 5 处,别的别动:
位置 | 示例值 | 说明 |
|
| 一次提交一个 Job,名字不能重复 |
|
| 总共要成功的 Pod 数 |
|
| 同时跑几个 Pod |
|
|
|
|
| 每 Pod 用几张卡 |
改完保存即可。
2️⃣ 提交到集群
kubectl apply --dry-run=client -f gpu-job.yaml
kubectl apply -f gpu-job.yaml成功提示
job.batch/my-experiment created
3️⃣ 实时看 Pod 状态
watch -n 1 kubectl get po -l app=gpu-job-pi输出示例
NAME READY STATUS RESTARTS AGEmy-experiment-5shk9 2/2 Running 0 14smy-experiment-7v4kp 2/2 Running 0 14smy-experiment-h6abc 0/2 Pending 0 2s # 还没调度STATUS 列常见值
Pending → 正在找 GPU 节点 / 拉镜像
ContainerCreating → 创建中
Running → 可以 exec 进去了
Completed → 正常退出
Error / CrashLoopBackOff → 出错了看日志
4️⃣ 进终端调试(两种容器)
a) 进主容器(pi)——里面有 GPU、训练环境
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 环境,调驱动、看卡
kubectl exec -it my-experiment-5shk9 -c pi-debug -- bash[root@5shk9 /]# nvcc --version[root@5shk9 /]# nvidia-smi -q # 详细显卡信息退出 exit
5️⃣ 看日志(排错必用)
kubectl logs my-experiment-5shk9 -c pi
kubectl logs my-experiment-5shk9 -c pi-debug6️⃣ 清理 Job(跑完及时删)
kubectl delete job my-experiment因为模板里写了 ttlSecondsAfterFinished: 86400,集群也会在 1 天后自动清掉。
5.多容器资源分配算法
Section titled “5.多容器资源分配算法”
当使用多容器配置时,系统采用智能的资源分配算法来确保每个容器获得合理的资源分配。
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,这种配置方式既保证了资源的有效利用,又避免了资源过度预留。