使用容器镜像部署 Go Lambda 函数
有两种方法可以为 Go Lambda 函数构建容器映像:
-
Go 的实施方式与其他托管式运行时系统不同。由于 Go 本机编译为可执行的二进制文件,因此它不需要专用的语言运行时。使用仅限操作系统的基础映像为 Lambda 构建 Go 映像。要使映像与 Lambda 兼容,您必须在映像中包含
aws-lambda-go/lambda软件包。 -
您还可以使用其他容器注册表的备用基本映像,例如 Alpine Linux 或 Debian。您还可以使用您的组织创建的自定义映像。要使映像与 Lambda 兼容,您必须在映像中包含
aws-lambda-go/lambda软件包。
提示
要缩短 Lambda 容器函数激活所需的时间,请参阅 Docker 文档中的使用多阶段构建
此页面介绍了如何为 Lambda 构建、测试和部署容器映像。
用于部署 Go 函数的 Amazon 基础映像
Go 的实施方式与其他托管式运行时系统不同。由于 Go 本机编译为可执行的二进制文件,因此它不需要专用的语言运行时。使用仅限操作系统的基础映像将 Go 函数部署到 Lambda。
| 名称 | 标识符 | 操作系统 | 弃用日期 | 阻止函数创建 | 阻止函数更新 |
|---|---|---|---|---|---|
|
仅限操作系统的运行时系统 |
|
Amazon Linux 2023 |
2029 年 6 月 30 日 |
2029 年 7 月 31 日 |
2029 年 8 月 31 日 |
|
仅限操作系统的运行时系统 |
|
Amazon Linux 2 |
2026 年 6 月 30 日 |
2026 年 7 月 31 日 |
2026 年 8 月 31 日 |
Amazon Elastic Container Registry Public Gallery:gallery.ecr.aws/lambda/provided
Go 运行时系统接口客户端
aws-lambda-go/lambda 程序包包括运行时接口的实施。有关如何在映像中使用 aws-lambda-go/lambda 的示例,请参阅 使用 Amazon 仅限操作系统的基础镜像 或 使用非 Amazon 基本映像。
使用 Amazon 仅限操作系统的基础镜像
Go 的实施方式与其他托管式运行时系统不同。由于 Go 本机编译为可执行的二进制文件,因此它不需要专用的语言运行时。使用仅限操作系统的基础映像为 Go 函数构建容器映像。
| 标签 | 运行时 | 操作系统 | Dockerfile | 弃用 |
|---|---|---|---|---|
al2023 |
仅限操作系统的运行时系统 | Amazon Linux 2023 | GitHub 上用于仅限操作系统的运行时系统的 Dockerfile |
2029 年 6 月 30 日 |
al2 |
仅限操作系统的运行时系统 | Amazon Linux 2 | GitHub 上用于仅限操作系统的运行时系统的 Dockerfile |
2026 年 6 月 30 日 |
有关这些基本映像的更多信息,请参阅 Amazon ECR Public Gallery 中的 provided
您必须在 Go 处理程序中包含 aws-lambda-go/lambda
使用 provided.al2023 基本映像构建和部署 Go 函数
-
为项目创建一个目录,然后切换到该目录。
mkdir hello cd hello -
初始化一个新的 Go 模块。
go mod initexample.com/hello-world -
添加 lambda 库作为新模块的依赖项。
go get github.com/aws/aws-lambda-go/lambda -
创建一个名为
main.go的文件,然后在文本编辑器中打开它。这是适用于 Lambda 函数的代码。您可以使用以下示例代码进行测试,也可以将其替换为您自己的代码。package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) } -
使用文本编辑器在项目目录中创建一个 Dockerfile。
-
以下示例 Dockerfile 将使用多阶段构建
。这样便可在每个步骤中使用不同的基本映像。您可以使用一个映像(例如 Go 基本映像 )来编译代码并构建可执行二进制文件。然后,您可以在最后的 FROM语句中使用不同的映像(例如provided.al2023)来定义部署到 Lambda 的映像。构建过程与最终部署映像分开,因此最终映像仅包含运行应用程序所需的文件。 -
您可以使用可选的
lambda.norpc标签排除 lambda库的远程过程调用(RPC)组件。只有在使用已弃用的 Go 1.x 运行时系统时才需要 RPC 组件。排除 RPC 会减小部署包的大小。 -
请注意,示例 Dockerfile 不包含 USER 指令
。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER指令时默认为root用户。
例 – 多阶段构建 Dockerfile
注意
确保您在 Dockerfile 中指定的 Go 版本(例如
golang:1.20)与用于创建应用程序的 Go 版本相同。FROMgolang:1.20as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build with optional lambda.norpc tag COPY main.go . RUN go build-tags lambda.norpc-o main main.go # Copy artifacts to a clean image FROMpublic.ecr.aws/lambda/provided:al2023COPY --from=build /helloworld/main ./main ENTRYPOINT [ "./main" ] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image并为其提供test标签。要使您的映像与 Lambda 兼容,您必须使用 --provenance=false选项。docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.注意
该命令指定了
--platform linux/amd64选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64选项。
使用运行时系统接口仿真器provided.al2023 基本映像还包括运行时系统接口仿真器。
在本地计算机上运行运行时系统接口仿真器
-
使用 docker run 命令启动 Docker 映像。请注意以下几点:
-
docker-image是映像名称,test是标签。 -
./main是您的 Dockerfile 中的ENTRYPOINT。
docker run -d -p 9000:8080 \ --entrypoint /usr/local/bin/aws-lambda-rie \docker-image:test ./main此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations创建本地端点。 -
-
在新的终端窗口中,使用 curl 命令将事件发布到以下端点:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'此命令使用空事件调用函数并返回响应。某些函数可能需要 JSON 负载。示例:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}' -
获取容器 ID。
docker ps -
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c替换为上一步中的容器 ID。docker kill3766c4ab331c
将映像上传到 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 --regioncn-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-namehello-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 tagdocker-image:test111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest。docker push111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 Lambda 函数。对于
ImageUri,指定之前的存储库 URI。确保 URI 末尾包含:latest。aws lambda create-function \ --function-namehello-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-namehello-worldresponse.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-namehello-world\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest\ --publish
使用非 Amazon 基本映像
您可以从非 Amazon 基本映像为 Go 构建容器映像。以下步骤中的示例 Dockerfile 使用 Alpine 基本映像
您必须在 Go 处理程序中包含 aws-lambda-go/lambda
使用 Alpine 基本映像构建和部署 Go 函数
-
为项目创建一个目录,然后切换到该目录。
mkdir hello cd hello -
初始化一个新的 Go 模块。
go mod initexample.com/hello-world -
添加 lambda 库作为新模块的依赖项。
go get github.com/aws/aws-lambda-go/lambda -
创建一个名为
main.go的文件,然后在文本编辑器中打开它。这是适用于 Lambda 函数的代码。您可以使用以下示例代码进行测试,也可以将其替换为您自己的代码。package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) } -
使用文本编辑器在项目目录中创建一个 Dockerfile。以下示例 Dockerfile 使用 Alpine 基本映像
。请注意,示例 Dockerfile 不包含 USER 指令 。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER指令时默认为root用户。例 Dockerfile
注意
确保您在 Dockerfile 中指定的 Go 版本(例如
golang:1.20)与用于创建应用程序的 Go 版本相同。FROM golang:1.20.2-alpine3.16 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build COPY main.go . RUN go build -o main main.go # Copy artifacts to a clean image FROM alpine:3.16 COPY --from=build /helloworld/main /main ENTRYPOINT [ "/main" ] -
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image并为其提供test标签。要使您的映像与 Lambda 兼容,您必须使用 --provenance=false选项。docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.注意
该命令指定了
--platform linux/amd64选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64选项。
使用运行时系统接口仿真器
在本地计算机上安装并运行运行时系统接口仿真器
-
从项目目录中,运行以下命令以从 GitHub 下载运行时系统接口仿真器(x86-64 架构)并将其安装在本地计算机上。
-
使用 docker run 命令启动 Docker 映像。请注意以下几点:
-
docker-image是映像名称,test是标签。 -
/main是您的 Dockerfile 中的ENTRYPOINT。
此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations创建本地端点。注意
如果为 ARM64 指令集架构创建 Docker 映像,请务必使用
--platform linux/选项,而不是arm64--platform linux/选项。amd64 -
-
将事件发布到本地端点。
-
获取容器 ID。
docker ps -
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c替换为上一步中的容器 ID。docker kill3766c4ab331c
将映像上传到 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 --regioncn-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-namehello-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 tagdocker-image:test111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest。docker push111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 Lambda 函数。对于
ImageUri,指定之前的存储库 URI。确保 URI 末尾包含:latest。aws lambda create-function \ --function-namehello-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-namehello-worldresponse.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-namehello-world\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest\ --publish