更新时间:2026-07-17 GMT+08:00
分享

在ECS上构建自定义镜像并在Notebook中使用

为了满足用户的定制需求,用户可以使用ModelArts提供的基础镜像或第三方的镜像来编写Dockerfile,在ECS服务器上构建出完全适合自己的镜像并注册到SWR服务,用以创建新的开发环境,满足自己的业务需求。

自定义镜像构建流程

  1. 准备一台Linux服务器,本文以ECS服务器为例。
  2. 在ECS中构建自定义镜像(本文提供了Dockfile样例文件)。
  3. 将构建的镜像推送到SWR。
  4. 注册SWR镜像到ModelArts。
  5. 创建Notebook并验证新镜像。

Notebook自定义镜像规范

制作自定义镜像时,Base镜像需满足如下规范:

  • 基于昇腾、Dockerhub官网等官方开源的镜像制作,开源镜像需要满足如下操作系统约束:

    x86:Ubuntu 22.04、Ubuntu20.04、Ubuntu 18.04

    ARM:Euler2.10.x、Euler2.9.x、Euler2.8.x、HCE3.0、HCE2.0

  • 不满足以上镜像规范,所制作的镜像使用可能会出现故障,请用户检查镜像规范,并参考Notebook自定义镜像故障基础排查自行排查,如未解决请联系华为技术工程师协助解决。

本案例将基于ModelArts提供的PyTorch预置镜像,安装pytorch 2.7、ffmpeg 4和gcc 8依赖包,构建一个面向AI开发的新镜像。

步骤一:准备ECS服务器并配置环境信息

准备一台具有Docker功能的机器,如果没有,建议申请一台x86架构的ECS服务器并购买弹性公网IP,并在准备好的机器上安装必要的软件。ModelArts提供了Ubuntu系统的脚本,方便安装Docker。

  • 本地Linux机器的操作等同ECS服务器上的操作,请参考本案例。
  • Docker镜像架构需与宿主机架构保持一致。
  1. 登录ECS控制台,购买ECS服务器。
    • 快速购买:在“操作系统”区域,选择Ubuntu 22.04镜像。具体操作,请参见快速购买ECS
      图1 操作系统

    • 自定义购买:在“操作系统”区域,选择公共镜像Ubuntu 22.04。在“存储与备份”区域,系统盘大小配置为100GiB。具体操作,请参见自定义购买ECS
      图2 操作系统

      图3 存储与备份

  2. 购买弹性公网IP并绑定到ECS服务器。具体操作请参考绑定弹性公网IP
  3. 登录ECS服务器并配置Docker环境。
    1. 在ECS服务器中,使用如下命令下载安装配置脚本。当前仅支持Ubuntu系统的脚本。
      wget https://cnnorth4-modelarts-sdk.obs.cn-north-4.myhuaweicloud.com/modelarts/custom-image-build/install_on_ubuntu1804.sh
    2. 在ECS服务器中执行如下命令,即可完成环境配置。
      bash install_on_ubuntu1804.sh
      图4 配置成功
      source /etc/profile

      安装脚本依次执行了如下任务:

      1. 安装Docker。
      2. 如果挂载了GPU,则会安装nvidia-docker2,用以将GPU挂载到Docker容器中。

步骤二:制作自定义镜像

