Como muchos ya sabéis, Docker es una tecnología que ha tenido muy buena aceptación a la hora de virtualizar entornos y hacer que el trabajo de configurar ciertas herramientas y aplicaciones sea una tarea más sencilla gracias al uso de imágenes y ficheros Dockerfile que ya vienen preparados con todo lo necesario para “descargar y ejecutar”.  Se trata de una tecnología cuyo uso básico no es complejo, pero tiene características que le convierten en una solución muy potente y flexible, lo que implica también cierto nivel de dificultad a la hora de aplicar ciertas configuraciones.
Dicho esto, en los siguientes dos artículos explicaré cómo crear scripts en Python que permitan automatizar el proceso de creación de contenedores y su posterior gestión. Se trata de labores que normalmente se hacen desde el cliente de Docker para Linux, por ejemplo, pero en ocasiones resulta conveniente ejecutar dichas operaciones de forma programática y aunque sería una solución perfectamente valida utilizar batch, no es una alternativa tan limpia y potente como la posibilidad de realizar todo el proceso desde un script en Python.

NOTA: Antes de continuar, si no tienes conocimientos en Docker y te interesa aprender los fundamentos de esta tecnología (algo que te recomiendo) hace algunos meses he publicado un curso en Udemy en el que se explica desde cero cada una de las cuestiones a tener en cuenta para utilizarlo correctamente. Docker y DevOps: De novato a experto.

Bien, ahora para poder interactuar con un servicio de Docker hay varias alternativas disponibles, aunque las más comunes consisten en ejecutar las instrucciones utilizando la clase Popen de Python e ir manejando el stderr, stdin y stdout de forma manual (casi que artesanal) o un enfoque más limpio que consiste en utilizar el SDK de Docker para Python. Evidentemente esta última alternativa será la que se explicará en estos dos artículos.

Instalar el SDK de Docker para Python.

En primer lugar, el SDK de Python es una librería muy completa que tiene todo lo que se necesita para aprovechar las características disponibles en un servicio de Docker. Dichas funcionalidades van desde la creación de contenedores, hasta la gestión de volúmenes e imágenes. Su potencia no es nada despreciable y es la alternativa número 1 si se necesita controlar Docker de forma programática desde Python. Cabe aclarar que hay SDKs para otros lenguajes de programación, en el caso de que sea necesario utilizar otro lenguaje por el motivo que sea. La documentación del SDK de Docker para Python se encuentra disponible en el siguiente enlace y como se puede ver en la página de introducción, se encuentra disponible en Pypi por lo tanto es tan simple como ejecutar el comando de instalación típico pip install docker. No obstante hay que tener en cuenta un detalle importante y es que si el servicio se ha configurado para aceptar conexiones seguras vía TLS, el cliente debe tener la CA del servicio y opcionalmente, en el caso de que se requiera Mutual TLS, un certificado creado para efectos de autenticación en el cliente. Además de esto, también sería necesario instalar pip install docker[tls]

Una vez instalado el SDK en un VirtualEnv o directamente sobre el interprete de Python ubicado en el PATH del sistema, es el momento de comprobar que funciona correctamente. Es tan simple como ejecutar la importación del paquete correspondiente e intentar ejecutar una conexión contra el servicio de Docker.

En la imagen anterior se aprecian varias cosas, en primer lugar se crea una instancia del cliente de Docker para Python que se encuentra en el SDK y partiendo de dicha instancia, se crea un contenedor. Si se sabe utilizar el cliente de Docker para Linux no habrá ningún problema en entender la instrucción que crea dicho contenedor. En resumen, es equivalente a ejecutar el comando docker run con la imagen “alpine”, cuyo nombre será “testing_from_python” en modo “detach” y con la posibilidad de generar una shell TTY. Finalmente, se crea un volumen en donde el directorio “/root” en el sistema anfitrión se montará en el directorio “/mnt/voltest” en el contenedor y dicho volumen será de lectura y escritura desde dicho contenedor. Fácil, no? esto queda perfectamente aclarado en el curso de Docker y DevOps: De novato a experto. disponible en Udemy.

 

Utilidades básicas del SDK de Docker para Python.

Como se ha podido comprobar, crear contenedores resulta una labor sencilla utilizando el SDK de Docker, pero esto no es todo lo que se puede hacer. Entre otras cosas, es posible gestionar el propio servicio de Docker, volúmenes, imágenes, contenedores, redes y todo lo que normalmente se puede hacer desde el cliente de Docker para Linux. En lo que queda de este post y en el siguiente, se explicarán algunas de estas características disponibles en el SDK  de python.

Información del proceso Docker.

Con una instancia del cliente de Docker es posible ejecutar el método info() el cual simplemente devuelve un diccionario con toda la información disponible sobre el servicio de Docker. De hecho, esto es equivalente a ejecutar el comando docker info desde la terminal.

Devuelve un diccionario completo con toda la información del proceso con la ventaja de que evidentemente, se puede procesar para extraer solamente las propiedades que sean necesarias en un momento determinado para ejecutar algún tipo de operación, validación o un bloque de código en el programa que requiera de estos valores.

Entorno del cliente de Docker.

En el momento en el que se crea una instancia del cliente de Docker utilizando el método “from_env()” lo que está ocurriendo es que se leen una serie de variables de entorno muy especificas que de no encontrarse establecidas, la librería asumirá nos valores por defecto. Dichas variables incluyen el host y puerto en el que se encuentra en ejecución el servicio de Docker. No obstante, hay otras formas de instanciar el cliente, por ejemplo sería perfectamente valido crear una instancia de la clase DockerClient e indicar, por ejemplo, la ubicación del socket Unix correspondiente al servicio o indicar manualmente la IP/Dominio y puerto en el que se encuentra en ejecución.

Como se puede apreciar, se ha utilizado el parámetro “base_url” que apunta a un socket de red o uno de Unix tal como se ha indicado anteriormente. Crear un objeto cliente perfectamente funcional se puede conseguir con 2 líneas de código.

Listado de imágenes, contenedores y volumenes.

Para finalizar este post introductorio, se explicarán algunas funciones sencillas disponibles en el cliente de Docker para el listado de imágenes, contenedores y volúmenes que se encuentran actualmente registrados en el servidor. Cada una de estas características (así como otras más) se encuentran debidamente separadas en clases independientes, las cuales no solamente permiten el listado de los objetos disponibles en el servidor de  Docker, sino que además permite su gestión. Por ejemplo, tal como se ha visto antes, es posible crear un contenedor que quedará registrado en el servicio de Docker gracias al método run que se encuentra definido en la clase Containers

Como se puede ver, el objeto DockerClient contiene todo lo necesario para acceder a los elementos principales del servidor. En la imagen anterior simplemente se listan los contenedores, imágenes y volúmenes que en este momento se encuentran registrados en el servicio de Docker pero sería posible crear nuevas imágenes con configuraciones muy completas, así como crear volúmenes y contenedores partiendo de alguna imagen (tal como se ha visto anteriormente).
Como en todas las librerías disponibles en Python que sigue la filosofía del lenguaje, o como muchos suelen llamar: “pythonic”, se trata de una librería que cuenta con componentes fáciles de utilizar y que con pocas instrucciones permiten realizar labores que en otras circunstancias o con otros lenguajes de programación requeriría más esfuerzo.

Este primer post es muy sencillo y se pueden apreciar las características básicas del SDK de Python. En el siguiente se verán más cosas que se pueden hacer con esta librería y a lo mejor, te puede ser útil para integrarla en tus proyectos con Docker.

Un saludo y Happy Hack!
Adastra.