下载
中文
注册

制作容器镜像

本章节介绍如何制作容器包含NNRT软件的镜像来部署容器。

前提条件

  • 容器OS镜像可从Docker Hub拉取,请确保安装环境能够连接网络。
  • 用户需自行准备业务推理程序压缩包(支持tar、tgz格式),业务推理程序的压缩包格式,应为容器内自带的压缩程序支持的格式。

外挂磁盘至/var/lib/docker目录

由于小站默认内存容量较小,而制作容器镜像所需容量较大,因此如果小站外接了磁盘或其他存储介质,建议将外接磁盘或其他存储介质挂载到“/var/lib/docker”目录。

  1. 解挂“/var/lib/docker”目录所在分区。
    1. 登录智能小站web管理界面。
    2. 单击选择“管理 > 存储配置 > 存储管理”,进入磁盘设置界面。
    3. 选择挂载了“/var/lib/docker”目录所在分区,单击“解挂”,如图1所示。
      图1 解挂

      若用户环境存在Docker容器,可能导致解挂失败。因此需要用户先删除Docker容器。操作如下:

      1. root用户登录服务器。
      2. 执行docker ps -a查询所有的容器(CONTAINER ID为容器ID)。
      3. 执行如下命令停止正在运行的容器。
        docker stop CONTAINER ID
      4. 执行如下命令删除容器。
        docker rm CONTAINER ID
  2. 创建分区挂载“/var/lib/docker”目录。
    1. 登录智能小站web管理界面。
    2. 单击选择“管理 > 存储配置 > 存储管理”,进入磁盘设置界面。
    3. 选择外接磁盘或其他存储介质,单击“创建分区”创建一个ext4格式的分区,如图2所示。
      图2 创建分区
    4. 分区创建成功后,单击“挂载”,将分区挂载至“/var/lib/docker”,如图3所示。
      图3 挂载成功

