部署与版本指南

更新时间:
复制 MD 格式

灵骏 Runtime Kit 包含资源层 Runtime 包与容器层开源组件套件。阅读本文可了解交付构成、部署前置条件、获取方式、部署步骤、版本号体系、兼容策略及升级方法。

说明

公测中:本产品当前处于公测阶段,如有问题或建议,请联系灵骏技术支持。

说明

当前暂无系统化的查询/升级/回滚 Runtime Kit 版本机制,如果有相关需求,请联系 PDSA 确认并商讨升级方案。

1. 交付构成与使用前提

1.1 交付构成

Runtime Kit 由两部分构成,二者之间通过统一的 gRPC 接口对接:

层

交付物

形态

维护责任

资源层

Runtime 包

闭源,随灵骏裸金属 OS 镜像预装

阿里云灵骏团队负责发布与迭代

容器层

开源组件套件(Device Plugin、Scheduler Framework、Exporter、Controller)

开源参考实现及预编译镜像

用户自行部署或二次开发

gRPC 接口是两层之间唯一的对接边界:资源层能力由阿里云灵骏提供,容器层由用户基于开源组件自行适配。本文档所有版本兼容结论均以该接口为分析基础。

问题归属与支持渠道:以 gRPC 接口为界——资源层 Runtime 自身问题属阿里云灵骏产品问题,提交阿里云灵骏技术支持渠道处理;直接使用官方预编译版本的开源组件可通过开源仓库 Issue 等渠道反馈解决;用户二次开发或自行适配的实现由用户自行维护,阿里云灵骏视情况提供定位协助。

1.2 使用前提

  1. 灵骏裸金属节点:Runtime 包随灵骏裸金属 OS 镜像预装,仅存在于灵骏裸金属环境。部署开源组件前,节点上的 Runtime 服务应已正常运行(可通过检查 /run/amp/eKitC/xdm/sockets/ 目录下的 socket 文件确认);

  2. Kubernetes 集群:Device Plugin 与 Scheduler Framework 要求 Kubernetes >= 1.18;

  3. kubelet 只读端口:开源组件需通过 kubelet 只读端口(10255)获取节点 Pod 信息,详见3.2 节;

  4. 容器运行时配置:GPU/PPU 设备注入依赖 lj-runtime runtime handler 与对应 RuntimeClass,详见3.2 节;

  5. 可选依赖:使用跨节点 Gang 拓扑调度时,如用户集群本身不具备 Gang 调度能力,需安装 JobSet(建议 v0.8.0),详见3.2 节。

1.3 使用限制

  1. 在 Kubernetes 中使用 Runtime Kit 能力,须通过开源组件套件提供的标准方式接入,即经由统一的 gRPC 接口对接底层能力;

  2. 时分复用(TDM)与 MIG 空分不能在同一张卡上同时启用;

  3. MIG 为 NVIDIA 硬件级技术,支持所有在硬件层面具备 MIG 能力的卡型。

2. 获取方式

2.1 开源仓库

开源组件代码发布在 GitHub 仓库 aliyun/LJ-RuntimeKit。main 分支始终保持最新可用代码;稳定版本以 Tag 形式发布,用户获取稳定版本应使用 Tag,获取最新代码使用 main 分支。

2.2 预编译镜像

无定制需求的用户可直接使用预编译组件镜像,无需自行编译。预编译组件由阿里云灵骏官方发布与维护,并提供相应的技术支持;使用过程中遇到问题,也可通过开源仓库 Issue 等渠道反馈解决。

发布镜像仓库为 lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/,各组件预编译镜像的版本对照关系如下:

组件名

镜像名

当前版本 Tag

对应 K8s 版本范围

Device Plugin

lj-runtimekit-device-plugin

v1.13.0

v1.28 / v1.30 / v1.32 / v1.34 / v1.35

说明

以组件Device Plugin,K8s版本v1.35为例,镜像为:lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-device-plugin:1.13.0-k8s1.35

Scheduler Framework

lj-runtimekit-scheduler

Exporter

lj-runtimekit-exporter

Controller / Controller Job Agent

lj-runtimekit-controller
lj-runtimekit-controller-job-agent

注:表中 Controller Job Agent 为随 Controller 部署的节点侧执行镜像(见3.1 组件构成),用户无需单独部署。

3. 部署

3.1 组件构成

组件

职责

部署形态

Controller

监听节点标签变化,自动管理节点 Runtime Kit 功能的启用/禁用

Deployment

Device Plugin

设备发现、资源上报与分配转发

DaemonSet(打标节点)

Scheduler Framework

