"Solo hay que preocuparse de ser excepcionalmente bueno en una única cosa" (Warren Buffett)

ContenedoresArquitectura software

¿Qué es un contenedor?

Basta echar un vistazo a las ofertas de empleo para descubrir que este nuevo término informático (y normalmente referido a «docker» por ser el más popular) se ha vuelto de uso común, siendo muy solicitado, junto a programas que lo gestionan como Kubernates. Todo esto está también muy unido a los grandes cambios que están ocurriendo a nivel de arquitectura informática, incluyendo microservicios y plataformas cloud (como AWS y Azure).

Una búsqueda rápida en internet de que es Docker nos muestra lo siguiente:

Docker es un sistema operativo para contenedores. De manera similar a cómo una máquina virtual virtualiza (elimina la necesidad de administrar directamente) el hardware del servidor, los contenedores virtualizan el sistema operativo de un servidor.

Vamos a ver primero algo de historia evolutiva, es decir, como hemos llegado a esto de los contenedores, y que tipo de problemas nos resuelve.

Un poco de historia

Uno de los eternos problemas que solía tener un programador era distribuir su aplicación, instalándola en los clientes, y que todo fuera bien.

En los primeros tiempos esas aplicaciones podían ser muy simples por lo que la instalación a veces era algo tan trivial como copiar el ejecutable ene la carpeta de destino. Esos «buenos tiempos» se fueron acabando y empezaron a aparecer programas específicos que hacían la instalación (por ejemplo InstallShield), permitiendo seleccionar cada vez más cosas, desde el directorio destino, hasta las funcionalidades a instalar (si había varias), así como todas las dependencias (por ejemplo DLLs en el caso de Windows). Pronto empezaron los problemas de compatibilidad entre versiones de DLLs, del sistema operativo de turno, de las versiones de otras aplicaciones usadas por el programa a distribuir (por ejemplo el acceso a bases de datos).

Los problemas de versiones de programas de consola o escritorio no aparecían solo en estos casos, sino que también eran comunes en las aplicaciones de la web, que dependían de la compatibilidad de sistemas operativos y navegadores, de plug-ins (por ejemplo Flash).

Con la evolución de la web y los servicios proporcionados por esta (hosting y similar) empezaron a aparecer máquinas virtuales (VMWare, VirtualBox) que abstraían la máquina física proporcionando una máquina virtual donde podíamos instalar determinado sistema operativo y aplicaciones y que en teoría podríamos mover sin problemas entre distintos servidores reales. Así nuestro, por ejemplo Windows funcionando en una de esas máquinas virtuales, podría estar ejecutándose en un Windows Server, un linux, o cualquier sistema operativo que permitiera ejecutar la máquina virtual que abstraía el hardware real. Esto desde luego era una ventaja, y comodo para el proveedor de hosting de este tipo de solución, pero no deja de ser algo «pesado» tener toda una máquina virtual para determinadas tareas.

Paralelamente, incluso podría decirse que anterior, lenguajes como Java (y posteriormente Microsoft .NET) buscaron también crear esa abstracción del hardware y sistema operativo real creando su propia máquina virtual que ejecutaba ese código intermedio común a todos los sistemas operativos y hardware, de tal manera que se conseguía el objetivo de poder programar una aplicación y que pudiera funcionar en cualquier lugar donde hubiera una implementación de esa máquina virtual. Ese fue el gran paso que ayudo al lenguaje Java a triunfar con el paso del tiempo (al principio era demasiado lento comparado con lenguajes como C o C++). MIcrosoft con .NET busco algo similar, usando su máquina que compilaba a lenguaje intermedio, pero no solo un lenguaje dado sino cualquier lenguaje (C#, Visual Basic, F#, etc) aunque en este caso para no perder mucho rendimiento compilaba con un JIT (compilador Just In Time, o compilador sobre la marcha) el código intermedio que iba ejecutándose al código real de la máquina donde estaba ejecutándose. A pesar de que la idea de todo esto es buena, sigue habiendo problemas de versiones, aunque en menor medida que antes.

Y entonces llego la nube, el cloud, y lo cambio todo

Las aplicaciones de la web, incluyendo Web Services, fueron extendiéndose cada vez más, y también la necesidades de las grandes empresas, cada vez gestionando más y más software, y haciendo imposible de manejar adecuadamente programas monolíticos, demasiado grandes, difíciles de escalar, y difícil de separar en modulos gestionados por distintos equipos de programadores.

Un primer paso dado por Amazon para resolver este problema, termino originando Amazon Web Services, y poco después la respuesta de Microsoft con Azure, y por supuesto Google con la suya propia. Nacen los microservicios y conceptos tales como los contenedores, que resuelven problemas de escalado y de independizar un módulo software del hardware real y sistema operativo donde se ejecuta, permitiendo que distintos equipos de informáticos desarrollen módulos con las herramientas y lenguajes más apropiados en cada caso (y permitiendo también aprovechar mejor el código legacy – heredado).

Así pues, podemos definir un contenedor como un «paquete» autónomo, ligero (muchísimo más que una máquina virtual) que permite ejecutar un código que contiene todo lo necesario para funcionar (herramientas, dependencias, configuraciones), y que al ser ligero permite ejecutar muchos dentro de un mismo servidor, y nos permite aislarnos de los problemas derivados de esas dependencias de donde se ejecuta el software.

El esquema gráfico es algo como esto

Hay contenedores para distintos sistemas operativos (linux, Windows) lo cual nos permite usar lo que veamos más apropiado.

Al ser paquetes que contienen todo sabemos que el servicio que proporciona va a funcionar igual en cualquier lugar donde lo ejecutemos, y al ser ligero podremos crear muchos en caso de necesidad de atender muchas solicitudes simultáneas. También nos aísla de tener diferentes entornos de desarrollo, preproducción y producción, haciendo que funcione igual con independencia de diferencias de configuración entre estos entornos.

Este cambio de paradigma también nos permite aprovechar diferentes lenguajes y librerías para que la funcionalidad, el servicio, que debe proporcionar ese contenedor sea el más óptimo, con independencia de que otros contenedores que puedan usar el servicio del otro contenedor este hecho con otro lenguaje y tecnología distinto (el protocolo de comunicación es el mismo), con lo que no hay problema de integración.

En un entorno DevOps todo el ciclo de construcción, testeo, despliegue se puede automatizar, por lo cual conseguimos aumentar la productividad, dentro de las metodologías ágiles tan de moda y útiles en los desarrollos de hoy en día.

Los contenedores nacieron como un proyecto de Linux

Para acabar esta introducción a que son los contenedores, y volviendo un poco a la historia, en realidad los primeros desarrollos de este tipo aparecieron en el año 2001 en un proyecto llamado VServer.

Por un lado usa una tecnología de «espacios de nombres» que admite el kernel de Linux que permite virtualizar los procesos y las funciones de red, definiendo de forma virtual directorios tales como mnt, net, user o ipc, asi pues sus principios tienen ya bastantes años, aunque sea el desarrollo de los servicios en la nube lo que ha impulsado su desarrollo y uso cada vez más frecuente.

Alfonso Espinosa

Programador, analista, jefe de proyecto, hago lo necesario en cada momento u oportunidad, ya que la informática es mi pasión, aparte de mi familia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *