使用容器映像來部署 Go Lambda 函數 - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用容器映像來部署 Go Lambda 函數

有兩種方法可以為 Go Lambda 函數建置容器映像:

  • 使用僅限 AWS 作業系統的基礎映像

    Go 的實作方式與其他受管執行期不同。由於 Go 原生編譯至可執行的二進位檔案,因此不需要專用語言執行時間。使用僅限作業系統的基礎映像來建置 Lambda 的 Go 映像。若要使映像檔與 Lambda 相容,您必須在映像中加入 aws-lambda-go/lambda 套件。

  • 使用非AWS 基礎映像

    您可以使用其他容器登錄檔中的替代基礎映像 (例如 Alpine Linux 或 Debian)。您也可以使用組織建立的自訂映像。若要使映像檔與 Lambda 相容,您必須在映像中加入 aws-lambda-go/lambda 套件。

提示

若要縮短 Lambda 容器函數變成作用中狀態所需的時間,請參閱 Docker 文件中的使用多階段建置。若要建置有效率的容器映像,請遵循撰寫 Dockerfiles 的最佳實務

本頁面會說明如何為 Lambda 建置、測試和部署容器映像。

AWS 部署 Go 函數的基本映像

Go 的實作方式與其他受管執行期不同。由於 Go 原生編譯至可執行的二進位檔案,因此不需要專用語言執行時間。使用僅限作業系統的基礎映像,將 Go 函數部署至 Lambda。

名稱 識別符 作業系統 取代日期 封鎖函數建立 封鎖函數更新

僅限作業系統的執行期

provided.al2023

Amazon Linux 2023

未排程

未排程

未排程

僅限作業系統的執行期

provided.al2

Amazon Linux 2

未排程

未排程

未排程

Amazon Elastic Container Registry 公有資源庫:gallery.ecr.aws/lambda/provided

Go 執行期介面用戶端

aws-lambda-go/lambda 套件包含執行期介面實作。如需在映像中使用 aws-lambda-go/lambda 的範例,請參閱 使用僅限 AWS 作業系統的基礎映像 或 使用非AWS 基礎映像

使用僅限 AWS 作業系統的基礎映像

Go 的實作方式與其他受管執行期不同。由於 Go 原生編譯至可執行的二進位檔案,因此不需要專用語言執行時間。使用僅限作業系統的基礎映像來建置 Go 函數的容器映像。

標籤 執行期 作業系統 Dockerfile 棄用

al2023

僅限作業系統的執行期 Amazon Linux 2023 Dockerfile 適用於 上的僅限作業系統執行期 GitHub

未排程

al2

僅限作業系統的執行期 Amazon Linux 2 Dockerfile 適用於 上的僅限作業系統執行期 GitHub

未排程

如需這些基本映像的詳細資訊,請參閱 Amazon ECR公有圖庫https://gallery.ecr.aws/lambda/provided中提供。

您必須在 Go 處理常式中包含 aws-lambda-go/lambda 套件。此套件會實作 Go 的程式設計模型 (包括執行期介面)。

若要完成本節中的步驟,您必須執行下列各項:

使用 provided.al2023 基礎映像建置和部署 Go 函數
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir hello cd hello
  2. 初始化新的 Go 模組。

    go mod init example.com/hello-world
  3. lambda 程式庫新增為新模組的相依項。

    go get github.com/aws/aws-lambda-go/lambda
  4. 建立名為 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) }
  5. 使用文字編輯器在專案目錄中建立 Dockerfile。

    • 下列範例 Dockerfile 使用多階段建置。這可讓您在每個步驟中使用不同的基礎映像。您可以使用一個映像 (例如 Go 基礎映像檔) 來編譯程式碼並建置可執行二進位檔案。然後,可以在最終的 FROM 陳述式中使用不同的映像 (例如 provided.al2023) 來定義您部署到 Lambda 的映像。建置程序與最終部署映像是分開的,因此最終映像僅包含執行應用程式所需的檔案。

    • 您可以使用選用lambda.norpc標籤來排除 lambda 程式庫的遠端程序呼叫 (RPC) 元件。只有在您使用已棄用 Go 1.x 執行期時,才需要 RPC元件。排除 會RPC減少部署套件的大小。

    • 請注意,範例 Dockerfile 不包含USER指令 。當您將容器映像部署至 Lambda 時,Lambda 會自動定義具有最低權限許可的預設 Linux 使用者。這與標準 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 FROM public.ecr.aws/lambda/provided:al2023 COPY --from=build /helloworld/main ./main ENTRYPOINT [ "./main" ]
  6. 使用 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 基礎映像中。

