已关闭
[Feature]: Ascend Docker Runtime安装易用性提升 #232
weihaoran创建于  4月28日关闭于  7月24日
weihaoran成员
4月28日 创建

提交提案之前,请先检索仓库内是否已有相同的提案,如已有请在同一提案中进行讨论。

💻 需求背景、当前现状、期望实现的功能内容、具体的设计方案、以及测试方案

需求背景
随着容器技术的发展,越来越多的用户选择使用containerd作为容器运行时。为了满足用户在containerd环境下使用Ascend Docker Runtime的需求,需要对containerd场景下的配置方式进行优化,确保Ascend Docker Runtime能够无缝集成到containerd生态系统中。

当前现状
Ascend Docker Runtime在containerd场景下存在以下问题:
当前是根据cgroup版本来指定containerd应该使用哪个shim 程序来管理容器的生命周期。
但是这种判断方式和cgroup版本是强耦合的,而且是不准确的,该配置和containerd的版本相关。
遇到的问题:例如,对于openEuler的24.03版本,虽然cgroup为v1版本,实际管理容器的shim应该参照cgroup为v2版本时的配置来选择。

期望实现的功能内容
简化配置,提升配置的准确性。

具体的设计方案
读取并继承runc运行时的配置参数,将这些参数赋值给即将添加的ascend运行时。确保ascend运行时与节点上已有的runc行为一致,避免出错。
同时,支持多版本containerd,自动适配不同版本的containerd配置格式(v1/v2/v3)。


1. 概述

1.1 简介

本提案针对 Ascend Docker Runtime 在 containerd 场景下的配置方式进行优化。核心目标是消除当前基于 cgroup 版本判断 shim 程序的强耦合问题,改为读取并继承 runc 运行时的配置参数,确保 ascend 运行时与节点上已有的 runc 行为一致,同时支持多版本 containerd 配置格式的自动适配(v1/v2/v3)。

1.2 动机

随着容器技术的发展,越来越多的用户选择使用 containerd 作为容器运行时。为了满足用户在 containerd 环境下使用 Ascend Docker Runtime 的需求,需要对 containerd 场景下的配置方式进行优化,确保 Ascend Docker Runtime 能够无缝集成到 containerd 生态系统中。

当前 Ascend Docker Runtime 在 containerd 场景下存在以下痛点:

  1. cgroup 版本强耦合:当前根据 cgroup 版本来指定 containerd 应该使用哪个 shim 程序来管理容器的生命周期,这种判断方式和 cgroup 版本是强耦合的,而且是不准确的。
  2. 配置与 containerd 版本相关:shim 的选择实际上与 containerd 的版本相关,而非 cgroup 版本,当前逻辑无法准确反映这一关系。
  3. 特定发行版兼容性问题:例如 openEuler 24.03 版本,虽然 cgroup 为 v1 版本,但实际管理容器的 shim 应该参照 cgroup 为 v2 版本时的配置来选择,当前逻辑无法处理此类场景。
  4. 配置复杂度高:用户需要了解 cgroup 版本和 shim 的对应关系,增加了配置出错的风险。

不做此提案的影响:用户在特定操作系统(如 openEuler 24.03)上使用 containerd + Ascend Docker Runtime 时,会因 shim 配置错误导致容器无法正常启动或运行异常,严重影响用户体验和产品可用性。

1.3 目标

目标:

  • 简化 containerd 场景下 Ascend Docker Runtime 的配置方式,提升配置准确性
  • 读取并继承 runc 运行时的配置参数,确保 ascend 运行时与节点上已有的 runc 行为一致
  • 支持多版本 containerd 配置格式的自动适配(v1/v2/v3)
  • 消除基于 cgroup 版本判断 shim 的强耦合逻辑

非目标:

  • 不改变 Docker 场景下的配置方式
  • 不涉及 containerd 本身的代码修改
  • 不支持非 runc 作为默认运行时的 containerd 环境

2. 用例分析

