Ascend Docker Runtime v26.0.1 系统级架构分析

基于源码的深度架构剖析
分析日期:2026-07-26
代码规模:13个Go源文件 + C/Shell辅助组件,约8,436行核心Go代码
项目路径:component/ascend-docker-runtime


目录


第一章:项目整体架构

1.1 项目概述

Ascend Docker Runtime 是华为昇腾(Ascend) NPU 的容器化运行时插件,基于 OCI 标准实现,为 AI 训练/推理作业提供 NPU 容器化支持。它不修改 Docker 引擎,而是以插件方式在 runc 启动容器过程中注入 NPU 设备。

功能 说明
NPU 设备挂载 根据 ASCEND_VISIBLE_DEVICES 将对应 NPU 设备挂载到容器 namespace
设备 cgroup 配置 在 Host 上配置 device cgroup,确保容器只使用指定 NPU
CANN 运行时库挂载 将 Host 上的 CANN Runtime Library 挂载到容器
vNPU 虚拟化 支持虚拟设备(vdavinci)切分与创建
Prestart Hook 在容器 created→running 过渡期执行设备注入
安装/卸载 自动修改 Docker/containerd 配置文件

1.2 整体设计思路

多后端抽象

DcDriverV1

Ascend 910/310 旧版

DcDriverV2

Ascend 910B/A5 新版

Hook 机制

Prestart Hook

容器 namespace 已创建

但作业未启动

挂载设备 + 配置 cgroup

挂载 CANN 库

核心设计

OCI 标准兼容

不修改 Docker 引擎

作为 Docker Runtime 插件

在 runc 前拦截 config.json

修改 OCI Spec 注入 NPU 设备

执行 runc 完成容器创建

1.3 整体运行流程

Docker/Containerd 收到容器创建请求

调用 ascend-docker-runtime

runtime/main.go 启动

命令是 create?

直接 exec runc 透传

读取 config.json OCI Spec

解析 ASCEND_VISIBLE_DEVICES

需要 NPU 设备?

直接 exec runc

获取 NPU Worker
V1或V2驱动

注入 Prestart Hook 到 Spec

创建虚拟设备 vNPU
如果 VIRTUAL 模式

挂载 davinci 设备到 Spec

挂载管理设备到 Spec

添加 device cgroup 规则

写入修改后的 config.json

exec runc 创建容器

runc 触发 Prestart Hook

hook/main.go 执行

解析挂载配置列表

调用 ascend-docker-cli 挂载文件/目录

容器启动,NPU 可用

1.4 系统整体架构图

底层

安全工具

install

ascend-docker-cli (C语言)

ascend-docker-hook

ascend-docker-runtime

容器运行时

create

修改Spec+注入Hook

Prestart Hook

exec

挂载设备

修改

Docker/Containerd

runc

runtime/main.go
运行时入口

runtime/process
Spec修改+设备注入

runtime/dcmi
NPU设备管理

hook/main.go
Hook入口

hook/process
挂载配置解析

cli/src/main.c
实际挂载执行

install/main.go
安装/卸载

install/process
配置修改

mindxcheckutils
路径/文件校验

libdcmi.so
设备管理接口

NPU 硬件
davinci0-N

1.5 技术栈概览

依赖 用途
github.com/opencontainers/runtime-spec OCI 运行时规范
github.com/containerd/containerd containerd 配置解析
github.com/pelletier/go-toml TOML 配置文件解析
ascend-common 华为昇腾公共库(api/工具)
libdcmi.so (CGO) NPU 设备管理 C 库
hwlog 华为日志库

第二章:子模块划分

2.1 运行时入口 (runtime/)

核心作用:作为 Docker Runtime 插件入口,拦截容器创建请求,修改 OCI Spec 注入 NPU 设备,然后透传给 runc。

args

+string bundleDirPath

+string cmd

process

+DoProcess() : error

-getArgs()(*args, error)

-modifySpecFile(path) : error

-execRunc() : error

-addDevice(w, spec, devices) : error

-addHook(w, spec, devices) : error

-addManagerDevice(w, spec) : error

