在Amazon SageMaker平台上使用Docker部署Lambda函数

发布时间 2023-04-28 22:31:59作者: 云野Winfield

1 相关工具

AWS CLI

Docker

Amazon ECR

2 准备工作

配置AWS CLI和Docker环境:

  1. 登录SageMaker,运行Jupyter Lab实例
  2. 在Jupyer中新建Terminal
  3. 在终端中使用命令 aws sts get-caller-identity 检查AWS CLI是否正确安装并配置用户信息
  4. 在终端中使用命令 docker --version 检查docker服务是否正常运行

3 构建镜像

流程示例:

  • 在SageMaker Jupyter Terminal下选择一个干净的镜像构建目录,比如:~/Docker/images/demo

  • 在镜像构建目录下创建代码目录:mkdir src,并在该目录下放入项目代码。这里我们先放入一个测试文件 src/demo.py

    import xgboost as xgb
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score
    
    
    def iris():
        iris = load_iris()
        X, y = iris.data, iris.target
        X_train, X_test, y_train, y_test = train_test_split(X, y)
        xgb_clf = xgb.XGBClassifier(use_label_encoder=False)
        xgb_clf.fit(X_train, y_train)
        y_pred = xgb_clf.predict(X_test)
        accuracy = accuracy_score(y_test, y_pred)
        return f"Accuracy: {accuracy * 100.0:.2f}%"
        
    
    if __name__ == "__main__":
        iris()
    
  • 接着,在镜像构建目录下创建Lambda函数入口 app.py

    from src.demo import iris
    
    def handler(event, context):
        res = iris()
        print(res)
        return 'Execution complete.'
    
  • 记得在src目录下创建__init__.py,以确保该目录下的代码能正确地被 app.py 引用

  • 接着,在镜像构建目录下放入python依赖库文档 requirements.txt,比如:

    xgboost==1.4.0
    scikit-learn==0.24.2
    
  • 最后,使用 vi Dockerfile 命令在镜像构建目录下创建 Dockerfile 文件,该文件内容如下:

    FROM public.ecr.aws/lambda/python:3.9
    
    # Copy codes
    COPY app.py ${LAMBDA_TASK_ROOT}
    COPY src ${LAMBDA_TASK_ROOT}/src
    
    # Install dependencies
    COPY requirements.txt .
    RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --target "${LAMBDA_TASK_ROOT}"
    
    # Set handler
    CMD [ "app.handler" ]
    
  • 此时镜像构建目录(~/Docker/images/demo)下的文件结构应为:

    .
      |-src
      |  |-demo.py
      |  |-__init__.py
      |-Dockerfile
      |-app.py
      |-requirements.txt
    
  • 以上内容准备完毕后,就可以在镜像构建目录下执行:docker build -t demo . 进行镜像构建了。如果镜像构建成功,命令行中将出现以下提示:

    ...
    Step 6/6 : CMD [ "app.handler" ]
     ---> Running in 619d5209a704
    Removing intermediate container 619d5209a704
     ---> 90b3206652cd
    Successfully built 90b3206652cd
    Successfully tagged demo:latest
    
  • 镜像构建完成后,我们可通过以下命令来启动容器:

    docker run -p 9000:8080 demo
    

    接着,我们可以在新终端中使用以下命令来测试容器:

    curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
    

    看到命令行反馈以下结果,即说明该镜像Demo构建成功:

    Execution complete. Accuracy: 92.11%
    

4 配置ECR并推送镜像

由于SageMaker使用的默认角色没有ECR访问权限,因此我们要先配置相关角色权限:

  • 在SageMaker命令行中使用aws sts get-caller-identity命令查看当前角色的Arn标识符

    • Arn标识符就是下面方括号中的字串 xxx

      {
          "UserId": "...:SageMaker",
          "Account": "...",
          "Arn": ".../AmazonSageMaker-ExecutionRole-[xxx]/SageMaker"
      }
      
  • 在Amazon Web页面左上角的Services中检索IAM,进入IAM控制台

  • 在IAM > 角色页面下,使用之前获得的Arn标识符来找到SageMaker中使用的角色

  • 点击角色名称,然后点“添加权限-附加策略”

    • 如果之前没创建过相关策略,则需要点右上角“创建策略”
    • 服务选择“ Elastic Container Registry”,在手动操作栏中勾选“所有 Elastic Container Registry 操作 (ecr:*)”,在资源栏中选择“所有资源”
  • 检索相应的策略名称,勾选策略,并点击右下角“添加权限”


配置好权限后,我们开始配置ECR:

  • 在Amazon Web页面左上角的Services中检索ECR,进入ECR控制台
  • 在 “Amazon ECR > 存储库” 页面下,点击右上角“创建存储库”,接着指定存储库名称,然后创建存储库
  • 在 “Amazon ECR > 存储库” 页面下点击存储库名称,接着点击右上角“查看推送命令”,记录相关的命令内容

接下来,我们回到SageMaker的命令行中,开始准备推送镜像

首先,用刚才配置ECR时记录的命令进行身份认证:

aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com

接着,使用 docker tagdocker push 命令来建立本地镜像与远程存储库间的关联,并上传镜像:

docker tag [镜像名称] [repositoryUri]
docker push [repositoryUri]
  • 镜像名称 可以用 docker images 命令查看
  • repositoryUri 可以在之前配置 ECR 时记录的命令中查看

如果镜像推送成功,我们可以看到如下提示:

The push refers to repository [xxx.dkr.ecr.xxx.amazonaws.com.cn/...]
5de42a5b9119: Pushed 
5de42a5b9119: Pushed 
067c834639a8: Pushed 
247be14e2d7d: Pushed 
99dbacd26707: Pushed 
99dbacd26707: Pushed 
6bc71b616cc0: Pushed 
2d244e0816c6: Pushed 
c9e4c0dbfe49: Pushed 
c9e4c0dbfe49: Pushed 
b7f75c52e232: Pushed 
latest: digest: sha256:... size: ...

我们也可以在Amazon Web页面上的ECR控制台中查看刚刚上传的镜像。

5 使用镜像创建Lambda函数

在Amazon Web页面中依次进入:Lambda -> 函数 -> 创建函数,接着选择“从容器映像中创建函数”

  • 容器映像 URI 可以直接点下方“浏览映像”来获取

注:容器运行需要更大的内存,因此建议在 “函数配置 - 常规配置”中设置更大的内存配额(比如512M或1024M)。

6 参考信息