用例 1:openEuler 24.03 + containerd 环境

功能点:

  • 在 cgroup v1 但实际应使用 v2 shim 的场景下,自动正确配置 ascend 运行时
  • 无需用户手动判断和修改配置

关键性能指标:

  • 配置准确性:100%
  • 配置生成时间:< 1秒

可靠性要求:

  • 配置生成后容器可正常启动
  • 与 runc 运行时行为一致

用例 2:多版本 containerd 自动适配

功能点:

  • 自动识别 containerd 配置格式版本(v1/v2/v3)
  • 根据不同版本生成对应格式的 ascend 运行时配置

约束:

  • 需兼容 containerd 1.x、1.6+、1.7+、2.x 等主流版本
  • 配置格式变更不影响已有 runc 运行时配置

用例 3:继承 runc 运行时配置

功能点:

  • 读取 containerd 配置中 runc 运行时的 shim、runtime 等参数
  • 将这些参数赋值给 ascend 运行时
  • 确保 ascend 运行时与 runc 运行时使用相同的 shim 程序

可靠性要求:

  • 继承的参数与 runc 运行时完全一致
  • 不遗漏关键配置项

3. 方案设计

3.1 总体方案

核心设计思路:放弃基于 cgroup 版本判断 shim 的方式,改为读取并继承 containerd 配置中 runc 运行时的配置参数,将这些参数赋值给 ascend 运行时。这样无论底层 cgroup 版本如何,ascend 运行时都能与节点上已有的 runc 行为保持一致,从根本上解决 cgroup 版本强耦合问题。

方案架构:

┌─────────────────────────────────────────────────────────────┐
│                  Containerd 配置文件                         │
│                                                              │
│  [plugins."io.containerd.grpc.v1.cri".containerd]           │
│    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]│
│      [plugins."io.containerd.grpc.v1.cri".containerd        │
│       .runtimes.runc]                                       │
│        runtime_type = "io.containerd.runc.v2"               │
│        runtime_engine = ""                                   │
│        runtime_root = ""                                     │
│                                                              │
│      [plugins."io.containerd.grpc.v1.cri".containerd        │
│       .runtimes.ascend]    ◄── 新增,继承 runc 配置          │
│        runtime_type = ← 继承自 runc                          │
│        runtime_engine = "/usr/bin/ascend-docker-runtime"    │
│        runtime_root = ← 继承自 runc                          │
└─────────────────────────────────────────────────────────────┘

配置生成流程:

读取 containerd 配置文件
        │
        ▼
识别配置格式版本 (v1/v2/v3)
        │
        ▼
解析 runc 运行时配置
        │
        ▼
提取关键参数 (runtime_type, runtime_root 等)
        │
        ▼
生成 ascend 运行时配置(继承 runc 参数 + 替换 runtime_engine)
        │
        ▼
写入 containerd 配置文件
        │
        ▼
重启 containerd 服务

3.2 技术选型

方案 优势 劣势 选择结果
方案A:继承 runc 运行时配置 与 runc 行为一致,无需判断 cgroup 版本,配置准确 依赖 runc 运行时已正确配置 ✅ 选择
方案B:基于 containerd 版本判断 比基于 cgroup 版本更准确 需要维护 containerd 版本与 shim 的映射表,版本更新需同步 ❌ 放弃
方案C:用户手动配置 实现简单 用户体验差,容易出错,无法解决核心问题 ❌ 放弃

选择理由:方案A从根本上解决了 cgroup 版本强耦合问题,通过继承 runc 配置确保行为一致性,且无需维护额外的版本映射关系,实现简洁可靠。

3.3 功能与性能设计

3.3.1 containerd 配置格式识别

containerd 存在多种配置格式版本,需要自动识别并适配:

v1 格式(containerd 1.x):

[plugins.cri.containerd.runtimes.runc]
  type = "io.containerd.runc.v2"
  engine = ""
  root = ""