-checkVisibleDevice(spec)([]int, error)

-addAscendDockerEnv(spec)

main

+main()

DoProcess

cmd == create?

execRunc 透传

获取 bundle 路径

读取 config.json

checkVisibleDevice
解析 ASCEND_VISIBLE_DEVICES

设备列表为空?

addAscendDockerEnv
直接 exec runc

GetMatchingNpuWorker
选择V1/V2驱动

addHook
注入 Prestart + Poststop Hook

addDevice
挂载 davinci 设备

addManagerDevice
挂载管理设备

addUBDevice
挂载UB设备

写入 config.json

execRunc

关键文件 核心函数/方法 作用
runtime/main.go main() 入口,初始化日志,调用 DoProcess
runtime/process/process.go DoProcess() 主流程:拦截create命令,修改Spec,exec runc
runtime/process/process.go modifySpecFile() 读取→修改→写回 config.json
runtime/process/process.go checkVisibleDevice() 解析 ASCEND_VISIBLE_DEVICES 环境变量
runtime/process/process.go addDevice() 挂载 davinci/vdavinci 设备到 Spec
runtime/process/process.go addManagerDevice() 根据芯片类型挂载管理设备
runtime/process/process.go addHook() 注入 Prestart Hook 和 Poststop Hook
runtime/process/process.go GetDeviceTypeByChipName() 根据芯片名获取设备类型
runtime/process/process.go parseDevices() 解析设备ID列表(支持范围"0-3"和单个"0,1,2")
runtime/process/process.go execRunc() 查找并执行 runc/docker-runc

2.2 DCMI 设备管理模块 (runtime/dcmi/)

核心作用:封装 NPU 设备管理接口,通过 CGO 调用 libdcmi.so,提供设备查询、虚拟设备创建/销毁能力。

«interface»

WorkerInterface

+Initialize() : error

+ShutDown()

+CreateVDevice(uniqueID int32, coreNum string)(VDeviceInfo, error)

+DestroyVDevice(uniqueID int32, vDevID int32) : error

+GetProductType()(string, error)

+GetChipName()(string, error)

«interface»

DcDriverV1Interface

+DcInitialize() : error

+DcShutDown()

+DcGetCardList()(int32, []int32, error)

+DcGetDeviceNumInCard(cardID)(int32, error)

+DcGetDeviceLogicID(card, device)(int32, error)

+DcGetProductType(card, device)(string, error)

+DcCreateVDevice(card, device, coreNum)(int32, error)

+DcDestroyVDevice(card, device, vDevID) : error

+DcGetChipInfo(card, device)(*ChipInfo, error)

«interface»

DcDriverV2Interface

+DcInitialize() : error

+DcShutDown()

+DcGetDeviceList()(int32, []int32, error)

+DcCreateVDevice(deviceID, coreNum)(int32, error)

+DcDestroyVDevice(deviceID, vDevID) : error

+DcGetChipInfo(deviceID)(*ChipInfo, error)

NpuV1Worker

+driver DcDriverV1Interface

+cardID int32

+deviceID int32

NpuV2Worker

+driver DcDriverV2Interface

+deviceID int32

DcV1Manager

-nvmllib nvml.Interface

DcV2Manager

-nvmllib nvml.Interface

VDeviceInfo

+int32 VdeviceID

+int32 CardID

+int32 DeviceID

ChipInfo

+string ChipName

+string ChipType

V1 旧版

V2 新版

GetMatchingNpuWorker

检测驱动版本

NpuV1Worker
+DcV1Manager

NpuV2Worker
+DcV2Manager

Initialize: DcInitialize

Initialize: DcInitialize

FindDevice
遍历Card+Device

DcGetDeviceList
直接获取设备列表

GetChipName
DcGetChipInfo

GetProductType
DcGetProductType

CreateVDevice
切分虚拟设备

返回 VDeviceInfo