制作容器镜像

  1. root用户登录智能小站,执行docker images命令查看宿主机上是否已存在容器OS镜像,如下所示,如果已存在镜像,则直接执行3,否则执行2拉取容器OS镜像。
    ubuntu       22.04            d5ca7a445605   5 months ago    65.6MB
  2. 执行docker pull ubuntu:22.04命令拉取容器OS镜像,拉取后可以按照1方法查看镜像是否已拉取成功。
    • ubuntu:22.04请根据现场实际OS和版本刷新。
    • 如果拉取镜像速度极为缓慢,可执行vi /etc/docker/daemon.json命令,添加如下内容配置镜像加速器:
      {
              "registry-mirrors": ["http://docker.mirrors.ustc.edu.cn"]
      }
      添加内容后,执行以下命令重启Docker。
      systemctl daemon-reload 
      systemctl restart docker
    • 如果拉取镜像时,出现类似如下报错,可能为系统时间不对,执行date -s "当前时间"(如:date -s "20230309 15:00:30")修改时间,然后再执行docker pull ubuntu:22.04命令。
      Error response from daemon: Get "https://registry-1.docker.io/v2/": x509: certificate has expired or is not yet valid: current time 1970-01-01T20:57:32Z is before 2023-02-22T00:00:00Z
  3. 构建容器镜像。
    1. 规划Dockerfile路径,如“/home/imagetest”
    2. 进入规划的Dockerfile路径,执行cp /etc/slog.conf slog.conf命令,将“slog.conf”日志配置文件拷贝到当前目录。
    3. 下载软件中获取的NNRT包和用户自行准备的业务推理程序压缩包上传到当前目录。
    4. 执行以下命令创建Dockerfile文件。

      vi Dockerfile

    5. 在键盘按I键进入编辑模式,在文件中写入以下内容后,在键盘按Esc键退出编辑模式,输入:wq命令保存内容。
      # 容器操作系统及TAG,根据实际修改
      FROM ubuntu:22.04
      
      ARG NNRT_PKG
      ARG DIST_PKG
      # 本文以/usr/local/Ascend目录为例作为NNRT安装目录,如果您希望安装在其他目录,请修改为您希望的目录
      ARG ASCEND_BASE=/usr/local/Ascend
      WORKDIR /home/AscendWork
      COPY $NNRT_PKG .
      COPY $DIST_PKG .
      COPY install.sh .
      
      # 创建运行推理应用的用户及组,HwHiAiUser,HwDmUser,HwBaseUser的UID与GID分别为1000,1101,1102为例
      RUN umask 0022 && \
          groupadd  HwHiAiUser -g 1000 && \
          useradd -d /home/HwHiAiUser -u 1000 -g 1000 -m -s /bin/bash HwHiAiUser && \
          groupadd HwDmUser -g 1101 && \
          useradd -d /home/HwDmUser -u 1101 -g 1101 -m -s /bin/bash HwDmUser && \
          usermod -aG HwDmUser HwHiAiUser && \
          groupadd HwBaseUser -g 1102 && \
          useradd -d /home/HwBaseUser -u 1102 -g 1102 -m -s /bin/bash HwBaseUser && \
          usermod -aG HwBaseUser HwHiAiUser
      
      # 安装nnrt,解压推理程序
      RUN chmod +x $NNRT_PKG && \
          ./$NNRT_PKG --quiet --install --install-path=$ASCEND_BASE \
          --install-for-all --force && \
          sh install.sh && \
          chown -R HwHiAiUser:HwHiAiUser /home/AscendWork/ && \
          rm $NNRT_PKG && \
          rm $DIST_PKG && \
          rm install.sh
      
      ENV LD_LIBRARY_PATH=/usr/local/Ascend/nnrt/latest/lib64:/usr/local/Ascend/driver/lib64:/usr/lib64
      ENV LD_PRELOAD=/lib/aarch64-linux-gnu/libc.so.6
      
      RUN ln -sf /lib /lib64 && \
          mkdir /var/dmp && \
          mkdir /usr/slog && \
          chown HwHiAiUser:HwHiAiUser /usr/slog && \
          chown HwHiAiUser:HwHiAiUser /var/dmp
      
      # 拷贝日志配置文件
      COPY --chown=HwHiAiUser:HwHiAiUser slog.conf /etc
      
      COPY --chown=HwHiAiUser:HwHiAiUser run.sh /home/AscendWork/run.sh
      RUN chmod 640 /etc/slog.conf && \
          chmod +x /home/AscendWork/run.sh
      	
      # 若用户需要使用AICPU算子,则请用户将如下指令中的注释“#”删除
      #RUN cp /usr/local/Ascend/nnrt/latest/opp/Ascend/aicpu/Ascend-aicpu_syskernels.tar.gz /home/HwHiAiUser/ && \
      #    rm -rf /usr/local/Ascend/nnrt/latest/opp/Ascend/aicpu/Ascend-aicpu_syskernels.tar.gz && \
      #    echo $(wc -c /home/HwHiAiUser/Ascend-aicpu_syskernels.tar.gz|awk ' {print$1} ') > /home/HwHiAiUser/aicpu_package_install.info && \
      #    tail -c +8449 /home/HwHiAiUser/Ascend-aicpu_syskernels.tar.gz > /home/HwHiAiUser/aicpu.tar.gz && \
      #    rm -rf /home/HwHiAiUser/Ascend-aicpu_syskernels.tar.gz && \
      #    chown HwHiAiUser:HwHiAiUser /home/HwHiAiUser/aicpu.tar.gz && \
      #    mkdir -p /home/HwHiAiUser/aicpu_kernels
      #RUN tar -xvf /home/HwHiAiUser/aicpu.tar.gz -C /home/HwHiAiUser/ 2>/dev/null;exit 0
      #RUN rm -rf /home/HwHiAiUser/aicpu.tar.gz && \
      #    mv /home/HwHiAiUser/aicpu_kernels_device/* /home/HwHiAiUser/aicpu_kernels/ && \
      #    chown -R HwHiAiUser:HwHiAiUser /home/HwHiAiUser/
      
      # 若用户不需要使用AICPU算子,请将如下指令的注释“#”删除
      #RUN rm -rf /usr/local/Ascend/nnrt/latest/opp/Ascend/aicpu/Ascend-aicpu_syskernels.tar.gz && \
      #    chown -R HwHiAiUser:HwHiAiUser /home/HwHiAiUser/
      
      USER 1000
      CMD bash /home/AscendWork/run.sh

      制作镜像时,出现如下图错误,表示磁盘空间不足。

      参考如下解决方法:

      • 执行docker system prune命令,用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及无tag的镜像。
      • 参见删除容器镜像删除无用的镜像和容器。
    6. 执行vi install.sh命令创建install.sh文件,解压业务推理程序压缩包。
      #!/bin/bash
      #进入容器工作目录
      cd /home/AscendWork
      #解压业务推理程序压缩包的命令请根据压缩包格式适配,压缩包名称请根据实际文件名称配置
      tar xf dist.tar
    7. 执行vi run.sh命令创建run.sh文件,用于启动NPU驱动dmp进程和推理程序。
      #!/bin/bash
      mkdir /dev/shm/dmp
      mkdir /home/HwHiAiUser/hdc_ppc
      nohup /var/dmp_daemon -I -M -U 8087 >&/dev/null &
      /var/slogd -d
      #启动推理程序,若用户不涉及推理程序可将如下命令注释
      #进入业务推理程序的可执行文件所在目录,请根据实际可执行文件所在目录配置
      cd /home/AscendWork/dist
      #运行可执行文件,请根据实际文件名称配置
      ./main
    8. 在当前目录执行以下命令构建镜像。
      docker build -t ascend-infer:infer_TAG --build-arg NNRT_PKG=nnrt-name --build-arg DIST_PKG=distpackage-name .

      注意不要遗漏命令结尾的“.”,命令解释如表1所示。

      表1 命令参数说明

      参数

      说明

      ascend-infer:infer_TAG

      镜像名称与标签,建议将infer_TAG命名为“软件包版本-容器OS-架构”(例如“7.0.0-ubuntu22.04-arm64”)。

      --build-arg

      指定dockerfile文件内的参数。

      NNRT_PKG

      nnrt-name为推理引擎包名称,注意不要遗漏文件后缀,请用户自行更换。

      DIST_PKG

      distpackage-name为业务推理程序压缩包名称,注意不要遗漏文件后缀,请用户自行更换。以dist.tar为例。

      命令示例如下所示。

      docker build -t ascend-infer:7.0.0-ubuntu22.04-arm64 --build-arg NNRT_PKG=Ascend-cann-nnrt_7.0.0_linux-aarch64.run --build-arg DIST_PKG=dist.tar . 

      当出现“Successfully built xxx”表示镜像构建成功。

