28/05/2018Artículo original
Como explicamos ya hace un par de años en el artículo ¿Qué es Docker?, el objetivo de Docker es permitirte la creación “paquetes estándar” pensados para despliegue llamados “contenedores” que incluyen todo lo necesario para que una aplicación funcione (dependencias, servicios…) y que se aíslan del sistema subyacente para lograr que siempre funcionen exactamente igual.
Docker no es el único sistema de contenedores. Ni siquiera es el primero. Pero se ha convertido en el estándar de facto, y el que tienen en cuenta todos los fabricantes y proveedores de sistemas operativos y de Cloud.
Cuando se piensa en Docker, por lo general no se asocia con tecnologías Microsoft como .NET o Windows, pero en realidad existen un montón de buenos motivos para usar Docker con ASP.NET, especialmente con .NET Core y .NET Core MVC.
En este artículo vamos a repasar las principales razones para utilizar Docker en general en tu proceso de desarrollo, y Docker con .NET en particular, mostrándote cómo te puede ayudar en tus desarrollos.
1.- Olvídate del sistema operativo y las configuraciones manuales
Normalmente cuando configuras una máquina física o virtual, tienes que instalar el sistema operativo, el software que necesite tu aplicación (servidor web, SDKs, bibliotecas,…) y realizar las configuraciones específicas que necesite la aplicación.
Si usas Docker puedes especificar todo esto en tu dockerfile y cada vez que se arranca el entorno, garantizará que el software apropiado esté instalado en el contenedor.
Cuando se necesiten actualizaciones, puedes actualizar simplemente la definición del contenedor y volver a desplegarlo. Esto puede disminuir mucho los tiempos de mantenimiento.
2.- Adiós al “Pero… en mi máquina funciona”
Si trabajas en programación lo has dicho muchas veces seguro. Y si también estás en el otro lado te lo habrán dicho muchas más veces todavía.
Y es que no hay nada más frustrante que tener una aplicación lista y más que probada (en tu máquina) y llevarla a producción y que empiece a fallar. Y luego averiguar el motivo :-S
Bueno, pues con Docker eso se acabó. Lo que te ofrece es, sobre todo, consistencia. Garantía de que lo que va dentro de un contenedor se va a ejecutar de la misma manera en tu máquina y en cualquier otra del mundo, aquí y en la China. Y eso vale millones.
Si funciona en desarrollo, funcionará en producción porque son la misma cosa.
3.- Mucho más ligero y escalable que una máquina virtual
Cuando defines una máquina virtual tienes que especificar cuántos recursos (memoria, procesadores, disco…) de la máquina host vas a destinar en el momento en el que la creas. Esos recursos además dejan de estar disponibles para el sistema operativo subyacente.
Por el contrario, un contenedor Docker utiliza tan solo los recursos que necesita en cada momento. Y además se pueden desplegar varias instancias del mismo contenedor al mismo tiempo, sin que la única opción sea darle más y más recursos de hardware a un contenedor pre-existente.
Además, puedes controlar el consumo de los recursos del host a los que tendrá acceso un contenedor o conjunto de ellos. Si un contenedor en concreto está sobrepasado de capacidad porque tiene mucho uso, no acaparará todos los recursos de la máquina ni hará que se caigan otros contenedores en ese host.
Transformar un único contenedor Docker en una granja en ejecución no podría resultar más sencillo. Solo es cuestión de actualizar los archivos docker-compose.yml con instrucciones sobre cuántas instancias del contenedor se deben ejecutar y cómo, y crear un contenedor para usar como proxyinverso y balanceador de carga. NGINX ha creado muchas imágenes prefabricadas para ayudarte en este escenario, por ello la mayoría de las veces solo hay que añadir ese contenedor al archivo compose y configurarlo.
Si además quieres características más potentes, Kubernetes te permite orquestar todos tus contenedores, monitorizarlos, asegurarlos, ejecutarlos periódicamente, y muchas cosas más, para crear entornos empresariales con la complejidad que necesites.
4.- Tan seguro como una máquina virtual
Los contenedores Docker usan los recursos de la máquina host, pero tienen su propio entorno de tiempo de ejecución (runtime). Disponen de una versión reducida del espacio de usuario del sistema operativo. Esto significa que puedes asegurar un contenedor de una forma muy similar a la que utilizarías en una máquinas real, ya que en el fondo es casi como si fuera una máquina real.
Un contenedor no puede acceder a otros contenedores ni al sistema operativo subyacente (a excepción de los volúmenes de almacenamiento a los que les des permiso), y se comunicará con otras redes y contenedores, con la configuración de red concreta que le quieras otorgar.
Además, si le das acceso a una carpeta o unidad del sistema operativo host, lo verá realmente como si fuera una carpeta en su sistema operativo interno, no teniendo constancia (ni acceso) de nada de lo que haya en la ubicación original fuera de esa carpeta.
Quédate con que un contenedor te aísla tanto como una máquina virtual, pero es mucho menos pesado, requiere menos configuración y además puede abrir “agujeros de gusano” a carpetas concretas si lo necesitamos, con total seguridad.
5.- Control de versiones para la Infraestructura
Para mí este es un concepto rompedor. Siempre se piensa en control de versiones para el código fuente, claro. Pero teniendo en cuenta que en Docker (y Kubernetes) todo se gestiona mediante archivos de texto plano, y esto es lo único que necesitas para desplegar, pueden ir al control de código fuente también.
Esto significa que, en la práctica, ¡puedes versionar tu infraestructura!.
Cuando actualizas una versión del software requerido para ejecutar la aplicación que veíamos en el apartado anterior (servidor web, bibliotecas, etc.), ese entorno se actualiza junto con el código de la aplicación.
Esto es muy útil cuando estás intentando saber por qué una versión anterior de una app tenía un comportamiento determinado: simplemente tienes que ir a la versión de ese código que te interese, iniciar el contenedor Docker y tienes replicada la aplicación y la infraestructura. Genial.
6.- Concebido para trabajar en la nube
Los contenedores se pensaron con la nube en mente. Y en la actualidad los principales actores Cloud, ofrecen estupendas opciones para el despliegue de contenedores en sus infraestructuras.
Así, tanto Amazon Web Services, como Microsoft Azure o Google Compute Engine (entre muchos otros) te permiten desplegar contenedores en la nube desde la comodidad de tu silla, usando la línea de comandos o herramientas visuales. Incluso te permiten facturar los contenedores por segundos, lo cual abre un mundo de posibilidades.
Además todos ellos soportan Kubernetes para poder hacer despliegues complejos de múltiples contenedores orquestados para trabajar y escalar de manera independiente.
Desplegar infraestructuras simples o complejas nunca ha sido tan fácil que ahora.
7.- Ventajas concretas para .NET
Otra de las ventajas de Docker es que puede utilizarse para unificar también los entornos de desarrollo y el flujo de trabajo en éstos. Es decir, ni siquiera tienes que instalar en tu equipo los SDKs de trabajo, ni los compiladores: definís un entorno de trabajo basado en imágenes Docker para todo el equipo, y os aseguráis de que todos tenéis exactamente lo mismo y que todo funcionará exactamente igual. Microsoft está contribuyendo mucho a la comunidad Docker, y ofrecen una integración muy buena de Docker y estos flujos de trabajo en sus herramientas para desarrolladores, tanto en Visual Studio y Visual Studio Code, como en Team System.
Si creas aplicaciones .NET Core, y en especial aplicaciones web con .NET Core MVC, pueden funcionar en contenedores Linux de la misma manera que cualquier aplicación de lenguajes com Node.js, Go, PHP u otros que tradicionalmente se han usado en este sistema.
Desde hace ya tiempo, los contenedores tradicionales Linux funcionan en Windows Server (y en Windows 10: no necesitas Linux o Mac para trabajar con Docker), pero es que además ahora existen también contenedores nativos de Windows, que te permiten ejecutar en forma de contenedor aplicaciones de este sistema operativo. Esto implica que si, por ejemplo, tienes una aplicación antigua de ASP.NET Web Forms, podrás utilizarla dentro de un contenedor y obtener todas las ventajas que ello te brinda y que hemos repasado más arriba, combinándola a lo mejor con contenedores de otro tipo de aplicaciones, y desplegándolos en la nube.
De hecho, como sabes, ASP.NET Core utiliza Kestrel para servir las aplicaciones, y debes usar algún proxy inverso para Kestrel para dotarlo de las capacidades de un servidor de aplicaciones real. Si tus aplicaciones se despliegan en contenedores, puedes conseguir esto de muchas maneras estandarizadas: desde utilizar un proxy NGINX específico partiendo de una imagen ya hecha, a utilizar Ingress en Kubernetes.
Aunque Docker se creó en y para Linux, su uso en .NET y Windows no para de crecer y es cada vez mejor. Microsoft trabaja muy de cerca con el equipo de Docker y su comunidad.
Espero que te haya aclarado las principales ventajas de usar Docker y que tengas ganas de desarrollar y desplegar tu siguiente aplicación en .NET (o en otra plataforma o lenguaje) en un contenedor Docker. Honestamente creo que en los próximos años todas las aplicaciones web se van a desplegar usando Docker. Y muchas otras también.
Y recuerda, si tienes interés en aprender a fondo tanto Docker como Kubernetes, tenemos el curso que necesitas.