

# 使用容器映像创建 Lambda 函数
<a name="images-create"></a>

您的 AWS Lambda 函数代码由脚本或编译的程序及其依赖项组成。您可以使用*部署包*将函数代码部署到 Lambda。Lambda 支持两种类型的部署包：容器镜像和 .zip 文件归档。

有三种方法可以为 Lambda 函数构建容器映像：
+ [使用 Lambda 的 AWS 基本映像](#runtimes-images-lp)

  [AWS 基本映像](#runtimes-images-lp)会预加载一个语言运行时系统、一个用于管理 Lambda 和函数代码之间交互的运行时系统接口客户端，以及一个用于本地测试的运行时系统接口仿真器。
+ [使用 AWS 仅限操作系统的基础镜像](#runtimes-images-provided)

  [AWS 仅限操作系统的运行时系统](https://gallery.ecr.aws/lambda/provided)包含 Amazon Linux 发行版和[运行时系统接口模拟器](https://github.com/aws/aws-lambda-runtime-interface-emulator/)。这些镜像通常用于为编译语言（例如 [Go](go-image.md#go-image-provided) 和 [Rust](lambda-rust.md)）以及 Lambda 未提供基础映像的语言或语言版本（例如 Node.js 19）创建容器镜像。您也可以使用仅限操作系统的基础映像来实施[自定义运行时系统](runtimes-custom.md)。要使映像与 Lambda 兼容，则必须在映像中包含适用于您的语言的[运行时系统接口客户端](#images-ric)。
+ [使用非 AWS 基本映像](#images-types)

  您还可以使用其他容器注册表的备用基本映像，例如 Alpine Linux 或 Debian。您还可以使用您的组织创建的自定义映像。要使映像与 Lambda 兼容，则必须在映像中包含适用于您的语言的[运行时系统接口客户端](#images-ric)。

**提示**  
要缩短 Lambda 容器函数激活所需的时间，请参阅 Docker 文档中的[使用多阶段构建](https://docs.docker.com/build/building/multi-stage/)。要构建高效的容器映像，请遵循[编写 Dockerfiles 的最佳实践](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)。

要从容器映像创建 Lambda 函数，请在本地构建映像，然后将其上传到 Amazon Elastic Container Registry（Amazon ECR）存储库。如果您使用的是 [AWS Marketplace](https://docs.aws.amazon.com/marketplace/latest/userguide/container-based-products.html) 卖家提供的容器映像，则需要先将该映像克隆到您的私有 Amazon ECR 存储库中。然后，在您创建该函数时指定存储库 URI。Amazon ECR 存储库必须与 Lambda 函数位于同一 AWS 区域 内。只要映像与 Lambda 函数位于同一区域内，您就可以使用其他 AWS 账户中的映像创建函数。有关更多信息，请参阅 [Amazon ECR 跨账户权限](#configuration-images-xaccount-permissions)。

**注意**  
对于容器映像，Lambda 不支持 Amazon ECR FIPS 端点。如果您的存储库 URI 包含 `ecr-fips`，则表示您使用的是 FIPS 端点。示例：`111122223333.dkr.ecr-fips.us-east-1.amazonaws.com`。

本页面介绍了创建与 Lambda 兼容的容器映像的基本映像类型和要求。

**注意**  
您无法更改现有函数的[部署包类型](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType)（.zip 或容器映像）。例如，您无法将容器映像函数转换为使用 .zip 文件归档。您必须创建新函数。

**Topics**
+ [

## 要求
](#images-reqs)
+ [

## 使用 Lambda 的 AWS 基本映像
](#runtimes-images-lp)
+ [

## 使用 AWS 仅限操作系统的基础镜像
](#runtimes-images-provided)
+ [

## 使用非 AWS 基本映像
](#images-types)
+ [

## 运行时接口客户端
](#images-ric)
+ [

## Amazon ECR 权限
](#gettingstarted-images-permissions)
+ [

## 函数周期
](#images-lifecycle)

## 要求
<a name="images-reqs"></a>

安装 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 和 [Docker CLI](https://docs.docker.com/get-docker)。此外，请注意以下要求：
+ 容器映像必须实施 [将 Lambda 运行时 API 用于自定义运行时](runtimes-api.md)。AWS开源[运行时接口客户端](#images-ric)实施 API。您可以将运行时接口客户端添加到首选基本映像中以使其与 Lambda 兼容。
+ 容器映像必须能够在只读文件系统上运行。您的函数代码可以访问具有介于 512 MB 至 10,240 MB（以 1 MB 为增量）的存储空间的可写 `/tmp` 目录。
+ 默认 Lambda 用户必须能够读取运行函数代码所需的所有文件。Lambda 通过定义具有最低权限的默认 Linux 用户来遵循安全最佳实践。这意味着您无需在 Dockerfile 中指定 [USER](https://docs.docker.com/reference/dockerfile/#user)。验证您的应用程序代码是否不依赖于其他 Linux 用户被限制运行的文件。
+ Lambda 仅支持基于 Linux 的容器映像。
+ Lambda 提供多架构基础映像。但是，您为函数构建的映像必须仅针对其中一个架构。Lambda 不支持使用多架构容器映像的函数。

## 使用 Lambda 的 AWS 基本映像
<a name="runtimes-images-lp"></a>

您可以使用 Lambda 的其中一个 [AWS 基本映像](https://gallery.ecr.aws/lambda/)，为函数代码构建容器映像。基本镜像预加载了语言运行时和在 Lambda 上运行容器镜像所需的其他组件。将函数代码和依赖项添加到基本镜像中，然后将其打包为容器镜像。

AWS定期为 Lambda 的AWS基本映像提供更新。如果 Dockerfile 在 FROM 属性中包含映像名称，则 Docker 客户端将从 [Amazon ECR 存储库](https://gallery.ecr.aws/lambda/)中提取最新版本的映像。要使用更新后的基本映像，必须重建容器映像并[更新函数代码](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html)。

Node.js 20、Python 3.12、Java 21、.NET 8、Ruby 3.3 及更高版本的基础映像都基于 [Amazon Linux 2023 最小容器映像](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html)。早期的基础映像使用 Amazon Linux 2。与 Amazon Linux 2 相比，AL2023 具有多项优势，包括较小的部署占用空间以及 `glibc` 等更新版本的库。

基于 AL2023 的映像使用 `microdnf`（符号链接为 `dnf`）作为软件包管理器，而不是 Amazon Linux 2 中的默认软件包管理器 `yum`。`microdnf` 是 `dnf` 的独立实现。有关基于 AL2023 的映像中已包含软件包的列表，请参阅[比较 Amazon Linux 2023 容器映像上安装的软件包](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html)中的**最小容器**列。有关 AL2023 和 Amazon Linux 2 之间区别的更多信息，请参阅 AWS Compute Blog 上的 [Introducing the Amazon Linux 2023 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/)。

**注意**  
要在本地运行基于 AL2023 的映像，包括使用 AWS Serverless Application Model（AWS SAM），您必须使用 Docker 版本 20.10.10 或更高版本。

要使用 AWS 基本映像构建容器映像，请选择您的首选语言的说明：
+ [Node.js](nodejs-image.md#nodejs-image-instructions)
+ [TypeScript](typescript-image.md#base-image-typescript)（使用 Node.js 基本映像）
+ [Python](python-image.md#python-image-instructions)
+ [Java](java-image.md#java-image-instructions) 
+ [Go](go-image.md#go-image-provided)
+ [.NET](csharp-image.md#csharp-image-instructions)
+ [Ruby](ruby-image.md#ruby-image-instructions)

## 使用 AWS 仅限操作系统的基础镜像
<a name="runtimes-images-provided"></a>

[AWS 仅限操作系统的运行时系统](https://gallery.ecr.aws/lambda/provided)包含 Amazon Linux 发行版和[运行时系统接口模拟器](https://github.com/aws/aws-lambda-runtime-interface-emulator/)。这些镜像通常用于为编译语言（例如 [Go](go-image.md#go-image-provided) 和 [Rust](lambda-rust.md)）以及 Lambda 未提供基础映像的语言或语言版本（例如 Node.js 19）创建容器镜像。您也可以使用仅限操作系统的基础映像来实施[自定义运行时系统](runtimes-custom.md)。要使映像与 Lambda 兼容，则必须在映像中包含适用于您的语言的[运行时系统接口客户端](#images-ric)。


| 标签 | 运行时 | 操作系统 | Dockerfile | 弃用 | 
| --- | --- | --- | --- | --- | 
| al2023 | 仅限操作系统的运行时系统 | Amazon Linux 2023 | [GitHub 上用于仅限操作系统的运行时系统的 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2023/Dockerfile.provided.al2023) |   2029 年 6 月 30 日   | 
| al2 | 仅限操作系统的运行时系统 | Amazon Linux 2 | [GitHub 上用于仅限操作系统的运行时系统的 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2/Dockerfile.provided.al2) |   2026 年 7 月 31 日   | 

Amazon Elastic Container Registry Public Gallery：[gallery.ecr.aws/lambda/provided](https://gallery.ecr.aws/lambda/provided)

## 使用非 AWS 基本映像
<a name="images-types"></a>

Lambda 支持符合以下映像清单格式之一的任何映像：
+ Docker Image Manifest V2，Schema 2（与 Docker 版本 1.10 和更新版本配合使用）
+ Open Container Initiative (OCI) 规范（v1.0.0 和更高版本）

Lambda 支持的最大未压缩图像大小为 10GB，包括所有层。

**注意**  
要使映像与 Lambda 兼容，则必须在映像中包含适用于您的语言的[运行时系统接口客户端](#images-ric)。
为了获得最佳性能，请将图像清单大小保持在 25,400 字节以下。为了减少图像清单的大小，请尽量减少图像中的图层数量并减少注释。

## 运行时接口客户端
<a name="images-ric"></a>

如果使用[仅限操作系统的基础映像](#runtimes-images-provided)或者备用基础映像，则必须在映像中包括运行时系统接口客户端。该运行时系统接口客户端必须扩展 [将 Lambda 运行时 API 用于自定义运行时](runtimes-api.md)，它管理 Lambda 与函数代码之间的交互。AWS 为以下语言提供开源运行时系统接口客户端：
+  [Node.js](nodejs-image.md#nodejs-image-clients) 
+  [Python](python-image.md#python-image-clients) 
+  [Java](java-image.md#java-image-clients) 
+  [.NET](csharp-image.md#csharp-image-clients) 
+  [Go](go-image.md#go-image-clients) 
+  [Ruby](ruby-image.md#ruby-image-clients) 
+  [Rust](lambda-rust.md) – 

如果您使用的语言没有 AWS 提供的运行时系统接口客户端，则必须创建您自己的运行时系统接口客户端。

## Amazon ECR 权限
<a name="gettingstarted-images-permissions"></a>

在从容器映像创建 Lambda 函数之前，您必须在本地构建映像并将其上传到 Amazon ECR 存储库。在您创建该函数时，指定 Amazon ECR 存储库 URI。

确保创建函数的用户或角色的权限包含 `GetRepositoryPolicy`、`SetRepositoryPolicy`、`BatchGetImage` 和 `GetDownloadUrlForLayer`。

例如，使用 IAM 控制台创建具有以下策略的角色：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "ecr:SetRepositoryPolicy",
        "ecr:GetRepositoryPolicy",
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ],
      "Resource": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world"
    }
  ]
}
```

------

### Amazon ECR 存储库策略
<a name="configuration-images-permissions"></a>

要将相同账户中的函数用作 Amazon ECR 中的容器映像，您可以向 Amazon ECR 存储库策略添加 `ecr:BatchGetImage` 和 `ecr:GetDownloadUrlForLayer` 权限。以下示例显示最小策略：

```
{
        "Sid": "LambdaECRImageRetrievalPolicy",
        "Effect": "Allow",
        "Principal": {
          "Service": "lambda.amazonaws.com"
        },
        "Action": [
          "ecr:BatchGetImage",
          "ecr:GetDownloadUrlForLayer"
        ]
    }
```

有关更多 Amazon ECR 存储库权限的信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的[私有存储库策略](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html)。

如果 Amazon ECR 存储库不包含这些权限，则 Lambda 会尝试自动添加这些权限。仅当调用 Lambda 的主体具有 `ecr:getRepositoryPolicy` 和 `ecr:setRepositoryPolicy` 权限时，Lambda 才能添加这些权限。

要查看或编辑您的 Amazon ECR 存储库权限，请参阅《Amazon Elastic Container Registry 用户指南》**中的[设置私有存储库策略声明](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html)。

#### Amazon ECR 跨账户权限
<a name="configuration-images-xaccount-permissions"></a>

相同区域中的不同账户可以创建一个使用您的账户拥有的容器镜像的函数。在以下示例中，您的 [Amazon ECR 存储库权限策略](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html)需要以下语句，才能向账号 123456789012 授予访问权限。
+ **CrossAccountPermission** – 允许账号 123456789012 创建和更新使用此 ECR 存储库中的镜像的 Lambda 函数。
+ **LambdaECRImageCrossAccountRetrievalPolicy**：如果在延迟期内未调用 Lambda，则 Lambda 最终会将函数的状态设置为不活动。此语句是必需的，以便 Lambda 可以检索容器镜像，代表 123456789012 拥有的函数进行优化和缓存。

**Example – 添加对存储库的跨账户权限**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "CrossAccountPermission",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ],
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Resource": "arn:aws:ecr:us-east-1:123456789012:repository/example-lambda-repository"
    },
    {
      "Sid": "LambdaECRImageCrossAccountRetrievalPolicy",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ],
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Condition": {
        "ArnLike": {
          "aws:sourceARN": "arn:aws:lambda:us-east-1:123456789012:function:*"
        }
      },
      "Resource": "arn:aws:ecr:us-east-1:123456789012:repository/example-lambda-repository"
    }
  ]
}
```

要授予对多个账户的访问权限，您可以在 `CrossAccountPermission` 策略中将该账户 ID 添加到主体列表，并在 `LambdaECRImageCrossAccountRetrievalPolicy` 中将该账户 ID 添加到条件评估列表。

如果您在 AWS Organization 中使用多个账户，我们建议您在 ECR 权限策略中枚举每个账户 ID。此方法遵循在 IAM 策略中设置窄权限的 AWS 安全最佳实践。

除了 Lambda 权限外，创建函数的用户或角色还必须拥有 `BatchGetImage` 和 `GetDownloadUrlForLayer` 权限。

## 函数周期
<a name="images-lifecycle"></a>

上传新的或更新的容器镜像后，Lambda 会在函数可以处理调用之前优化镜像。优化过程可能需要几秒钟的时间。函数会一直处于 `Pending` 状态，直到过程完成，此时状态将转为 `Active`。在函数到达 `Active` 状态之前，您无法调用该函数。

如果函数在数周内未被调用，则 Lambda 回收其优化版本，函数将转换为 `Inactive` 状态。要重新激活函数，必须调用它。Lambda 拒绝第一次调用，函数进入 `Pending` 状态，直到 Lambda 重新优化镜像。然后函数返回到 `Active` 状态。

Lambda 定期从 Amazon ECR 存储库获取关联的容器映像。如果相应的容器镜像不再存在于 Amazon ECR 上或权限已撤消，则函数将进入 `Failed` 状态，并且 Lambda 将对任何函数调用返回失败。

您可以使用 Lambda API 获取函数状态的相关信息。有关更多信息，请参阅 [Lambda 函数状态](functions-states.md)。