关键文件 核心类型/函数 作用
dcmi.go WorkerInterface 接口 NPU Worker 统一接口
dcmi.go NpuV1Worker V1驱动实现(Ascend 910/310)
dcmi.go NpuV2Worker V2驱动实现(Ascend 910B/A5)
dcmi.go GetMatchingNpuWorker() 工厂函数,选择V1/V2
dcmi.go ChipInfo 芯片信息结构体
dcmi_api.go VDeviceInfo 虚拟设备信息
dcmi_api.go CreateVDevice() 创建虚拟设备顶层API
dcmi_api.go extractVpuParam() 从OCI Spec提取vNPU参数
dcManager.go DcV1Manager V1 CGO调用封装
dcManager.go DcV2Manager V2 CGO调用封装
dcManager.go DcGetCardList() 获取NPU卡列表
dcManager.go DcGetChipInfo() 获取芯片信息
dcManager.go DcCreateVDevice() CGO创建虚拟设备
dcManager.go DcDestroyVDevice() CGO销毁虚拟设备

2.3 Hook 模块 (hook/)

核心作用:OCI Prestart Hook 实现,在容器 namespace 已创建但作业未启动时,解析挂载配置并调用 CLI 执行实际挂载。

hook/main.go 启动

InitLogModule 日志初始化

StringChecker 安全校验

DoPrestartHook

getContainerConfig
从stdin读取OCI State

getValueByKey
检查 ASCEND_VISIBLE_DEVICES

visibleDevices 为空?

直接返回 不处理

parseMounts
解析 ASCEND_RUNTIME_MOUNTS

readConfigsOfDir
读取 /etc/ascend-docker-runtime.d/

addUBMount
添加HCCL+Topo

parseRuntimeOptions
解析 NODRV/VIRTUAL

parseSoftLinkMode
解析软链接模式

查找 ascend-docker-cli

组装 CLI 参数

syscall.Exec
执行 CLI 挂载

关键文件 核心函数/方法 作用
hook/main.go main() Hook入口,安全校验+调用DoPrestartHook
hook/process/process.go DoPrestartHook() 主逻辑:解析配置→调用CLI挂载
hook/process/process.go getContainerConfig() 从stdin读取OCI State,解析config.json
hook/process/process.go parseMounts() 解析 ASCEND_RUNTIME_MOUNTS 环境变量
hook/process/process.go readConfigsOfDir() 读取配置目录下的 .list 文件
hook/process/process.go parseRuntimeOptions() 解析 NODRV/VIRTUAL 选项
hook/process/process.go addUBMount() 添加UB挂载(hccl_rootinfo + topo)

2.4 安装模块 (install/)

核心作用:安装/卸载 ascend-docker-runtime,自动修改 Docker daemon.json 或 containerd config.toml。

docker/isula

containerd

add

rm

cgroup v2

cgroup v1

add

rm

install/main.go

参数校验

场景判断

DockerProcess

ContainerdProcess

action

读取 daemon.json

读取 daemon.json

addDockerDaemon
添加 ascend runtime

rmDockerDaemon
删除 ascend runtime

设置 default-runtime

写入 daemon.json

cgroup 版本

changeCgroupV2BinaryNameConfig
修改 BinaryName

action

changeCgroupV1RuntimeConfig
修改 runtime 路径

恢复默认 runc

changeCgroupV1RuntimeTypeConfig
修改 runtime_type

写入 config.toml

关键文件 核心函数/方法 作用
install/main.go main() 安装入口,参数校验,分发到Docker/Containerd处理
install/process/common.go CheckParamLength() 参数数量校验
install/process/constant.go 常量定义 命令长度、位置索引、场景名等
install/process/docker_process.go DockerProcess() 修改Docker daemon.json
install/process/docker_process.go addDockerDaemon() 添加ascend runtime配置
install/process/docker_process.go rmDockerDaemon() 移除ascend runtime配置
install/process/docker_process.go loadOriginJson() 读取原始daemon.json
install/process/containerd_process.go ContainerdProcess() 修改containerd config.toml
install/process/containerd_process.go editContainerdConfig() 编辑containerd配置
install/process/containerd_process.go changeCgroupV2BinaryNameConfig() cgroup v2配置
install/process/containerd_process.go changeCgroupV1Config() cgroup v1配置

