使用容器映像部署 Node.js Lambda 函數 - AWS Lambda

使用容器映像部署 Node.js Lambda 函數

您可以透過三種方式為 Node.js Lambda 函數建置容器映像:

提示

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

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

Node.js 的 AWS 基礎映像

AWS 針對 Node.js 提供以下基礎映像:

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

18

Node.js 18 Amazon Linux 2 Dockerfile for Node.js 18 on GitHub

16

Node.js 16 Amazon Linux 2 Dockerfile for Node.js 16 on GitHub

2024 年 3 月 11 日

14

Node.js 14 Amazon Linux 2 Dockerfile for Node.js 14 on GitHub

2023 年 11 月 27 日

Amazon ECR 儲存庫:gallery.ecr.aws/lambda/nodejs

使用適用於 Node.js 的 AWS 基礎映像

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

若要從 Node.js 的 AWS 基礎映像建立容器映像
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir example cd example
  2. 使用 npm 建立新 Node.js 專案。若要接受互動體驗中提供的預設選項,請按下 Enter

    npm init
  3. 建立稱為 index.js 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試,或使用您自己的函數程式碼。

    範例 CommonJS 處理常式
    exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
  4. 如果您的函數依賴於 AWS SDK for JavaScript 以外的程式庫,則請使用 npm 將其新增至您的套件。

  5. 建立包含下列組態的新 Dockerfile。

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

    • 使用 COPY 命令將函數程式碼和執行期相依性複製到 {LAMBDA_TASK_ROOT}

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

    範例 Dockerfile
    FROM public.ecr.aws/lambda/nodejs:16 # Copy function code COPY index.js ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "index.handler" ]
  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 -p 9000:8080 docker-image:test

    此命令將映像作為容器執行,並在 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 命令,向 Amazon ECR 登錄檔驗證 Docker CLI。

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

    • 用您的 AWS 帳戶 ID 取代 111122223333

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

    aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

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

    { "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 tag 命令,將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中:

    • docker-image:test 替換為 Docker 映像檔的名稱和標籤

    • <ECRrepositoryUri> 替換為複製的 repositoryUri。確保在 URI 的末尾包含 :latest

    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 儲存庫。確保在儲存庫 URI 的末尾包含 :latest

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

  7. 建立 Lambda 函數。對於 ImageUri,從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 :latest

    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
  8. 調用函數。

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

    您應該看到如下回應:

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

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

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

If you use a 適用於自訂執行期的基礎映像 or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Lambda 執行階段 API, which manages the interaction between Lambda and your function code.

使用 npm 套件管理員安裝 Node.js 執行期界面用戶端

npm install aws-lambda-ric

您還可以從 GitHub 下載 Node.js 執行時間界面用戶端。執行期介面用戶端支援下列 NodeJS 版本:

  • 14.x

  • 16.x

  • 18.x

以下範例示範如何使用非 AWS 基礎映像為 Node.js 建置容器映像。範例 Dockerfile 使用 buster 基礎映像。Dockerfile 包含執行期界面用戶端。

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

若要從非 AWS 基礎映像建立容器映像
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir example cd example
  2. 使用 npm 建立新 Node.js 專案。若要接受互動體驗中提供的預設選項,請按下 Enter

    npm init
  3. 建立稱為 index.js 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試,或使用您自己的函數程式碼。

    範例 CommonJS 處理常式
    exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
  4. 建立新的 Dockerfile。下列 Dockerfile 使用 buster 基礎映像,而非 AWS 基礎映像。Dockerfile 包含執行期介面用戶端,可讓映像與 Lambda 相容。Dockerfile 使用多階段建置。第一階段會建立組建映像,這是安裝函數相依項的標準 Node.js 環境。第二階段會建立更細微的映像,包含函數程式碼及其相依項。這會減少最終映像的大小。

    • FROM 屬性設為基礎映像識別符。

    • 使用 COPY 命令複製函數程式碼和執行期相依項。

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

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

    範例 Dockerfile
    # Define custom function directory ARG FUNCTION_DIR="/function" FROM node:18-buster as build-image # Include global arg in this stage of the build ARG FUNCTION_DIR # Install build dependencies RUN apt-get update && \ apt-get install -y \ g++ \ make \ cmake \ unzip \ libcurl4-openssl-dev # Copy function code RUN mkdir -p ${FUNCTION_DIR} COPY . ${FUNCTION_DIR} WORKDIR ${FUNCTION_DIR} # Install Node.js dependencies RUN npm install # Install the runtime interface client RUN npm install aws-lambda-ric # Grab a fresh slim copy of the image to reduce the final size FROM node:18-buster-slim # Required for Node runtimes which use npm@8.6.0+ because # by default npm writes logs under /home/.npm and Lambda fs is read-only ENV NPM_CONFIG_CACHE=/tmp/.npm # Include global arg in this stage of the build ARG FUNCTION_DIR # Set working directory to function root directory WORKDIR ${FUNCTION_DIR} # Copy in the built dependencies COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} # Set runtime interface client as default command for the container runtime ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"] # Pass the name of the function handler as an argument to the runtime CMD ["index.handler"]
  5. 使用 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. 在您的專案目錄中執行以下命令,從 GitHub 下載執行期介面模擬器 (x86-64 架構),並安裝在本機電腦上。

    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 模擬器,請將上一個命令中的 GitHub 儲存庫 URL 替換為以下內容:

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

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

    • /usr/local/bin/npx aws-lambda-ric index.handler 是 Dockerfile 中的 ENTRYPOINT,後面接著 CMD

    docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \ --entrypoint /aws-lambda/aws-lambda-rie \ docker-image:test \ /usr/local/bin/npx aws-lambda-ric index.handler

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

  3. 使用 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!"}'
  4. 取得容器 ID。

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

    docker kill 3766c4ab331c
若要將映像上傳至 Amazon ECR 並建立 Lambda 函數
  1. 使用 get-login-password 命令,向 Amazon ECR 登錄檔驗證 Docker CLI。

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

    • 用您的 AWS 帳戶 ID 取代 111122223333

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

    aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

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

    { "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 tag 命令,將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中:

    • docker-image:test 替換為 Docker 映像檔的名稱和標籤

    • <ECRrepositoryUri> 替換為複製的 repositoryUri。確保在 URI 的末尾包含 :latest

    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 儲存庫。確保在儲存庫 URI 的末尾包含 :latest

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

  7. 建立 Lambda 函數。對於 ImageUri,從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 :latest

    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
  8. 調用函數。

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

    您應該看到如下回應:

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

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