在aws上以lambda方式部署golang应用 -(上)用.zip压缩文件部署Go Lambda functions
aws的部署涉及到很多的部分,但aws也跟阿里云、腾讯云类似,都是云原生的服务提供商,所以牵扯到方方面面,不一而足。所以,这篇文章只涉及两种部署方式,一种是zip
压缩文件的部署方式,另外一种是以镜像方式做部署,也就是现在基于Dockerfile创建出的容器镜像。
用.zip
压缩文件方式部署Go Lambda
函数
通常AWS Lambda函数的代码包含脚本和编译程序和它们的相关依赖。你使用部署package
将函数代码部署到Lambda。Lambda支持两种类型的部署包:容器镜像和.zip压缩文件。这里我们首先介绍怎么创建一个供Go runtime使用.zip
压缩文件,然后通过AWS提供的命令行交互文件(AWS CLI)操作这个.zip
文件,就能把你的函数代码部署到AWS Lambda上了。
前置条件
AWS CLI
是一个让你能够和AWS
服务交互的开源工具,如果想让这个工具生效,你必须解决掉:
工具和库
Lambda
为Go runtime
提供了以下的工具和类库:
- AWS SDK for Go:golang语言官方AWS SDK
- github.com/aws/aws-lambda-go/lambda:实现了面向Go的Lambda编程模型。这个包被AWS Lambda用来调用您的handler
- github.com/aws/aws-lambda-go/lambdacontext:从context object访问上下文信息的帮助程序
- github.com/aws/aws-lambda-go/events:这个库针对于通用事件资源整合提供了各种类型定义
- github.com/aws/aws-lambda-go/cmd/build-lambda-zip:这个工具可供在windows系统创建
.zip
压缩文件
应用样例
Lambda
为Go runtime
提供了以下样例。
blank-go:一个Go函数,展示了Lambda的Go库、日志、环境变量和AWS SDK的使用
在macOS
和Linux
系统上创建.zip
压缩文件
-
- 从
Github
上下载lambda
库
- 从
go get github.com/aws/aws-lambda-go/lambda
-
- 编译你的执行
GOOS=linux GOARCH=amd64 go build -o main main.go
在linux
上设置GOOS
,要确保编译可执行文件与Go runtime
相兼容,非linux
也要注意这种兼容。
-
- (可选)如果你的
main
package包括多个文件,用如下go build
命令编译该package
- (可选)如果你的
GOOS=linux GOARCH=amd64 go build main
-
- (可选)
linux
系统上需要设置CGO_ENABLED=0
来编译package
- (可选)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o main main.go
这个命令为C标准library(libc)
创建一个非常稳定的二进制包版本,在Lambda
和其它设备上有所不同。
-
lambda
使用POSIX
文件权限,所以在创建.zip
压缩文件前,你需要为这些部署包目录设置权限
-
- 通过将可执行文件打包到
.zip
文件中来创建部署包
- 通过将可执行文件打包到
zip main.zip main
在Windows
系统上创建.zip
压缩文件
-
- 从
Github
上下载lambda
库
- 从
go get github.com/aws/aws-lambda-go/lambda
-
- 从
Github
上下载build-lambda-zip
工具
- 从
go.exe install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest
-
- 使用工具,从
GOPATH
环境变量位置创建.zip
压缩文件,如果你默认安装的golang
语言,它通常是在%USERPROFILE%\Go\bin
。否则,就要切换到你安装Go runtime
的位置,然后做以下操作:
- 使用工具,从
-
cmd.exe脚本
set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0
go build -o main main.go
%USERPROFILE%\Go\bin\build-lambda-zip.exe -o main.zip main
这个脚本用cmd.exe命令行工具在Windows系统上编译一个可以在Linux系统上运行的程序。我们首先使用set命令设置GOOS为linux和GOARCH为amd64,表示我们要编译的目标平台是Linux 64位。然后,我们将CGO_ENABLED设置为0,以禁用CGO功能,从而确保程序不会依赖任何C代码。接着,我们使用go build命令编译main.go文件,并将其输出到main可执行文件中。最后,我们使用build-lambda-zip.exe工具将可执行文件打包成一个ZIP压缩文件。
-
PowerShell脚本
$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -o main main.go
~\Go\Bin\build-lambda-zip.exe -o main.zip main
这个脚本用PowerShell命令行工具在Windows系统上编译一个可以在Linux系统上运行的程序。与cmd.exe脚本不同,我们没有使用set命令来设置环境变量,而是使用$env:变量名 = 值的方式来设置环境变量。然后,我们使用go build命令编译main.go文件,并将其输出到main可执行文件中。最后,我们使用build-lambda-zip.exe工具将可执行文件打包成一个ZIP压缩文件。
使用.zip
归档文件创建一个Lambda
函数
除了你已经创建的main.zip
部署包以外,创建Lambda
函数你还需要一个执行角色。这个执行角色具有使用AWS服务的权限,例如使用Amazon CloudWatch Logs进行日志流处理,使用AWS X-Ray进行请求跟踪。你可以在IAM
控制台为你的函数创建执行角色,当然你也可以用AWS Command Line Interface(AWS CLI)
以下角色展示如何用AWS CLI
创建可执行角色,之后就可以用.zip
部署压缩包来创建Lambda
函数了。
-
- 创建信任策略,给可执行角色赋予
Lambda
服务权限。拷贝下面的JSON
文件,在当前目录下重命名成trust-policy.json
。
- 创建信任策略,给可执行角色赋予
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
-
- 创建可执行角色
aws iam create-role --role-name lambda-ex --asume-role-policy-document file://trust-policy.json
会得到如下输出,记下你角色的ARN
,你需要这个用于创建你的函数。
{
"Role": {
"Path": "/",
"RoleName": "lambda-ex",
"RoleId": "AROAQFOXMPL6TZ6ITKWND",
"Arn": "arn:aws:iam::123456789012:role/lambda-ex",
"CreateDate": "2020-01-17T23:19:12Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
-
- 用
attach-role-policy
命令给角色加权限。下面的例子,加上了AWSLambdaBasicExecutionRole
管理政策,这允许你的Lambda
函数可以把日志之类的上传到CloudWatch
。如果你的Lambda
函数与其它的AWS
服务做交互,比如Amazon S3
或者DynamoDB
,你需要加很多policies
以便你的Lambda
函数能访问这些服务。更多相关可以查看AWS管理Lambda特性的策略。
- 用
aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
-
- 创建函数
aws lambda create-function --function-name my-function --runtime go1.x --role arn:aws:iam::123456789012:role/lambda-ex --handler main --zip-file fileb://main.zip
用provided.al2 runtime
构建Go
Go的实现与其他的native runtimes
是有所不同的。Lambda
视Go
作为一个自定义runtime
,所以你可以在provided.al2 runtime
上创建Go
函数。你可以用AWS SAM
创建命令来构建.zip
文件包。
使用AWS SAM
来构建Go for AL2
函数
-
- 为了用
provided.al2 runtime
来更新AWS SAM
模板。同时针对makefile
设置BuildMethod
- 为了用
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: my.bootstrap.file
Runtime: provided.al2
Architectures: [arm64]
Metadata:
BuildMethod: makefile
移除Architectures
属性来构建x86_64指令结构集
-
- 用以下内容,把
makefile
文件加到项目目录
- 用以下内容,把
GOOS=linux go build -o bootstrap
cp ./bootstrap $(ARTIFACTS_DIR)/.
也可以在Go on AL2上下载示例程序。readme
文件中包含创建和运行应用程序的各种指令,也可以查看Migrating AWS Lambda functions to Amazon Linux 2
这篇文章只对.zip
压缩文件方式部署AWS Lambda
函数类应用做了介绍,后面文章会对使用docker image
方式继续做补充。