若要在本機電腦上執行執行期界面模擬器
  1. 使用 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 建立本機端點。

  2. 從新的終端機視窗,使用 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!"}'
  3. 取得容器 ID。

    docker ps
  4. 使用 docker kill 命令停止容器。在此命令中,將 3766c4ab331c 替換為上一步驟中的容器 ID。

    docker kill 3766c4ab331c
將映像上傳至 Amazon ECR並建立 Lambda 函數
  1. 執行 get-login-password命令,以驗證 Docker CLI與您的 Amazon ECR登錄檔的身分。

    • --region 值設定為您要 AWS 區域 在其中建立 Amazon ECR儲存庫的 。

    • 111122223333 以您的 AWS 帳戶 ID 取代 。

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
  2. ECR 使用 create-repository 命令在 Amazon 中建立儲存庫

    aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
    注意

    Amazon ECR儲存庫必須與 Lambda 函數 AWS 區域 位於相同位置。

    如果成功,您將會看到以下回應:

    { "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
  3. 從上一步驟的輸出中複製 repositoryUri

  4. 執行 docker 標籤命令,將本機映像標記為最新版本的 Amazon ECR儲存庫。在此命令中:

    • docker-image:test 是 Docker 映像的名稱和標籤。這是您在docker build命令中指定的映像名稱和標籤。

    • <ECRrepositoryUri> 替換為複製的 repositoryUri。請務必:latest在 結尾包含 URI。

    docker tag docker-image:test <ECRrepositoryUri>:latest

    範例:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. 執行 docker push 命令,將本機映像部署到 Amazon ECR儲存庫。請務必在儲存庫 的:latest結尾包含 URI。

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. 建立函數的執行角色 (若您還沒有的話)。在下一個步驟中,您需要角色的 Amazon Resource Name (ARN)。

  7. 建立 Lambda 函數。針對 ImageUri,指定URI先前儲存庫。請務必:latest在 結尾包含 URI。

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
    注意

    只要映像與 Lambda 函數位於相同的區域中,您就可以使用不同 AWS 帳戶中的影像建立函數。如需詳細資訊,請參閱 Amazon ECR跨帳戶許可

  8. 調用函數。

    aws lambda invoke --function-name hello-world response.json

    您應該看到如下回應:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. 若要查看函數的輸出,請檢查 response.json 檔案。

若要更新函數程式碼,您必須再次建置映像、將新映像上傳至 Amazon ECR儲存庫,然後使用 update-function-code命令將映像部署至 Lambda 函數。

Lambda 會將影像標籤解析為特定影像摘要。這表示,如果您指向用於將函數部署到 Amazon 中新映像的映像標籤ECR,Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數,您必須使用 update-function-code命令,即使 Amazon 中的映像標籤ECR保持不變。在下列範例中, --publish選項會使用更新後的容器映像建立新的 函數版本。

aws lambda update-function-code \ --function-name hello-world \ --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --publish

使用非AWS 基礎映像

您可以從非AWS 基礎映像建置 Go 的容器映像。下列步驟中的 Dockerfile 範例使用 Alpine 基礎映像

您必須在 Go 處理常式中包含 aws-lambda-go/lambda 套件。此套件會實作 Go 的程式設計模型 (包括執行期介面)。

若要完成本節中的步驟,您必須執行下列各項:

使用 Alpine 基礎映像建置和部署 Go 函數
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir hello cd hello
  2. 初始化新的 Go 模組。

    go mod init example.com/hello-world
  3. lambda 程式庫新增為新模組的相依項。

    go get github.com/aws/aws-lambda-go/lambda
  4. 建立名為 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) }
  5. 使用文字編輯器在專案目錄中建立 Dockerfile。下列 Dockerfile 範例使用 Alpine 基礎映像。請注意,範例 Dockerfile 不包含USER指令 。當您將容器映像部署至 Lambda 時,Lambda 會自動定義具有最低權限許可的預設 Linux 使用者。這與未提供USER指示時預設給root使用者的標準 Docker 行為不同。

    範例 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" ]
  6. 使用 docker build 命令建立 Docker 映像檔。以下範例將映像命名為 docker-image 並為其提供 test 標籤

    docker build --platform linux/amd64 -t docker-image:test .
    注意

    此命令會指定 --platform linux/amd64 選項,確保無論建置機器的架構為何,您的容器都與 Lambda 執行環境相容。如果您打算使用ARM64指示集架構建立 Lambda 函數,請務必將命令變更為使用 --platform linux/arm64選項。

使用 執行期界面模擬器 以在本機測試映像。您可以在映像中建置模擬器,或使用下列程序在本機機器上安裝模擬器。