启动容器

  • 若在M.2外接存储制作文件系统时选装了MEF功能,则不支持使用docker后台管理容器。
  • 若系统安装了MEF功能,则不支持使用docker后台管理容器。
  1. 请执行如下命令基于新镜像运行一个容器,其中加粗部分内容需替换成填写3.h中构建的镜像和tag(如“ascend-infer:7.0.0-ubuntu22.04-arm64”)。
    docker run -it -u HwHiAiUser:HwHiAiUser --pid=host \
    --device=/dev/upgrade:/dev/upgrade \
    --device=/dev/davinci0:/dev/davinci0 \
    --device=/dev/davinci_manager_docker:/dev/davinci_manager \
    --device=/dev/vdec:/dev/vdec \
    --device=/dev/vpc:/dev/vpc \
    --device=/dev/pngd:/dev/pngd \
    --device=/dev/venc:/dev/venc \
    --device=/dev/sys:/dev/sys \
    --device=/dev/svm0 \
    --device=/dev/acodec:/dev/acodec \
    --device=/dev/ai:/dev/ai \
    --device=/dev/ao:/dev/ao \
    --device=/dev/vo:/dev/vo \
    --device=/dev/hdmi:/dev/hdmi \
    --device=/dev/ts_aisle:/dev/ts_aisle \
    --device=/dev/dvpp_cmdlist:/dev/dvpp_cmdlist \
    -v /etc/sys_version.conf:/etc/sys_version.conf:ro \
    -v /etc/hdcBasic.cfg:/etc/hdcBasic.cfg:ro \
    -v /usr/lib64/libaicpu_processer.so:/usr/lib64/libaicpu_processer.so:ro \
    -v /usr/lib64/libaicpu_prof.so:/usr/lib64/libaicpu_prof.so:ro \
    -v /usr/lib64/libaicpu_sharder.so:/usr/lib64/libaicpu_sharder.so:ro \
    -v /usr/lib64/libadump.so:/usr/lib64/libadump.so:ro \
    -v /usr/lib64/libtsd_eventclient.so:/usr/lib64/libtsd_eventclient.so:ro \
    -v /usr/lib64/libaicpu_scheduler.so:/usr/lib64/libaicpu_scheduler.so:ro \
    -v /usr/lib/aarch64-linux-gnu/libcrypto.so.1.1:/usr/lib64/libcrypto.so.1.1:ro \
    -v /usr/lib/aarch64-linux-gnu/libyaml-0.so.2.0.6:/usr/lib64/libyaml-0.so.2:ro \
    -v /usr/lib64/libdcmi.so:/usr/lib64/libdcmi.so:ro \
    -v /usr/lib64/libmpi_dvpp_adapter.so:/usr/lib64/libmpi_dvpp_adapter.so:ro \
    -v /usr/lib64/aicpu_kernels/:/usr/lib64/aicpu_kernels/:ro \
    -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi:ro \
    -v /usr/lib64/libstackcore.so:/usr/lib64/libstackcore.so:ro \
    -v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64:ro \
    -v /var/slogd:/var/slogd:ro \
    -v /var/dmp_daemon:/var/dmp_daemon:ro \
    ascend-infer:7.0.0-ubuntu22.04-arm64 /bin/bash
    • 运行大内存业务超内存时,可配置限制内存方式启动,避免系统挂死。

      可在上述命令中添加如下参数配置(xxx:表示上述命令中映射的设备和库文件)。

      命令示例:

      docker run -itd -m 2GB --cpus 2 -u HwHiAiUser:HwHiAiUser --pid=host xxx /bin/bash
      • “-m”:分配的内存大小(主机至少预留1GB内存)。
      • “--cpus”:CPU核数。

      可执行如下命令查看配置(cdf1098f632e为容器ID,可执行docker ps -a查询)。

      docker inspect cdf1098f632e

      回显类似如下信息,表示配置正确。

      "Memory":21474836484,
      "NanoCpus":2000000000,
    • 请用户根据实际操作系统配置libcrypto.so.1.1文件和libyaml-0.so.2.0.x文件的挂载路径。
      • Ubuntu宿主机操作系统:
        -v /usr/lib/aarch64-linux-gnu/libcrypto.so.1.1:/usr/lib64/libcrypto.so.1.1:ro
        -v /usr/lib/aarch64-linux-gnu/libyaml-0.so.2.0.6:/usr/lib64/libyaml-0.so.2:ro
      • openEuler宿主机操作系统:
        -v /usr/lib64/libcrypto.so.1.1:/usr/lib64/libcrypto.so.1.1:ro
        -v /usr/lib64/libyaml-0.so.2.0.9:/usr/lib64/libyaml-0.so.2:ro

    执行该命令后,回显以下信息,表示成功进入该容器。

    HwHiAiUser@6889930edc7b:/home/AscendWork$
  2. 容器启动后,执行以下命令查看当前docker容器中可以使用的davinci设备:
    ls /dev/ | grep davinci*

    命令执行情况如下图。

    其中:

    • davinci_manager为管理模块的字符设备节点。
    • davinci0为该容器使用的davinci设备。
  3. 在容器内执行以下命令。
    1. 执行run.sh脚本启动NPU驱动dmp进程和推理程序。
      cd /home/AscendWork
      ./run.sh
    2. 执行npu-smi info命令,查看芯片状态,如下图所示,表示容器挂载的芯片状态正常。