[plugins.cri.containerd.runtimes.ascend]
  type = "io.containerd.runc.v2"
  engine = "/usr/bin/ascend-docker-runtime"
  root = ""

v2 格式(containerd 1.6+):

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  runtime_type = "io.containerd.runc.v2"
  runtime_engine = ""
  runtime_root = ""

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.ascend]
  runtime_type = "io.containerd.runc.v2"
  runtime_engine = "/usr/bin/ascend-docker-runtime"
  runtime_root = ""

v3 格式(containerd 2.x):

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  runtime_type = "io.containerd.runc.v2"
  runtime_path = ""
  options = {}

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.ascend]
  runtime_type = "io.containerd.runc.v2"
  runtime_path = "/usr/bin/ascend-docker-runtime"
  options = {}

3.3.2 runc 配置继承逻辑

核心实现:

// RuntimeConfig 运行时配置结构
type RuntimeConfig struct {
    RuntimeType   string // runtime_type: shim 程序标识
    RuntimeEngine string // runtime_engine: 运行时引擎路径
    RuntimeRoot   string // runtime_root: 运行时根路径
}

// ReadRuncConfig 读取 runc 运行时配置
func ReadRuncConfig(configPath string) (*RuntimeConfig, error) {
    // 1. 识别配置格式版本
    version := detectConfigVersion(configPath)
    
    // 2. 根据版本解析 runc 配置
    switch version {
    case "v1":
        return parseV1RuncConfig(configPath)
    case "v2":
        return parseV2RuncConfig(configPath)
    case "v3":
        return parseV3RuncConfig(configPath)
    default:
        return nil, fmt.Errorf("unsupported containerd config version")
    }
}

// GenerateAscendConfig 生成 ascend 运行时配置
func GenerateAscendConfig(runcConfig *RuntimeConfig) *RuntimeConfig {
    return &RuntimeConfig{
        RuntimeType:   runcConfig.RuntimeType,   // 继承 runc 的 shim 类型
        RuntimeEngine: "/usr/bin/ascend-docker-runtime", // 替换为 ascend 运行时
        RuntimeRoot:   runcConfig.RuntimeRoot,   // 继承 runc 的根路径
    }
}

关键设计点:

配置项 runc 运行时 ascend 运行时 说明
runtime_type io.containerd.runc.v2 ← 继承 确保使用相同的 shim 程序
runtime_engine "" 或 /usr/bin/runc /usr/bin/ascend-docker-runtime 替换为 ascend 运行时引擎
runtime_root "" 或自定义路径 ← 继承 确保运行时根路径一致

3.3.3 配置写入与生效

配置写入流程:

// WriteAscendRuntimeConfig 写入 ascend 运行时配置
func WriteAscendRuntimeConfig(configPath string, ascendConfig *RuntimeConfig) error {
    // 1. 备份原始配置
    if err := backupConfig(configPath); err != nil {
        return err
    }
    
    // 2. 读取现有配置
    config, err := readConfig(configPath)
    if err != nil {
        return err
    }
    
    // 3. 添加/更新 ascend 运行时配置
    version := detectConfigVersion(configPath)
    switch version {
    case "v1":
        setV1AscendConfig(config, ascendConfig)
    case "v2":
        setV2AscendConfig(config, ascendConfig)
    case "v3":
        setV3AscendConfig(config, ascendConfig)
    }
    
    // 4. 写入配置文件
    return writeConfig(configPath, config)
}

生效方式:写入配置后需要重启 containerd 服务使配置生效。

3.3.4 配置格式版本检测

// detectConfigVersion 检测 containerd 配置格式版本
func detectConfigVersion(configPath string) string {
    content, _ := os.ReadFile(configPath)
    configStr := string(content)
    
    // v3 格式特征:runtime_path 字段
    if strings.Contains(configStr, "runtime_path") {
        return "v3"
    }
    
    // v2 格式特征:runtime_type 字段
    if strings.Contains(configStr, "runtime_type") {
        return "v2"
    }
    
    // v1 格式特征:type 字段
    if strings.Contains(configStr, "plugins.cri.containerd") {
        return "v1"
    }
    
    // 默认使用 v2 格式
    return "v2"
}

