針對 Python Lambda 函數使用層 - AWS Lambda

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

針對 Python Lambda 函數使用層

Lambda 層是含有補充程式碼或資料的 .zip 封存檔。層通常具備程式庫相依性、自訂執行期或組態檔案。建立層包含三個一般步驟:

  1. 封裝層內容。這表示建立 .zip 封存檔,其中包含您要在函數中使用的相依項。

  2. 在 Lambda 中建立層。

  3. 將層新增至函數中。

本主題包含如何正確封裝和建立具有外部程式庫相依項的 Python Lambda 層的步驟和指導。

先決條件

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

在本主題中,我們會參考 awsdocs GitHub 儲存庫上的 layer-python 範例應用程式。此應用程式包含可下載相依項並產生層的指令碼。該應用程式也包含對應的函數,這些函數使用來自層的相依項。建立層之後,您可以部署並調用對應的函數,以驗證一切是否正常運作。由於您針對函數使用 Python 3.11 執行時期,因此層也必須與 Python 3.11 相容。

layer-python 範例應用程式中,有兩個範例:

  • 第一個範例涉及將 requests 程式庫封裝到 Lambda 層中。layer/ 目錄包含用於產生層的指令碼。function/ 目錄包含一個範例函數,可協助測試層是否正常運作。本教學課程的主要部分會逐步說明如何建立和封裝此層。

  • 第二個範例涉及將 numpy 程式庫封裝到 Lambda 層中。layer-numpy/ 目錄包含用於產生層的指令碼。function-numpy/ 目錄包含一個範例函數,可協助測試層是否正常運作。如需如何建立和封裝此層的範例,請參閱使用 manylinux wheel 發布

Python 層與 Amazon Linux 的相容性

建立層的第一步是將所有層內容綁定至 .zip 封存檔。由於 Lambda 函數是在 Amazon Linux 上執行,因此您的層內容必須能夠在 Linux 環境中編譯和建置。

在 Python 中,除了來源發布之外,大多數套件還以 wheel (.whl 檔案) 的形式提供。每個 wheel 都是一種內建發布類型,可支援 Python 版本、作業系統和機器指令集的特定組合。

Wheel 有助於確保您的層 與 Amazon Linux 相容。當您下載相依項時,請盡可能地下載通用 wheel。(根據預設,如果通用 wheel 可用,pip 會安裝通用 wheel。) 通用 wheel 包含 any 作為平台標籤,表示它與所有平台相容,包括 Amazon Linux。

在下面的範例中,您將 requests 程式庫封裝到 Lambda 層中。requests 程式庫是做為通用 wheel 提供的套件範例。

並非所有 Python 套件都以通用 wheel 的形式發布。例如,numpy 具有多個 wheel 發布,每個都支援一組不同的平台。對於此類套件,請下載 manylinux 發布,以確保與 Amazon Linux 的相容性。如需如何封裝這類層的詳細說明,請參閱使用 manylinux wheel 發布

在極少數情況下,Python 套件可能無法以 wheel 的形式提供。如果只有來源發布 (sdist),我們建議您根據 Amazon Linux 2023 基礎容器映像,在 Docker 環境中安裝和封裝相依項。如果您想要包含以其他語言 (例如 C/C++) 撰寫的自訂程式庫,我們也建議使用此方法。此方法會模擬 Docker 中的 Lambda 執行環境,並確保您的非 Python 套件相依項與 Amazon Linux 相容。

Python 執行時期的層路徑

將層新增至函數時,Lambda 會將層內容載入該執行環境的 /opt 目錄。在每一次 Lambda 執行期中,PATH 變數已包含 /opt 目錄中的特定資料夾路徑。為了確保 Lambda 取得您的 layer 內容,您的 layer .zip 檔案應該在以下資料夾路徑中具有其相依性:

  • python

  • python/lib/python3.x/site-packages

例如,您在本教學課程中建立的層 .zip 檔案具有下列目錄結構:

layer_content.zip └ python └ lib └ python3.11 └ site-packages └ requests └ <other_dependencies> (i.e. dependencies of the requests package) └ ...

requests 程式庫位於正確的 python/lib/python3.11/site-packages 目錄中。這可確保 Lambda 可以在函數調用期間找到程式庫。

封裝層內容

在此範例中,您會將 Python requests 程式庫封裝到層 .zip 檔案中。請完成下列步驟,以安裝和封裝層內容。

