
# 在ECS中通过Dockerfile从0制作自定义镜像用于推理
针对ModelArts目前不支持的AI引擎，您可以针对该引擎构建自定义镜像，并将镜像导入ModelArts，创建为模型。本文详细介绍如何使用自定义镜像完成模型的创建，并部署成在线服务。
操作流程如下：
1. [本地构建镜像]：在本地制作自定义镜像包，镜像包规范可参考[创建模型的自定义镜像规范](https://support.huaweicloud.com/usermanual-standard-modelarts/modelarts_23_0219.html)。
2. [本地验证镜像并上传镜像至SWR服务]：验证自定义镜像的API接口功能，无误后将自定义镜像上传至SWR服务。
3. [将自定义镜像创建为模型]：将上传至SWR服务的镜像导入ModelArts的模型管理。
4. [将模型部署为在线服务]：将导入的模型部署上线。
 #### 本地构建镜像
以Linux x86_x64架构的主机为例，您可以购买相同规格的ECS或者应用本地已有的主机进行自定义镜像的制作。
购买ECS服务器的具体操作请参考[购买并登录弹性云服务器](https://support.huaweicloud.com/qs-ecs/ecs_01_0103.html)。镜像选择公共镜像，推荐使用ubuntu18.04的镜像。
图1创建ECS服务器-选择X86架构的公共镜像   
![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586953633.png "点击放大")
1. 登录主机后，安装Docker，可参考[Docker官方文档](https://docs.docker.com/engine/install/binaries/#install-static-binaries)。也可执行以下命令安装docker。
   ```
   curl -fsSL get.docker.com -o get-docker.sh
   sh get-docker.sh
   ```
   
2. 获取基础镜像。本示例以Ubuntu18.04为例。
   ```
   docker pull ubuntu:18.04
   ```
   
3. 新建文件夹"self-define-images"，在该文件夹下编写自定义镜像的"Dockerfile"文件和应用服务代码"test_app.py"。本样例代码中，应用服务代码采用了flask框架。
   文件结构如下所示
   ```
   self-define-images/
       --Dockerfile
       --test_app.py
   ```
   - "Dockerfile"
     ```
     From ubuntu:18.04
     # 配置华为云的源，安装 python、python3-pip 和 Flask
     RUN cp -a /etc/apt/sources.list /etc/apt/sources.list.bak && \
       sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \
       sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \
       apt-get update && \
       apt-get install -y python3 python3-pip && \
       pip3 install  --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple  Flask
     # 复制应用服务代码进镜像里面
     COPY test_app.py /opt/test_app.py
     # 指定镜像的启动命令
     CMD python3  /opt/test_app.py
     ```
     
   
   - "test_app.py"
     ```
     from flask import Flask, request
     import json 
     app = Flask(__name__)
     @app.route('/greet', methods=['POST'])
     def say_hello_func():
         print("----------- in hello func ----------")
         data = json.loads(request.get_data(as_text=True))
         print(data)
         username = data['name']
         rsp_msg = 'Hello, {}!'.format(username)
         return json.dumps({"response":rsp_msg}, indent=4)
     @app.route('/goodbye', methods=['GET'])
     def say_goodbye_func():
         print("----------- in goodbye func ----------")
         return '\nGoodbye!\n'
     @app.route('/', methods=['POST'])
     def default_func():
         print("----------- in default func ----------")
         data = json.loads(request.get_data(as_text=True))
         return '\n called default func !\n {} \n'.format(str(data))
     # host must be "0.0.0.0", port must be 8080
     if __name__ == '__main__':
         app.run(host="0.0.0.0", port=8080)
     ```
     
    
4. 进入"self-define-images"文件夹，执行以下命令构建自定义镜像"test:v1"。
   ```
   docker build -t test:v1 .
   ```
   
5. 您可以使用"docker images"查看您构建的自定义镜像。
 
 #### 本地验证镜像并上传镜像至SWR服务
1. 在本地环境执行以下命令启动自定义镜像
   ```
   docker run -it -p 8080:8080 test:v1
   ```
   图2启动自定义镜像   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556433736.png "点击放大") 
2. 另开一个终端，执行以下命令验证自定义镜像的三个API接口功能。
   ```
   curl -X POST -H "Content-Type: application/json" --data '{"name":"Tom"}'  127.0.0.1:8080/
   curl -X POST -H "Content-Type: application/json" --data '{"name":"Tom"}' 127.0.0.1:8080/greet
   curl -X GET 127.0.0.1:8080/goodbye
   ```
   如果验证自定义镜像功能成功，结果如下图所示。
   图3校验接口   
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002556274084.png "点击放大") 

3. 上传自定义镜像至SWR服务。
4. 完成自定义镜像上传后，您可以在"容器镜像服务\>我的镜像\>自有镜像"列表中看到已上传镜像。
 
 #### 将自定义镜像创建为模型
参考[从容器镜像中导入模型文件创建模型](https://support.huaweicloud.com/usermanual-standard-modelarts/inference-modelarts-0009.html)，导入元模型，您需要特别关注以下参数：
- 元模型来源：选择"从容器镜像中选择"
  - 容器镜像所在的路径：选择已制作好的自有镜像
    图4选择已制作好的自有镜像   
    ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002586793689.png "点击放大") 
  
  - 容器调用接口：指定模型启动的协议和端口号。请确保协议和端口号与自定义镜像中提供的协议和端口号保持一致。
  
  - 镜像复制：选填，选择是否将容器镜像中的模型镜像复制到ModelArts中。
  
  - 健康检查：选填，用于指定模型的健康检查。仅当自定义镜像中配置了健康检查接口，才能配置"健康检查"，否则会导致模型创建失败。
   
- apis定义：选填，用于编辑自定义镜像的apis定义。模型apis定义需要遵循ModelArts的填写规范，参见[模型配置文件编写说明](https://support.huaweicloud.com/usermanual-standard-modelarts/inference-modelarts-0056.html)。
  本样例的配置文件如下所示：
  ```
  [{
          "url": "/",
          "method": "post",
          "request": {
              "Content-type": "application/json"
          },
          "response": {
              "Content-type": "application/json"
          }
      },
  {
          "url": "/greet",
          "method": "post",
          "request": {
              "Content-type": "application/json"
          },
          "response": {
              "Content-type": "application/json"
          }
      },
  {
          "url": "/goodbye",
          "method": "get",
          "request": {
              "Content-type": "application/json"
          },
          "response": {
              "Content-type": "application/json"
          }
      }
  ]
  ```
  
 
 #### 将模型部署为在线服务
1. [部署模型为在线服务](https://support.huaweicloud.com/inference-modelarts/inference2.0-modelarts-0004.html)。
2. 在线服务创建成功后，您可以在服务详情页查看服务详情。
3. 您可以通过"预测"页签访问在线服务。
 