容器镜像导出

用户可将容器导出为一个镜像文件,再导入其它服务器使用。操作步骤如下:

  1. root用户登录小站。
  2. 执行docker ps -a命令查看容器。
    回显类似如下信息(该容器仅为示例,请用户以实际情况为准):
    CONTAINER ID        IMAGE                                   COMMAND        CREATED           STATUS         PORTS        NAMES
    e43c96ec5ec7        ascend-infer:7.0.0-ubuntu22.04-arm64   "/bin/bash"     41 hours ago      Up 41 hours             cranky_lamport
  3. 执行如下命令将容器保存成镜像。
    docker commit CONTAINER ID image-name:tag
    表2 命令参数说明

    参数

    参数说明

    CONTAINER ID

    容器ID。

    image-name:tag

    镜像名称与标签,用户可自定义。

    命令示例如下:

    docker commit e43c96ec5ec7 ascend-infer:7.0.0-ubuntu22.04-arm64-20230109
  4. 执行docker images命令查看镜像。
    回显类似如下信息(该镜像仅为示例,请用户以实际情况为准):
    REPOSITORY          TAG                                   IMAGE ID       CREATED          SIZE
    ascend-infer      7.0.0-ubuntu22.04-arm64-20230109      e43c96ec5ec7  9 seconds ago    1.35GB
  5. 执行如下命令保存镜像文件。
    docker save -o image.tar image-name:tag
    表3 命令参数说明

    参数

    参数说明

    image.tar

    镜像压缩文件名称,用户可自定义。(例:ascend-infer.tar)

    image-name:tag

    镜像名称与标签,填写步骤3中保存的镜像和tag(如“ascend-infer:7.0.0-ubuntu22.04-arm64-20230109”)。

    命令示例如下:

    docker save -o ascend-infer.tar ascend-infer:7.0.0-ubuntu22.04-arm64-20230109

    镜像打包完成后,会在当前目录下生成,执行ls命令查看。

    ascend-infer.tar
  6. 将生成的镜像文件下载至本地,用于后续通过FusionDirector部署到Atlas 500 A2智能小站。

