获取容器镜像
本章节介绍如何制作容器包含NNRT软件的镜像来部署容器。部署容器最耗时的操作为制作容器镜像,为了让开发者更快的部署容器,我们在AscendHub发布了包含了CANN软件和典型模型的容器镜像,用户可以在宿主机直接拉取容器镜像从而实现快速部署容器。不过AscendHub上发布的镜像版本相较最新的CANN版本会有所延迟,所以如果AscendHub上的容器镜像不满足现场版本需求,您可以按照制作容器镜像的方法制作容器镜像来部署容器。
前提条件
- 容器OS镜像可从Docker Hub拉取,请确保安装环境能够连接网络。
- 用户需自行准备业务推理程序压缩包(支持tar、tgz格式),业务推理程序的压缩包格式,应为容器内自带的压缩程序支持的格式。
外挂磁盘至/var/lib/docker目录
由于小站默认内存容量较小,而制作容器镜像所需容量较大,因此如果小站外接了磁盘或其他存储介质,建议将外接磁盘或其他存储介质挂载到“/var/lib/docker”目录。
- 解挂“/var/lib/docker”目录所在分区。
- 登录智能小站web管理界面。
- 单击选择“管理 > 存储配置 > 存储管理”,进入磁盘设置界面。
- 选择挂载了“/var/lib/docker”目录所在分区,单击“解挂”,如图1所示。
若用户环境存在Docker容器,可能导致解挂失败。因此需要用户先删除Docker容器。操作如下:
- 以root用户登录服务器。
- 执行docker ps -a查询所有的容器(CONTAINER ID为容器ID)。
- 执行如下命令停止正在运行的容器。
docker stop CONTAINER ID
- 执行如下命令删除容器。
docker rm CONTAINER ID
- 创建分区挂载“/var/lib/docker”目录。
制作容器镜像
- 以root用户登录智能小站,执行docker images命令查看宿主机上是否已存在容器OS镜像,如下所示,如果已存在镜像,则直接执行3,否则执行2拉取容器OS镜像。
ubuntu 22.04 d5ca7a445605 5 months ago 65.6MB
- 执行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
- 构建容器镜像。
- 规划Dockerfile路径,如“/home/imagetest”。
- 进入规划的Dockerfile路径,执行cp /etc/slog.conf slog.conf命令,将“slog.conf”日志配置文件拷贝到当前目录。
- 将下载软件中获取的NNRT包和用户自行准备的业务推理程序压缩包上传到当前目录。
- 执行以下命令创建Dockerfile文件。
- 在键盘按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的镜像。
- 参见删除容器镜像删除无用的镜像和容器。
- 执行vi install.sh命令创建install.sh文件,解压业务推理程序压缩包。
#!/bin/bash #进入容器工作目录 cd /home/AscendWork #解压业务推理程序压缩包的命令请根据压缩包格式适配,压缩包名称请根据实际文件名称配置 tar xf dist.tar
- 执行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
- 在当前目录执行以下命令构建镜像。
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”表示镜像构建成功。
启动容器
若系统存在MEF功能,则不支持使用docker后台管理容器。
- 请执行如下命令基于新镜像运行一个容器,其中加粗部分内容需替换成填写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/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 \ -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,
执行该命令后,回显以下信息,表示成功进入该容器。
HwHiAiUser@6889930edc7b:/home/AscendWork$
- 容器启动后,执行以下命令查看当前docker容器中可以使用的davinci设备:
ls /dev/ | grep davinci*
命令执行情况如下图。
其中:
- davinci_manager为管理模块的字符设备节点。
- davinci0为该容器使用的davinci设备。
- 在容器内执行以下命令。
- 执行run.sh脚本启动NPU驱动dmp进程和推理程序。
cd /home/AscendWork ./run.sh
- 执行npu-smi info命令,查看芯片状态,如下图所示,表示容器挂载的芯片状态正常。
- 执行run.sh脚本启动NPU驱动dmp进程和推理程序。
容器镜像导出
用户可将容器导出为一个镜像文件,再导入其它服务器使用。操作步骤如下:
- 以root用户登录小站。
- 执行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
- 执行如下命令将容器保存成镜像。
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
- 执行docker images命令查看镜像。回显类似如下信息(该镜像仅为示例,请用户以实际情况为准):
REPOSITORY TAG IMAGE ID CREATED SIZE ascend-infer 7.0.0-ubuntu22.04-arm64-20230109 e43c96ec5ec7 9 seconds ago 1.35GB
- 执行如下命令保存镜像文件。
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
- 将生成的镜像文件下载至本地,用于后续通过FusionDirector部署到Atlas 500 A2智能小站。
进入容器
如果退出了容器,希望重新进入容器,可以按照本步骤。
- 执行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
- 执行以下命令重新启动容器。
docker start cdff266d01c9
- 执行以下命令进入容器。
docker exec -it cdff266d01c9 /bin/bash
删除容器镜像
智能小站内存空间较小,如果出现空间不够问题,可以删除不需要使用的容器和容器镜像。
- 删除容器
- 以root用户登录智能小站。
- 执行如下命令查看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
- 删除正在运行的容器,需要先将容器停止运行。若删除的是已经停止运行的容器,请跳过该步骤。
docker stop CONTAINER ID # 命令示例 docker stop 5f45daf9eb8f
- 执行如下命令删除容器。
docker rm CONTAINER ID # 命令示例 docker rm 5f45daf9eb8f