

# MicroVM 映像
<a name="microvms-images"></a>

本节介绍如何构建、配置、更新和管理 MicroVM 映像。

MicroVM 映像是一种用于为 MicroVM 定义的文件系统和应用程序环境的资源。MicroVM 映像包含您的运行时环境、应用程序代码和支持程序，例如后台进程和可观测性代理。要创建 MicroVM 映像，您需要提供一个 zip 压缩包，其中包含您上传到 Amazon S3 的 `Dockerfile` 以及您的应用程序构件。`Dockerfile` 用于定义应用程序的打包方式。Lambda 通过在 Lambda 托管式 MicroVM 基础映像提供的操作系统环境上运行您的 `Dockerfile`，从而构建您的应用程序容器映像。有关 MicroVM 基础映像的说明相见下文标题为“[MicroVM 基础映像](#microvms-images-base-images)“的部分。

您可以通过更新 MicroVM 基础映像来更新 MicroVM 的应用程序代码或配置。您触发的每次更新都会创建一个新的 MicroVM 映像版本。

## Lambda 如何构建 MicroVM 映像
<a name="microvms-images-creating"></a>

当您创建 MicroVM 映像时，Lambda 会执行以下操作：
+ 从 Amazon S3 中检索您打包的构件。
+ 从 Lambda 托管式基础映像启动一个全新的 MicroVM。
+ 执行您的 `Dockerfile` 中的指令。
+ 使用 `ENTRYPOINT` 或 `CMD` 指令启动您的应用程序。
+ 等待初始化完成，由生命周期挂钩发出信号。
+ 拍摄磁盘和内存状态的快照。

快照进程完成后，您的 MicroVM 映像将进入 `CREATED` 状态。这时您可以使用该 MicroVM 映像来创建 MicroVM，并且每个 MicroVM 映像都可用于创建多个独立的 MicroVM。从 MicroVM 映像运行的 MicroVM 会直接从快照状态恢复，从而实现快速启动。每个 MicroVM 映像都可用于运行多个 MicroVM，只要不超过您账户的可用限制即可。

有关打包代码和创建第一个 MicroVM 映像的分步演练，请参阅[创建您的第一个 MicroVM](microvms-getting-started.md)。

## MicroVM 大小调整
<a name="microvms-images-sizing"></a>

Lambda MicroVMs 使用基准-峰值模式运行，因此无需针对峰值活动调整每个计算环境的大小。您可以为 MicroVM 配置基准计算资源。在峰值活动期间，您的 MicroVM 可以自动垂直扩展到基准水平的 4 倍。您只需按 MicroVM 的运行时间支付基准费率，并且只需为超过基准水平的实际使用量按秒付费。

您可以在创建 MicroVM 映像时通过 `memory` 参数设置基准水平。vCPU 与内存将按比例扩展（2 GB = 1 vCPU）。默认基准水平为 2 GB/1 vCPU。

可使用的大小详见下表：


| 基准 | Peak | 最大磁盘空间 | 
| --- | --- | --- | 
| 0.5 GB 内存，0.25 个 vCPU | 2 GB 内存，1 个 vCPU | 8 GB | 
| 1 GB 内存，0.5 个 vCPU | 4 GB 内存，2 个 vCPU | 8 GB | 
| 2 GB 内存，1 个 vCPU（默认值） | 8 GB 内存，4 个 vCPU | 8 GB | 
| 4 GB 内存，2 个 vCPU | 16 GB 内存，8 个 vCPU | 16 GB | 
| 8 GB 内存，4 个 vCPU | 32 GB 内存，16 个 vCPU | 32 GB | 

## MicroVM 基础映像
<a name="microvms-images-base-images"></a>

MicroVM 基础映像是您的 MicroVM 映像的基础。Lambda 发布了 MicroVM 基础映像，其中包含 Amazon Linux 2023 操作系统以及运行 MicroVM 所需的服务组件。当您创建或更新 MicroVM 映像时，Lambda 会从该基础映像启动一个新的 MicroVM，并在此操作系统环境中运行您的 `Dockerfile` 指令。

Lambda 会定期（例如在应用安全补丁时）发布服务托管式 MicroVM 基础映像的新版本，以更新操作系统或服务组件。默认情况下，当您创建/更新自己的 MicroVM 映像时，将会使用服务托管式基础映像的最新版本。要进行问题排查或调试，您可以在使用 `base-image-version` 参数创建自己的 MicroVM 映像时，选择覆盖服务托管式基础映像的版本。

基础映像版本遵循如下弃用生命周期：
+ **`AVAILABLE`**：最新版本，建议使用。
+ **`DEPRECATED`**（60 天）：存在更新的版本。您仍然可以构建和运行。
+ **`EXPIRING`**（30 天）：无法创建新映像。现有映像仍然可以运行。
+ **`EXPIRED`**：无法生成或运行。需要使用支持的版本重建映像。
+ **`RECALLED`**：由于存在严重安全问题，立即不可用（罕见）。

要确保使用的最新版本，请关注弃用通知，并在新的基础映像版本发布后重建 MicroVM 映像。

请注意，MicroVM 基础映像不同于您在 Dockerfiles 中指定的容器基础映像。前者用于定义您的 MicroVM 操作系统环境，而后者用于定义在打包应用程序时要使用的基础容器映像，以确保能与 Lambda MicroVMs 配合使用。有关更多详细信息，请参阅有关[容器基本映像](#microvms-images-container-base)的一节。

使用以下 API 来发现可用的托管式 MicroVM 基础映像及其版本：

```
# List all managed MicroVM base images
aws lambda-microvms list-managed-microvm-images

# List the versions of a specific managed MicroVM base image
aws lambda-microvms list-managed-microvm-image-versions \
  --image-identifier arn:aws:lambda:{{us-east-1}}:aws:microvm-image:al2023-1
```

## MicroVM 映像构建钩子
<a name="microvms-images-build-hooks"></a>

Lambda 提供了多个 MicroVM 映像构建钩子，让您能够在创建 MicroVM 映像期间验证应用程序是否正确并优化性能。钩子在 Lambda 拍摄用于初始化每个 MicroVM 的快照之前运行。每个钩子都是您的应用程序公开的一个 HTTP 端点，Lambda 在构建过程中会调用该端点。通过响应这些请求，您可以控制和验证 MicroVM 映像的构建过程。Lambda 使用 HTTP 状态代码来确定钩子是否成功完成。

**重要**  
如果您配置了任何钩子，则必须指定应用程序用来侦听钩子请求的端口。


| 钩子 | 路径 | 说明 | HTTP 状态代码 | 超时 | 
| --- | --- | --- | --- | --- | 
| /ready | /aws/lambda-microvms/runtime/v1/ready | 在 MicroVM 映像构建期间，在您的应用程序通过 ENTRYPOINT 或 CMD 启动之后调用。表示您的应用程序准备就绪，可以拍摄快照。 | HTTP 503：尚未准备就绪；Lambda 会不断重试，直至超时。HTTP 200：初始化完成；Lambda 已拍摄快照。 | 1-3600 秒 (readyTimeoutInSeconds) | 
| /validate | /aws/lambda-microvms/runtime/v1/validate | 构建完成后，在从创建的映像启动的新 MicroVM 上调用。确认应用程序在恢复后运行正常。 | HTTP 503：需要更多时间才能完成验证；Lambda 会不断重试，直至超时。HTTP 200：验证通过。 | 1-3600 秒 (validateTimeoutInSeconds) | 

**重要**  
返回 HTTP 503 消息时，应立即将其退回，而不是在等待期间保持请求处于打开状态。如果在请求处于打开状态时超时，Lambda 将结束构建。

**注意**  
您还可以使用 /validate 钩子来优化启动时间。要执行此操作，请在验证期间运行模拟载荷。这使 Lambda 能够跟踪快照的访问区域，并在 MicroVM 启动期间优化其检索。

## 更新 MicroVM 映像
<a name="microvms-images-updating"></a>

您可以通过调用 `update-microvm-image` API 来更新现有的 MicroVM 映像。每次更新都会触发一个新的 MicroVM 映像版本构建。通常，您会出于下列目的更新 MicroVM 映像：
+ **部署新的应用程序代码**：指向新的代码构件（上传到 Amazon S3 的新 zip 文件）以发布应用程序的新版本。
+ **迁移至更新的 MicroVM 基础映像**：更改 MicroVM 基础映像 ARN 以升级到更新版本的 Lambda MicroVM 基础映像。有关更多信息，请参阅[MicroVM 映像修补](#microvms-images-patching)和[MicroVM 基础映像](#microvms-images-base-images)。
+ **更改构建角色**：在 Lambda 在构建期间需要的权限更改时更新构建角色 ARN，例如当您的代码构件移至其他 Amazon S3 存储桶或您开始从私有 ECR 存储库拉取时。
+ **调整运行时配置**：更改钩子、环境变量或功能，以重新配置 MicroVM 映像的构建和运行方式。
+ **更新描述**：更改 MicroVM 映像描述以记录该版本中更改的内容。

以下 CLI 命令演示了如何更新 MicroVM 映像。每次触发新构建的 `update-microvm-image` 调用都必须使用 `--base-image-arn` 和 `--build-role-arn` 参数，即使仅更改代码构件也不例外，省略这些参数会导致 `ValidationException`：

```
aws lambda-microvms update-microvm-image \
  --image-identifier {{arn:aws:lambda:us-east-1:123456789012:microvm-image:my-microvm-image}} \
  --code-artifact uri=s3://my-bucket/deployments/app-v2.zip \
  --base-image-arn arn:aws:lambda:{{us-east-1}}:aws:microvm-image:al2023-1 \
  --build-role-arn arn:aws:iam::123456789012:role/MicrovmBuildRole \
  --description "Updated with v2 application code"
```

## 映像状态和构建状态
<a name="microvms-images-states"></a>

每次创建或更新 MicroVM 映像时，Lambda 都会利用您的代码构件和基础映像构建一个**新版本**。随着时间的推移，一个 MicroVM 映像可能会有多个版本，并且您可以运行特定版本的 MicroVM。

三个独立的状态用于跟踪生命周期的不同方面：
+ **映像状态** ：MicroVM 映像资源的整体生命周期（正在创建、已就绪可以使用、正在更新、失败或正在删除）。
+ **版本状态**：特定版本的构建进度（待处理、正在构建、成功或失败）。检查 `stateReason` 或 CloudWatch 日志 (`/aws/lambda/microvms/<image-name>`) 以了解失败详情。
+ **版本激活**：是否允许某个已成功构建的版本运行 MicroVMS。Lambda 会自动将新版本设置为 `ACTIVE`；您可以将任何版本设置为 `INACTIVE`，以将其禁用而不删除。


| 州 | 可能的值 | 状态变换控制者 | 
| --- | --- | --- | 
| 映像状态 | CREATING, CREATED, CREATION\_FAILED, UPDATING, UPDATED, UPDATE\_FAILED, DELETING, DELETED, DELETION\_FAILED | Lambda（自动） | 
| 版本状态 | PENDING, IN\_PROGRESS, SUCCESSFUL, FAILED | Lambda（自动） | 
| 版本激活 | ACTIVE, INACTIVE | 您 (update-microvm-image-version --state) | 

要从某个版本运行 MicroVM，映像状态必须为 `CREATED` 或 `UPDATED`，版本状态必须为 `SUCCESSFUL`，切版本必须为 `ACTIVE`。

**注意**  
这些状态是相互独立的。处于 `CREATED` 状态的映像可以包含状态为 `FAILED` 的版本。

```
# De-activate a version
aws lambda-microvms update-microvm-image-version \
  --image-identifier my-image \
  --image-version 1.0 \
  --state INACTIVE
```

## 环境变量
<a name="microvms-images-env-vars"></a>

环境变量将在构建 MicroVM 映像时通过 `environmentVariables` 字段设置（最多 50 个变量）。环境变量会在快照构建过程中注入到容器中。您可以在运行新 MicroVM 时传递动态设置的有效载荷。要了解更多信息，请参阅有关运行 MicroVM 的部分。

## MicroVM 映像修补
<a name="microvms-images-patching"></a>

当有新的 MicroVM 基础映像可用时，您可以发出 `update-microvm-image` 调用以触发包含最新补丁的 MicroVM 映像构建。您可以省略 `base-image-version` 参数（对于最新版本），也可使用最新版本指定该参数。

## 容器基本映像
<a name="microvms-images-container-base"></a>

Lambda MicroVMs 会在 MicroVM 操作系统环境中将您的应用程序作为容器运行。您可以使用自己的 `Dockerfile` 来定义该容器，并且您的 `Dockerfile` 中的 `FROM` 指令会为您的应用程序设置*容器基础映像*。

您可以从适用于 Amazon Linux 2023 的 Lambda 基础容器映像 (`public.ecr.aws/lambda/microvms:al2023-minimal`) 开始，然后在该映像上添加自己的 `Dockerfile` 指令，也可以使用自己的基础容器映像。使用自己的容器映像时，请验证以下要求：

### 要求
<a name="microvms-images-container-base-requirements"></a>
+ 容器基础映像必须与目标 CPU 架构兼容。
+ 如果容器基础映像来自私有 AWS ECR 存储库，则构建角色需要具有 `ecr:GetAuthorizationToken` 和 `ecr:BatchGetImage` 权限。
+ 容器基础映像必须基于 Linux 操作系统。
+ 容器基础映像必须可以从 Lambda 构建基础设施（公共互联网或同一 AWS 账户中的 ECR 存储库）进行访问。
+ 容器基础映像必须与快照兼容，详见以下说明。

### 与快照兼容的基础映像
<a name="microvms-images-container-base-snapshot-compat"></a>

当 Lambda MicroVMs 从预初始化的快照启动每个 MicroVM 时，基础映像都必须与快照兼容。当您将自己的基础映像用于 Lambda MicroVMs 时，我们建议您查看[兼容性注意事项](microvms-images-snapshots.md#microvms-images-snapshots-compatibility)部分。

### 使用私有 ECR 映像
<a name="microvms-images-container-base-private"></a>

在您的 `Dockerfile` 的 `FROM` 指令中引用您的私有 ECR 容器基础映像：

```
FROM 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-base:latest
WORKDIR /app
COPY . .
CMD ["./my-app"]
```

将以下权限添加到您的构建角色：

```
{
  "Effect": "Allow",
  "Action": [
    "ecr:GetAuthorizationToken",
    "ecr:BatchCheckLayerAvailability",
    "ecr:GetDownloadUrlForLayer",
    "ecr:BatchGetImage"
  ],
  "Resource": "*"
}
```

## 操作系统功能
<a name="microvms-images-os-capabilities"></a>

默认情况下，Lambda MicroVMs 使用一组标准的 Linux 功能运行。在创建或更新 MicroVM 映像时，您可以使用 `additionalOsCapabilities` 字段来授予升级权限的 Linux 功能。`["ALL"]` 是唯一受支持的值。启用升级权限的功能，您将可以执行挂载文件系统、创建网络命名空间或运行 eBPF 程序等操作。这些功能将在 VM 隔离边界内应用，不会影响主机或其他 MicroVM。

```
aws lambda-microvms create-microvm-image \
  --name my-network-tool \
  --code-artifact uri=s3://my-bucket/app.zip \
  --base-image-arn arn:aws:lambda:{{us-east-1}}:aws:microvm-image:al2023-1 \
  --build-role-arn arn:aws:iam::123456789012:role/BuildRole \
  --additional-os-capabilities '["ALL"]'
```