在Amazon SageMaker平台上使用Docker部署Lambda函数
本文记录了笔者使用SageMaker在Amazon云平台上构建Docker镜像,并通过容器部署Lambda函数的过程。
1 相关工具
AWS CLI
- AWS Command Line Interface (AWS CLI) 是一个命令行工具,我们可以用它在终端中与 AWS 服务进行交互
- 文档:什么是 AWS Command Line Interface? - AWS Command Line Interface (amazon.com)
Docker
- Docker 是一个开源的应用容器引擎,我们可以用它来打包项目代码和依赖库
- 文档:Docker Docs: How to build, share, and run applications | Docker Documentation
Amazon ECR
- Amazon Elastic Container Registry (Amazon ECR) 是 AWS 托管容器映像注册表服务,我们可以用它来管理我们构建的docker镜像
- 文档:什么是 Amazon Elastic Container Registry? - Amazon ECR
2 准备工作
配置AWS CLI和Docker环境:
- 登录SageMaker,运行Jupyter Lab实例
- 在Jupyer中新建Terminal
- 在终端中使用命令
aws sts get-caller-identity
检查AWS CLI是否正确安装并配置用户信息 - 在终端中使用命令
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 tag
和 docker 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)。