3.4 安全隐私与DFX设计

3.4.1 兼容性

  • 支持 containerd 1.x(v1 格式)、1.6+/1.7+(v2 格式)、2.x(v3 格式)
  • 不影响已有 runc 运行时配置
  • 支持平滑升级:配置变更后重启 containerd 即可生效
  • 支持回滚:配置前自动备份原始配置文件

3.4.2 可维护性

  • 配置继承逻辑清晰,通过读取 runc 配置自动生成 ascend 配置
  • 支持多版本配置格式,无需手动区分
  • 配置变更前自动备份,便于问题排查和回滚

3.4.3 可测试性

  • 可通过模拟不同版本的 containerd 配置文件进行测试
  • 可通过检查生成的 ascend 配置是否与 runc 配置一致来验证正确性

3.4.4 可靠性

  • 配置写入前自动备份原始配置
  • 继承 runc 配置确保与节点实际运行环境一致
  • 配置格式版本自动检测,避免格式错误

3.4.5 安全性

  • 配置文件操作需要 root 权限
  • 不修改 runc 运行时的原有配置
  • ascend 运行时引擎路径固定为 /usr/bin/ascend-docker-runtime

3.5 编程与调用设计

3.5.1 编程模型基本设计

运行环境:

  • 操作系统:Linux(支持 openEuler、Ubuntu、CentOS 等主流发行版)
  • 容器运行时:containerd 1.x / 1.6+ / 1.7+ / 2.x
  • 依赖组件:Ascend Docker Runtime 已安装

开发约束:

  • 配置操作需要 root 权限
  • containerd 配置文件路径默认为 /etc/containerd/config.toml
  • 需确保 runc 运行时已在 containerd 配置中正确配置

可验收设计:

  • 功能验收:在不同 cgroup 版本和 containerd 版本下,验证 ascend 运行时配置正确生成
  • 兼容性验收:在 openEuler 24.03(cgroup v1 但需使用 v2 shim)等特殊场景下验证
  • 回归验收:验证已有 runc 运行时配置不受影响

3.5.2 接口定义与设计

3.5.2.1 containerd 配置接口

  • 接口描述:读取 containerd 配置中 runc 运行时参数,生成并写入 ascend 运行时配置

  • 接口原型:

    func ConfigureAscendRuntime(configPath string) error
    
  • 输入/输出参数:

    参数名称 输入/输出 类型 描述 取值范围
    configPath 输入 string containerd 配置文件路径 有效的文件路径,默认 /etc/containerd/config.toml
  • 返回参数:

    参数名称 类型 描述 取值范围
    error error 配置过程中的错误信息 nil 表示成功
  • 异常处理:

    • 配置文件不存在:返回错误提示
    • runc 运行时未配置:返回错误提示
    • 配置格式无法识别:返回错误提示
    • 配置写入失败:自动回滚到备份配置
  • 约束说明:

    • 执行前需确保 containerd 服务已停止或配置写入后需重启 containerd
    • 需确保 runc 运行时已在配置中存在
  • 调用参考代码:

    // 配置 ascend 运行时
    if err := ConfigureAscendRuntime("/etc/containerd/config.toml"); err != nil {
        log.Fatalf("failed to configure ascend runtime: %v", err)
    }
    
    // 重启 containerd 服务
    exec.Command("systemctl", "restart", "containerd").Run()
    

