Erstellen von Lambda-Container-Images - AWS Lambda

Erstellen von Lambda-Container-Images

AWS bietet eine Reihe von Open-Source-Basis-Images, mit denen Sie Ihr Container-Image erstellen können. Zu diesen Basis-Images gehört ein Laufzeit-Schnittstellen-Client zur Verwaltung der Interaktion zwischen Lambda und Ihrem Funktionscode.

Beispielanwendungen, einschließlich eines Node.js-Beispiels und eines Python-Beispiels, finden Sie unter Unterstützung für Container-Images für Lambda im AWS-Blog.

Anmerkung

Container-Images werden für Lambda-Funktionen in der Region Naher Osten (UAE) nicht unterstützt.

Voraussetzungen

Um ein Container-Image an Lambda bereitzustellen, benötigen Sie die AWS CLI und die Docker-CLI. Beachten Sie außerdem die folgenden Anforderungen:

  • Das Container-Image muss die Lambda-Runtime-API implementieren. Die AWS Open-Source-Laufzeitschnittstellen-Clients implementieren die API. Sie können Ihrem bevorzugten Basis-Image einen Laufzeitschnittstellen-Client hinzufügen, damit es mit Lambda kompatibel ist.

  • Das Container-Image muss auf einem schreibgeschützten Dateisystem laufen können. Ihr Funktionscode kann auf ein beschreibbares /tmp-Verzeichnis mit einem Speicherplatz zwischen 512 MB bis 10 240 MB, in 1-MB-Schritten, zugreifen.

  • Der Lambda-Standardbenutzer muss in der Lage sein, alle Dateien zu lesen, die zum Ausführen Ihres Funktionscodes erforderlich sind. Lambda folgt den bewährten Methoden für die Sicherheit, indem es einen Standard-Linux-Benutzer mit den geringsten Berechtigungen definiert. Stellen Sie sicher, dass Ihr Anwendungscode nicht auf Dateien angewiesen ist, von denen andere Linux-Benutzer nicht ausgeführt werden können.

  • Lambda unterstützt nur Linux-basierte Container-Images.

  • Lambda bietet Multi-Architektur-Basis-Images. Das Image, das Sie für Ihre Funktion erstellen, muss jedoch nur auf eine der Architekturen abzielen. Lambda unterstützt keine Funktionen, die Container-Images mit mehreren Architekturen verwenden.

Image-Typen

Sie können ein von AWS bereitgestelltes Basis-Image oder ein alternatives Basis-Image wie Alpine oder Debian verwenden. Lambda unterstützt jedes Image, das einem der folgenden Image-Manifestformate entspricht:

  • Docker Image Manifest V2 Schema 2 (mit Docker-Version 1.10 und neuer)

  • Open Container Initiative (OCI)-Spezifikationen (v1.0.0 und höher)

Lambda unterstützt Image mit einer Größe von bis zu 10 GB.

Container-Tools

Um Ihr Container-Image zu erstellen, können Sie jedes Entwicklungstool verwenden, das eines der folgenden Container-Image-Manifestformate unterstützt:

  • Docker Image Manifest V2 Schema 2 (mit Docker-Version 1.10 und neuer)

  • OCI-Spezifikationen (v1.0.0 und höher)

Sie können beispielsweise die Docker-CLI verwenden, um Ihre Container-Images zu erstellen, zu testen und bereitzustellen.

Container-Image-Einstellungen

Lambda unterstützt die folgenden Container-Image-Einstellungen im Dockerfile:

  • ENTRYPOINT – Gibt den absoluten Pfad zum Eintrittspunkt der Anwendung an.

  • CMD – Gibt zusätzliche Parameter an, die Sie mit ENTRYPOINT übergeben sollten.

  • WORKDIR – Gibt den absoluten Pfad zum Arbeitsverzeichnis an.

  • ENV – Gibt eine Umgebungsvariable für die Lambda-Funktion an.

Anmerkung

Lambda ignoriert die Werte aller nicht unterstützten Container-Image-Einstellungen in dem Dockerfile.

Weitere Informationen darüber, wie Docker die Container-Image-Einstellungen verwendet, finden Sie unter ENTRYPOINT in der Dockerfile-Referenz auf der Docker Docs-Website. Weitere Informationen zur Verwendung von ENTRYPOINT und CMD finden Sie unter Entmystifizierung von ENTRYPOINT und CMD in Docker im AWS Open Source Blog.

