请使用 AWS SAM CLI 来尝试 Lambda 容器支持
这篇文章是关于Saison Information Systems 2020年圣诞日历的第四篇文章。
首先
在2020年的AWS re:Invent大会上,宣布了对AWS Lambda的容器镜像支持。
AWS Lambda现在支持容器镜像作为打包格式。
最终在AWS上也出现了类似于Cloud Run的东西!你在那里期待了吗
然而, 遗憾的是,它并不是能够轻松地在Lambda中运行任何容器映像的功能。
它是一种功能,可以将Lambda函数封装为容器映像并进行部署,
因此创建的容器映像必须实现Lambda运行时API,并具备与Lambda函数的兼容性。
AWS SAM CLI 在 v1.13.1 版本中也支持容器镜像。
发布1.13.1版本-支持Lambda容器镜像
https://github.com/aws/aws-sam-cli/releases/tag/v1.13.1
试试看
如前所述,AWS SAM CLI 需要版本为 v1.13.1 或更高。
$ sam --version
SAM CLI, version 1.13.1
创建项目
我们可以使用sam init提供的项目模板来选择Image类型的包。
我们将使用nodejs12.x的基础镜像来创建示例项目。
$ sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 2
Which base image would you like to use?
1 - amazon/nodejs12.x-base
2 - amazon/nodejs10.x-base
3 - amazon/python3.8-base
4 - amazon/python3.7-base
5 - amazon/python3.6-base
6 - amazon/python2.7-base
7 - amazon/ruby2.7-base
8 - amazon/ruby2.5-base
9 - amazon/go1.x-base
10 - amazon/java11-base
11 - amazon/java8.al2-base
12 - amazon/java8-base
13 - amazon/dotnetcore3.1-base
14 - amazon/dotnetcore2.1-base
Base image: 1
Project name [sam-app]:
Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates
-----------------------
Generating application:
-----------------------
Name: sam-app
Base Image: amazon/nodejs12.x-base
Dependency Manager: npm
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
以下是已创建的文件清单。
可以看到已创建了 Dockerfile。
$ cd sam-app
$ tree
.
├── events
│ └── event.json
├── hello-world
│ ├── app.js
│ ├── Dockerfile
│ ├── package.json
│ └── tests
│ └── unit
│ └── test-handler.js
├── README.md
└── template.yaml
在Dockerfile中指定了由AWS提供的基础镜像。
只要使用AWS提供的基础镜像,就可以预加载执行Lambda函数所需的运行时以及其他组件,
因此只需添加Lambda函数的代码和其依赖关系即可,不会有任何问题。
FROM public.ecr.aws/lambda/nodejs:12
COPY app.js package.json ./
RUN npm install
# Command can be overwritten by providing a different command in the template directly.
CMD ["app.lambdaHandler"]
为了将独立的容器映像转换为与Lambda兼容,需要在基础映像中添加一系列软件包,这些软件包实现了Lambda Runtime API,称为Runtime Interface Clients (RIC)。
template.yaml文件的内容如下:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
# ImageConfig:
# Uncomment this to override command here from the Dockerfile
# Command: ["app.lambdaHandler"]
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Metadata:
DockerTag: nodejs12.x-v1
DockerContext: ./hello-world
Dockerfile: Dockerfile
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
要对容器镜像进行打包,需要指定 PackageType: Image。
指定是可选的,可指定的值为 Zip 或 Image。
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-packagetype
Properties:
PackageType: Image
在SAM CLI中构建容器镜像,您可以使用Metadata资源属性声明Dockerfile、Context、Tag等信息。您还可以使用DockerBuildArgs条目指定构建时的参数。详细信息请参阅此链接:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html#build-container-image
Metadata:
DockerTag: nodejs12.x-v1
DockerContext: ./hello-world
Dockerfile: Dockerfile
构建形象
使用sam build命令来构建容器镜像。
$ sam build
Building codeuri: . runtime: None metadata: {'DockerTag': 'nodejs12.x-v1', 'DockerContext': './hello-world', 'Dockerfile': 'Dockerfile'} functions: ['HelloWorldFunction']
Building image for HelloWorldFunction function
Setting DockerBuildArgs: {} for HelloWorldFunction function
Step 1/4 : FROM public.ecr.aws/lambda/nodejs:12
---> ccbddaf00c51
Step 2/4 : COPY app.js package.json ./
---> fb16c5342f63
Step 3/4 : RUN npm install
---> Running in faa9eb4d503c
npm WARN deprecated debug@3.2.6: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)
npm WARN deprecated mkdirp@0.5.4: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
npm notice created a lockfile as package-lock.json. You should commit this file.
added 107 packages from 544 contributors and audited 107 packages in 5.755s
16 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
---> 8db6f5505058
Step 4/4 : CMD ["app.lambdaHandler"]
---> Running in 08e14cc877aa
---> 271c7f34a0c7
Successfully built 271c7f34a0c7
Successfully tagged helloworldfunction:nodejs12.x-v1
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
已经创建了被封装的容器镜像。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworldfunction nodejs12.x-v1 271c7f34a0c7 3 minutes ago 471MB
本地测试
为了在本地测试作为容器映像打包的 Lambda 函数,您可以使用一个轻量级的 Web 服务器,即 Lambda Runtime Interface Emulator(RIE)。由于 AWS 提供的基础映像已经集成了 RIE,因此您只需从构建映像中创建容器即可立即执行测试。
$ docker run -d -p 9000:8080 helloworldfunction:nodejs12.x-v1
a510b1f8bf0fd5c0d7c6a3716ddaf96462452abcdff26285d1e8471c6e829cc8
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
{"statusCode":200,"body":"{\"message\":\"hello world\"}"}
由于 RIE 将 HTTP 请求转换为 JSON 事件并进行代理,因此不支持 X-Ray 和其他 Lambda 集成功能。
如果使用自己独特的基础映像,可以通过将 RIE 集成到映像中或者绑定安装 RIE 并将其用作容器的入口点来运行测试。有关更多信息,请参考:https://docs.aws.amazon.com/lambda/latest/dg/images-test.html#images-test-alternative
当然,由于我们正在使用 SAM CLI,所以也可以通过 sam local invoke 进行测试。
$ sam local invoke
Invoking Container created from helloworldfunction:nodejs12.x-v1
Image was not found.
Building image.................
Skip pulling image and use local one: helloworldfunction:rapid-1.13.1.
START RequestId: 05284faf-5a20-46fc-a695-111eb3d0f085 Version: $LATEST
END RequestId: 05284faf-5a20-46fc-a695-111eb3d0f085
REPORT RequestId: 05284faf-5a20-46fc-a695-111eb3d0f085 Init Duration: 1.86 ms Duration: 96.09 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 128 MB
” 简化部署”
为了推送容器镜像,需要事先创建一个仓库,但可以把镜像推送给 SAM CLI!
$ aws ecr create-repository --repository-name lambda-container-test
{
"repository": {
"repositoryUri": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-test",
"imageScanningConfiguration": {
"scanOnPush": false
},
"registryId": "123456789012",
"imageTagMutability": "MUTABLE",
"repositoryArn": "arn:aws:ecr:ap-northeast-1:123456789012:repository/lambda-container-test",
"repositoryName": "lambda-container-test",
"createdAt": 1606926983.0
}
}
执行 sam deploy –guided。通过指定刚才创建的仓库作为图像仓库,将在部署时自动进行图像推送。
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [us-east-1]: ap-northeast-1
Image Repository []: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-test
Images that will be pushed:
helloworldfunction:nodejs12.x-v1 to 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-test:helloworldfunction-271c7f34a0c7-nodejs12.x-v1
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: n
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment: Found!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx
A different default S3 bucket can be set in samconfig.toml
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-test]
6d7acece320f: Pushed
105893862807: Pushed
3642f26c4fcb: Pushed
1807102b87b6: Pushed
120614c3628c: Pushed
0d8c48ae73f7: Pushed
e4f26f8be15f: Pushed
af6d16f2417e: Pushed
helloworldfunction-271c7f34a0c7-nodejs12.x-v1: digest: sha256:7a83998f07e54249948db91846abd9dbfecbe175181fe0876b5980a635b9e70f size: 1998
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : False
Deployment image repository : 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-container-test
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
~~以降省略~~
发送请求到创建的API Gateway并确认其功能。
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello world"}
请注意事项等
-
- CloudFormation のスタックを削除しても、ECR 側のイメージは削除されません。
- コールドスタード時の実行時間
由于无法进行严格比较,所以我认为不可能一概而论,但是与zip的部署包相比,
我听说它似乎需要更多的时间来进行初始化。
- 課金期間
构建自定义运行时
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html#runtimes-custom-build
初始化时间计入计费执行时间和超时时间。
请参阅此处
新款AWS Lambda – 容器镜像支持
https://aws.amazon.com/cn/blogs/aws/new-for-aws-lambda-container-image-support/
AWS Lambda – 开发者指南
https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/lambda-images.html
AWS无服务器应用模型 – 开发者指南
https://docs.aws.amazon.com/zh_cn/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html
希望您能从上面的内容中获得所需的参考。