Resumen de contenidos
Se van acercando las vacaciones de verano y ya están tan cerca que se pueden sentir. Con las vacaciones de verano llega el final de la temporada y un merecido descanso. Con esa idea en mente, pensaba cerrar la temporada con una entrada sobre Dapper que se iba a publicar en lugar de esta, pero el reciente anuncio de Microsoft sobre el soporte experimental para desplegar contenedores Docker directamente en Azure Container Instances (aci de aquí en adelante) desde Docker Desktop ha trastocado un poco los planes.
Si quieres saber como desplegar un agente de DevOps efímero sobre aci, no te pierdas la entrada ‘Azure DevOps Ephimeral Agents: Agentes de usar y tirar‘
¿Por qué es tan interesante poder desplegar aci directamente desde Docker Desktop?
Normalmente, trabajar con Docker en local es más que suficiente para poder hacer pruebas y desarrollos que antes o después acaben desplegados por ejemplo en Kubernetes. Aunque este suele ser el proceso habitual, también existen modelos de orquestación basados en docker-compose.
Imagina que necesitas que un equipo de testing haga pruebas sobre una web que estas desarrollando. Si bien es cierto que se podría desplegar la imagen sobre un App Service directamente, habría que gestionarlo a parte, actualizar sus imágenes,…
Gracias a este nuevo modelo, vamos a poder tener un funcionamiento mucho más sencillo, ya que va a ser directamente desde Docker Desktop donde vamos a gestionar los despliegues a contenedores en Azure Container Instances. Nuestro flujo de trabajo sería algo como esto:
Aunque ahora mismo está en una fase muy preliminar (se hizo público el 25 de junio de 2020), la idea detras de esto es conectar el aci con por ejemplo un Storage de Azure de modo que tengamos volúmenes persistentes o que podamos por ejemplo crear un despliegue complejo utilizando directamente docker-compose.
Esto se suma a que los recursos dejan de ser parte de nuestra máquina para empezar a ser parte de la infraestructura de Azure. De este modo, si nuestro entorno tiene un consumo que nuestra máquina no puede soportar bien, al estar alojado en Azure ese problema desaparece de raíz.
Configurando Docker Desktop para desplegar sobre ACI
Llegados a este punto, vamos a empezar a configurar Docker Desktop para poder desplegar sobre ACI. El primero de los requisitos es tener la versión 2.3.2.0 Edge (o superior). Esta versión se puede descargar desde le propia web de descargas de Docker Desktop:
En caso de que todavía no este disponible la versión 2.3.2.0 en las descargas (a mí me ha pasado), puedes descargarlo utilizando uno de estos enlaces para Windows o para MacOS.
Una vez que hemos instalado la nueva versión, lo primero que vamos a necesitar es autenticarnos con nuestra cuenta de Azure. Para esto basta con ejecutar el comando:
docker login azure
Esto nos enviará a la web de Azure para que introduzcamos las credenciales. Una vez que nos autentiquemos, en la consola recibiremos un mensaje de confirmación de que todo ha ido bien:
PS C:\Users\jorge> docker login azure
login succeeded
Con esto, ya casi tenemos todo listo para desplegar contenedores en Azure (aci) desde Docker Desktop. Solo nos falta un paso más, crear un contexto de tipo aci en Docker Desktop. Para esto basta con ejecutar:
docker context create aci myacicontext
Este comando nos permite a día de hoy, definir ciertos parámetros adicionales para poder ajustar más la configuración. Estos parámetros son:
- location: Permite definir la ubicación de los contenedores
- resource-group: Permite indicar que los contenedores deben crearse en un grupo de recursos concreto (que debe existir previamente)
- subscription-id: Permite indicar el Id de una suscripción en concreto de Azure, especialmente útil si tienes más de una suscripción en tu cuenta.
Por ejemplo, en caso de definir los 3 parámetros el comando sería algo así:
docker context create aci myacicontext --location westeurope --subscription-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --resource-group docker-aci
Con esto, ya tenemos disponible el contexto myacicontext listo para desplegar contenedores aci desde Docker Desktop. Esto podemos comprobarlo con el comando:
docker context ls
Como mínimo, este comando debería respondernos 2 contextos, el default de Docker Desktop y el que acabamos de crear.
PS C:\Users\jorge> docker context ls
NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm
myacicontext * aci docker-aci@westeurope
De ahora en adelante, podemos especificar sobre que contexto queremos aplicar los comandos Docker con el argumento –context Contexto. También podemos especificar el contexto por defecto que debe utilizarse si no se informa específicamente con el comando:
docker context use contexto
Vamos a probarlo
Una vez que tenemos el contexto listo, basta con ejecutar un run normal para que se despliegue automáticamente. Por ejemplo, podemos utilizar el comando:
docker run -p 80:80 -d nginx
Esto mostrará por consola una salida un tanto diferente a la habitual cuando se usa el contexto local:
PS C:\Users\jorge> docker run -p 80:80 -d nginx
[+] Running 2/2
- sleepy-cray Created 4.5s
- single--container--aci Done 20.6s
sleepy-cray
Si ahora vamos a la suscripción de Azure en el grupo de recursos que le hemos indicado, podemos encontrarnos algo como esto:
En caso de que cuando creásemos el contexto no le indicásemos un grupo de recursos, se crearía uno automáticamente con un GUID como nombre.
Podemos gestionar el propio contenedor desde el mismo Docker. En este caso hemos desplegado una imagen de nginx y hemos mapeado el puerto 80, por tanto, si obtenemos la IP del contendor, deberíamos poder acceder desde cualquier navegador. Para obtener esa IP basta con que ejecutemos:
docker ps
Esto nos mostrará por consola la salida habitual del comando, indicándonos la IP del contenedor:
CONTAINER ID IMAGE COMMAND STATUS PORTS
sleepy-cray nginx Running 52.143.11.203:80->80/tcp
Basta con navegar a la dirección IP para ver que todo funciona correctamente:
Al igual que hacemos con cualquier otro contenedor, también podríamos obtener los logs desde el aci utilizando en Docker Desktop el comando:
docker logs id-del-contenedor
Por ejemplo, para nuestro nginx:
PS C:\Users\jorge> docker logs sleepy-cray
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
10.240.255.56 - - [28/Jun/2020:19:37:17 +0000] "GET / HTTP/1.1" 400 157 "-" "-" "-"
10.240.255.55 - - [28/Jun/2020:19:43:13 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56" "-"
10.240.255.55 - - [28/Jun/2020:19:43:13 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://52.143.11.203/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56" "-"
2020/06/28 19:43:13 [error] 27#27: *154 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.240.255.55, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "52.143.11.203", referrer: "http://52.143.11.203/"
PS C:\Users\jorge>
Por último, para borrar el contenedor basta con que ejecutemos el comando:
docker rm id-del-contenedor
Utilizando Docker Compose sobre aci
Hasta ahora hemos planteado el uso de docker para levantar contenedores individuales, pero no es la única posibilidad. Gracias a Docker Compose podemos orquestar diferentes configuraciones de contenedores de manera que podamos por ejemplo levantar una web y una base de datos. Como no podía ser de otra manera, esta es una característica soportada por esta versión preview (aunque con muchas limitaciones).
Para poder usar esta funcionalidad, basta con que creemos un fichero docker-compose.yml con un contenido como este:
version: '3.4'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "80:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
Una vez hecho el fichero, basta con ejecutar el comando:
docker compose -f .\docker-compose.yml up
OJO. El comando es docker compose y no docker-compose. Esto es porque se utiliza la docker cli en vez de docker-compose cli.
Tras la ejecución del comando, podremos obtener una salida como esta:
PS C:\Users\jorge\OneDrive\Escritorio\aci> docker compose -f .\docker-compose.yml up
[+] Running 4/4
- aci Created 4.4s
- db Done 66.7s
- wordpress Done 66.7s
- aci--dns--sidecar Done 66.7s
Esto va a levantar un aci con varios contenedores dentro para la base de datos, el propio wordpress y un contenedor adicional que sirve de dns entre ambos. Ahora mismo, podemos ir a la interfaz de Azure y ver que efectivamente se han creado:
Con esto deberíamos poder entrar en la IP que se ha asignado y usar nuestro wordpress, pero actualmente parece que o no está soportado el uso de variables o tiene algún bug por lo que nuestro escenario no es capaz de arrancar al no asignar las variables de entorno en el contenedor. Puedes seguir la información al respecto en esta incidencia.
Conclusión
Gracias a esta nueva vuelta de tuerca de la mano de Docker y Microsoft, se amplían mucho los posibles escenarios de desarrollo que podemos conseguir con Docker antes de llegar a desplegar en un Kubernetes. Es posible hacer despliegues de entornos de pruebas de manera muy sencilla y gestionarlo tal cual haríamos como si el entorno fuese local de nuestra máquina.
Hay que reconocer que la línea actual de desarrollo es muy interesante en cuanto a sus ambiciones, despliegue de aci desde Docker Desktop directamente, pudiendo utilizar cuentas de almacenamiento de Azure como volúmenes para los contenedores o pudiendo desplegar con docker-compose como sistema de orquestación.
Llegados a este punto, es también muy importante señalar que es un producto extremadamente reciente, que no está recomendado para su uso en producción y que su documentación actualmente brilla por su ausencia. Si bien es cierto que se detalla cómo crear un contenedor, no hay nada de información sobre cómo utilizar los volúmenes, o solución de errores.
Aun así y con todo, pienso que apunta muchas maneras para tener su hueco en el día a día del desarrollo con Docker una vez que madure un poco.