

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用容器映像部署 Lambda 函数
<a name="deploy-lambda-functions-with-container-images"></a>

*Ram Kandaswamy，Amazon Web Services*

## Summary
<a name="deploy-lambda-functions-with-container-images-summary"></a>

AWS Lambda 支持将容器镜像作为部署模型。此模式介绍了如何通过容器映像部署 Lambda 函数。 

Lambda 是一项无服务器、事件驱动计算服务，让您能够为几乎任何类型的应用程序或后端服务运行代码，而无需预调配或管理服务器。借助对 Lambda 函数的容器映像支持，您可以为应用程序构件提供高达 10 GB 的存储空间，并能够使用熟悉的容器映像开发工具。

此模式中的示例使用 Python 作为基础编程语言，但您也可以使用其他语言，例如 Java、Node.js 或 Go。要获取来源，可以考虑基于 Git 的系统，例如 GitHub、或 Bitbucket GitLab，或者使用亚马逊简单存储服务 (Amazon S3) Service。

## 先决条件和限制
<a name="deploy-lambda-functions-with-container-images-prereqs"></a>

**先决条件**
+ Amazon Elastic Container Registry(Amazon ECR) 已激活
+ 应用程序代码
+ 带运行时系统接口客户端以及最新版本的 Python 的 Docker 映像
+ Git 的工作知识

**限制**
+ 支持的最大映像大小为 10 GB。
+ 基于容器部署的 Lambda 的最长运行时间为 15 分钟。

## 架构
<a name="deploy-lambda-functions-with-container-images-architecture"></a>

**目标架构**