算力/显存双维度感知调度、拓扑感知调度

Deployment

Exporter

GPU 运行监控与健康检测指标采集

DaemonSet(打标节点)

Controller Job Agent 为 Controller 用于节点功能启用/禁用的节点侧执行镜像,通过 Controller 的 --job-image 参数引用、随 Controller 一并部署,用户无需单独部署或管理;其工作机制见3.5 功能启用与开关。

3.2 部署前置操作

以下操作按顺序执行。

第一步:验证 K8s 集群可用(任一有 kubectl 权限的机器):

kubectl cluster-info
kubectl get nodes

预期结果:集群运行正常。

第二步:验证 GPU 节点环境(每台 GPU 节点):

# 验证加速卡驱动已安装(按设备类型选择)
nvidia-smi    # NVIDIA GPU
ppu-smi       # PPU
rocm-smi      # AMD

# 验证灵骏 Runtime 服务已运行(灵骏裸金属默认已预装)
ls /run/amp/eKitC/xdm/sockets/
# 应返回 socket 文件列表(如 config-daemon.sock)

预期结果:驱动已正常安装,可查询到设备信息。

灵骏容器套件自带兼容 GPU/PPU/AMD 异构设备的容器运行时(已内置,无需用户单独安装),只需确认驱动正常且 socket 文件存在;运行时与 containerd 的注册配置见第五步。

第三步:开启 kubelet 只读端口(10255)(每台 GPU 节点,需 root 权限):

# 检查端口是否已开启
curl -s http://localhost:10255/pods | head -c 100

如未开启,在 kubelet 配置文件(如 /var/lib/kubelet/config.yaml,路径因集群部署方式而异)中设置 readOnlyPort: 10255,随后 systemctl restart kubelet 重启 kubelet 并复验。10255 为只读端口,仅提供查询能力;如集群安全策略不允许开启,请联系集群管理员评估。

第四步:为使用 Runtime Kit 能力的节点打标签:

kubectl label node <node-name> lj_runtimekit_enable=true
kubectl get nodes -l lj_runtimekit_enable=true   # 验证

只有标记了 lj_runtimekit_enable=true 的节点才会运行 Device Plugin 和 Exporter;未打标节点不会部署 Runtime Kit 相关组件,其相关能力也不会打开。该标签同时是功能启用开关,详见3.5 功能启用与开关。

第五步:配置容器运行时(GPU/PPU 设备注入必须):

containerd config.toml 中的 lj-runtime runtime handler 由 Runtime Kit 自动完成配置,用户无需手动修改 config.toml,会在现有 runtimes.nvidia 段之后添加如下配置:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.lj-runtime]
  runtime_type = "io.containerd.runc.v2"
  container_annotations = ["xdm.amp.com*"]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.lj-runtime.options]
  BinaryName = "/usr/local/harp/kitC/xpu-container-runtime"
  SystemdCgroup = true

用户需要在集群中创建对应的 RuntimeClass 资源:

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: lj-runtime
handler: lj-runtime
kubectl apply -f lj-runtime-class.yaml

验证方法:

# 在节点上确认 containerd 已加载该 handler
containerd config dump | grep -A 5 "lj-runtime"

# 确认 RuntimeClass 已创建
kubectl get runtimeclass lj-runtime

后续业务 Pod 须指定 runtimeClassName: lj-runtime,否则 GPU/PPU 设备无法正确注入容器。

第六步(可选):部署 JobSet。当用户集群本身不具备 Gang 调度能力,又需要拓扑感知调度且涉及大批量 Pod 同时启停时,须部署 JobSet。安装方式参考 https://jobset.sigs.k8s.io/docs/installation,建议 v0.8.0。

3.3 一键部署(推荐)

无定制需求的用户建议直接使用预编译镜像,通过以下脚本完成部署。

注意将 <version> 替换为版本对照表中的目标版本 Tag:

export lj_runtimekit_version=<version>

# Device Plugin
crictl pull lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-device-plugin:${lj_runtimekit_version}

# Scheduler Framework
crictl pull lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-scheduler:${lj_runtimekit_version}

# Exporter
crictl pull lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-exporter:${lj_runtimekit_version}

# Controller
crictl pull lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-controller:${lj_runtimekit_version}

# Controller Job Agent
crictl pull lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-controller-job-agent:${lj_runtimekit_version}

./deploy/deploy-all.sh deploy      # 一键部署所有组件
#./deploy/deploy-all.sh undeploy    # 一键卸载所有组件

