使用容器镜像部署 Python Lambda 函数
有三种方法可以为 Python Lambda 函数构建容器映像:
-
Amazon 基本映像会预加载一个语言运行时系统、一个用于管理 Lambda 和函数代码之间交互的运行时系统接口客户端,以及一个用于本地测试的运行时系统接口仿真器。
-
Amazon 仅限操作系统的运行时系统
包含 Amazon Linux 发行版和运行时系统接口模拟器 。这些镜像通常用于为编译语言(例如 Go 和 Rust)以及 Lambda 未提供基础映像的语言或语言版本(例如 Node.js 19)创建容器镜像。您也可以使用仅限操作系统的基础映像来实施自定义运行时系统。要使映像与 Lambda 兼容,您必须在映像中包含 Python 的运行时系统接口客户端。 -
您还可以使用其他容器注册表的备用基本映像,例如 Alpine Linux 或 Debian。您还可以使用您的组织创建的自定义映像。要使映像与 Lambda 兼容,您必须在映像中包含 Python 的运行时系统接口客户端。
提示
要缩短 Lambda 容器函数激活所需的时间,请参阅 Docker 文档中的使用多阶段构建
此页面介绍了如何为 Lambda 构建、测试和部署容器映像。
Python Amazon 基本映像
Amazon为 Python 提供了以下基本映像:
标签 | 运行时 | 操作系统 | Dockerfile | 淘汰 |
---|---|---|---|---|
3.13 |
Python 3.13 | Amazon Linux 2023 | GitHub 上适用于 Python 3.13 的 Dockerfile |
未计划 |
3.12 |
Python 3.12 | Amazon Linux 2023 | GitHub 上适用于 Python 3.12 的 Dockerfile |
未计划 |
3.11 |
Python 3.11 | Amazon Linux 2 | GitHub 上适用于 Python 3.11 的 Dockerfile |
未计划 |
3.10 |
Python 3.10 | Amazon Linux 2 | GitHub 上适用于 Python 3.10 的 Dockerfile |
未计划 |
3.9 |
Python 3.9 | Amazon Linux 2 | GitHub 上的适用于 Python 3.9 的 Dockerfile |
未计划 |
Amazon ECR 存储库:gallery.ecr.aws/lambda/python
Python 3.12 及更高版本的基础映像基于 Amazon Linux 2023 最小容器映像。Python 3.8-3.11 基础映像基于 Amazon Linux 2 映像。与 Amazon Linux 2 相比,基于 AL2023 的映像具有多项优势,包括较小的部署占用空间以及 glibc
等更新版本的库。
基于 AL2023 的映像使用 microdnf
(符号链接为 dnf
)作为软件包管理器,而不是 Amazon Linux 2 中的默认软件包管理器 yum
。microdnf
是 dnf
的独立实现。有关基于 AL2023 的映像中已包含软件包的列表,请参阅 Comparing packages installed on Amazon Linux 2023 Container Images 中的 Minimal Container 列。有关 AL2023 和 Amazon Linux 2 之间区别的更多信息,请参阅 Amazon 计算博客上的 Introducing the Amazon Linux 2023 runtime for Amazon Lambda
注意
要在本地运行基于 AL2023 的映像,包括使用 Amazon Serverless Application Model(Amazon SAM),您必须使用 Docker 版本 20.10.10 或更高版本。
基本映像中的依赖项搜索路径
在代码中使用 import
语句时,Python 运行时系统会搜索其搜索路径中的目录,直到找到相应模块或包。默认情况下,运行时系统会首先搜索 {LAMBDA_TASK_ROOT}
目录。如果映像含有包含运行时系统的库的某个版本,则此版本将优先于运行时系统中包含的版本。
搜索路径中的其他步骤取决于您使用的 Python Lambda 基本映像的版本:
-
Python 3.11 及更高版本:包含运行时系统的库和安装了 pip 的库均安装在
/var/lang/lib/python3.11/site-packages
目录中。此目录优先于搜索路径中的/var/runtime
。您可以通过使用 pip 安装更新版本来覆盖 SDK。您可以使用 pip 来验证包含运行时系统的 SDK 及其依赖项是否与您安装的任何程序包兼容。 -
Python 3.8-3.10:包含运行时系统的库安装在
/var/runtime
目录中。安装了 pip 的库安装在/var/lang/lib/python3.x/site-packages
目录中。此/var/runtime
目录优先于搜索路径中的/var/lang/lib/python3.x/site-packages
。
通过添加以下代码段,您可以查看 Lambda 函数的完整搜索路径。
import sys search_path = sys.path print(search_path)
使用 Python 的 Amazon 基本映像
要完成本节中的步骤,您必须满足以下条件:
-
Docker
(Python 3.12 及更高版本基础映像的最低版本为 20.10.10) -
Python
要从 Python 的 Amazon 的基本映像创建容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
创建名为
lambda_function.py
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 Python 函数
import sys def handler(event, context): return 'Hello from Amazon Lambda using Python' + sys.version + '!'
-
创建名为
requirements.txt
的新文件。如果您使用的是上一步中的示例函数代码,则可以将文件留空,因为没有依赖项。否则,请列出每个必需的库。例如,如果您的函数使用的是 Amazon SDK for Python (Boto3),则requirements.txt
应如下所示:例 requirements.txt
boto3
-
使用以下配置创建一个新的 Dockerfile。
-
将
FROM
属性设置为基本映像的 URI。 -
使用 COPY 命令将函数代码和运行时系统依赖项复制到
{LAMBDA_TASK_ROOT}
,此为 Lambda 定义的环境变量。 -
将
CMD
参数设置为 Lambda 函数处理程序。
请注意,示例 Dockerfile 不包含 USER 指令
。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER
指令时默认为root
用户。例 Dockerfile
FROM public.ecr.aws/lambda/python:3.12 # Copy requirements.txt COPY requirements.txt ${LAMBDA_TASK_ROOT} # Install the specified packages RUN pip install -r requirements.txt # Copy function code COPY lambda_function.py ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.handler" ]
-
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build --platform linux/amd64 -t
docker-image
:test
.注意
该命令指定了
--platform linux/amd64
选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64
选项。
-
使用 docker run 命令启动 Docker 映像。在此示例中,
docker-image
是映像名称,test
是标签。docker run --platform linux/amd64 -p 9000:8080
docker-image
:test
此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations
创建本地端点。注意
如果为 ARM64 指令集架构创建 Docker 映像,请务必使用
--platform linux/
选项,而不是arm64
--platform linux/
选项。amd64
-
在新的终端窗口中,将事件发布到本地端点。
-
获取容器 ID。
docker ps
-
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c
替换为上一步中的容器 ID。docker kill
3766c4ab331c
将映像上传到 Amazon ECR 并创建 Lambda 函数
-
运行 get-login-password
命令,以针对 Amazon ECR 注册表进行 Docker CLI 身份验证。 -
将
--region
值设置为要在其中创建 Amazon ECR 存储库的 Amazon Web Services 区域。 -
将
111122223333
替换为您的 Amazon Web Services 账户 ID。
aws ecr get-login-password --region
cn-north-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn -
-
使用 create-repository
命令在 Amazon ECR 中创建存储库。 aws ecr create-repository --repository-name
hello-world
--regioncn-north-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注意
Amazon ECR 存储库必须与 Lambda 函数位于同一 Amazon Web Services 区域 内。
如果成功,您将会看到如下响应:
{ "repository": { "repositoryArn": "arn:aws:ecr:cn-north-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 docker tag
命令,将本地映像作为最新版本标记到 Amazon ECR 存储库中。在此命令中: -
docker-image:test
是 Docker 映像的名称和标签。这是您在 docker build
命令中指定的映像名称和标签。 -
将
<ECRrepositoryUri>
替换为复制的repositoryUri
。确保 URI 末尾包含:latest
。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例如:
docker tag
docker-image
:test
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest
。docker push
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 Lambda 函数。对于
ImageUri
,指定之前的存储库 URI。确保 URI 末尾包含:latest
。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注意
只要映像与 Lambda 函数位于同一区域内,您就可以使用其他 Amazon 账户中的映像创建函数。有关更多信息,请参阅 Amazon ECR 跨账户权限。
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code
Lambda 会将映像标签解析为特定的映像摘要。这意味着,如果您将用于部署函数的映像标签指向 Amazon ECR 中的新映像,则 Lambda 不会自动更新该函数以使用新映像。
要将新映像部署到相同的 Lambda 函数,即使 Amazon ECR 中的映像标签保持不变,也必须使用 update-function-code--publish
选项使用更新的容器映像创建函数的新版本。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
\ --publish
将备用基本映像与运行时系统接口客户端配合使用
如果使用仅限操作系统的基础映像或者备用基础映像,则必须在映像中包括运行时系统接口客户端。运行时系统接口客户端可扩展 将 Lambda 运行时 API 用于自定义运行时,用于管理 Lambda 和函数代码之间的交互。
使用 pip 程序包管理器安装 Python 的运行时系统接口客户端
pip install awslambdaric
您还可以从 GitHub 下载 Python 运行时接口客户端
以下示例演示了如何使用非 Amazon 基本映像为 Python 构建容器映像。示例 Dockerfile 使用官方 Python 基本映像。Dockerfile 包含 Python 的运行时系统接口客户端。
要完成本节中的步骤,您必须满足以下条件:
-
Python
要从非 Amazon 基本映像创建容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
创建名为
lambda_function.py
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 Python 函数
import sys def handler(event, context): return 'Hello from Amazon Lambda using Python' + sys.version + '!'
-
创建名为
requirements.txt
的新文件。如果您使用的是上一步中的示例函数代码,则可以将文件留空,因为没有依赖项。否则,请列出每个必需的库。例如,如果您的函数使用的是 Amazon SDK for Python (Boto3),则requirements.txt
应如下所示:例 requirements.txt
boto3
-
创建新 Dockerfile。以下 Dockerfile 使用官方 Python 基本映像而不是 Amazon 基本映像。Dockerfile 包含运行时系统接口客户端
,该客户端可使映像与 Lambda 兼容。以下示例 Dockerfile 将使用多阶段构建 。 -
将
FROM
属性设置为基本映像。 -
将
ENTRYPOINT
设置为您希望 Docker 容器在启动时运行的模块。在本例中,模块为运行时系统接口客户端。 -
将
CMD
设置为 Lambda 函数处理程序。
请注意,示例 Dockerfile 不包含 USER 指令
。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER
指令时默认为root
用户。例 Dockerfile
# Define custom function directory ARG FUNCTION_DIR="/function" FROM
python:3.12
AS build-image # Include global arg in this stage of the build ARG FUNCTION_DIR # Copy function code RUN mkdir -p ${FUNCTION_DIR} COPY . ${FUNCTION_DIR} # Install the function's dependencies RUN pip install \ --target ${FUNCTION_DIR} \ awslambdaric # Use a slim version of the base Python image to reduce the final image size FROMpython:3.12-slim
# Include global arg in this stage of the build ARG FUNCTION_DIR # Set working directory to function root directory WORKDIR ${FUNCTION_DIR} # Copy in the built dependencies COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric
" ] # Pass the name of the function handler as an argument to the runtime CMD [ "lambda_function.handler
" ] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build --platform linux/amd64 -t
docker-image
:test
.注意
该命令指定了
--platform linux/amd64
选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64
选项。
使用运行时系统接口仿真器
在本地计算机上安装并运行运行时系统接口仿真器
-
从项目目录中,运行以下命令以从 GitHub 下载运行时系统接口仿真器(x86-64 架构)并将其安装在本地计算机上。
-
使用 docker run 命令启动 Docker 映像。请注意以下几点:
-
docker-image
是映像名称,test
是标签。 -
/usr/local/bin/python -m awslambdaric lambda_function.handler
是ENTRYPOINT
,后跟您 Dockerfile 中的CMD
。
此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations
创建本地端点。注意
如果为 ARM64 指令集架构创建 Docker 映像,请务必使用
--platform linux/
选项,而不是arm64
--platform linux/
选项。amd64
-
-
将事件发布到本地端点。
-
获取容器 ID。
docker ps
-
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c
替换为上一步中的容器 ID。docker kill
3766c4ab331c
将映像上传到 Amazon ECR 并创建 Lambda 函数
-
运行 get-login-password
命令,以针对 Amazon ECR 注册表进行 Docker CLI 身份验证。 -
将
--region
值设置为要在其中创建 Amazon ECR 存储库的 Amazon Web Services 区域。 -
将
111122223333
替换为您的 Amazon Web Services 账户 ID。
aws ecr get-login-password --region
cn-north-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn -
-
使用 create-repository
命令在 Amazon ECR 中创建存储库。 aws ecr create-repository --repository-name
hello-world
--regioncn-north-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注意
Amazon ECR 存储库必须与 Lambda 函数位于同一 Amazon Web Services 区域 内。
如果成功,您将会看到如下响应:
{ "repository": { "repositoryArn": "arn:aws:ecr:cn-north-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 docker tag
命令,将本地映像作为最新版本标记到 Amazon ECR 存储库中。在此命令中: -
docker-image:test
是 Docker 映像的名称和标签。这是您在 docker build
命令中指定的映像名称和标签。 -
将
<ECRrepositoryUri>
替换为复制的repositoryUri
。确保 URI 末尾包含:latest
。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例如:
docker tag
docker-image
:test
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest
。docker push
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 Lambda 函数。对于
ImageUri
,指定之前的存储库 URI。确保 URI 末尾包含:latest
。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注意
只要映像与 Lambda 函数位于同一区域内,您就可以使用其他 Amazon 账户中的映像创建函数。有关更多信息,请参阅 Amazon ECR 跨账户权限。
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code
Lambda 会将映像标签解析为特定的映像摘要。这意味着,如果您将用于部署函数的映像标签指向 Amazon ECR 中的新映像,则 Lambda 不会自动更新该函数以使用新映像。
要将新映像部署到相同的 Lambda 函数,即使 Amazon ECR 中的映像标签保持不变,也必须使用 update-function-code--publish
选项使用更新的容器映像创建函数的新版本。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
\ --publish
对于如何从 Alpine 基本镜像创建 Python 镜像的示例,请参阅Amazon博客上的 Lambda 容器镜像支持