2.5 安全检查模块 (mindxcheckutils/)

核心作用:提供路径安全校验、文件信息检查、字符串白名单过滤等安全工具函数。

mindxcheckutils

+CheckPath(path, allowLink) : error

+CheckFileInfo(file, size) : error

+RealFileChecker(path, checkParent, allowLink, size)(string, error)

+RealDirChecker(path, checkParent, allowLink)(string, error)

+FileChecker(path, allowDir, checkParent, allowLink, deep)(bool, error)

+StringChecker(text, minLen, maxLen, whiteList) : bool

+GetLogPrefix()(string, error)

+ChangeRuntimeLogMode(prefix) : error

关键文件 核心函数 作用
mindxcheckutils.go RealFileChecker() 文件路径安全校验(防软链接攻击)
mindxcheckutils.go RealDirChecker() 目录路径安全校验
mindxcheckutils.go FileChecker() 递归文件检查(深度限制)
mindxcheckutils.go StringChecker() 字符串白名单过滤(防注入)
mindxcheckutils.go CheckFileInfo() 文件大小检查
mindxcheckutils.go ChangeRuntimeLogMode() 日志文件权限修改

2.6 CLI 工具 (cli/) — C语言实现

核心作用:实际执行文件/目录挂载到容器 namespace 的 C 语言工具,被 Hook 调用。

cli/src (C语言)

main.c
入口

u_mount.c
挂载逻辑

options.c
参数解析

ns.c
namespace操作

cgrp.c
cgroup配置

utils.c
工具函数

logger.c
日志

2.7 Destroy 工具 (destroy/) — C语言实现

核心作用:Poststop Hook 执行器,容器停止时销毁虚拟设备。

destroy/src/main.c

读取参数
cardID, deviceID, vDevID

调用 dcmi 销毁vDevice

清理资源


第三章:模块调用关系

3.1 模块依赖关系图

外部

工具层

设备层

处理层

入口层

exec

exec

注入Poststop

runtime/main.go

hook/main.go

install/main.go

runtime/process

hook/process

install/process

runtime/dcmi

libdcmi.so
CGO

mindxcheckutils

hwlog
日志库

ascend-common/api
常量定义

runc

ascend-docker-cli
C语言

ascend-docker-destroy
C语言

3.2 容器创建主流程时序图

ascend-docker-cli hook/main.go runc dcmi runtime/process runtime/main.go Docker ascend-docker-cli hook/main.go runc dcmi runtime/process runtime/main.go Docker alt [VIRTUAL模式] alt [需要 NPU] create --bundle /path DoProcess() getArgs() 解析参数 读取 config.json checkVisibleDevice() 解析设备列表 GetMatchingNpuWorker() 选择V1/V2驱动 GetChipName() 获取芯片类型 addHook() 注入Prestart+Poststop CreateVDevice() 创建虚拟设备 updateEnvAndPostHook() addDevice() 挂载davinci设备 addManagerDevice() 挂载管理设备 addUBDevice() 挂载UB设备 写回 config.json exec runc create 触发 Prestart Hook DoPrestartHook() 解析挂载配置 .list文件 exec ascend-docker-cli --mount-file ... --mount-dir ... 挂载设备文件+目录到容器namespace 配置device cgroup 容器创建完成,NPU可用

3.3 安装流程时序图

文件系统 ContainerdProcess DockerProcess install/main.go 用户/脚本 文件系统 ContainerdProcess DockerProcess install/main.go 用户/脚本 alt [add] [rm] alt [cgroup v2] [cgroup v1] alt [Docker场景] [Containerd场景] add/rm <args> 参数校验 CheckParamLength DockerProcess(command) 读取 daemon.json addDockerDaemon() 设置 default-runtime=ascend rmDockerDaemon() 删除 default-runtime 写入 daemon.json ContainerdProcess(command) 读取 config.toml editContainerdConfig() changeCgroupV2BinaryNameConfig() changeCgroupV1RuntimeConfig() changeCgroupV1RuntimeTypeConfig() 写入 config.toml