# 按组件单独部署/卸载
#./deploy/deploy-all.sh deploy --components=device-plugin
#./deploy/deploy-all.sh deploy --components=scheduler
#./deploy/deploy-all.sh deploy --components=exporter
#./deploy/deploy-all.sh deploy --components=controller

如需简单的定制,可以灵活调整上面的脚本,以及调用的脚本,如 deploy-all.sh,详见脚本内注释。

部署脚本支持可重复调用:部署失败后,根据提示修复环境即可直接重复调用尝试。脚本执行全程输出完整操作日志,便于部署后核对与问题排查。

说明

细节待确认:脚本可重复调用与全量日志输出能力正在开发中,具体行为以实际发布版本为准。

3.4 部署验证

部署完成后,按以下步骤逐项验证。

第一步:检查组件运行状态

执行如下命令:

kubectl get pods -n kube-system | grep -E 'lj-runtimekit-device-plugin|lj-runtimekit-scheduler|lj-runtimekit-exporter|lj-runtimekit-controller'

预期结果:

组件

Pod 名称前缀

部署形态

预期数量

正常状态

Device Plugin

lj-runtimekit-device-plugin-ds-

DaemonSet

等于已打 lj_runtimekit_enable=true 标签的节点数

Running,READY 1/1

Scheduler Framework

lj-runtimekit-scheduler-framework-

Deployment

1(默认副本数)

Running,READY 1/1

Exporter

lj-runtimekit-exporter-ds-

DaemonSet

等于已打 lj_runtimekit_enable=true 标签的节点数

Running,READY 1/1

Controller

lj-runtimekit-controller-manager-

Deployment

1(默认副本数)

Running,READY 1/1

判断标准:

  • 所有 Pod 状态均为 Running 且 READY 列为 1/1,表示部署成功。

  • 若 Pod 处于 CrashLoopBackOff,查看日志定位原因:kubectl logs -n kube-system <pod-name>。

  • 若 Pod 处于 Pending 或 Init,检查节点标签与资源是否满足调度条件:kubectl describe pod -n kube-system <pod-name>。

第二步:检查节点资源上报

kubectl describe node <node-name> | grep -E 'aliyun.com|alibabacloud.com'

预期结果(以整卡场景为例):在节点的 Capacity 和 Allocatable 区段中出现加速卡相关的扩展资源,例如:

alibabacloud.com/ppu:     8
aliyun.com/gpu:           8
aliyun.com/gpu-core:      800
aliyun.com/gpu-memory:    1152

判断标准:

  • Capacity 中对应资源数量应与节点实际设备数一致(如 8 卡节点应为 8)。

  • 对于 Device Plugin 上报的扩展资源,Allocatable 数量正常情况下始终等于 Capacity(Pod 的资源占用情况可通过 kubectl describe node 的 Allocated resources 部分查看);若 Allocatable 为 0 但 Capacity 非 0,通常是 修改资源名称后的残留。

  • 若未出现任何扩展资源,说明 Device Plugin 未成功上报,检查 Device Plugin Pod 日志和节点 Runtime 服务状态(socket 文件是否存在)。

第三步:检查 Exporter 指标暴露(在已部署 Exporter 的节点上执行)

# 默认端口 9501,若已通过 Exporter 部署配置修改端口,请替换为实际值
curl -s localhost:9501/metrics | head -20

