Azure Functions en Kubernetes

Si estás trabajando con Azure Functions y también con Kubernetes es posible que, en algunos escenarios, te interese valorar el despliegue de tus funciones en tu clúster. En este artículo te cuento cómo crear y desplegar una Azure Function dentro de Kubernetes.

Crear una Azure Function de ejemplo

Existen diferentes formas de crear una Azure Function. Lo más sencillo es haciendo uso de las extensión de Visual Studio Code, o a través de los asistentes de Visual Studio 2019 o Visual Studio for Mac. Sin embargo para este artículo voy a hacerlo a través de la línea de comandos con las Azure Functions Core Tools.

Parar crear el proyecto que almacenará tus funciones debes utilizar func init:

func init hello-k8s && cd hello-k8s

Durante el asistente he elegido node y javascript para este ejemplo.

Giselas-iMac:Azure-Functions-On-k8s gis$ func init hello-k8s && cd hello-k8s
Select a number for worker runtime:
1. dotnet
2. node
3. python
4. powershell
Choose option: 2
node
Select a number for language:
1. javascript
2. typescript
Choose option: 1
javascript
Writing package.json
Writing .gitignore
Writing host.json
Writing local.settings.json
Writing /Users/gis/Desktop/Azure-Functions-On-k8s/hello-k8s/.vscode/extensions.json

Esto crea el proyecto, pero ahora necesito crear una función que desplegar:

func new --name HttpHello --template "Http trigger" --language javascript

Antes de preparar nuestra función para poder ser desplegada en un contendor, puedes comprobar que funciona correctamente ejecutándola en local a través del siguiente comando:

func start

Si todo es correcto, en el resultado debería de devolverte la URL para acceder a tu función.

func start

Ahora que ya tienes todo listo, antes de continuar, para esta prueba modifica el nivel de autorización de tu Azure Functions en function.json a anonymous.

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

Dockerizar tu función para Kubernetes

Como te puedes imaginar, para que tu función pueda correr en Kubernetes esta debe estar dockerizada. La forma más sencilla de conseguirlo es a través del siguiente comando:

func init --docker-only

Esto generará dos archivos: un Dockerfile, con este contenido:

# To enable ssh & remote debugging on app service change the base image to the one below
# FROM mcr.microsoft.com/azure-functions/node:3.0-appservice
FROM mcr.microsoft.com/azure-functions/node:3.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true
COPY . /home/site/wwwroot
RUN cd /home/site/wwwroot && \
    npm install

y un .dockerignore para omitir el archivo local.settings.json de la imagen que se va a generar.

Desplegar tu Azure Function

El último paso es llevar a cabo el despliegue:

#Deploy it on AKS
docker login
func kubernetes deploy --name hello-k8s --registry 0gis0

Cuando lanzas este comando, lo primero que ocurre es la creación de la imagen y, en este ejemplo, la sube a la cuenta de docker con la que has iniciado sesión. Una vez que esta disponible genera tres recursos: un secreto, un servicio y un deployment en el Kubernetes que tienes en el contexto:

Giselas-iMac:hello-k8s gis$ func kubernetes deploy --name hello-k8s --registry 0gis0
Running 'docker build -t 0gis0/hello-k8s /Users/gis/Desktop/Azure-Functions-On-k8s/hello-k8s'..done
Running 'docker push 0gis0/hello-k8s'.............done
secret/hello-k8s created
service/hello-k8s-http created
deployment.apps/hello-k8s-http created

Si consultas tus pods verás que tu función ya está up and running 🙂

Giselas-iMac:hello-k8s gis$ kubectl get po
NAME                              READY   STATUS    RESTARTS   AGE
hello-k8s-http-86795b976c-kqssg   1/1     Running   0          112s

Para poder acceder a ella, necesitas consultar los servicios disponibles:

NAME             TYPE           CLUSTER-IP   EXTERNAL-IP    PORT(S)        AGE
hello-k8s-http   LoadBalancer   10.0.59.84   20.40.132.31   80:32079/TCP   2m10s
kubernetes       ClusterIP      10.0.0.1     <none>         443/TCP        7m18s

y a través de la IP que te haya asignado para el servicio hello-k8s-http, en este caso AKS, debes utilizar la siguiente URL para acceder a tu función: http://20.40.132.31/api/HttpHello?name=gis

¡Saludos!