3.5.2.2 配置查询接口

  • 接口描述:查询当前 ascend 运行时的配置信息

  • 接口原型:

    func GetAscendRuntimeConfig(configPath string) (*RuntimeConfig, error)
    
  • 输入/输出参数:

    参数名称 输入/输出 类型 描述 取值范围
    configPath 输入 string containerd 配置文件路径 有效的文件路径
  • 返回参数:

    参数名称 类型 描述 取值范围
    RuntimeType string 运行时类型(shim 标识) 如 io.containerd.runc.v2
    RuntimeEngine string 运行时引擎路径 /usr/bin/ascend-docker-runtime
    RuntimeRoot string 运行时根路径 继承自 runc
  • 异常处理:

    • 配置文件不存在:返回错误提示
    • ascend 运行时未配置:返回 nil 和错误提示
  • 调用参考代码:

    config, err := GetAscendRuntimeConfig("/etc/containerd/config.toml")
    if err != nil {
        log.Fatalf("failed to get ascend runtime config: %v", err)
    }
    fmt.Printf("runtime_type: %s\n", config.RuntimeType)
    fmt.Printf("runtime_engine: %s\n", config.RuntimeEngine)
    fmt.Printf("runtime_root: %s\n", config.RuntimeRoot)
    

3.5.3 编程手册设计

本特性涉及 containerd 配置管理,相关使用说明在《Ascend Docker Runtime 安装部署指南》中更新,包含以下内容:

  • containerd 场景下 Ascend Docker Runtime 的配置方法
  • 多版本 containerd 配置格式说明
  • 配置验证和故障排查方法
  • openEuler 等特殊发行版的注意事项

4. 缺点和风险

风险 影响 缓解措施
runc 运行时未配置 无法继承配置,ascend 运行时无法生成 配置前检查 runc 运行时是否存在,不存在时给出明确提示
containerd 配置格式变更 新版本 containerd 可能引入新的配置格式 持续跟踪 containerd 版本更新,及时适配新格式
配置写入失败 containerd 无法启动 写入前自动备份,失败时自动回滚
多运行时冲突 节点上存在多个运行时时可能配置冲突 仅继承默认 runc 运行时配置,避免歧义
升级兼容性 已有用户使用旧配置方式升级后行为变更 提供迁移指南,旧配置仍可使用但标记为废弃

5. 现有技术

项目/社区 类似设计 借鉴 差异
NVIDIA Container Runtime containerd 场景下的运行时配置 运行时配置继承思路 NVIDIA 使用 hook 方式注入,本提案直接继承 runc 配置
Kata Containers containerd 多运行时管理 多版本配置格式适配 Kata 使用独立的 runtime_type,本提案继承 runc 的 runtime_type
containerd 官方文档 运行时配置规范 配置格式定义 本提案在此基础上增加了自动继承和格式适配

附录

替代方案

补充说明

欢迎加入社区,感谢您对社区的贡献 🎉!

likedislike
Wweihaoran成员
4月28日 添加了label:feature
Wweihaoran成员
4月28日 修改标题为 “[Feature]: ascend docker runtime安装易用性提升”,原标题为“[Feature]: ”
Wweihaoran成员
4月28日 修改了issue 的描述
Wweihaoran成员
4月28日 修改了issue 的描述
Wweihaoran成员
4月28日 修改了issue 的描述
Atlas_zxp
Atlas_zxp成员
4月28日 评论:

/label add triaged

likedislike
ascend-robotascend-robot成员
4月28日 添加了label:triaged
此处折叠了8条事件消息 查看更多
ascend-robotascend-robot成员
7月7日 关联了看板:MindStudio ISSUE管理
lmztju成员
7月13日 评论:

/label add resolved

likedislike
ascend-robotascend-robot成员
7月13日 添加了label:resolved
ascend-robot
ascend-robot成员
7月20日 评论:

您好,当前Issue标记为resolved且有一段时间未进一步更新,因此我们将其标记为'stale'(闲置)状态。若您认为这是误操作,可通过添加任意评论来去除'stale'标签。标记为stale的Issue在4天内无更新活动将自动关闭。

likedislike
ascend-robotascend-robot成员
7月20日 添加了label:stale
ascend-robotascend-robot成员
7月24日 关闭了 issue
Xxiangjie10成员
27 天前 issue状态由 TODO 改变为 DONE