预期结果:返回 Prometheus 格式的指标文本(以 # HELP 和 # TYPE 开头的行)。

判断标准:

  • 能获取到指标文本,说明 Exporter 正常工作。

  • 若连接被拒绝(Connection refused),检查 Exporter Pod 是否正常运行,并确认端口是否一致。

3.5 功能启用与开关

节点 Runtime Kit 功能的启用/禁用由 Controller 根据节点标签自动管理:为节点添加 lj_runtimekit_enable=true 标签时,Controller 自动在该节点触发功能启用操作,节点移除时功能随之自动禁用。具体机制为:Controller 自动创建 K8s Job,在目标节点上运行 Controller Job Agent 镜像完成上述操作,完成后 Job 自动清理。注意在新增节点时打上标签。开关操作的影响如下:

影响项

说明

切换耗时

约 1 分钟

新 Pod 调度

切换期间暂时无法派发新的 GPU Pod

运行中 Pod

不受影响,已分配的 GPU 继续正常使用

监控数据

Exporter 短暂中断,监控图表可能出现 1–2 分钟数据缺失

组件升级和功能开关操作建议在业务低谷期执行。

3.6 进阶部署与定制

本节面向需要按组件部署、自行构建镜像或基于开源代码定制的用户。

执行部署前,需将组件镜像编译并推送到集群可访问的镜像仓库。各组件源码目录均支持 make docker 构建镜像,构建完成后推送至集群节点可拉取的仓库,并确保部署清单中配置的镜像名称与 Tag 与实际构建产物一致。各组件部署文件:

组件

职责

部署文件路径

Device Plugin

设备发现、资源上报与分配转发

deploy/deviceplugin/03-daemonset.yaml

Scheduler

算力/显存双维度感知调度、拓扑感知调度

deploy/scheduler/03-deployment.yaml

Exporter

GPU 运行监控与健康检测指标采集

deploy/deviceplugin/03-daemonset.yaml

Controller

监听节点标签变化,自动管理节点 Runtime Kit 功能的启用/禁用

deploy/controller/02-deployment.yaml

例如,Device Plugin 的部署文件位于 deploy/deviceplugin/03-daemonset.yaml,其中镜像配置:

containers:
- name: lj-runtimekit-device-plugin
  image: "<your-registry>/lj-runtimekit-device-plugin:<tag>"

如仅需修改扩展资源名、节点标签 key、annotation key 等配置项而不涉及代码逻辑变更,可直接编辑各组件部署清单中的配置(ConfigMap)后重新部署,无需重新编译镜像,方法详见3. 部署衔接。

4. 版本号体系与版本对应关系

4.1 版本号格式

Runtime Kit 采用统一版本号体系,格式为 v{大版本}.{功能版本}.{迭代版本}(如 v1.13.0)。

升级判断标准:用户升级后,在不修改任何配置/YAML 的前提下,原有行为是否发生变化——迭代版本升级不改变用户可见行为;功能版本可能引入新功能或行为变更;大版本可能包含不兼容变更,升级前须评估。

4.2 Runtime 版本与开源组件版本

Runtime 版本:自 1.13.0 版本起支持开源组件对接。

开源组件版本:与 Runtime 版本保持跟随对应。

5. 版本兼容说明

5.1 兼容政策

Runtime 与开源组件之间的 gRPC 接口承诺只增不改、向后兼容:接口仅做增量演进(新增接口与字段),不改变已有接口与字段语义。

若后续因特殊原因确需引入不兼容变更,该变更一定以大版本升级的形式发布,并在版本发布说明中显著标注;反之,大版本升级不一定包含不兼容变更,用户以对应版本的发布说明为准。

5.2 兼容结论

由上述政策可得:

  1. 同一大版本内,自 1.13.0 版本开始,任意版本的开源组件与任意版本的 Runtime 均可配合使用;

  2. Runtime 升级不会破坏已部署的组件,用户无需因兼容性原因执行任何升级;

  3. 基于历史版本 proto 二次开发的实现,在 Runtime 升级后可继续正常工作;

  4. 发生大版本升级时,用户应查阅版本发布说明,确认是否涉及不兼容变更并评估后再升级。

5.3 组件之间的版本依赖

开源组件之间不存在强版本绑定:组件向下通过统一 gRPC 接口对接 Runtime,向上通过 K8s 标准扩展机制(Device Plugin 框架、Scheduler Framework、Prometheus 指标协议)对接集群,不同版本的组件原则上可配合使用。

由于新功能通常需要 Runtime 与多个组件协同支撑,新功能对 Runtime 与整套组件设定统一的最低版本要求,详见第 6 章。

6. 功能最低版本要求

基线能力(整卡分配、时分算力/显存切分、基础监控等)自 1.13.0 版本起即具备,无额外版本要求。增量功能存在最低版本要求,规则如下:

用户使用某一功能前,须确认 Runtime 版本及所有配套开源组件版本均不低于该功能对应的最低版本。由于开源组件以统一版本号发布,该要求等价于 Runtime 版本与开源组件版本同时满足下表要求。

功能

Runtime 最低版本

开源组件最低版本

GPU 时分算力切分(TDM)

1.13.0

1.13.0

MIG 空分(动态实例管理)

拓扑感知调度(PPU)

健康监测 / 微感检测

注:版本不满足时仅该功能不可用,不影响已有功能的正常使用。

7. 升级说明

7.1 升级场景

版本兼容性不强制用户升级。升级仅发生于以下两种场景:

  1. 使用新功能:按第 6 章将 Runtime 与开源组件升级至对应最低版本(含)以上;

  2. 问题修复:已知问题在新版本中修复后,升级至包含修复的版本。

7.2 Runtime 升级

Runtime 升级对用户透明:用户无需关注升级的具体方式,如有需要请对接阿里云灵骏 PDSA、SRE 发起,按阿里云灵骏内部流程执行。

升级窗口影响:Runtime 升级期间,节点上的 gRPC 服务短暂不可用,依赖该接口的操作(新 GPU 资源分配、监控数据采集等)在此期间暂不可用,已完成资源分配的运行中任务不受影响。建议将升级操作安排在业务低谷期执行。

7.3 开源组件升级

各 K8s 组件(Device Plugin、Scheduler、Exporter、Controller)均以 DaemonSet/Deployment 形式部署,支持 K8s 原生滚动更新,逐节点升级对已有 Pod 无影响。

使用方式

升级方式

预编译组件

直接更新至目标版本;组件支持 K8s 原生滚动更新,Device Plugin 与 Exporter 逐节点升级对已有 Pod 无影响

二次开发实现

用户自行维护;如需使用新功能,按新版 proto 重新生成 stub 并适配

升级步骤(预编译组件):

  • 确认目标版本对应的镜像 Tag。

  • 修改一键部署目录中对应组件 YAML 的 image 字段为目标版本(如 deploy/deviceplugin/02-daemonset.yaml、deploy/scheduler/03-deployment.yaml 等)。

  • 升级 Controller 时,需同步将其 --job-image 参数引用的 Controller Job Agent 镜像更新至目标版本。

  • 执行一键部署脚本部署对应单个组件或全部组件。

  • 验证新版本 Pod 是否正常运行。

# 1. 修改对应组件 YAML 中的镜像版本(以 Device Plugin 为例)
# 编辑 deploy/deviceplugin/03-daemonset.yaml,将 image 字段改为目标版本
# image: lj-runtimekit-registry.cn-hangzhou.cr.aliyuncs.com/lj-runtimekit/lj-runtimekit-device-plugin:<new-version>

# 2. 部署单个组件
./deploy/deploy-all.sh deploy --components=device-plugin

# 或部署全部组件
./deploy/deploy-all.sh deploy

# 3. 验证滚动更新结果
kubectl rollout status daemonset/lj-runtimekit-device-plugin -n kube-system
kubectl get pods -n kube-system -l app=lj-runtimekit-device-plugin -o wide

回滚:

若新版本异常,将对应组件 YAML 中 image 字段的 Tag 改回原版本,重新执行一键部署脚本即可回滚。

7.4 升级责任划分

对象

责任划分

Runtime 包

阿里云灵骏团队负责发布与迭代,升级按内部流程执行

预编译组件

阿里云灵骏发布版本,用户直接更新

二次开发实现

用户自行维护

节点侧底层组件包(RPM)由阿里云灵骏统一推送,用户无需手动操作。

常见问题

Q1:资源分配失败,Pod 一直 Pending,报 Insufficient 资源

可能原因:集群无满足要求的节点、节点标签缺失、Device Plugin 未上报。处理:检查目标节点是否已打 lj_runtimekit_enable=true 标签;查看 Device Plugin 日志确认资源上报状态。

Q2:节点标签已设置 lj_runtimekit_enable=true,但功能未启用

排查步骤:

  1. 确认 Controller Pod 正常运行;

  2. 查看 Controller 日志是否检测到标签变化;

  3. 检查是否创建了对应的 Job;

  4. 查看 Job Agent 执行日志(kubectl logs -n kube-system job/lj-agent-<node-name>-<enable|disable>,namespace 默认 kube-system);

  5. 确认节点上 config-daemon socket 存在:ls /run/amp/eKitC/xdm/sockets/config-daemon.sock。

注意:成功的 Job 完成后由 Controller 自动删除,若对应 Job 已不存在,说明操作已成功完成,可通过节点 annotation lj-runtimekit-controller/last-action-status 或 Controller 日志中的 ActionSucceeded 事件确认结果;失败的 Job 会保留,可按第 4 步命令查看日志。

Q3:组件日志连续出现 EOF 或 connection reset

可能原因:节点核心服务重启、socket 文件被误删、客户端未实现重连。处理:检查核心服务进程和 socket 状态;客户端应实现指数退避重连(建议起始 1s、倍数 2、上限 30s)。

日志位置

组件

日志位置

Runtime 核心服务

/var/log/harp/ 目录下对应日志文件

Device Plugin

kubectl logs -n kube-system <dp-pod>

Scheduler Framework

kubectl logs -n kube-system <sched-pod>

Exporter

kubectl logs -n kube-system <exporter-pod>

Controller

kubectl logs -n kube-system <controller-pod>

Controller Job Agent

kubectl logs -n kube-system job/lj-agent-<node-name>-<enable|disable>(失败 Job 保留供查日志;成功 Job 完成后由 Controller 自动删除,见 Q2)