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

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

使用容器映像部署 Ruby Lambda 函數

有三種方法可以為 Ruby Lambda 函數構建容器映像:

提示

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

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

AWS Ruby 的基礎映像

AWS 為 Ruby 提供下列基本影像:

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

3.3

Ruby 3.3 Amazon Linux 2023 Ruby 3.3 on 的 Dockerfile GitHub

未排程

3.2

Ruby 3.2 Amazon Linux 2 Ruby 3.2 on 的 Dockerfile GitHub

未排程

Amazon ECR儲存庫:Galage.ecr.aws/lambda/ruby

使用 Ruby AWS 的基礎映像

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

建立適用於 Ruby 的容器映像
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir example cd example
  2. 建立稱為 Gemfile 的新檔案。您可以在此處列出應用程式的必要 RubyGems 套件。 AWS SDK for Ruby 可從 取得 RubyGems。您應該選擇要安裝的特定 AWS 服務寶石。例如,若要使用 Ruby Gem for Lambda,您的 Gemfile 看起來應該會像:

    source 'https://rubygems.org' gem 'aws-sdk-lambda'

    或者,aws-sdk 寶石包含每個可用的 AWS 服務寶石。這個 Gem 非常大,建議您只有在依賴許多 AWS 服務時才使用它。

  3. 使用套件安裝作業安裝 Gemfile 中指定的相依項。

    bundle install
  4. 建立稱為 lambda_function.rb 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試,或使用您自己的函數程式碼。

    範例 Ruby 函數
    module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
  5. 建立新的 Dockerfile。下列範例 Dockerfile 使用 AWS 基礎映像。此 Dockerfile 使用下列組態:

    • FROM 屬性設定為基本映像URI的 。

    • 使用 COPY命令將函數程式碼和執行時間相依項目複製到 {LAMBDA_TASK_ROOT},這是 Lambda 定義的環境變數

    • CMD 引數設定為 Lambda 函數處理常式。

    請注意,範例 Dockerfile 不包含USER指令 。當您將容器映像部署至 Lambda 時,Lambda 會自動定義具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同,其會在未提供USER指示時預設為root使用者。

    範例 Dockerfile
    FROM public.ecr.aws/lambda/ruby:3.2 # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPY lambda_function.rb ${LAMBDA_TASK_ROOT}/ # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
  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. 使用 docker run 命令啟動 Docker 影像。在此範例中,docker-image 為映像名稱,test 為標籤。

    docker run --platform linux/amd64 -p 9000:8080 --read-only docker-image:test

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

    注意

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

  2. 從新的終端機視窗,將事件張貼至本機端點。

    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"
  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

透過執行期介面用戶端使用替代基礎映像

如果您使用僅限作業系統的基礎映像或替代的基礎映像,則必須在映像中加入執行期介面用戶端。執行期介面用戶端會讓您擴充 API針對自訂執行階段使用 Lambda 執行階段,管理 Lambda 與函數程式碼之間的互動。

使用 RubyGems.org 套件管理員安裝適用於 Ruby 的 Lambda 執行期介面用戶端

gem install aws_lambda_ric

您也可以從 下載 Ruby 執行期介面用戶端 GitHub。執行期介面用戶端支援 Ruby 2.5.x 至 2.7.x 版。

下列範例示範如何使用非AWS 基礎映像為 Ruby 建置容器映像。範例 Dockerfile 使用官方 Ruby 基礎映像。Dockerfile 包含執行期界面用戶端。

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

使用替代基礎映像為 Ruby 建立容器映像
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir example cd example
  2. 建立稱為 Gemfile 的新檔案。您可以在此處列出應用程式的必要 RubyGems 套件。 AWS SDK for Ruby 可從 取得 RubyGems。您應該選擇要安裝的特定 AWS 服務寶石。例如,若要使用 Ruby Gem for Lambda,您的 Gemfile 看起來應該會像:

    source 'https://rubygems.org' gem 'aws-sdk-lambda'

    或者,aws-sdk 寶石包含所有可用的 AWS 服務寶石。這個 Gem 非常大,建議您只有在依賴許多 AWS 服務時才使用它。

  3. 使用套件安裝作業安裝 Gemfile 中指定的相依項。

    bundle install
  4. 建立稱為 lambda_function.rb 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試,或使用您自己的函數程式碼。

    範例 Ruby 函數
    module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
  5. 建立新的 Dockerfile。下列 Dockerfile 使用 Ruby 基礎映像,而非 AWS  基礎映像。Dockerfile 包含 適用於 Ruby 的執行期介面用戶端,可讓映像與 Lambda 相容。或者,您可以將執行期界面用戶端新增到應用程式的 Gemfile 中。

    • FROM 屬性設定為 Ruby 基礎映像。

    • 建立函數程式碼的目錄,以及指向該目錄的環境變數。在此範例中,目錄是 /var/task,它反映 Lambda 執行環境。不過,您可以選擇函數程式碼的任何目錄,因為 Dockerfile 不使用 AWS 基礎映像。

    • 將 ENTRYPOINT 設為您希望 Docker 容器在啟動時執行的模組。在此案例中,模組是執行期界面用戶端。

    • CMD 引數設定為 Lambda 函數處理常式。

    請注意,範例 Dockerfile 不包含USER指令 。當您將容器映像部署至 Lambda 時,Lambda 會自動定義具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同,其會在未提供USER指示時預設為root使用者。

    範例 Dockerfile
    FROM ruby:2.7 # Install the runtime interface client for Ruby RUN gem install aws_lambda_ric # Add the runtime interface client to the PATH ENV PATH="/usr/local/bundle/bin:${PATH}" # Create a directory for the Lambda function ENV LAMBDA_TASK_ROOT=/var/task RUN mkdir -p ${LAMBDA_TASK_ROOT} WORKDIR ${LAMBDA_TASK_ROOT} # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPY lambda_function.rb ${LAMBDA_TASK_ROOT}/ # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "aws_lambda_ric" ] # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
  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 是標籤。

    • aws_lambda_ric lambda_function.LambdaFunction::Handler.process 是 Dockerfile 中的 ENTRYPOINT,後面接著 CMD

    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 \ aws_lambda_ric lambda_function.LambdaFunction::Handler.process
    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 ` aws_lambda_ric lambda_function.LambdaFunction::Handler.process

    此命令將映像作為容器執行,並在 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