这一节描述如何编写一个Dockerfile,并据此构建出一个新镜像在Notebook创建实例并使用。关于Dockerfile的具体编写方法,请参考官网

  1. 查询基础镜像(第三方镜像可跳过此步骤)。

    ModelArts提供的公共镜像,请参考ModelArts统一镜像ModelArts预置镜像,获取镜像地址。

  2. 连接容器镜像服务。
    1. 登录容器镜像服务控制台,选择左侧导航栏的“总览”,单击页面右上角的“登录指令”,在弹出的页面中单击复制登录指令。
      图5 获取登录指令

      您可以按需选择有效时长。如果需要长期有效的登录指令,请参见获取长期有效登录指令。获取了长期有效的登录指令后,在有效期内的临时登录指令仍然可以使用。

    2. 在安装容器引擎的机器中执行上一步复制的登录指令。登录成功会显示“Login Succeeded”。
  3. 拉取ModelArts镜像或第三方镜像。

    此处以ModelArts镜像举例,第三方镜像直接替换镜像地址。关于如何获取ModelArts镜像地址,请参见ModelArts统一镜像ModelArts预置镜像

    docker pull swr.cn-north-4.myhuaweicloud.com/atelier/pytorch_cuda:pytorch_1.12.1-cuda_10.2-py_3.9.11-ubuntu_20.04-x86_64-20260425154604-d9a1f9f
  4. 编写Dockerfile。

    Dockerfile是一个文本文件,包含了一系列的指令,用于自动构建Docker镜像。可以通过Dockerfile定义一个镜像的构建过程,包括基础镜像、安装的软件包、配置文件的复制、环境变量的设置等。

    vim一个Dockerfile,如果使用的基础镜像是ModelArts提供的公共镜像,Dockerfile的具体内容可参考Dockerfile文件(基础镜像为ModelArts提供)

    如果使用的基础镜像是第三方镜像(非ModelArts提供的公共镜像),Dockerfile文件中需要添加uid为1000的用户ma-user和gid为100的用户组ma-group,具体可参考Dockerfile文件(基础镜像为非ModelArts提供)

    本例的Dockerfile将基于PyTorch镜像安装PyTorch 2.7.0、ffmpeg 4和gcc 8,构建一个面向AI任务的镜像。

    vim Dockerfile
  1. 构建镜像

    使用docker build命令从Dockerfile构建出一个新镜像。命令格式如下:

    docker build -t {局点信息}/{组织名称}/{镜像名称}:{版本名称} -f {Dockerfile文件名} .
    表1 命令参数说明

    参数

    说明

    示例

    -t

    指定了新的镜像地址,包括{局点信息}/{组织名称}/{镜像名称}:{版本名称},请根据实际填写。建议使用完整的SWR地址,供后续的调试和注册使用。

    -

    局点信息

    格式为swr.{regionName}.myhuaweicloud.com,regionName可通过API凭证的项目列获取。

    swr.cn-north-4.myhuaweicloud.com

    组织名称

    可通过SWR组织管理查看已有组织或创建新的组织。

    dev-custom

    镜像名称

    自定义镜像名称。

    pytorch2_7

    版本名称

    自定义版本名称。

    v1

    -f

    指定了Dockerfile的文件名,根据实际填写。

    -

    Dockerfile文件名

    自定义Dockerfile文件名。

    Dockerfile

    .

    表示在当前目录下。

    -

    命令示例如下。本示例镜像构建耗时约一小时,具体时长由镜像大小而定,请以实际耗时为准。

    docker build -t swr.cn-north-4.myhuaweicloud.com/dev-custom/pytorch2_7:v1 -f Dockerfile .
    图6 自定义镜像构建成功

步骤三:将镜像推送到SWR

镜像调试完成后,需要将镜像推送到SWR。

  1. 登录SWR控制台,使用docker push命令推送镜像。具体操作,请参见推送镜像到镜像仓库
    命令格式如下,关于命令参数的说明,请参见表1
    docker push {SWR地址}/{组织名称}/{镜像名称}:{版本名称}

    命令示例如下:

    docker push swr.cn-north-4.myhuaweicloud.com/dev-custom/pytorch2_7:v1
  2. SWR控制台左侧导航栏,单击“我的镜像”,执行刷新操作后可以看到新增的镜像,单击镜像名称,可查看镜像详情。
    图7 将镜像推到SWR

步骤四:在ModelArts注册新镜像

调试完成后,将新镜像注册到ModelArts镜像管理服务中,进而能够在ModelArts中使用该镜像。

  1. 登录ModelArts管理控制台,在左侧导航栏按需选择以下操作。
    • 新版控制台:选择“资产管理 > 镜像”,选择“已注册镜像”页签。
    • 旧版控制台:选择“资产管理 > 镜像管理”,选择“已注册镜像”页签。
  2. 单击“注册镜像”,镜像源即为步骤三推送到SWR中的镜像。

    注册镜像时,“架构”“类型”需要和镜像源保持一致,否则在使用此自定义镜像创建Notebook时会创建失败。

    • 架构:通过docker run --rm {image_name} uname -m命令查看架构。image_name请替换为实际镜像。示例如下:
      docker run --rm swr.cn-north-4.myhuaweicloud.com/dev-custom/pytorch2_7:v1 uname -m

      如下图所示,该镜像的架构为x86。

      图8 查看镜像架构
    • 类型:通过拉取镜像安装的是cuda或cann包来判断,cuda包为GPU,cann包为NPU。

      例如,拉取镜像的地址为swr.cn-north-4.myhuaweicloud.com/atelier/pytorch_cuda:pytorch_1.12.1-cuda_10.2-py_3.9.11-ubuntu_20.04-x86_64-20260425154604-d9a1f9f,从“cuda_10.2”可以看到安装的是cuda,因此类型为GPU。

    • 规格:当类型选择NPU时,需要选择规格,规格对应的机型和镜像机型需要保持一致。

      规格可以从镜像地址中获取。例如,镜像地址为swr.cn-north-4.myhuaweicloud.com/atelier/pytorch_ascend:pytorch_2.7.1-cann_8.5.2-py_3.12-euler_2.10.11-aarch64-snt9b-20260417112518-aabfd52,可以看到镜像规格为snt9b。

  3. “已注册镜像”页面,可以看到注册好的镜像。

步骤五:创建Notebook并使用自定义镜像

  1. ModelArts管理控制台左侧导航栏,按需选择以下操作。
    • 新版:选择模型开发与训练 > Notebook,进入“Notebook”页面。
    • 旧版:选择开发空间 > Notebook,进入“Notebook”页面。
  2. “Notebook”页面右上角,单击“创建”,在“环境配置”区域,选择“自定义镜像”,单击图标,选择步骤四注册的镜像,WebIDE选择JupyterLab。
    关于创建Notebook的参数说明,请参见创建Notebook实例
    图9 创建Notebook

    当Notebook实例的“状态”显示为“运行中”,表示Notebook实例创建成功。

  3. “Notebook”页面,单击操作列的“接入环境”,在“接入方式”对话框,单击JupyterLab接入右侧的“接入”
  4. “ModelArts Launcher”页面的Notebook区域,单击PyTorch,即可创建一个ipynb文件,导入PyTorch库,查看PyTorch版本号。
    import torch
    print(torch.__version__)
    图10 创建一个ipynb文件

    可以看到Dockerfile中安装的PyTorch版本号为2.7.0。

  5. 再打开一个Terminal,执行以下命令,查看ffmpeg和gcc的版本。
    ffmpeg -v 
    gcc -v
    图11 查看ffmpeg和gcc的版本

Dockerfile文件(基础镜像为ModelArts提供)

vim一个Dockerfile文件。基础镜像为ModelArts提供的镜像时,Dockerfile文件的具体内容如下:

# FROM后填写 ${基础镜像名称} 基础镜像名称为docker pull后的内容。
FROM swr.cn-north-4.myhuaweicloud.com/atelier/pytorch_cuda:pytorch_1.12.1-cuda_10.2-py_3.9.11-ubuntu_20.04-x86_64-20260425154604-d9a1f9f
USER root
# section1:  配置apt源
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 && \
    mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
    echo -e "deb http://repo.huaweicloud.com/ubuntu/ bionic main restricted\ndeb http://repo.huaweicloud.com/ubuntu/ bionic-updates main restricted\ndeb http://repo.huaweicloud.com/ubuntu/ bionic universe\ndeb http://repo.huaweicloud.com/ubuntu/ bionic-updates universe\ndeb http://repo.huaweicloud.com/ubuntu/ bionic multiverse\ndeb http://repo.huaweicloud.com/ubuntu/ bionic-updates multiverse\ndeb http://repo.huaweicloud.com/ubuntu/ bionic-backports main restricted universe multiverse\ndeb http://repo.huaweicloud.com/ubuntu bionic-security main restricted\ndeb http://repo.huaweicloud.com/ubuntu bionic-security universe\ndeb http://repo.huaweicloud.com/ubuntu bionic-security multiverse" > /etc/apt/sources.list && \
    apt-get update
# section2: 下载ffmpeg、gcc依赖包。
RUN apt-get -y -f install && \
    apt-get -y autoremove && \
    apt-get -y autoclean && \
    apt-get update && \ 
    echo Y | apt-get -y install openssh-server && \
    apt-get -y install ffmpeg && \
    apt-get -y install gcc-8 g++-8 && \
    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 --slave /usr/bin/g++ g++ /usr/bin/g++-8 && \
    if [ -f $HOME/.pip/pip.conf ]; then rm $HOME/.pip/pip.conf; fi
USER ma-user
# section3: 此处配置为清华源,用户可自行配置。
RUN echo -e "channels:\n  - defaults\nshow_channel_urls: true\ndefault_channels:\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2\ncustom_channels:\n  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud\n  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud" > $HOME/.condarc && \
    echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n[install]\ntrusted-host = https://pypi.tuna.tsinghua.edu.cn" > $HOME/.pip/pip.conf
# section4: create a conda environment(only support python=3.11.10) and install pytorch2.7.0
# torch版本和torchvision、torchaudio版本有配套关系,如果用户需要自建python环境并使用notebook功能,则需要下载ipykernel。
RUN source /home/ma-user/anaconda3/bin/activate && \
    conda create -y --name pytorch_2_7 python=3.11.10 && \
    conda activate pytorch_2_7 && \
    pip install torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 && \
    conda activate pytorch_2_7 && \
    pip install ipykernel && \
    
    conda deactivate

Dockerfile文件(基础镜像为非ModelArts提供)

如果使用的镜像是第三方镜像,Dockerfile文件中需要添加uid为1000的用户ma-user和gid为100的用户组ma-group。如果基础镜像中uid 1000或者gid 100已经被其他用户和用户组占用,需要将其对应的用户和用户组删除。如下Dockerfile文件已添加指定的用户和用户组,您直接使用即可。

用户只需要设置uid为1000的用户ma-user和gid为100的用户组ma-group,并使ma-user有对应目录的读写执行权限,其他如启动cmd不需要关心,无需设置或更改。