3.4 vNPU 虚拟设备创建流程

V1

V2

检测到 VIRTUAL 选项

extractVpuParam
从Spec提取切分参数

参数有效?

返回错误

Worker.CreateVDevice

Worker版本

DcV1Manager.DcCreateVDevice
CGO: 指定card+device

DcV2Manager.DcCreateVDevice
CGO: 指定deviceID

返回 vDevID

updateEnvAndPostHook

更新ASCEND_RUNTIME_OPTIONS
追加VIRTUAL标记

注入Poststop Hook
销毁vDevice

更新deviceIdList
改为vDeviceID

3.5 数据流描述

设备发现数据流
ASCEND_VISIBLE_DEVICES环境变量 → getValueByDeviceKey()parseDevices()/parseAscendDevices() → 设备ID列表 → GetMatchingNpuWorker() → NPU Worker → GetChipName() → 芯片类型

设备注入数据流
设备ID列表 → addDevice()/dev/davinci{N}oci.DeviceFromPath() → Spec.Linux.Devices → Spec.Linux.Resources.Devices(cgroup) → 写入config.json → runc读取并创建设备

Hook挂载数据流
runc触发Prestart → hook/main.go → stdin读取OCI State → 解析config.json → 读取 /etc/ascend-docker-runtime.d/base.list → 组装CLI参数 → syscall.Exec(ascend-docker-cli) → CLI挂载文件/目录到容器namespace


第四章:架构设计总结

4.1 设计模式总结

安全防御

mindxcheckutils

路径校验防软链接攻击

文件大小限制

字符串白名单过滤

递归深度限制

Hook模式

Prestart Hook

容器namespace已创建

挂载设备+配置cgroup

Poststop Hook

容器停止

销毁vDevice

拦截器模式

ascend-docker-runtime

拦截create命令

修改OCI Spec

透传给runc

工厂模式

V1

V2

GetMatchingNpuWorker

驱动版本检测

创建NpuV1Worker

创建NpuV2Worker

策略模式

运行时选择

WorkerInterface

NpuV1Worker
旧版驱动策略

NpuV2Worker
新版驱动策略

GetMatchingNpuWorker

4.2 关键设计决策

决策 原因 实现
不修改Docker引擎 保持与Docker原生兼容,升级无感知 OCI Runtime插件方式
Prestart Hook挂载 namespace已创建但作业未启动,安全窗口 OCI Spec注入Hook
V1/V2双驱动 新旧NPU硬件驱动接口不同 WorkerInterface策略模式
C语言CLI 挂载操作需要直接系统调用,C更高效 hook通过exec调用C CLI
安全检查模块 防止路径穿越、软链接攻击、注入攻击 mindxcheckutils统一校验
config.json修改 OCI标准方式,runc自动读取 读取→修改→写回
Poststop Hook vNPU虚拟设备需要销毁,避免资源泄漏 destroy C程序

4.3 扩展性分析

扩展点 机制 示例
新增NPU芯片类型 扩展 GetDeviceTypeByChipName() Ascend 910 → 910B → A5
新增驱动版本 实现 WorkerInterface V1 → V2
新增挂载配置 添加 .list 文件到配置目录 base.list + 自定义.list
新增运行时选项 扩展 validRuntimeOptions NODRV, VIRTUAL
新增容器运行时 扩展 install/process Docker, Containerd, iSula
新增管理设备 扩展 managerDevicesMap 芯片特定设备列表

4.4 架构特点总结

  1. OCI标准兼容:完全基于OCI标准实现,不侵入Docker/containerd引擎
  2. 分层设计:入口层(main) → 处理层(process) → 设备层(dcmi) → 底层(CGO/C库)
  3. 安全优先:所有外部输入都经过 mindxcheckutils 安全校验
  4. 多版本兼容:V1/V2双驱动策略,支持新旧NPU硬件
  5. 声明式配置:通过 .list 文件声明挂载列表,非硬编码
  6. Go+C混合实现:Go处理业务逻辑,C处理底层挂载操作
Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