Sie können die Einstellungen für Container-Images im Dockerfile angeben, wenn Sie Ihr Image erstellen. Sie können diese Konfigurationen auch mit der Lambda-Konsole oder Lambda-API überschreiben. Auf diese Weise können Sie mehrere Funktionen bereitstellen, die dasselbe Container-Image bereitstellen, jedoch mit unterschiedlichen Laufzeitkonfigurationen.

Warnung

Wenn Sie ENTRYPOINT oder CMD im Dockerfile oder als Überschreibung angeben, stellen Sie sicher, dass Sie den absoluten Pfad eingeben. Verwenden Sie auch keine Symlinks als Eintrittspunkt für den Container.

Erstellen von Images aus AWS-Basis-Images

Um ein Container-Image für eine neue Lambda-Funktion zu erstellen, können Sie mit einem AWS-Basis-Image für Lambda beginnen. Lambda bietet zwei Arten von Basis-Images:

  • Multi-Architektur-Basis-Image

    Geben Sie eines der Haupt-Image-Tags an (z. B. python:3.9 oder java:11) um diese Art von Image zu wählen.

  • Architekturspezifisches Basis-Image

    Geben Sie ein Image-Tag mit einem Architektursuffix an. Geben Sie beispielsweise 3.9-arm64 an, um das arm64-Basis-Image für Python 3.9 auszuwählen.

Sie können auch ein alternatives Basis-Image aus einer anderen Container-Registry verwenden. Lambda bietet Open-Source-Laufzeit-Schnittstellen-Clients, die Sie zu einem alternativen Basis-Image hinzufügen, damit es mit Lambda kompatibel ist.

Anmerkung

AWS stellt regelmäßig Aktualisierungen der AWS-Basis-Images für Lambda bereit. Wenn Ihr Dockerfile den Image-Namen in der FROM-Eigenschaft enthält, zieht Ihr Docker-Client die neueste Version des Images vom Amazon-ECR-Registry. Um das aktualisierte Basis-Image verwenden zu können, müssen Sie Ihr Container-Image neu erstellen und den Funktionscode aktualisieren.

Erstellen Sie ein Image aus einem AWS-Basis-Image für Lambda
  1. Erstellen Sie auf Ihrem lokalen Computer ein Projektverzeichnis für Ihre neue Funktion.

  2. Erstellen Sie ein Verzeichnis namens app im Projektverzeichnis und fügen Sie dann Ihren Funktionshandlercode zum App-Verzeichnis hinzu.

  3. Verwenden Sie einen Texteditor, um ein neues Dockerfile zu erstellen.

    Die AWS-Basis-Images enthalten die folgenden Umgebungsvariablen:

    • LAMBDA_TASK_ROOT=/var/task

    • LAMBDA_RUNTIME_DIR=/var/runtime

    Installieren Sie alle Abhängigkeiten unter dem ${LAMBDA_TASK_ROOT}-Verzeichnis neben dem Funktionshandler, um sicherzustellen, dass die Lambda-Laufzeitumgebung sie beim Aufruf der Funktion finden kann.

    Das Folgende zeigt ein Beispiel für Dockerfile für Node.js, Python und Ruby:

    Node.js 14
    FROM public.ecr.aws/lambda/nodejs:14 # Assumes your function is named "app.js", and there is a package.json file in the app directory COPY app.js package.json ${LAMBDA_TASK_ROOT} # Install NPM dependencies for function RUN npm install # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "app.handler" ]
    Python 3.8
    FROM public.ecr.aws/lambda/python:3.8 # Install the function's dependencies using file requirements.txt # from your project folder. COPY requirements.txt . RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" # Copy function code COPY app.py ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "app.handler" ]
    Ruby 2.7
    FROM public.ecr.aws/lambda/ruby:2.7 # Copy function code COPY app.rb ${LAMBDA_TASK_ROOT} # Copy dependency management file COPY Gemfile ${LAMBDA_TASK_ROOT} # Install dependencies under LAMBDA_TASK_ROOT ENV GEM_HOME=${LAMBDA_TASK_ROOT} RUN bundle install # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "app.LambdaFunction::Handler.process" ]
  4. Erstellen Sie Ihr Docker-Image mit dem docker build-Befehl. Geben Sie einen Namen für das Image ein. Im folgenden Beispiel wird das Image hello-world benannt.

    docker build -t hello-world .
  5. Starten Sie Ihr Docker-Image mit dem docker run-Befehl. Geben Sie für dieses Beispiel als Namen des Images hello-world ein.

    docker run -p 9000:8080 hello-world
  6. (Optional) Testen Sie Ihre Anwendung lokal mit dem Runtime Interface Emulator. Veröffentlichen Sie in einem neuen Terminalfenster ein Ereignis mit einem curl-Befehl an den folgenden Endpunkt:

    curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    Dieser Befehl ruft die im Container-Image ausgeführte -Funktion auf und gibt eine Antwort zurück.

