Creación de las primeras funciones contenedorizadas en Azure Container Apps
En este artículo, creará una aplicación de funciones que se ejecuta en un contenedor de Linux y la implementará en un entorno de Azure Container Apps desde un registro de contenedor. Al implementar en Container Apps, puede integrar las aplicaciones de funciones en microservicios nativos de la nube. Para más información, vea Hospedaje de Azure Functions en Azure Container Apps.
En este artículo se muestra cómo crear funciones que se ejecutan en un contenedor de Linux e implementar el contenedor en un entorno de Container Apps.
El costo de completar este inicio rápido apenas supone unos céntimos o menos en la cuenta de Azure, lo que puede minimizar mediante la limpieza de recursos cuando haya terminado.
Elija el lenguaje de desarrollo
En primer lugar, usará herramientas de Azure Functions para crear el código del proyecto como una aplicación de funciones en un contenedor de Docker mediante una imagen base de Linux específica del lenguaje. Asegúrese de seleccionar el lenguaje que prefiere en la parte superior del artículo.
Core Tools genera automáticamente un Dockerfile para el proyecto que usa la versión más actualizada de la imagen base correcta para el lenguaje de funciones. Debe actualizar periódicamente el contenedor desde la imagen base más reciente y volver a implementar desde la versión actualizada del contenedor. Para obtener más información, consulte Creación de aplicaciones de funciones en contenedor.
Prerrequisitos
Antes de comenzar, deberá asegurarse de que cumple con los siguientes requisitos:
Instalar el SDK de .NET 8.0.
Instale Azure Functions Core Tools versión 4.0.5198 u otra posterior.
- Instale Azure Functions Core Tools, versión 4.x.
- Instale una versión de Node.jscompatible con Azure Functions.
- Instale una versión de Python compatible con Azure Functions.
- Instale el SDK de .NET 6.
Instale una versión del kit de desarrollo de Javacompatible con Azure Functions.
Instale Apache Maven, versión 3.0 o posterior.
- La CLI de Azure, versión 2.4 o posterior.
Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar.
Para publicar la imagen de aplicación de funciones en contenedor que crea en un registro de contenedor, necesita un identificador de Docker y Docker en ejecución en el equipo local. Si no tiene un identificador de Docker, puede crear una cuenta de Docker.
También debe completar la sección Creación de un registro de contenedor del inicio rápido de Container Registry para crear una instancia del registro. Anote el nombre completo del servidor de inicio de sesión.
Creación y activación de un entorno virtual
En una carpeta adecuada, ejecute los comandos siguientes para crear y activar un entorno virtual denominado .venv
. Asegúrese de usar una de las versiones de Python compatibles con Azure Functions.
python -m venv .venv
source .venv/bin/activate
Si Python no instaló el paquete venv en la distribución de Linux, ejecute el siguiente comando:
sudo apt-get install python3-venv
Ejecute todos los comandos siguientes en este entorno virtual activado.
Creación y prueba de un proyecto local de Functions
En un terminal o símbolo del sistema, ejecute el siguiente comando para el lenguaje elegido a fin de crear un proyecto de aplicación de funciones en la carpeta actual.
func init --worker-runtime dotnet-isolated --docker
func init --worker-runtime node --language javascript --docker
func init --worker-runtime powershell --docker
func init --worker-runtime python --docker
func init --worker-runtime node --language typescript --docker
En una carpeta vacía, ejecute el comando siguiente para generar el proyecto de Functions desde un arquetipo Maven.
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker
El parámetro -DjavaVersion
indica al entorno de ejecución de Functions qué versión de Java debe usar. Use -DjavaVersion=11
si quiere que las funciones se ejecuten en Java 11. Cuando no se especifica -DjavaVersion
, el valor predeterminado de Maven es Java 8. Para obtener más información, consulte Versiones de Java.
Importante
Para llevar a cabo los pasos de este artículo, la variable de entorno JAVA_HOME
se debe establecer en la ubicación de instalación de la versión correcta del JDK.
Maven le pide los valores necesarios para finalizar la generación del proyecto en la implementación. Siga las solicitudes y proporcione la siguiente información:
Prompt | Valor | Descripción |
---|---|---|
groupId | com.fabrikam |
Un valor que identifica de forma única su proyecto entre todos los demás y que sigue las reglas de nomenclatura de paquetes de Java. |
artifactId | fabrikam-functions |
Un valor que es el nombre del archivo jar, sin un número de versión. |
version | 1.0-SNAPSHOT |
Seleccione el valor predeterminado. |
package | com.fabrikam.functions |
Un valor que es el paquete de Java para el código de función generado. Use el valor predeterminado. |
Escriba Y
o presione Entrar para confirmar.
Maven crea los archivos del proyecto en una carpeta nueva llamada artifactId que, en este ejemplo, es fabrikam-functions
.
La opción --docker
genera un Dockerfile para el proyecto, que define un contenedor adecuado para su uso con Azure Functions y el entorno de ejecución seleccionado.
Vaya a la carpeta del proyecto:
cd fabrikam-functions
Use el comando siguiente para agregar una función al proyecto mediante el comando siguiente, donde el argumento --name
es el nombre único de la función y el argumento --template
especifica el desencadenador de esta.
func new
crea un archivo de código de C# en el proyecto.
func new --name HttpExample --template "HTTP trigger"
Use el comando siguiente para agregar una función al proyecto mediante el comando siguiente, donde el argumento --name
es el nombre único de la función y el argumento --template
especifica el desencadenador de esta.
func new
crea una subcarpeta que coincide con el nombre de función que contiene un archivo de configuración denominado function.json.
func new --name HttpExample --template "HTTP trigger"
Para probar la función localmente, inicie el host en tiempo de ejecución de Azure Functions local en la carpeta raíz del proyecto:
func start
func start
npm install
npm start
mvn clean package
mvn azure-functions:run
Cuando vea el punto de conexión HttpExample
aparecer en la salida, vaya a ese punto de conexión. Debería ver un mensaje de bienvenida en la salida de la respuesta.
Cuando vea el punto de conexión HttpExample
aparecer en la salida, vaya a http://localhost:7071/api/HttpExample?name=Functions
. El explorador tiene que mostrar un mensaje "hello" que devuelve Functions
, el valor proporcionado al parámetro de consulta name
.
Presione Ctrl+C (Command+C en macOS) para detener el host.
Creación de la imagen de contenedor y verificación local
(Opcional) Examine el archivo Dockerfile en la carpeta raíz del proyecto. El archivo de Dockerfile describe el entorno necesario para ejecutar la aplicación de funciones en Linux. La lista completa de imágenes base admitidas para Azure Functions se puede encontrar en la página de imágenes base de Azure Functions.
En la carpeta raíz del proyecto, ejecute el comando docker build y especifique un nombre como azurefunctionsimage
y una etiqueta como v1.0.0
. Reemplace <DOCKER_ID>
por el identificador de su cuenta de Docker Hub. Este comando compila la imagen de Docker del contenedor.
docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .
Cuando el comando se complete, podrá ejecutar el nuevo contenedor de forma local.
Para verificar la compilación, ejecute la imagen en un contenedor local con el comando docker run. Para ello, reemplace de nuevo <DOCKER_ID>
por el identificador de la cuenta de Docker Hub y agregue el argumento de puertos como -p 8080:80
:
docker run -p 8080:80 -it <DOCKER_ID>/azurefunctionsimage:v1.0.0
Una vez que la imagen se inicie en el contenedor local, vaya a http://localhost:8080/api/HttpExample
, donde tiene que aparecer el mismo mensaje de saludo que antes. Dado que la función desencadenada por HTTP que creó usa la autorización anónima, puede llamar a la función que se ejecuta en el contenedor sin tener que obtener una clave de acceso. Para más información, consulte Claves de autorización.
Una vez que la imagen se inicie en el contenedor local, vaya a http://localhost:8080/api/HttpExample?name=Functions
, donde debe aparecer el mismo mensaje "hello" que antes. Dado que la función desencadenada por HTTP que creó usa la autorización anónima, puede llamar a la función que se ejecuta en el contenedor sin tener que obtener una clave de acceso. Para más información, consulte Claves de autorización.
Después de comprobar la aplicación de funciones en el contenedor, presione Ctrl+C (Command+C en macOS para detener la ejecución.
Publicación de la imagen de contenedor en un registro
Para que la imagen de contenedor esté disponible para la implementación en un entorno de hospedaje, debe insertarla en un registro de contenedor. Como procedimiento recomendado de seguridad, debe usar una instancia de Azure Container Registry y aplicar conexiones basadas en identidades administradas. Docker Hub requiere que se autentique mediante secretos compartidos, lo que hace que las implementaciones sean más vulnerables.
Azure Container Registry es un servicio de registro privado para compilar, almacenar y proporcionar imágenes de contenedor y artefactos relacionados. Debe usar un servicio de registro privado para publicar los contenedores en los servicios de Azure.
Use este comando para iniciar sesión en la instancia del Registro mediante las credenciales actuales de Azure:
az acr login --name <REGISTRY_NAME>
En el comando anterior, reemplace
<REGISTRY_NAME>
por el nombre de la instancia de Container Registry.Use este comando para etiquetar la imagen con el nombre completo del servidor de inicio de sesión del Registro:
docker tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
Reemplace
<LOGIN_SERVER>
por el nombre completo del servidor de inicio de sesión del registro y<DOCKER_ID>
por el identificador de Docker.Use este comando para insertar el contenedor en la instancia del Registro:
docker push <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
Creación de recursos auxiliares de Azure para la función
Antes de poder implementar el contenedor en Azure, debe crear tres recursos:
- Un grupo de recursos, que es un contenedor lógico de recursos relacionados.
- Una cuenta de almacenamiento, que se usa para mantener el estado y otra información sobre sus funciones.
- Un entorno de Azure Container Apps con un área de trabajo de Log Analytics.
- Una identidad administrada asignada por el usuario, que permite que la aplicación de funciones se conecte de forma segura a los recursos de Azure sin usar secretos compartidos. En su lugar, las conexiones a la cuenta de Azure Storage y a la instancia de Azure Container Registry se realizan mediante la autenticación de Microsoft Entra con la identidad, que se recomienda para este escenario.
Nota:
Docker Hub no admite identidades administradas.
Use estos comandos para crear los recursos de Azure necesarios:
Si es necesario, inicie sesión en Azure:
El comando
az login
inicia sesión en su cuenta de Azure. Useaz account set
cuando tenga más de una suscripción asociada a la cuenta.Ejecute el comando siguiente para actualizar la CLI de Azure a la versión más reciente:
az upgrade
Si la versión de la CLI de Azure no es la más reciente, se inicia una instalación. La forma de actualización depende del sistema operativo. Puede continuar una vez que se complete la actualización.
Ejecute los comandos siguientes que actualizan la extensión Azure Container Apps y registran los espacios de nombres necesarios para Container Apps:
az extension add --name containerapp --upgrade -y az provider register --namespace Microsoft.Web az provider register --namespace Microsoft.App az provider register --namespace Microsoft.OperationalInsights
Cree un grupo de recursos con el nombre
AzureFunctionsContainers-rg
.az group create --name AzureFunctionsContainers-rg --location eastus
Este comando
az group create
crea un grupo de recursos en la región Este de EE. UU. Si quiere usar una región cercana, utilice un código de región disponible devuelto por el comando az account list-locations. Debe modificar los comandos posteriores para usar la región personalizada en lugar deeastus
.Cree un entorno de Azure Container App con perfiles de carga de trabajo habilitados.
az containerapp env create --name MyContainerappEnvironment --enable-workload-profiles --resource-group AzureFunctionsContainers-rg --location eastus
Este comando puede tardar unos minutos en completarse.
Cree una cuenta de almacenamiento de uso general en el grupo de recursos y la región, sin acceso a claves compartidas.
az storage account create --name <STORAGE_NAME> --location eastus --resource-group AzureFunctionsContainers-rg --sku Standard_LRS --allow-blob-public-access false --allow-shared-key-access false
El
az storage account create
comando crea la cuenta de almacenamiento a la que sólo se puede acceder mediante el uso de identidades autenticadas de Microsoft Entra a las que se han concedido permisos para recursos específicos.En el ejemplo anterior, reemplace
<STORAGE_NAME>
por un nombre que sea apropiado para usted y único en Azure Storage. Los nombres deben contener entre 3 y 24 caracteres y solo letras minúsculas. El valorStandard_LRS
especifica que se trata de una cuenta de uso general y que Functions admite su uso.Cree una identidad administrada y use el devuelto
principalId
para concederle acceso a la cuenta de almacenamiento y permisos de incorporación de cambios en la instancia del Registro.principalId=$(az identity create --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --location eastus --query principalId -o tsv) acrId=$(az acr show --name <REGISTRY_NAME> --query id --output tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role acrpull --scope $acrId storageId=$(az storage account show --resource-group AzureFunctionsContainers-rg --name glengatestaca2 --query 'id' -o tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role "Storage Blob Data Owner" --scope $storageId
El
az identity create
comando crea una identidad administrada asignada por el usuario y losaz role assignment create
comandos agregan la identidad a los roles necesarios. Reemplace<REGISTRY_NAME>
,<USER_IDENTITY_NAME>
, y<STORAGE_NAME>
por el nombre del registro de contenedor existente, el nombre de su identidad administrada y el nombre de la cuenta de almacenamiento, respectivamente. Una aplicación puede usar la identidad administrada para acceder a la cuenta de almacenamiento y Azure Container Registry sin usar secretos compartidos.
Creación y configuración de una aplicación de funciones en Azure con la imagen
Una aplicación de funciones en Azure administra la ejecución de las funciones en el entorno de Azure Container Apps. En esta sección, usará los recursos de Azure de la sección anterior para crear una aplicación de funciones a partir de una imagen en un registro de contenedor en un entorno de Container Apps. También configurará el nuevo entorno con una cadena de conexión a la cuenta de Azure Storage necesaria.
Use el comando az functionapp create
para crear una aplicación de funciones en el nuevo entorno administrado respaldado por Azure Container Apps. En az functionapp create
, el --environment
parámetro especifica el entorno de Container Apps.
Sugerencia
Para asegurarse de que la aplicación de funciones usa una conexión basada en identidad administrada a la instancia del Registro, no establezca el --image
parámetro en az functionapp create
. Cuando se establece --image
en el nombre completo de la imagen en el repositorio, las credenciales secretas compartidas se obtienen del registro y se almacenan en la configuración de la aplicación.
En primer lugar, debe obtener el valor de identificador completo de la identidad administrada asignada por el usuario con acceso de extracción al registro y, a continuación, usar el az functionapp create
comando para crear una aplicación de funciones mediante la imagen predeterminada y con esta identidad asignada.
UAMI_RESOURCE_ID=$(az identity show --name $uami_name --resource-group $group --query id -o tsv)
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --assign-identity $UAMI_RESOURCE_ID
En az functionapp create
, asigna --assign-identity
la identidad administrada a la nueva aplicación. Dado que no estableció el --image
parámetro en az functionapp create
, la aplicación se crea con una imagen de marcador de posición.
En este ejemplo, reemplace <APP_NAME>
, <STORAGE_NAME>
, y <USER_IDENTITY_NAME>
por un nombre para la nueva aplicación de funciones, así como el nombre de la cuenta de almacenamiento y la identidad.
Por último, debe actualizar la configuración del linuxFxVersion
sitio al nombre completo de la imagen en el repositorio. También debe actualizar la configuración del sitio acrUseManagedIdentityCreds
y acrUserManagedIdentityID
para que se usen identidades administradas al obtener la imagen del Registro.
UAMI_RESOURCE_ID=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query id -o tsv)
az resource patch --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --resource-type "Microsoft.Web/sites" --properties "{ \"siteConfig\": { \"linuxFxVersion\": \"DOCKER|<REGISTRY_NAME>.azurecr.io/azurefunctionsimage:v1.0.0\", \"acrUseManagedIdentityCreds\": true, \"acrUserManagedIdentityID\":\"$UAMI_RESOURCE_ID\", \"appSettings\": [{\"name\": \"DOCKER_REGISTRY_SERVER_URL\", \"value\": \"<REGISTRY_NAME>.azurecr.io\"}]}}"
Además de la configuración del sitio necesaria, el az resource patch
comando también actualiza la DOCKER_REGISTRY_SERVER_URL
configuración de la aplicación a la dirección URL del servidor del Registro.
En este ejemplo, reemplace <APP_NAME>
, <REGISTRY_NAME>
, y <USER_IDENTITY_NAME>
por los nombres de la aplicación de funciones, el registro de contenedor y la identidad, respectivamente.
Al especificar --workload-profile-name "Consumption"
se crea la aplicación en un entorno con el perfil de carga de trabajo de Consumption
predeterminado, que cuesta lo mismo que la ejecución en un plan de consumo de Container Apps. La primera vez que se crea la aplicación de funciones, se extrae la imagen inicial del registro.
Actualización de la configuración de la aplicación
Para permitir que el host de Functions se conecte a la cuenta de almacenamiento predeterminada mediante secretos compartidos, debe reemplazar la AzureWebJobsStorage
configuración de cadena de conexión por una configuración equivalente que use la identidad administrada asignada por el usuario para conectarse a la cuenta de almacenamiento.
Quite la configuración de la
AzureWebJobsStorage
cadena de conexión existente:az functionapp config appsettings delete --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --setting-names AzureWebJobsStorage
El comando az functionapp config appsettings delete quita esta configuración de la aplicación. Reemplace
<APP_NAME>
por el nombre de la aplicación de función.Agregue una configuración equivalente, con un
AzureWebJobsStorage__
prefijo, que defina una conexión de identidad administrada asignada por el usuario a la cuenta de almacenamiento predeterminada:clientId=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query 'clientId' -o tsv) az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage__accountName=<STORAGE_NAME> AzureWebJobsStorage__credential=managedidentity AzureWebJobsStorage__clientId=$clientId
En este ejemplo, reemplace
<APP_NAME>
,<USER_IDENTITY_NAME>
,<STORAGE_NAME>
por el nombre de la aplicación de funciones, el nombre de la identidad y el nombre de la cuenta de almacenamiento, respectivamente.
En este momento, las funciones se ejecutan en un entorno de Container Apps, con la configuración de la aplicación necesaria ya agregada. Cuando lo necesite, puede agregar otras opciones de configuración en la aplicación de funciones, de la manera estándar para Functions. Para más información, vea Uso de la configuración de la aplicación.
Sugerencia
Al realizar cambios posteriores en el código de función, debe volver a generar el contenedor, volver a publicar la imagen en el registro y actualizar la aplicación de funciones con la versión de la nueva imagen. Para más información, vea Actualización de una imagen en el registro
Comprobación de las funciones en Azure
Con la imagen implementada en la aplicación de funciones en Azure, ya puede invocar la función mediante solicitudes HTTP.
Ejecute el siguiente comando
az functionapp function show
para obtener la dirección URL de la nueva función:az functionapp function show --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --function-name HttpExample --query invokeUrlTemplate
Reemplace
<APP_NAME>
por el nombre de la aplicación de función.
- Use la URL que acaba de obtener para llamar al punto de conexión de la función
HttpExample
, y anexe la cadena de consulta?name=Functions
.
- Use la dirección URL que acaba de obtener para llamar al punto de conexión de la función
HttpExample
.
Cuando vaya a esta dirección URL, el explorador tiene que mostrar una salida similar a cuando ejecutó la función localmente.
La URL solicitada debería ser similar a la siguiente:
https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample?name=functions
https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample
Limpieza de recursos
Si quiere seguir trabajando con Azure Functions y con los recursos que ha creado en este artículo, puede dejarlos todos activos.
Cuando haya terminado de trabajar con la implementación de esta aplicación de funciones, elimine el grupo de recursos AzureFunctionsContainers-rg
para limpiar todos los recursos de ese grupo:
az group delete --name AzureFunctionsContainers-rg