操操操

在aws上以lambda方式部署golang应用 -(上)用.zip压缩文件部署Go Lambda functions

2022-12-08
6分钟阅读时长

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服务交互的开源工具,如果想让这个工具生效,你必须解决掉:

工具和库

LambdaGo runtime提供了以下的工具和类库:

应用样例

LambdaGo runtime提供了以下样例。

blank-go:一个Go函数,展示了Lambda的Go库、日志、环境变量和AWS SDK的使用

macOSLinux系统上创建.zip压缩文件

    1. Github上下载lambda

go get github.com/aws/aws-lambda-go/lambda

    1. 编译你的执行

GOOS=linux GOARCH=amd64 go build -o main main.go

linux上设置GOOS,要确保编译可执行文件与Go runtime相兼容,非linux也要注意这种兼容。

    1. (可选)如果你的main package包括多个文件,用如下go build命令编译该package

GOOS=linux GOARCH=amd64 go build main

    1. (可选)linux系统上需要设置CGO_ENABLED=0来编译package

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o main main.go

这个命令为C标准library(libc)创建一个非常稳定的二进制包版本,在Lambda和其它设备上有所不同。

    1. lambda使用POSIX文件权限,所以在创建.zip压缩文件前,你需要为这些部署包目录设置权限
    1. 通过将可执行文件打包到.zip文件中来创建部署包

zip main.zip main

Windows系统上创建.zip压缩文件

    1. Github上下载lambda

go get github.com/aws/aws-lambda-go/lambda

    1. Github上下载build-lambda-zip工具

go.exe install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest

    1. 使用工具,从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函数了。

    1. 创建信任策略,给可执行角色赋予Lambda服务权限。拷贝下面的JSON文件,在当前目录下重命名成trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
    1. 创建可执行角色

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"
                }
            ]
        }
    }
}
    1. 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

    1. 创建函数

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是有所不同的。LambdaGo作为一个自定义runtime,所以你可以在provided.al2 runtime上创建Go函数。你可以用AWS SAM创建命令来构建.zip文件包。

使用AWS SAM来构建Go for AL2函数
    1. 为了用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指令结构集

    1. 用以下内容,把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方式继续做补充。

Avatar

Aisen

Be water,my friend.
扫码关注公众号,可领取以下赠品:
《夯实基础的go语言体系建设》645页涵盖golang各大厂全部面试题,针对云原生领域更是面面俱到;
扫码加微信,可领取以下赠品:
【完整版】本人所著,原价1299元的《爱情困惑者必学的七堂课》; 50个搞定正妹完整聊天记录列表详情点这里
【完整版】时长7小时,原价699元《中国各阶层男性脱单上娶指南》;