若要安裝和封裝層內容
  1. 複製 aws-lambda-developer-guide GitHub 儲存庫,其中包含您在 sample-apps/layer-python 目錄中需要的範例程式碼。

    git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
  2. 導覽至 layer-python 範例應用程式的 layer 目錄。此目錄包含您用來正確建立和封裝層的指令碼。

    cd aws-lambda-developer-guide/sample-apps/layer-python/layer
  3. 檢查 requirements.txt 檔案。此檔案會定義您要包含在層中的相依項,也就是 requests 程式庫。您可以更新此檔案,加入想要包含在自己的層中的任何相依項。

    範例 requirements.txt
    requests==2.31.0
  4. 確定您有執行這兩個指令碼的許可。

    chmod 744 1-install.sh && chmod 744 2-package.sh
  5. 使用以下命令來執行 1-install.sh 指令碼:

    ./1-install.sh

    此指令碼使用 venv 來建立名為 create_layer 的 Python 虛擬環境。接著,它在 create_layer/lib/python3.11/site-packages 目錄中安裝所有必要的相依項。

    範例 1-install.sh
    python3.11 -m venv create_layer source create_layer/bin/activate pip install -r requirements.txt
  6. 使用以下命令來執行 2-package.sh 指令碼:

    ./2-package.sh

    此指令碼會將 create_layer/lib 目錄中的內容複製到名為 python 的新目錄。然後,它會將 python 目錄的內容壓縮成名為 layer_content.zip 的檔案。這是層的 .zip 檔案。您可以解壓縮該檔案,並確認其包含正確的檔案結構,如Python 執行時期的層路徑一節所示。

    範例 2-package.sh
    mkdir python cp -r create_layer/lib python/ zip -r layer_content.zip python

建立層

在本節中,您會取得您在上一節中產生的 layer_content.zip 檔案,並將其上傳為 Lambda 層。您可以使用 AWS Management Console 或 Lambda API 透過 AWS Command Line Interface () 上傳 layer AWS CLI。當您上傳 layer .zip 檔案時,請在下列 PublishLayerVersion AWS CLI 命令中,指定 python3.11為相容的執行期,指定 arm64 為相容的架構。

aws lambda publish-layer-version --layer-name python-requests-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes python3.11 \ --compatible-architectures "arm64"

從回應中記下 LayerVersionArn,它類似於 arn:aws:lambda:us-east-1:123456789012:layer:python-requests-layer:1。在本教學課程的下一個步驟中,當您將層新增至函數時,將需要此 Amazon Resource Name (ARN)。

將層新增至函數

在本節中,您會部署一個在函數程式碼中使用 requests 程式庫的範例 Lambda 函數,然後連接層。若要部署函數,您需要執行角色。如果沒有現有的執行角色,請依可摺疊區段中的步驟操作。

若要建立執行角色
  1. 在 IAM 主控台中開啟角色頁面

  2. 選擇建立角色

  3. 建立具備下列屬性的角色。

    • 信任實體 - Lambda

    • 許可 - AWSLambdaBasicExecutionRole

    • 角色名稱 - lambda-role

    AWSLambdaBasicExecutionRole 政策具備函數將日誌寫入到 CloudWatch Logs 時所需的許可。

Lambda 函數程式碼會匯入 requests 程式庫、提出簡單的 HTTP 請求,然後傳回狀態碼和內文。

import requests def lambda_handler(event, context): print(f"Version of requests library: {requests.__version__}") request = requests.get('https://api.github.com/') return { 'statusCode': request.status_code, 'body': request.text }
若要部署 Lambda 函數
  1. 導覽至 function/ 目錄。如果您目前在 layer/ 目錄中,則執行下列命令:

    cd ../function
  2. 使用以下命令建立 .zip 檔案部署套件:

    zip my_deployment_package.zip lambda_function.py
  3. 部署函數。在下列 AWS CLI 命令中,將 --role 參數取代為您的執行角色 ARN:

    aws lambda create-function --function-name python_function_with_layer \ --runtime python3.11 \ --architectures "arm64" \ --handler lambda_function.lambda_handler \ --role arn:aws:iam::123456789012:role/lambda-role \ --zip-file fileb://my_deployment_package.zip
  4. 接著,將層連接至您的函數。在下列 AWS CLI 命令中,將 --layers 參數取代為您先前記下的 layer 版本 ARN:

    aws lambda update-function-configuration --function-name python_function_with_layer \ --cli-binary-format raw-in-base64-out \ --layers "arn:aws:lambda:us-east-1:123456789012:layer:python-requests-layer:1"
  5. 最後,嘗試使用以下 AWS CLI 命令叫用您的 函數:

    aws lambda invoke --function-name python_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{ "key": "value" }' response.json

    您應該會看到類似下面的輸出:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }

    輸出的 response.json 檔案包含回應的詳細資訊。

除非您想要保留為此教學課程建立的資源,否則您現在便可刪除。透過刪除不再使用 AWS 的資源,您可以避免不必要的費用 AWS 帳戶。

若要刪除 Lambda 層
  1. 開啟 Lambda 主控台中的層頁面

  2. 選取您建立的層。

  3. 選擇刪除,然後再次選擇刪除

若要刪除 Lambda 函數
  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇您建立的函數。

  3. 選擇 Actions (動作)、Delete (刪除)。

  4. 在文字輸入欄位中輸入 confirm,然後選擇刪除

