
# 准备镜像
![](https://support.huaweicloud.com/bestpractice-modelarts/public_sys-resources/note_3.0-zh-cn.png)
Kubernetes社区已经在v1.24版本中[移除Dockershim](https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/migrating-from-dockershim/)，建议将容器引擎从Docker逐步迁移至官方推荐的Containerd，以确保未来与Kubernetes版本的兼容性和持续支持。所以**轻量算力集群目前推荐使用containerd作为容器引擎，安装镜像**。
#### 步骤一：检查环境
1. SSH登录机器后，检查NPU设备检查。运行如下命令，返回NPU设备信息。
   ```
   npu-smi info                    # 在每个实例节点上运行此命令可以看到NPU卡状态
   npu-smi info -l | grep Total    # 在每个实例节点上运行此命令可以看到总卡数
   ```
   如出现错误，可能是机器上的NPU设备没有正常安装，或者NPU镜像被其他容器挂载。请先正常[安装NPU设备和驱动](https://support.huaweicloud.com/resmgmt-modelarts/umn-cluster-modelarts-0011.html)，或释放被挂载的NPU。
   
2. 检查containerd是否安装。
   ```
   containerd -v   # 检查containerd是否安装
   ```
   在创建CCE集群时，会选择containerd作为容器引擎，并默认给机器安装。**如尚未安装，说明机器操作系统安装错误。需要重新纳管机器，重新安装操作系统。**
   
3. 安装nerdctl工具。nerdctl是containerd的一个客户端命令行工具，使用方式和docker命令基本一致，可用于后续镜像构建步骤中。
   ```
   # 下载 nerdctl 工具，注意使用的是1.7.6 arm64版本
   wget https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-1.7.6-linux-arm64.tar.gz
   # 将程序解压至运行目录中
   tar -zxf nerdctl-1.7.6-linux-arm64.tar.gz -C /usr/bin/
   # 查看是否安装成功
   nerdctl -v
   ```
   
4. 安装buildkit工具。buildkit是从Docker从公司开源出来的下一代镜像构建工具，支持OCI标准的镜像构建，nerdctl需要结合buildkit一起使用。buildkit由两部分组成： buildkitd（服务端）：负责镜像构建，目前支持runc和containerd作为镜像构建环境，默认是runc。
   buildkitctl（客户端）：负责解析Dockerfile文件，并向服务端buildkitd发出构建请求。
   1. 下载并解压buildkit程序。
      ```
      # 下载 buildkit 工具，注意使用的是0.15.1 arm64版本
      wget https://github.com/moby/buildkit/releases/download/v0.15.1/buildkit-v0.15.1.linux-arm64.tar.gz
      # 创建解压的目录
      mkdir /usr/local/buildkit
      # 解压到指定的目录
      tar -zxf buildkit-v0.15.1.linux-arm64.tar.gz -C /usr/local/buildkit
      # 授予权限
      chmod -R 777 /usr/local/buildkit
      ```
      
   
   2. 添加环境变量。
      ```
      echo 'export PATH=/usr/local/buildkit/bin:$PATH' >> /etc/profile  
      # 注意这里的echo 要使用单引号，单引号会原样输出，双引号会解析变量
      source /etc/profile  # 使刚才配置生效
      ```
      
   
   3. 创建buildkitd的启动服务，如下为buildkitd.service的内容，复制以下全部命令并运行。
      ```
      cat <<EOF > /usr/lib/systemd/system/buildkitd.service
      [Unit]
      Description=buildkitd
      After=network.target
      [Service]
      ExecStart=/usr/local/buildkit/bin/buildkitd
      [Install]
      WantedBy=multi-user.target
      EOF
      ```
      
   
   4. 启动buildkitd的服务。
      ```
      # 重新加载Unit file
      systemctl daemon-reload
      # 启动服务
      systemctl start buildkitd
      # 开机自启动
      systemctl enable buildkitd
      # 查看状态
      systemctl status buildkitd
      ```
      
   
   5. 若buildkitd的服务运行状态如下图所示，则表示服务运行成功。使用Ctrl+C即可退出查看状态。 ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002503500639.png "点击放大")
      
    
 
 #### 步骤二：获取训练基础镜像
建议使用官方提供的镜像部署训练服务。镜像地址{image_url}参见[表2](https://support.huaweicloud.com/bestpractice-modelarts/modelarts_llm_train_c_5910002.html#ZH-CN_TOPIC_0000002510000949__zh-cn_topic_0000002503660297_table1512403716473)获取。
containerd 容器引擎有命名空间的概念，Kubernetes 下使用的 containerd 默认命名空间是 k8s.io。在导入镜像时需要指定命令空间为 k8s.io，否则使用 crictl images 无法查询到。以下命令可选其一进行镜像拉取：
- 使用 containerd 自带的工具 ctr 进行镜像拉取。
  ```
  ctr -n k8s.io image pull {image_url}
  ```
  
- 使用nerdctl工具拉取镜像。
  ```
  nerdctl --namespace k8s.io pull {image_url}
  ```
  
![](https://support.huaweicloud.com/bestpractice-modelarts/public_sys-resources/caution_3.0-zh-cn.png)
集群有多个节点，要确保每个节点都拥有镜像。
镜像获取完成后可通过如下其中一个命令进行查看：
```
# ctr 工具查看
ctr -n k8s.io image list
# 或
crictl image
# nerdctl 工具查看
nerdctl --namespace k8s.io image list
```
 #### 步骤三：构建训练镜像
1. 进入${workdir}/AscendCloud-LLM-\*/llm_train/AscendFactory目录下（[步骤一：上传代码包和权重文件](https://support.huaweicloud.com/bestpractice-modelarts/modelarts_llm_train_c_5910006.html#ZH-CN_TOPIC_0000002470740650__zh-cn_topic_0000002359962122_section2026095031315)中已经解压AscendCloud-\*.zip），目录下docker文件夹中有DockerFile用来构建镜像。
2. 进入docker/Dockerfile文件，将文件中 "image_name" 替换为[步骤二：获取训练基础镜像]中的基础镜像地址。

3. 执行以下命令制作训练镜像。安装过程需要连接互联网git clone，请确保机器可以访问公网。
   ```
   nerdctl --namespace k8s.io build  -f docker/Dockerfile --build-arg install_type=xxx -t <镜像名称>:<版本名称>  .
   ```
   nerdctl build 会去镜像仓库拉取镜像，**不会直接使用本地镜像** 。构建前可以 nerdctl pull 拉取测试以下镜像是否能拉取成功。
   - install_type：安装类型，可选mindspeed-llm, llamafactory, verl, mindspeed-rl, mindspeed-mm，mindspeed-mm-rl 根据实际要求选择。
   
   - \<镜像名称\>:\<版本名称\>：定义镜像名称。示例：pytorch_2_1_ascend:20240606。
   
   - 记住使用Dockerfile创建的新镜像名称， 后续使用 ${dockerfile_image_name} 表示。
     
 
 #### 步骤四：在节点机器中containerd登录
在SWR中单击右上角的"登录指令"，然后在跳出的登录指定窗口，单击复制临时登录指令。
图1复制登录指令   
![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002470740688.png "点击放大")
由于使用的容器引擎是containerd，不再是docker，因此需要改写复制的登录指令，将docker进行替换，使用nerdctl工具。
```
# docker login 替换为：
nerdctl login
```
 #### 步骤五：修改并上传镜像至SWR
1. 在机器中输入[步骤四：在节点机器中containerd登录]的登录指令后，使用下列示例命令将镜像上传至SWR：
   ```
   nerdctl --namespace k8s.io tag ${dockerfile_image_name} <镜像仓库地址>/<组织名称>/<镜像名称>:<版本名称>
   ```
   **参数说明：**
   - ${dockerfile_image_name}：在[步骤三：构建训练镜像]中使用Dockerfile创建的新镜像名称。
   
   - \<镜像仓库地址\>：可在SWR控制台上查询，容器镜像服务中登录指令末尾的域名即为镜像仓库地址。
   
   - \<组织名称\>：Step3中自己创建的组织名称。示例：GROUP_NAME
   
   - \<镜像名称\>:\<版本名称\>：定义镜像名称。示例：pytorch_2_3_ascend:20240606
   
   
   示例：
   ```
   nerdctl --namespace k8s.io tag  ${dockerfile_image_name}  swr.cn-southwest-2.myhuaweicloud.com/GPOUP_NAME/pytorch_2_3_ascend:20240606
   ```
   
2. 上传镜像至镜像仓库。
   ```
   nerdctl --namespace k8s.io push <镜像仓库地址>/<组织名称>/<镜像名称>:<版本名称>
   ```
   示例：
   ```
   nerdctl --namespace k8s.io push swr.cn-southwest-2.myhuaweicloud.com/GPOUP_NAME/pytorch_2_3_ascend:20240606
   ```
   
 
