Implementar funciones Java Lambda con imágenes de contenedor
Hay tres formas de crear una imagen de contenedor para una función de Lambda en Java:
-
Uso de una imagen base de AWS para Java
Las imágenes base de AWS vienen precargadas con un tiempo de ejecución de lenguaje, un cliente de interfaz de tiempo de ejecución para administrar la interacción entre Lambda y el código de la función y un emulador de interfaz de tiempo de ejecución para realizar pruebas a nivel local.
-
Uso de una imagen base exclusiva del sistema operativo de AWS
Las imágenes base exclusivas del sistema operativo de AWS
contienen una distribución de Amazon Linux y el emulador de interfaz de tiempo de ejecución . Por lo general, estas imágenes se utilizan para crear imágenes contenedoras para lenguajes compilados, como Go y Rust, y para un lenguaje o versión de un lenguaje para los que Lambda no proporciona una imagen base, como Node.js 19. También puede usar imágenes base exclusivas del sistema operativo para implementar un tiempo de ejecución personalizado. Para que la imagen sea compatible con Lambda, debe incluir el cliente de interfaz de tiempo de ejecución para Java en la imagen. -
Uso de una imagen base que no sea de AWS
Puede utilizar una imagen base alternativa de otro registro de contenedores, como Alpine Linux o Debian. También puede utilizar una imagen personalizada creada por su organización. Para que la imagen sea compatible con Lambda, debe incluir el cliente de interfaz de tiempo de ejecución para Java en la imagen.
sugerencia
Para reducir el tiempo que tardan las funciones de contenedor de Lambda en activarse, consulte Uso de compilaciones de varias fases
En esta página, se explica cómo compilar, probar e implementar imágenes de contenedor para Lambda.
Temas
Imágenes base de AWS para Java
AWS proporciona las siguientes imágenes base para Java:
Etiquetas | Tiempo de ejecución | Sistema operativo | Dockerfile | Obsolescencia |
---|---|---|---|---|
21 |
Java 21 | Amazon Linux 2023 | Dockerfile para Java 21 en GitHub |
No programado |
17 |
Java 17 | Amazon Linux 2 | Dockerfile para Java 17 en GitHub |
No programado |
11 |
Java 11 | Amazon Linux 2 | Dockerfile para Java 11 en GitHub |
No programado |
8.al2 |
Java 8 | Amazon Linux 2 | Dockerfile para Java 8 en GitHub |
No programado |
Repositorio de Amazon ECR: gallery.ecr.aws/lambda/java
Las imágenes base de Java 21 y versiones posteriores se basan en la imagen de contenedor mínima de Amazon Linux 2023. Las imágenes base anteriores utilizan Amazon Linux 2. AL2023 ofrece varias ventajas con respecto a Amazon Linux 2, incluida una huella de implementación más reducida y versiones actualizadas de bibliotecas como glibc
.
Las imágenes basadas en AL2023 utilizan microdnf
(enlazadas simbólicamente como dnf
) como administrador de paquetes en lugar de yum
, que es el administrador de paquetes predeterminado en Amazon Linux 2. microdnf
es una implementación independiente de dnf
. Para obtener una lista de los paquetes que se incluyen en las imágenes basadas en AL2023, consulte las columnas de Minimal Container de Comparing packages installed on Amazon Linux 2023 Container Images. Para obtener más información sobre las diferencias entre AL2023 y Amazon Linux 2, consulte Introducing the Amazon Linux 2023 runtime for AWS Lambda
nota
Para ejecutar imágenes basadas en AL2023 de forma local, incluso con AWS Serverless Application Model (AWS SAM), debe usar Docker en la versión 20.10.10 o posterior.
Uso de una imagen base de AWS para Java
Para completar los pasos de esta sección, debe disponer de lo siguiente:
-
Java (por ejemplo, Amazon Corretto
) -
Docker
(versión mínima 20.10.10 para las imágenes base de Java 21 y versiones posteriores)
-
Inicie la imagen de Docker con el comando docker run. En este ejemplo,
docker-image
es el nombre de la imagen ytest
es la etiqueta.docker run --platform linux/amd64 -p 9000:8080 --read-only
docker-image
:test
Este comando ejecuta la imagen como un contenedor y crea un punto de conexión local en
localhost:9000/2015-03-31/functions/function/invocations
.nota
Si creó la imagen de Docker para la arquitectura del conjunto de instrucciones ARM64, asegúrese de utilizar la opción
--platform linux/
en lugar dearm64
--platform linux/
.amd64
-
Desde una nueva ventana de terminal, publique un evento en el punto de conexión local.
-
Obtenga el ID del contenedor.
docker ps
-
Use el comando docker kill
para detener el contenedor. En este comando, reemplace 3766c4ab331c
por el ID del contenedor del paso anterior.docker kill
3766c4ab331c
Para cargar la imagen en Amazon ECR y crear la función de Lambda
-
Para autenticar la CLI de Docker en su registro de Amazon ECR, ejecute el comando get-login-password
. -
Establezca el valor de
--region
en la Región de AWS en la que desee crear el repositorio de Amazon ECR. -
Reemplace
111122223333
por el ID de su Cuenta de AWS.
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
Cree un repositorio en Amazon ECR con el comando create-repository
. aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLEnota
El repositorio de Amazon ECR debe estar en la misma Región de AWS que la función de Lambda.
Si se realiza de la forma correcta, verá una respuesta como la siguiente:
{ "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" } } }
-
Copie el valor de
repositoryUri
de la salida del paso anterior. -
Ejecute el comando docker tag
para etiquetar la imagen local en su repositorio de Amazon ECR como la versión más reciente. En este comando: -
docker-image:test
es el nombre y la etiquetade su imagen de Docker. Son el nombre y la etiqueta de la imagen que especificó en el comando docker build
. -
Reemplace
<ECRrepositoryUri>
por elrepositoryUri
que ha copiado. Asegúrese de incluir:latest
al final del URI.
docker tag docker-image:test
<ECRrepositoryUri>
:latestEjemplo:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
Ejecute el comando docker push
para implementar la imagen local en el repositorio de Amazon ECR. Asegúrese de incluir :latest
al final del URI del repositorio.docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
Cree un rol de ejecución para la función si aún no tiene uno. Necesitará el nombre de recurso de Amazon (ARN) del rol en el paso siguiente.
-
Cree la función de Lambda. En
ImageUri
, especifique el URI del repositorio anterior. Asegúrese de incluir:latest
al final del 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 \ --rolearn:aws:iam::111122223333:role/lambda-ex
nota
Puede crear una función con una imagen de una cuenta AWS diferente, siempre que la imagen esté en la misma región que la función de Lambda. Para obtener más información, consulte Permisos entre cuentas de Amazon ECR.
-
Invoque la función.
aws lambda invoke --function-name
hello-world
response.jsonDebería ver una respuesta como la siguiente:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
Para ver la salida de la función, compruebe el archivo
response.json
.
Para actualizar el código de la función, debe volver a compilar la imagen, cargar la nueva imagen en el repositorio de Amazon ECR y, a continuación, utilizar el comando update-function-code
Lambda resuelve la etiqueta de la imagen en un resumen de imagen específico. Esto significa que si apunta la etiqueta de imagen que se utilizó para implementar la función a una nueva imagen en Amazon ECR, Lambda no actualiza automáticamente la función para usar la nueva imagen.
Para implementar la nueva imagen en la misma función de Lambda, debe usar el comando update-function-code--publish
crea una nueva versión de la función con la imagen del contenedor actualizada.
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish
Uso de una imagen base alternativa con el cliente de interfaz de tiempo de ejecución
Si usa una imagen base exclusiva del sistema operativo o una imagen base alternativa, debe incluir el cliente de interfaz de tiempo de ejecución en su imagen. El cliente de interfaz de tiempo de ejecución extiende el Uso de la API de tiempo de ejecución de Lambda para tiempos de ejecución personalizados, que administra la interacción entre Lambda y el código de la función.
Instale el cliente de interfaz de tiempo de ejecución para Java en su Dockerfile o como una dependencia en su proyecto. Por ejemplo, para instalar el cliente de interfaz de tiempo de ejecución mediante el administrador de paquetes de Maven, agregue los siguientes a su archivo pom.xml
:
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-runtime-interface-client</artifactId> <version>2.3.2</version> </dependency>
Para obtener detalles sobre el paquete, consulte AWS Lambda Java Runtime Interface Client
En el siguiente ejemplo, se muestra cómo crear una imagen de contenedor para Java mediante una imagen de Amazon Corretto
Para completar los pasos de esta sección, debe disponer de lo siguiente:
-
Java (por ejemplo, Amazon Corretto
)
-
Cree un proyecto de Maven. Se requieren los siguientes parámetros:
-
groupId: el espacio de nombres completo del paquete de la aplicación.
-
artifactId: el nombre del proyecto. Esto se convierte en el nombre del directorio del proyecto.
-
-
Abra el directorio del proyecto.
cd
myapp
-
Reemplace el contenido del archivo
pom.xml
por lo siguiente. Este archivo contiene el aws-lambda-java-runtime-interface-clientcomo dependencia. Como opción, puede instalar el cliente de interfaz de tiempo de ejecución en el Dockerfile. Sin embargo, el enfoque más simple es incluir la biblioteca como una dependencia. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId> <artifactId>hello-lambda</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>hello-lambda</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>
aws-lambda-java-runtime-interface-client
</artifactId> <version>2.3.2
</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.1.2</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> -
Abra el directorio
y busque el archivomyapp
/src/main/java/com/example/myapp
App.java
. Se trata del código de la función de Lambda. Reemplace el código con lo siguiente.ejemplo controlador de funciones
package example; public class App { public static String sayHello() { return "Hello world!"; } }
-
El comando
mvn -B archetype:generate
del paso 1 también generó un caso de prueba ficticio en el directoriosrc/test
. Para los fines de este tutorial, evite la ejecución de las pruebas y elimine todo este directorio de/test
generado. -
Regrese al directorio raíz del proyecto y, a continuación, crea un nuevo Dockerfile. El siguiente Dockerfile de ejemplo usa una imagen de Amazon Corretto
. Amazon Corretto es una distribución sin costo, multiplataforma y lista para producción de OpenJDK. -
Establezca la propiedad
FROM
en el URI de la imagen base. -
Configure
ENTRYPOINT
como el módulo que desea que el contenedor de Docker ejecute cuando se inicie. En este caso, el módulo es el cliente de interfaz de tiempo de ejecución. -
Establezca el argumento
CMD
para el controlador de la función de Lambda.
Tenga en cuenta que el Dockerfile de ejemplo no incluye una instrucción USER
. Al implementar una imagen de contenedor en Lambda, Lambda define automáticamente un usuario predeterminado de Linux con permisos de privilegio mínimo. Esto es diferente del comportamiento estándar de Docker, que utiliza de forma predeterminada el usuario root
cuando no se proporciona ninguna instrucciónUSER
.ejemplo Dockerfile
FROM
public.ecr.aws/amazoncorretto/amazoncorretto:21
as base # Configure the build environment FROM base as build RUN yum install -y maven WORKDIR /src # Cache and copy dependencies ADD pom.xml . RUN mvn dependency:go-offline dependency:copy-dependencies # Compile the function ADD . . RUN mvn package # Copy the function artifact and dependencies onto a clean base FROM base WORKDIR /function COPY --from=build /src/target/dependency/*.jar ./ COPY --from=build /src/target/*.jar ./ # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "/usr/bin/java", "-cp", "./*", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda
" ] # Pass the name of the function handler as an argument to the runtime CMD [ "example.App::sayHello
" ] -
-
Cree la imagen de Docker con el comando docker build
. En el siguiente ejemplo se asigna un nombre a la imagen docker-image
y se le asigna la etiquetatest
.docker build --platform linux/amd64 -t
docker-image
:test
.nota
El comando especifica la opción
--platform linux/amd64
para garantizar que el contenedor sea compatible con el entorno de ejecución de Lambda, independientemente de la arquitectura de la máquina de compilación. Si tiene intención de crear una función de Lambda con la arquitectura del conjunto de instrucciones ARM64, asegúrese de cambiar el comando para utilizar la opción--platform linux/arm64
en su lugar.
Utilice el emulador de interfaz de tiempo de ejecución
Para instalar y ejecutar el emulador de interfaz de tiempo de ejecución en su equipo local
-
Desde el directorio del proyecto, ejecute el siguiente comando para descargar el emulador de interfaz de tiempo de ejecución (arquitectura x86-64) de GitHub e instalarlo en su equipo local.
-
Inicie la imagen de Docker con el comando docker run. Tenga en cuenta lo siguiente:
-
docker-image
es el nombre de la imagen ytest
es la etiqueta. -
/usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello
es elENTRYPOINT
seguido delCMD
de su Dockerfile.
Este comando ejecuta la imagen como un contenedor y crea un punto de conexión local en
localhost:9000/2015-03-31/functions/function/invocations
.nota
Si creó la imagen de Docker para la arquitectura del conjunto de instrucciones ARM64, asegúrese de utilizar la opción
--platform linux/
en lugar dearm64
--platform linux/
.amd64
-
-
Publique un evento en el punto de conexión local.
-
Obtenga el ID del contenedor.
docker ps
-
Use el comando docker kill
para detener el contenedor. En este comando, reemplace 3766c4ab331c
por el ID del contenedor del paso anterior.docker kill
3766c4ab331c
Para cargar la imagen en Amazon ECR y crear la función de Lambda
-
Para autenticar la CLI de Docker en su registro de Amazon ECR, ejecute el comando get-login-password
. -
Establezca el valor de
--region
en la Región de AWS en la que desee crear el repositorio de Amazon ECR. -
Reemplace
111122223333
por el ID de su Cuenta de AWS.
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
Cree un repositorio en Amazon ECR con el comando create-repository
. aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLEnota
El repositorio de Amazon ECR debe estar en la misma Región de AWS que la función de Lambda.
Si se realiza de la forma correcta, verá una respuesta como la siguiente:
{ "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" } } }
-
Copie el valor de
repositoryUri
de la salida del paso anterior. -
Ejecute el comando docker tag
para etiquetar la imagen local en su repositorio de Amazon ECR como la versión más reciente. En este comando: -
docker-image:test
es el nombre y la etiquetade su imagen de Docker. Son el nombre y la etiqueta de la imagen que especificó en el comando docker build
. -
Reemplace
<ECRrepositoryUri>
por elrepositoryUri
que ha copiado. Asegúrese de incluir:latest
al final del URI.
docker tag docker-image:test
<ECRrepositoryUri>
:latestEjemplo:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
Ejecute el comando docker push
para implementar la imagen local en el repositorio de Amazon ECR. Asegúrese de incluir :latest
al final del URI del repositorio.docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
Cree un rol de ejecución para la función si aún no tiene uno. Necesitará el nombre de recurso de Amazon (ARN) del rol en el paso siguiente.
-
Cree la función de Lambda. En
ImageUri
, especifique el URI del repositorio anterior. Asegúrese de incluir:latest
al final del 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 \ --rolearn:aws:iam::111122223333:role/lambda-ex
nota
Puede crear una función con una imagen de una cuenta AWS diferente, siempre que la imagen esté en la misma región que la función de Lambda. Para obtener más información, consulte Permisos entre cuentas de Amazon ECR.
-
Invoque la función.
aws lambda invoke --function-name
hello-world
response.jsonDebería ver una respuesta como la siguiente:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
Para ver la salida de la función, compruebe el archivo
response.json
.
Para actualizar el código de la función, debe volver a compilar la imagen, cargar la nueva imagen en el repositorio de Amazon ECR y, a continuación, utilizar el comando update-function-code
Lambda resuelve la etiqueta de la imagen en un resumen de imagen específico. Esto significa que si apunta la etiqueta de imagen que se utilizó para implementar la función a una nueva imagen en Amazon ECR, Lambda no actualiza automáticamente la función para usar la nueva imagen.
Para implementar la nueva imagen en la misma función de Lambda, debe usar el comando update-function-code--publish
crea una nueva versión de la función con la imagen del contenedor actualizada.
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish