Distribuzione delle funzioni Go Lambda con immagini di container - AWS Lambda

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Distribuzione delle funzioni Go Lambda con immagini di container

Esistono due modi per creare un'immagine contenitore per una funzione Go Lambda:

  • Utilizzo di un'immagine di AWS base solo per il sistema operativo

    Go è implementato in modo diverso rispetto ad altri runtime gestiti. Poiché Go viene compilato in modo nativo in un file binario eseguibile, non richiede un runtime linguistico dedicato. Usa un'immagine di base solo per il sistema operativo per creare immagini Go per Lambda. Per rendere l'immagine compatibile con Lambda, devi includere il pacchetto aws-lambda-go/lambda nell'immagine.

  • Utilizzo di un'immagine non AWS di base

    È possibile utilizzare un'immagine di base alternativa da un altro registro del container, come ad esempio Alpine Linux o Debian. Puoi anche utilizzare un'immagine personalizzata creata dalla tua organizzazione. Per rendere l'immagine compatibile con Lambda, devi includere il pacchetto aws-lambda-go/lambda nell'immagine.

Suggerimento

Per ridurre il tempo necessario all'attivazione delle funzioni del container Lambda, consulta Utilizzo di compilazioni a più fasi nella documentazione Docker. Per creare immagini di container efficienti, segui le best practice per scrivere file Docker.

Questa pagina spiega come creare, testare e implementare le immagini di container per Lambda.

AWS immagini di base per l'implementazione delle funzioni Go

Go è implementato in modo diverso rispetto ad altri runtime gestiti. Poiché Go viene compilato in modo nativo in un file binario eseguibile, non richiede un runtime linguistico dedicato. Usa un'immagine di base solo per il sistema operativo per distribuire le funzioni Go su Lambda.

Nome Identificatore Sistema operativo Data di ritiro Blocco creazione funzioni Blocco aggiornamento funzioni

Runtime solo per il sistema operativo

provided.al2023

Amazon Linux 2023

Non pianificato

Non programmato

Non programmato

Runtime solo per il sistema operativo

provided.al2

Amazon Linux 2

Non programmato

Non programmato

Non programmato

Galleria pubblica di Amazon Elastic Container Registry: gallery.ecr.aws/lambda/provided

Client di interfaccia di runtime per Go

Il pacchetto aws-lambda-go/lambda include un'implementazione dell'interfaccia di runtime. Per esempi di come utilizzare aws-lambda-go/lambda nell'immagine, consulta le sezioni Utilizzo di un'immagine di AWS base solo per il sistema operativo o Utilizzo di un'immagine non AWS di base.

Utilizzo di un'immagine di AWS base solo per il sistema operativo

Go è implementato in modo diverso rispetto ad altri runtime gestiti. Poiché Go viene compilato in modo nativo in un file binario eseguibile, non richiede un runtime linguistico dedicato. Usa un'immagine di base solo per il sistema operativo per creare immagini di contenitori per le funzioni Go.

Tag Runtime Sistema operativo Dockerfile Definizione come obsoleto

al2023

Runtime solo per il sistema operativo Amazon Linux 2023 Dockerfile per Runtime solo per sistema operativo su GitHub

Non pianificato

al2

Runtime solo per il sistema operativo Amazon Linux 2 Dockerfile per Runtime solo per sistema operativo attivo GitHub

Non pianificato

Per ulteriori informazioni su queste immagini di base, consulta la pagina fornita nella galleria ECR pubblica di Amazon.

È necessario includere il pacchetto aws-lambda-go/lambda nel gestore Go. Questo pacchetto implementa il modello di programmazione per Go, inclusa l'interfaccia di runtime.

Per completare le fasi riportate in questa sezione, è necessario:

Creazione e implementazione di una funzione Go con l'immagine di base provided.al2023
  1. Crea una directory per il progetto, quindi passa a quella directory.

    mkdir hello cd hello
  2. Inizializza un nuovo modulo Go.

    go mod init example.com/hello-world
  3. Aggiungi la libreria lambda come dipendenza del nuovo modulo.

    go get github.com/aws/aws-lambda-go/lambda
  4. Crea un file denominato main.go, quindi aprilo in un editor di testo. Questo è il codice per la funzione Lambda. A fini di test, puoi utilizzare il codice di esempio seguente o sostituirlo con il tuo codice personalizzato.

    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. Utilizza un editor di testo per creare un file Dockerfile nella directory del progetto.

    • Il seguente Dockerfile di esempio utilizza una build multi-fase. Ciò consente di utilizzare un'immagine di base diversa in ogni passaggio. Puoi utilizzare un'immagine, ad esempio un'immagine di base Go, per compilare il codice e creare il file binario eseguibile. È quindi possibile utilizzare un'immagine diversa, ad esempio provided.al2023, nell'istruzione FROM finale per definire l'immagine da implementare in Lambda. Il processo di compilazione è separato dall'immagine di implementazione finale, quindi l'immagine finale contiene solo i file necessari per eseguire l'applicazione.

    • È possibile utilizzare il lambda.norpc tag opzionale per escludere il componente Remote Procedure Call (RPC) della libreria lambda. Il RPC componente è necessario solo se si utilizza il runtime Go 1.x obsoleto. L'esclusione di RPC riduce le dimensioni del pacchetto di distribuzione.

    • Nota che l'esempio Dockerfile non include un'USERistruzione. Quando distribuisci un'immagine del contenitore in Lambda, Lambda definisce automaticamente un utente Linux predefinito con le autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente quando non viene fornita alcuna istruzione. root USER

    Esempio - Dockerfile di compilazione multi-fase
    Nota

    Assicurati che la versione di Go specificata nel tuo Dockerfile (ad esempio golang:1.20) sia la stessa versione di Go che hai usato per creare l'applicazione.

    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. Crea l'immagine Docker con il comando docker build. L'esempio seguente assegna un nome all'immagine docker-image e le assegna il tag test.

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

    Il comando specifica l’opzione --platform linux/amd64 per garantire che il container sia compatibile con l'ambiente di esecuzione di Lambda, indipendentemente dall'architettura della macchina di sviluppo. Se intendi creare una funzione Lambda utilizzando l'architettura del set di ARM64 istruzioni, assicurati di modificare il comando per utilizzare invece l'--platform linux/arm64opzione.

Usa il simulatore dell'interfaccia di runtime per testare l'immagine in locale. Il simulatore dell'interfaccia di runtime è incluso nell'immagine di base provided.al2023.

Esecuzione del simulatore dell'interfaccia di runtime sul computer locale
  1. Avvia l'immagine Docker con il comando docker run. Tieni presente quanto segue:

    • docker-image è il nome dell'immagine e test è il tag.

    • ./main è l'ENTRYPOINT del Dockerfile.

    docker run -d -p 9000:8080 \ --entrypoint /usr/local/bin/aws-lambda-rie \ docker-image:test ./main

    Questo comando esegue l'immagine come container e crea un endpoint locale in localhost:9000/2015-03-31/functions/function/invocations.

  2. Da una nuova finestra di terminale, invia un evento al seguente endpoint utilizzando un comando curl:

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

    Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Alcune funzioni potrebbero richiedere un JSON payload. Esempio:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  3. Ottieni l'ID del container.

    docker ps
  4. Utilizza il comando docker kill per arrestare il container. In questo comando, sostituisci 3766c4ab331c con l'ID del container del passaggio precedente.

    docker kill 3766c4ab331c
Per caricare l'immagine su Amazon ECR e creare la funzione Lambda
  1. Esegui il get-login-passwordcomando per autenticare il Docker nel CLI tuo registro AmazonECR.

    • Imposta il --region valore nel Regione AWS punto in cui desideri creare il ECR repository Amazon.

    • 111122223333Sostituiscilo con il tuo Account 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. Crea un repository in Amazon ECR utilizzando il comando create-repository.

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

    Il ECR repository Amazon deve corrispondere alla funzione Regione AWS Lambda.

    In caso di esito positivo, dovresti ottenere una risposta simile a questa:

    { "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. Copia il repositoryUri dall'output del passaggio precedente.

  4. Esegui il comando docker tag per taggare la tua immagine locale nel tuo ECR repository Amazon come versione più recente. In questo comando:

    • docker-image:testè il nome e il tag della tua immagine Docker. Si tratta del nome e del tag dell'immagine che hai specificato nel docker build comando.

    • Sostituisci l’<ECRrepositoryUri> con l’repositoryUri copiato. Assicurati di includere :latest alla fine diURI.

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

    Esempio:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. Esegui il comando docker push per distribuire l'immagine locale nel repository Amazon. ECR Assicurati di includerla alla :latest fine del repository. URI

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. Crea un ruolo di esecuzione per la funzione, se non lo hai già fatto. Nella fase successiva è necessario l'Amazon Resource Name (ARN) del ruolo.

  7. Creazione della funzione Lambda PerImageUri, specifica il repository URI di cui hai parlato in precedenza. Assicurati di includere :latest alla fine di. 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
    Nota

    È possibile creare una funzione utilizzando un'immagine in un AWS account diverso, purché l'immagine si trovi nella stessa regione della funzione Lambda. Per ulteriori informazioni, consulta Autorizzazioni Amazon ECR per più account.

  8. Richiama la funzione.

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

    Dovresti ottenere una risposta simile a questa:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. Per vedere l'output della funzione, controlla il file response.json.

Per aggiornare il codice della funzione, devi creare nuovamente l'immagine, caricare la nuova immagine nel ECR repository Amazon e quindi utilizzare il update-function-codecomando per distribuire l'immagine nella funzione Lambda.

Lambda risolve il tag image in un digest di immagini specifico. Ciò significa che se punti il tag image utilizzato per distribuire la funzione su una nuova immagine in AmazonECR, Lambda non aggiorna automaticamente la funzione per utilizzare la nuova immagine.

Per distribuire la nuova immagine nella stessa funzione Lambda, devi usare update-function-codeil comando, anche se il tag dell'immagine in ECR Amazon rimane lo stesso. Nell'esempio seguente, l'--publishopzione crea una nuova versione della funzione utilizzando l'immagine del contenitore aggiornata.

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

Utilizzo di un'immagine non AWS di base

Puoi creare un'immagine contenitore per Go da un'immagine non di AWS base. Nei passaggi di esempio che seguono, Dockerfile utilizza un'immagine di base Alpine.

È necessario includere il pacchetto aws-lambda-go/lambda nel gestore Go. Questo pacchetto implementa il modello di programmazione per Go, inclusa l'interfaccia di runtime.

Per completare le fasi riportate in questa sezione, è necessario:

Creazione e implementazione di una funzione Go con un'immagine di base Alpine
  1. Crea una directory per il progetto, quindi passa a quella directory.

    mkdir hello cd hello
  2. Inizializza un nuovo modulo Go.

    go mod init example.com/hello-world
  3. Aggiungi la libreria lambda come dipendenza del nuovo modulo.

    go get github.com/aws/aws-lambda-go/lambda
  4. Crea un file denominato main.go, quindi aprilo in un editor di testo. Questo è il codice per la funzione Lambda. A fini di test, puoi utilizzare il codice di esempio seguente o sostituirlo con il tuo codice personalizzato.

    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. Utilizza un editor di testo per creare un file Dockerfile nella directory del progetto. Nell'esempio che segue, Dockerfile utilizza un'immagine di base Alpine. Nota che l'esempio Dockerfile non include un'USERistruzione. Quando distribuisci un'immagine del contenitore in Lambda, Lambda definisce automaticamente un utente Linux predefinito con le autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente quando non viene fornita alcuna istruzione. root USER

    Esempio Dockerfile
    Nota

    Assicurati che la versione di Go specificata nel tuo Dockerfile (ad esempio golang:1.20) sia la stessa versione di Go che hai usato per creare l'applicazione.

    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. Crea l'immagine Docker con il comando docker build. L'esempio seguente assegna un nome all'immagine docker-image e le assegna il tag test.

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

    Il comando specifica l’opzione --platform linux/amd64 per garantire che il container sia compatibile con l'ambiente di esecuzione di Lambda, indipendentemente dall'architettura della macchina di sviluppo. Se intendi creare una funzione Lambda utilizzando l'architettura del set di ARM64 istruzioni, assicurati di modificare il comando per utilizzare invece l'--platform linux/arm64opzione.

Usa il simulatore dell'interfaccia di runtime per testare l'immagine in locale. Puoi creare l'emulatore nell'immagine o utilizzare la seguente procedura per installarlo sul tuo computer locale.

Installazione ed esecuzione dell'emulatore di interfaccia di runtime sul computer locale
  1. Dalla directory del progetto, esegui il comando seguente per scaricare l'emulatore di interfaccia di runtime (architettura x86-64) GitHub e installarlo sul computer locale.

    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

    Per installare l'emulatore arm64, sostituisci il GitHub repository URL nel comando precedente con quanto segue:

    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

    Per installare l'emulatore arm64, sostituisci $downloadLink con quanto segue:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
  2. Avvia l'immagine Docker con il comando docker run. Tieni presente quanto segue:

    • docker-image è il nome dell'immagine e test è il tag.

    • /main è l'ENTRYPOINT del Dockerfile.

    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

    Questo comando esegue l'immagine come container e crea un endpoint locale in localhost:9000/2015-03-31/functions/function/invocations.

    Nota

    Se hai creato l'immagine Docker per l'architettura del set di ARM64 istruzioni, assicurati di utilizzare l'--platform linux/arm64opzione anziché. --platform linux/amd64

  3. Pubblica un evento nell'endpoint locale.

    Linux/macOS

    Su MacOS o Linux, esegui il comando seguente curl:

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

    Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se utilizzi il tuo codice di funzione anziché il codice di funzione di esempio, potresti voler richiamare la funzione con un JSON payload. Esempio:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
    PowerShell

    In PowerShell, esegui il seguente Invoke-WebRequest comando:

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

    Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se utilizzi il tuo codice di funzione anziché il codice di funzione di esempio, potresti voler richiamare la funzione con un JSON payload. Esempio:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
  4. Ottieni l'ID del container.

    docker ps
  5. Utilizza il comando docker kill per arrestare il container. In questo comando, sostituisci 3766c4ab331c con l'ID del container del passaggio precedente.

    docker kill 3766c4ab331c
Per caricare l'immagine su Amazon ECR e creare la funzione Lambda
  1. Esegui il get-login-passwordcomando per autenticare il Docker nel CLI tuo registro AmazonECR.

    • Imposta il --region valore nel Regione AWS punto in cui desideri creare il ECR repository Amazon.

    • 111122223333Sostituiscilo con il tuo Account 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. Crea un repository in Amazon ECR utilizzando il comando create-repository.

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

    Il ECR repository Amazon deve corrispondere alla funzione Regione AWS Lambda.

    In caso di esito positivo, dovresti ottenere una risposta simile a questa:

    { "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. Copia il repositoryUri dall'output del passaggio precedente.

  4. Esegui il comando docker tag per taggare la tua immagine locale nel tuo ECR repository Amazon come versione più recente. In questo comando:

    • docker-image:testè il nome e il tag della tua immagine Docker. Si tratta del nome e del tag dell'immagine che hai specificato nel docker build comando.

    • Sostituisci l’<ECRrepositoryUri> con l’repositoryUri copiato. Assicurati di includere :latest alla fine diURI.

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

    Esempio:

    docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  5. Esegui il comando docker push per distribuire l'immagine locale nel repository Amazon. ECR Assicurati di includerla alla :latest fine del repository. URI

    docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
  6. Crea un ruolo di esecuzione per la funzione, se non lo hai già fatto. Nella fase successiva è necessario l'Amazon Resource Name (ARN) del ruolo.

  7. Creazione della funzione Lambda PerImageUri, specifica il repository URI di cui hai parlato in precedenza. Assicurati di includere :latest alla fine di. 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
    Nota

    È possibile creare una funzione utilizzando un'immagine in un AWS account diverso, purché l'immagine si trovi nella stessa regione della funzione Lambda. Per ulteriori informazioni, consulta Autorizzazioni Amazon ECR per più account.

  8. Richiama la funzione.

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

    Dovresti ottenere una risposta simile a questa:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. Per vedere l'output della funzione, controlla il file response.json.

Per aggiornare il codice della funzione, devi creare nuovamente l'immagine, caricare la nuova immagine nel ECR repository Amazon e quindi utilizzare il update-function-codecomando per distribuire l'immagine nella funzione Lambda.

Lambda risolve il tag image in un digest di immagini specifico. Ciò significa che se punti il tag image utilizzato per distribuire la funzione su una nuova immagine in AmazonECR, Lambda non aggiorna automaticamente la funzione per utilizzare la nuova immagine.

Per distribuire la nuova immagine nella stessa funzione Lambda, devi usare update-function-codeil comando, anche se il tag dell'immagine in ECR Amazon rimane lo stesso. Nell'esempio seguente, l'--publishopzione crea una nuova versione della funzione utilizzando l'immagine del contenitore aggiornata.

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