进入容器

如果退出了容器,希望重新进入容器,可以按照本步骤。

  1. 执行docker ps -a查看容器ID,本步骤以cdff266d01c9为例。
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
    cdff266d01c9        0c251c6f2ebd        "/bin/bash"         2 hours ago         Exited (0) 14 minutes ago                       nifty_einstein
  2. 执行以下命令重新启动容器。
    docker start cdff266d01c9
  3. 执行以下命令进入容器。
    docker exec -it cdff266d01c9 /bin/bash

删除容器镜像

智能小站内存空间较小,如果出现空间不够问题,可以删除不需要使用的容器和容器镜像。

  • 删除容器
    1. root用户登录智能小站。
    2. 执行如下命令查看CONTAINER ID(容器ID)。
      # 查看正在运行的容器
      docker ps
      # 查看所有容器
      docker ps -a

      回显类似如下信息(容器ID为“5f45daf9eb8f”):

      CONTAINER ID      IMAGE                    COMMAND       CREATED            STATUS          PORTS       NAMES
      5f45daf9eb8f      ascend-toolkit:7.0.0     "/bin/bash"   39 seconds ago     Up 28 minutes               boring_wright
    3. 删除正在运行的容器,需要先将容器停止运行。若删除的是已经停止运行的容器,请跳过该步骤。
      docker stop CONTAINER ID
      # 命令示例
      docker stop 5f45daf9eb8f
    4. 执行如下命令删除容器。
      docker rm CONTAINER ID
      # 命令示例
      docker rm 5f45daf9eb8f
  • 删除镜像

    删除镜像前,先要删除依赖它的容器,删除镜像步骤如下:

    1. 参见1~4删除依赖镜像的容器。若没有依赖镜像的容器,可跳过该步骤。
    2. 执行docker images命令查看IMAGE ID(镜像ID)。

      回显类似如下信息(镜像ID为“feb5d9fea6a5”):

      REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
      docker.io/hello-world   latest              feb5d9fea6a5        14 months ago       13.3 kB
    3. 执行如下命令删除镜像。
      docker rmi IMAGE ID
      # 命令示例
      docker rmi feb5d9fea6a5