若要在本機電腦上安裝並執行執行期介面模擬器
  1. 從專案目錄中,執行下列命令,從本機機器下載執行期介面模擬器 (x86-64 架構) GitHub 並將其安裝。

    Linux/macOS
    mkdir -p ~/.aws-lambda-rie && \ curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \ chmod +x ~/.aws-lambda-rie/aws-lambda-rie

    若要安裝 arm64 模擬器,請將上一個命令URL中的 GitHub 儲存庫取代為下列項目:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
    PowerShell
    $dirPath = "$HOME\.aws-lambda-rie" if (-not (Test-Path $dirPath)) { New-Item -Path $dirPath -ItemType Directory } $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie" $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie" Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath

    若要安裝 arm64 模擬器,請將 $downloadLink 更換為下列項目:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
  2. 使用 docker run 命令啟動 Docker 影像。注意下列事項:

    • docker-image 是映像名稱,而 test 是標籤。

    • /main 是來自 Dockerfile 的 ENTRYPOINT

    Linux/macOS
    docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \ --entrypoint /aws-lambda/aws-lambda-rie \ --read-only \ docker-image:test \ /main
    PowerShell
    docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 ` --entrypoint /aws-lambda/aws-lambda-rie ` --read-only ` docker-image:test ` /main

    此命令將映像作為容器執行,並在 localhost:9000/2015-03-31/functions/function/invocations 建立本機端點。

    注意

    如果您為ARM64指令集架構建置 Docker 映像,請務必使用 --platform linux/arm64選項,而非 --platform linux/amd64

  3. 將事件張貼至本機端點。

    Linux/macOS

    在 Linux 或 macOS 中,執行下列 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!"}'
    PowerShell

    在 中 PowerShell,執行下列Invoke-WebRequest命令:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"

    此命令會透過空白事件調用函數,並傳回一個回應。如果您使用的是自己的函數程式碼,而不是範例函數程式碼,您可能想要使用JSON承載叫用函數。範例:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
  4. 取得容器 ID。

    docker ps
  5. 使用 docker kill 命令停止容器。在此命令中,將 3766c4ab331c 替換為上一步驟中的容器 ID。

    docker kill 3766c4ab331c
將映像上傳至 Amazon ECR並建立 Lambda 函數
  1. 執行 get-login-password命令,以驗證 Docker CLI與您的 Amazon ECR登錄檔的身分。

    • --region 值設定為您要 AWS 區域 在其中建立 Amazon ECR儲存庫的 。

    • 111122223333 以您的 AWS 帳戶 ID 取代 。

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
  2. ECR 使用 create-repository 命令在 Amazon 中建立儲存庫

    aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
    注意

    Amazon ECR儲存庫必須與 Lambda 函數 AWS 區域 位於相同位置。

    如果成功,您將會看到以下回應:

    { "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
  3. 從上一步驟的輸出中複製 repositoryUri

  4. 執行 docker 標籤命令,將本機映像標記為最新版本的 Amazon ECR儲存庫。在此命令中:

    • docker-image:test 是 Docker 映像的名稱和標籤。這是您在docker build命令中指定的映像名稱和標籤。

    • <ECRrepositoryUri> 替換為複製的 repositoryUri。請務必:latest在 結尾包含 URI。

    docker tag docker-image:test <ECRrepositoryUri>:latest

    範例:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. 執行 docker push 命令,將本機映像部署到 Amazon ECR儲存庫。請務必在儲存庫 的:latest結尾包含 URI。

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. 建立函數的執行角色 (若您還沒有的話)。在下一個步驟中,您需要角色的 Amazon Resource Name (ARN)。

  7. 建立 Lambda 函數。針對 ImageUri,指定URI先前儲存庫。請務必:latest在 結尾包含 URI。

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
    注意

    只要映像與 Lambda 函數位於相同的區域中,您就可以使用不同 AWS 帳戶中的影像建立函數。如需詳細資訊,請參閱 Amazon ECR跨帳戶許可

  8. 調用函數。

    aws lambda invoke --function-name hello-world response.json

    您應該看到如下回應:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. 若要查看函數的輸出,請檢查 response.json 檔案。

若要更新函數程式碼,您必須再次建置映像、將新映像上傳至 Amazon ECR儲存庫,然後使用 update-function-code命令將映像部署至 Lambda 函數。

Lambda 會將影像標籤解析為特定影像摘要。這表示,如果您指向用於將函數部署到 Amazon 中新映像的映像標籤ECR,Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數,您必須使用 update-function-code命令,即使 Amazon 中的映像標籤ECR保持不變。在下列範例中, --publish選項會使用更新後的容器映像建立新的 函數版本。

aws lambda update-function-code \ --function-name hello-world \ --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --publish