使用 manylinux wheel 發布

有時候,您想要做為相依項包含的套件沒有通用 wheel (具體而言,沒有 any 平台標籤)。在此情況下,請改而下載支援 manylinux 的 wheel。這可確保您的層程式庫與 Amazon Linux 相容。

numpy 是一個沒有通用 wheel 的套件。如果您想要在層中包含 numpy 套件,則可以完成下列範例步驟,正確地安裝和封裝層。

若要安裝和封裝層內容
  1. 複製 aws-lambda-developer-guide GitHub 儲存庫,其中包含您在 sample-apps/layer-python 目錄中需要的範例程式碼。

    git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
  2. 導覽至 layer-python 範例應用程式的 layer-numpy 目錄。此目錄包含您用來正確建立和封裝層的指令碼。

    cd aws-lambda-developer-guide/sample-apps/layer-python/layer-numpy
  3. 檢查 requirements.txt 檔案。此檔案會定義您要包含在層中的相依項,也就是 numpy 程式庫。在這裡,您可以指定與 Python 3.11、Amazon Linux 以及 x86_64 指令集相容的 manylinux wheel 發布 URL:

    範例 requirements.txt
    https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  4. 確定您有執行這兩個指令碼的許可。

    chmod 744 1-install.sh && chmod 744 2-package.sh
  5. 使用以下命令來執行 1-install.sh 指令碼:

    ./1-install.sh

    此指令碼使用 venv 來建立名為 create_layer 的 Python 虛擬環境。接著,它在 create_layer/lib/python3.11/site-packages 目錄中安裝所有必要的相依項。在此情況下,pip 命令是不同的,因為您必須將 --platform 標籤指定為 manylinux2014_x86_64。這會通知 pip 安裝正確的 manylinux wheel,即使您的本機電腦使用 macOS 或 Windows。

    範例 1-install.sh
    python3.11 -m venv create_layer source create_layer/bin/activate pip install -r requirements.txt --platform=manylinux2014_x86_64 --only-binary=:all: --target ./create_layer/lib/python3.11/site-packages
  6. 使用以下命令來執行 2-package.sh 指令碼:

    ./2-package.sh

    此指令碼會將 create_layer/lib 目錄中的內容複製到名為 python 的新目錄。然後,它會將 python 目錄的內容壓縮成名為 layer_content.zip 的檔案。這是層的 .zip 檔案。您可以解壓縮該檔案,並確認其包含正確的檔案結構,如Python 執行時期的層路徑一節所示。

    範例 2-package.sh
    mkdir python cp -r create_layer/lib python/ zip -r layer_content.zip python

若要將此 layer 上傳至 Lambda,請使用下列 PublishLayerVersion AWS CLI 命令:

aws lambda publish-layer-version --layer-name python-numpy-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes python3.11 \ --compatible-architectures "x86_64"

從回應中記下 LayerVersionArn,它類似於 arn:aws:lambda:us-east-1:123456789012:layer:python-numpy-layer:1。若要驗證您的層是否正常運作,請在 function-numpy 目錄中部署 Lambda 函數。

若要部署 Lambda 函數
  1. 導覽至 function-numpy/ 目錄。如果您目前在 layer-numpy/ 目錄中,則執行下列命令:

    cd ../function-numpy
  2. 檢閱函數程式碼。函數會匯入 numpy 程式庫,建立簡單的 numpy 數組,然後傳回虛擬狀態碼和內文。

    import json import numpy as np def lambda_handler(event, context): x = np.arange(15, dtype=np.int64).reshape(3, 5) print(x) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
  3. 使用以下命令建立 .zip 檔案部署套件:

    zip my_deployment_package.zip lambda_function.py
  4. 部署函數。在下列 AWS CLI 命令中,將 --role 參數取代為您的執行角色 ARN:

    aws lambda create-function --function-name python_function_with_numpy \ --runtime python3.11 \ --handler lambda_function.lambda_handler \ --role arn:aws:iam::123456789012:role/lambda-role \ --zip-file fileb://my_deployment_package.zip
  5. 接著,將層連接至您的函數。在下列 AWS CLI 命令中,將 --layers 參數取代為您的 layer 版本 ARN:

    aws lambda update-function-configuration --function-name python_function_with_numpy \ --cli-binary-format raw-in-base64-out \ --layers "arn:aws:lambda:us-east-1:123456789012:layer:python-requests-layer:1"
  6. 最後,嘗試使用以下 AWS CLI 命令叫用您的 函數:

    aws lambda invoke --function-name python_function_with_numpy \ --cli-binary-format raw-in-base64-out \ --payload '{ "key": "value" }' response.json

    您應該會看到類似下面的輸出:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }

    您可以檢查函數日誌,確認程式碼列印 numpy 數組至標準輸出。