在 AWS lambda 上部署 docker 应用
前言
使用 AWS lambda,我们可以在不考虑服务器的情况下上传代码并运行,但是这种方式最大的缺点就是代码包的大小限制,每一个 lambda 函数的代码包不能高于几十M。
现在,AWS lambda 允许以 docker 容器的方式运行,每一个 docker image 的大小允许高达 10G。通过这种方式,还可以轻松构建和部署依赖于较大依赖的工作任务,例如机器学习或数据密集型工作任务。与打包为 ZIP 部署的函数的功能一样,容器化部署的功能也具有相同的操作简单性、自动扩展、高可用性以及与许多服务的天然集成。
AWS lambda 提供了两种方式来部署容器,一种是基于 AWS 提供的镜像的部署方式,另一种是自定义镜像的部署方式,下面我们将对这种中方式的不同和使用做出阐述。
准备工作
在进行镜像部署之前,首先应该准备好以下几点:
- 拥有合规的 AWS 的账号
- 为每个将要部署的 lambda 函数提供一个 ECR(Elastic Container Registry)
基于 AWS 提供的镜像的部署方式
这种方式的最大好处就是操作比较简单,我们只需要把自己的代码复制到容器中并安装依赖即可。
选择镜像
选择 AWS 官方提供的 python 3.7 镜像 public.ecr.aws/lambda/python:3.7
。我们可以在 docker hub 上搜索 amazon/aws-lambda
来搜索其他语言的官方镜像。
定义 Dockerfile
定义代码结构如下:
1 | project |
这是一个最简单的代码结构,app.py 是函数的运行入口,我们需要按照 lambda 提供的运行模版来定义:
1 | import sys |
requirements.txt 是 python 程序的依赖包
最后我们定义最重要的 Dockerfile 文件:
1 | # 选择官方镜像 |
测试代码
由于 AWS 提供的基础镜像已经默认集成了运行时接口模拟器(Runtime Interface Emulator),我们可以直接通过下面命令启动一个容器:
1 | docker run --rm -p 9000:8080 <IMAGE_NAME>:latest |
容器运行起来之后我们可以通过 http 请求的方式进行测试请求:
1 | curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'\n |
基于自定义的镜像部署方式
有时,您需要使用自定义容器镜像。例如,为了遵循公司的指导原则或使用 AWS 不支持的运行时版本。
选择镜像
这里我们选择 python 的官方镜像 python:3.7
,我们也可以基于这个镜像预先安装一些常用的依赖包,这样我们就可以基于自己的镜像进行构建了。
定义 Dockerfile
定义代码结构如下:
1 | project |
相对于基于官方镜像构建的方式,项目目录中只是多了一个 entry.sh
文件。
app.py 是函数的运行入口,我们仍然需要按照 lambda 提供的运行模版来定义:
1 | import sys |
requirements.txt 是 python 程序的依赖包
最后我们定义最重要的 Dockerfile 文件,与上面不同的是,我们需要自己安装 AWS lambda 运行需要的依赖包:
1 | # 定义全局变量 |
测试代码
由于构建好的镜像中集成了运行时接口模拟器(Runtime Interface Emulator),我们可以直接通过下面命令启动一个容器:
1 | docker run --rm -p 9000:8080 <IMAGE_NAME>:latest |
容器运行起来之后我们可以通过 http 请求的方式进行测试请求:
1 | curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'\n |
上传部署
文章开头提高我们需要为每一个运行 docker 容器的 lambda 提供一个 ECR(Elastic Container Registry),用于上传定义好的镜像文件。假设我们已经创建好一个 ECR 仓库,这个仓库的地址为 100000000009.dkr.ecr.us-west-2.amazonaws.com/test-la-pure-func
,我们依据下面的步骤上传定义好的镜像到这个仓库。
构建 image
1 | sudo docker build -t 100000000009.dkr.ecr.us-west-2.amazonaws.com/test-la-pure-func:latest . |
登录 Registry
运行这一步必须在电脑安装安装好 aws-cli,并且已经做好相应的配置
1 | aws ecr get-login-password | docker login --username AWS --password-stdin 100000000009.dkr.ecr.us-west-2.amazonaws.com |
推动 image
1 | docker push 100000000009.dkr.ecr.us-west-2.amazonaws.com/test-la-pure-func:latest |
部署 lambda
建立 lambda 的时候只需要选择使用 docker 运行的方式,然后选择相应的镜像即可。
参考文献
[1] Deploy Python Lambda functions with container images https://docs.aws.amazon.com/lambda/latest/dg/python-image.html#python-image-create-alt
[2] New for AWS Lambda – Container Image Support https://aws.amazon.com/blogs/aws/new-for-aws-lambda-container-image-support/
[3] https://hub.docker.com/search?q=amazon%2Faws-lambda