Erstellen von Images aus alternativen Basis-Images

Voraussetzungen

  • Der AWS CLI

  • Docker-Desktop

  • Ihr Funktionscode

So erstellen Sie ein Image mit einem alternativen Basis-Image
  1. Wählen Sie ein Basis-Image aus. Lambda unterstützt alle Linux-Verteilungen wie Alpine, Debian und Ubuntu.

  2. Erstellen Sie auf Ihrem lokalen Computer ein Projektverzeichnis für Ihre neue Funktion.

  3. Erstellen Sie ein Verzeichnis namens app im Projektverzeichnis und fügen Sie dann Ihren Funktionshandlercode zum App-Verzeichnis hinzu.

  4. Verwenden Sie einen Texteditor, um ein neues Dockerfile mit der folgenden Konfiguration zu erstellen:

    • Setzen Sie die FROM-Eigenschaft auf den URI des Basis-Images.

    • Fügen Sie Anweisungen zur Installation des Laufzeitschnittstellen-Clients hinzu.

    • Legen Sie die ENTRYPOINT-Eigenschaft fest, um den Laufzeitschnittstellen-Client aufzurufen.

    • Legen Sie das CMD-Argument zur Angabe des Lambda-Funktionshandlers fest.

    Das folgende Beispiel zeigt ein Dockerfile für Python:

    # Define function directory ARG FUNCTION_DIR="/function" FROM python:buster as build-image # Install aws-lambda-cpp build dependencies RUN apt-get update && \ apt-get install -y \ g++ \ make \ cmake \ unzip \ libcurl4-openssl-dev # Include global arg in this stage of the build ARG FUNCTION_DIR # Create function directory RUN mkdir -p ${FUNCTION_DIR} # Copy function code COPY app/* ${FUNCTION_DIR} # Install the runtime interface client RUN pip install \ --target ${FUNCTION_DIR} \ awslambdaric # Multi-stage build: grab a fresh copy of the base image FROM python:buster # 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 build image dependencies COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ] CMD [ "app.handler" ]
  5. Erstellen Sie Ihr Docker-Image mit dem docker build-Befehl. Geben Sie einen Namen für das Image ein. Im folgenden Beispiel wird das Image hello-world benannt.

    docker build -t hello-world .
  6. (Optional) Testen Sie Ihre Anwendung lokal mit dem Runtime Interface Emulator.

Image in das Amazon-ECR-Repository hochladen

Ersetzen Sie in den folgenden Befehlen 123456789012 durch Ihre AWS-Konto-ID und legen Sie den Regionswert auf die Region fest, in der Sie das Amazon-ECR-Repository erstellen möchten.

Anmerkung

Wenn Sie in Amazon ECR das Image-Tag einem anderen Image neu zuweisen, wird Lambda die Image-Version nicht aktualisieren.

  1. Authentifizieren Sie die Docker CLI in Ihrer Amazon-ECR-Registry.

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
  2. Erstellen Sie ein Repository in Amazon ECR mithilfe des create-repository-Befehls.

    aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
  3. Kennzeichnen Sie Ihr Image so, dass es Ihrem Repository-Namen entspricht, und stellen Sie das Image Amazon ECR mithilfe des docker push-Befehls bereit.

    docker tag hello-world:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest

Da sich Ihr Container-Image in der Amazon-ECR-Container-Registry befindet, können Sie die Lambda-Funktion erstellen und ausführen.

Erstellen eines Images mit dem AWS SAM-Toolkit

Sie können das AWS Serverless Application Model (AWS SAM)-Toolkit verwenden, um eine Funktion zu erstellen und bereitzustellen, die als Container-Image definiert ist. Für ein neues Projekt können Sie den AWS SAM CLI-init-Befehl verwenden, um das Gerüst für Ihr Projekt in Ihrer bevorzugten Laufzeit einzurichten.

In Ihrer AWS SAM-Vorlage legen Sie den Runtime-Typ auf Image fest und geben den URI des Basis-Images an.

Weitere Informationen finden Sie unter Erstellen von Anwendungen im AWS Serverless Application Model-Entwicklerhandbuch.