使用容器镜像部署 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 |
未计划 |
未计划 |
未计划 |
仅限操作系统的运行时系统 |
|
Amazon Linux 2 |
未计划 |
未计划 |
未计划 |
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 |
未计划 |
al2 |
仅限操作系统的运行时系统 | Amazon Linux 2 | GitHub 上用于仅限操作系统的运行时系统的 Dockerfile |
未计划 |
有关这些基本映像的更多信息,请参阅 Amazon ECR Public Gallery 中的 provided
您必须在 Go 处理程序中包含 aws-lambda-go/lambda
要完成本节中的步骤,您必须满足以下条件:
使用 provided.al2023
基本映像构建和部署 Go 函数
-
为项目创建一个目录,然后切换到该目录。
mkdir hello cd hello
-
初始化一个新的 Go 模块。
go mod init
example.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 版本相同。FROM
golang:1.20
as 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:al2023
COPY --from=build /helloworld/main ./main ENTRYPOINT [ "./main" ] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build --platform linux/amd64 -t
docker-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 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
使用非 Amazon 基本映像
您可以从非 Amazon 基本映像为 Go 构建容器映像。以下步骤中的示例 Dockerfile 使用 Alpine 基本映像
您必须在 Go 处理程序中包含 aws-lambda-go/lambda
要完成本节中的步骤,您必须满足以下条件:
使用 Alpine 基本映像构建和部署 Go 函数
-
为项目创建一个目录,然后切换到该目录。
mkdir hello cd hello
-
初始化一个新的 Go 模块。
go mod init
example.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
标签。 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
是标签。 -
/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 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