![\[创建 Lambda 函数的四步流程。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/e421cc58-d33e-493d-b0bb-c3ffe39c2eb9/images/7f36d3d8-d161-497a-b036-26d886a16c69.png)


 

1. 您可以创建 Git 存储库，并将应用程序代码提交至该存储库。

1. 该 AWS CodeBuild 项目由提交更改触发。

1. 该 CodeBuild 项目创建 Docker 映像并将构建的映像发布到 Amazon ECR。

1. 您可以使用 Amazon ECR 中的映像创建 Lambda 函数。

**自动化和扩展**

可以通过使用 SDK 中的 AWS CloudFormation AWS Cloud Development Kit (AWS CDK)、或 API 操作来自动执行此模式。Lambda 可根据请求数量自动扩缩，您可以使用并发参数对其进行优化。有关更多信息，请参阅 [Lambda 文档](https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html)。

## 工具
<a name="deploy-lambda-functions-with-container-images-tools"></a>

**AWS 服务**
+ [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)AWS CloudFormationhelps 您可以设置 AWS 资源，快速一致地配置资源，并在和的整个生命周期中 AWS 账户 对其进行管理 AWS 区域。此模式使用 App [AWS CloudFormation lication Composer](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/app-composer-for-cloudformation.html)，它可以帮助您直观地查看和编辑 CloudFormation 模板。
+ [AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) 是一项完全托管式构建服务，可编译源代码、运行单元测试和生成部署就绪的构件。
+ [Amazon Elastic Container Registry（Amazon ECR）](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html)是一项安全、可扩展且可靠的托管容器映像注册表服务。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，无需预调配或管理服务器。它只在需要时运行您的代码，并自动进行扩展，因此您只需为使用的计算时间付费。

**其他工具**
+ [Docker](https://www.docker.com/) 是一组平台即服务（PaaS）产品，它们利用操作系统级的虚拟化技术在容器中提供软件。
+ [GitHub[GitLab](https://docs.gitlab.com/ee/user/get_started/get_started_projects.html)](https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories)、和 [Bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/tutorial-learn-bitbucket-with-git/) 是一些常用的基于 Git 的源代码控制系统，用于跟踪源代码更改。

## 最佳实践
<a name="deploy-lambda-functions-with-container-images-best-practices"></a>
+ 使函数足够高效足够小，以避免加载不必要的文件。
+ 努力将静态层置于 Docker 文件列表的高处，并将变化频率更高的层置于低处。这将改善缓存，从而提高性能。
+ 映像拥有者负责更新和修补映像。将此更新周期添加至您的操作流程。有关详情，请参阅 [AWS Lambda 文档](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-code)。

## 操作说明
<a name="deploy-lambda-functions-with-container-images-epics"></a>

### 在中创建项目 CodeBuild
<a name="create-a-project-in-codebuild"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建 Git 存储库。 | 创建 Git 存储库，其中将包含应用程序源代码、Dockerfile 和 `buildspec.yaml` 文件。 | 开发者版 | 
| 创建 CodeBuild 项目。 | 要使用 CodeBuild 项目创建自定义 Lambda 映像，请执行以下操作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-lambda-functions-with-container-images.html) | 开发者版 | 
| 编辑 Dockerfile。 | Dockerfile 应位于您开发应用程序的顶级目录中。Python 代码应该在 `src` 文件夹中。创建映像时，使用 [Lambda 支持的官方映像](https://gallery.ecr.aws/lambda?page=1)。否则，将发生引导错误，从而导致打包过程更加困难。有关详细信息，请参阅[其他信息](#deploy-lambda-functions-with-container-images-additional)部分。 | 开发者版 | 
| 在 Amazon ECR 中创建一个存储库。 | 在 Amazon ECR 中创建容器存储库。在以下示例命令中，创建名为 `cf-demo` 的存储库：<pre>aws ecr create-repository --cf-demo </pre>存储库将在 `buildspec.yaml` 文件中引用。 | AWS 管理员、开发人员 | 
| 将映像推送到 Amazon ECR | 您可以使用 CodeBuild 来执行映像构建过程。 CodeBuild 需要获得权限才能与 Amazon ECR 交互并使用 S3。作为该过程的一部分，将构建 Docker 映像并将其推送至 Amazon ECR 注册表。有关模板和代码的详细信息，请参阅 [其他信息](#deploy-lambda-functions-with-container-images-additional)部分。 | 开发者版 | 
| 验证映像是否在存储库中。 | 若要验证映像是否在存储库中，请在 Amazon ECR 控制台上选择**存储库**。如果 Amazon ECR 设置中启用了漏洞扫描功能，则应列出带有标签和漏洞扫描报告结果的映像。 有关更多信息，请参阅 [AWS 文档](https://docs.aws.amazon.com/cli/latest/reference/ecr/put-registry-scanning-configuration.html)。 | 开发者版 | 

### 创建运行映像的 Lambda 函数
<a name="create-the-lambda-function-to-run-the-image"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建 Lambda 函数。 | 在 Lambda 控制台上，选择**创建函数**，然后选择**容器映像**。输入函数名称和 Amazon ECR 存储库中映像的 URI，然后选择**创建函数**。有关更多信息，请参阅 [AWS Lambda 文档](https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html)。 | 应用程序开发人员 | 
| 测试 Lambda 函数。 | 若要调用并测试该函数，请选择**测试**。有关更多信息，请参阅 [AWS Lambda 文档](https://docs.aws.amazon.com/lambda/latest/dg/testing-functions.html)。 | 应用程序开发人员 | 

## 问题排查
<a name="deploy-lambda-functions-with-container-images-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 构建未成功。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-lambda-functions-with-container-images.html) | 

## 相关资源
<a name="deploy-lambda-functions-with-container-images-resources"></a>
+ [Lambda 的基本映像](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-images.html)
+ [的 Docker 示例 CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html)
+ [传递临时凭证](https://aws.amazon.com/premiumsupport/knowledge-center/codebuild-temporary-credentials-docker/)

## 附加信息
<a name="deploy-lambda-functions-with-container-images-additional"></a>

**编辑 Dockerfile**

以下代码显示了您在 Dockerfile 中编辑的命令。

```
FROM public.ecr.aws/lambda/python:3.xx

# Copy function code
COPY app.py ${LAMBDA_TASK_ROOT} 
COPY requirements.txt  ${LAMBDA_TASK_ROOT} 

# install dependencies
RUN pip3 install --user -r requirements.txt

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.lambda_handler" ]
```

在 `FROM` 命令中，为 Lambda 支持的 Python 版本使用适当的值（例如，`3.12`）。这将是公有 Amazon ECR 映像存储库中可用的基础映像。 

`COPY app.py ${LAMBDA_TASK_ROOT}` 命令将代码复制至 Lambda 函数将使用的任务根目录。此命令使用环境变量，因此我们无要担心实际路径。将要运行的函数作为参数传递至 `CMD [ "app.lambda_handler" ]` 命令。

`COPY requirements.txt` 命令捕获代码所需依赖项。 

`RUN pip install --user -r requirements.txt` 命令将依赖项安装至本地用户目录。 

若要构建映像，请运行以下命令。

```
docker build -t <image name> .
```

**在 Amazon ECR 中添加映像**

在以下代码中，将 `aws_account_id` 替换为账号，如果正在使用其他区域，则替换为 `us-east-1`。该`buildspec`文件使用 CodeBuild 内部版本号将图像版本唯一标识为标签值。您可以更改此设置，以满足您的要求。

*buildspec 自定义代码*

```
phases:
  install:
    runtime-versions:
       python: 3.xx
  pre_build:
    commands:
      - python3 --version
      - pip3 install --upgrade pip
      - pip3 install --upgrade awscli
      - sudo docker info
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - ls
      - cd app
      - docker build -t cf-demo:$CODEBUILD_BUILD_NUMBER .
      - docker container ls
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.us-east-1.amazonaws.com
      - docker tag cf-demo:$CODEBUILD_BUILD_NUMBER aws_account_id.dkr.ecr.us-east-1.amazonaws.com/cf-demo:$CODEBUILD_BUILD_NUMBER
      - docker push aws_account_id.dkr.ecr.us-east-1.amazonaws.com/cf-demo:$CODEBUILD_BUILD_NUMBER
```