vim一个Dockerfile文件,添加第三方镜像(即非ModelArts提供的官方镜像)为基础镜像,如以ubuntu 20.04为例。下文提供两种Dockerfile文件示例,您可以按需选择。

  • 示例一:基础配置,即添加指定的用户和用户组。
    FROM ubuntu:20.04
    # Create ma-user UID=1000 GID=100
    USER root
    RUN default_user=$(getent passwd 1000 | awk -F ':' '{print $1}') || echo "uid: 1000 does not exist" && \
        default_group=$(getent group 100 | awk -F ':' '{print $1}') || echo "gid: 100 does not exist" && \
        if [ ! -z "${default_user}" ] && [ "${default_user}" != "ma-user" ]; then \
            userdel -r ${default_user}; \
        fi && \
        if [ ! -z "${default_group}" ] && [ "${default_group}" != "ma-group" ]; then \
            groupdel -f ${default_group}; \
        fi && \
        if ! getent group 100 > /dev/null; then \
            groupadd -g 100 ma-group; \
        fi && \
        useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user && \
        chmod -R 750 /home/ma-user
  • 示例二:基础配置+相关工具与环境配置样例。
    • 基础配置:添加指定的用户和用户组。
    • (可选)相关工具与环境配置样例:
      • 配置APT源以加速软件包下载。
      • 安装Miniconda并配置Conda和Pip源。
      • 创建一个包含特定Python包(如PyTorch和TorchVision)的Conda环境。
      • 安装三方包样例,例如安装ffmpeg和gcc 8,以支持多媒体处理和编译任务。
        FROM ubuntu:20.04
        # section1: 创建ma-user用户组与用户
        USER root
        RUN default_user=$(getent passwd 1000 | awk -F ':' '{print $1}') || echo "uid: 1000 does not exist" && \
            default_group=$(getent group 100 | awk -F ':' '{print $1}') || echo "gid: 100 does not exist" && \
            if [ ! -z "${default_user}" ] && [ "${default_user}" != "ma-user" ]; then \
                userdel -r ${default_user}; \
            fi && \
            if [ ! -z "${default_group}" ] && [ "${default_group}" != "ma-group" ]; then \
                groupdel -f ${default_group}; \
            fi && \
            if ! getent group 100 > /dev/null; then \
                groupadd -g 100 ma-group; \
            fi && \
            useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user && \
            chmod -R 750 /home/ma-user
        
        # section2: 使用标准focal源
        RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
            printf "deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse\n\
            deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse\n\
            deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse\n\
            deb http://archive.ubuntu.com/ubuntu focal-security main restricted universe multiverse\n" > /etc/apt/sources.list && \
            apt-get update && \
            apt-get install -y zip wget ca-certificates && \ 
            apt update && echo Y | apt install openssh-server
        RUN rm /bin/sh && ln -s /bin/bash /bin/sh
        
        # section3: 以 ma-user 身份安装 Miniconda3
        USER ma-user
        RUN cd /home/ma-user/ && \
            wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
            bash Miniconda3-latest-Linux-x86_64.sh -b -p /home/ma-user/anaconda3 && \
            rm -rf Miniconda3-latest-Linux-x86_64.sh
        
        # section4: 配置 conda、pip 清华镜像源 + 初始化 conda
        RUN mkdir -p /home/ma-user/.pip && \
            echo -e "channels:\nshow_channel_urls: true\ndefault_channels:\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2\nremote_read_timeout: 120" > /home/ma-user/.condarc && \
            echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n[install]\ntrusted-host = pypi.tuna.tsinghua.edu.cn" > /home/ma-user/.pip/pip.conf && \
            /home/ma-user/anaconda3/bin/conda init bash && \
            source /home/ma-user/anaconda3/bin/activate base && \
            conda config --remove-key channels || true && \
            conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main && \
            conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r && \
            conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 && \
            conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main && \
            conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r && \
            conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
        
        # section5: 创建 PyTorch 专属 conda 虚拟环境 ,如果用户需要自建python环境,并使用notebook功能则需要下载ipykernel
        RUN /bin/bash -c '\
            source /home/ma-user/anaconda3/bin/activate base && \
            conda create -y --override-channels \
            -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main \
            -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r \
            -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 \
            -n pytorch_2_7 python=3.11.10 && \
            conda run -n pytorch_2_7 \
            pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn \
            torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 ipykernel==6.7.0 \
        '
        
        # section6: 修复依赖冲突,分阶段安装系统包,增加修复依赖命令
        USER root
        RUN apt-get update && apt-get --fix-broken install -y
        RUN apt-get install -y --no-install-recommends libc6-dev libstdc++-8-dev
        RUN apt-get install -y --no-install-recommends ffmpeg gcc-8 g++-8
        # 创建软链接,让gcc/g++ 默认指向gcc-8/g++-8
        RUN ln -s /usr/bin/gcc-8 /usr/bin/gcc && \
            ln -s /usr/bin/g++-8 /usr/bin/g++
        RUN apt-get autoremove -y && apt-get autoclean

相关文档