Capítulo 1. Introducción Introducción

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

Docker fue presentado por primera vez al mundo de -sin anuncio previo y con poca fanfarria- por Solomon Hykes, fundador y director general de una empresa llamada entonces dotCloud, en una charla relámpago de cinco minutos en la Conferencia de Desarrolladores de Python en Santa Clara, California, el 15 de marzo de 2013. En el momento de este anuncio, sólo unas 40 personas ajenas a dotCloud habían tenido la oportunidad de jugar con Docker.

A las pocas semanas de este anuncio, hubo una sorprendente cantidad de prensa. El código fuente se publicó rápidamente en GitHub como proyecto público y totalmente de código abierto. En los meses siguientes, cada vez más gente del sector empezó a oír hablar de Docker y de cómo iba a revolucionar la forma de crear, entregar y ejecutar software. Y al cabo de un año, casi nadie en la industria desconocía Docker, pero muchos seguían sin saber qué era exactamente y por qué la gente estaba tan entusiasmada con él.

Docker es una herramienta que promete encapsular fácilmente el proceso de creación de un artefacto distribuible para cualquier aplicación, desplegándolo a escala en cualquier entorno y agilizando el flujo de trabajo y la capacidad de respuesta de las organizaciones de software ágil.

La promesa de Docker

Al principio, muchas personas que no estaban familiarizadas con Docker lo veían como una especie de plataforma de virtualización, pero en realidad, fue la primera herramienta ampliamente accesible que se basó en una tecnología mucho más nueva llamada contenedorización. Docker y los contenedores Linux han tenido un impacto significativo en una amplia gama de segmentos de la industria que incluyen herramientas y tecnologías como Vagrant, KVM, OpenStack, Mesos, Capistrano, Ansible, Chef, Puppet, etc. Hay algo muy revelador en la lista de productos cuya cuota de mercado se ha visto directamente afectada por Docker, y quizá ya lo hayas detectado. Al repasar esta lista, la mayoría de los ingenieros reconocerían que estas herramientas abarcan muchos casos de uso diferentes, pero todos estos flujos de trabajo han cambiado para siempre gracias a Docker. Esto se debe en gran parte a que Docker ha alterado significativamente las expectativas de todos sobre cómo debe funcionar un flujo de trabajo de integración continua y entrega continua (CI/CD). En lugar de que cada paso implique un proceso lento gestionado por especialistas, la mayoría de la gente espera que una canalización DevOps de esté totalmente automatizada y fluya de un paso al siguiente sin ninguna intervención humana. Las tecnologías de esa lista también son generalmente aclamadas por su capacidad para mejorar la productividad, y eso es exactamente lo que ha dado tanto que hablar a Docker. Docker se encuentra justo en medio de algunas de las tecnologías más habilitadoras de la última década y puede aportar mejoras significativas a casi todos los pasos del pipeline.

Si hicieras una comparación característica por característica de Docker y el campeón reinante en cualquiera de estas áreas individuales (por ejemplo, la gestión de la configuración), Docker parecería muy probablemente un competidor mediocre. Es más fuerte en algunas áreas que en otras, pero lo que Docker pone sobre la mesa es un conjunto de características que atraviesa una amplia gama de retos de flujo de trabajo. Combinando la facilidad de las herramientas de prueba y despliegue de aplicaciones como Vagrant y Capistrano con la facilidad de administración de los sistemas de virtualización, y proporcionando luego interfaces que facilitan la implementación de la automatización y orquestación del flujo de trabajo, Docker ofrece un conjunto de funciones muy habilitadoras.

Muchas tecnologías nuevas van y vienen, y una dosis de escepticismo sobre el último grito siempre es saludable. Cuando Docker era una tecnología nueva, habría sido fácil descartar Docker como una tecnología más que resuelve unos pocos problemas muy concretos para los desarrolladores o los equipos de operaciones. Si consideras Docker únicamente como una tecnología de pseudovirtualización o implementación, puede que no parezca muy convincente. Pero Docker es mucho más de lo que parece en la superficie.

Es difícil y a menudo caro conseguir una comunicación y unos procesos adecuados entre equipos de personas, incluso en las organizaciones más pequeñas. Sin embargo, vivimos en un mundo en el que comunicar información detallada entre equipos es cada vez más necesario para tener éxito. Descubrir e implantar una herramienta que reduzca la complejidad de esa comunicación al tiempo que ayuda a producir software más robusto es una gran victoria. Y ése es exactamente el motivo por el que Docker merece una mirada más profunda. No es la panacea, y la forma en que implementes Docker en tu organización requiere una reflexión crítica, pero Docker y los contenedores Linux ofrecen un buen enfoque para resolver algunos problemas organizativos del mundo real y ayudar a las empresas a enviar mejor software más rápidamente. Ofrecer un flujo de trabajo de contenedores Linux bien diseñado puede conducir a equipos técnicos más felices y a ahorros reales para el balance final de la organización.

Entonces, ¿dónde sienten más dolor las empresas? Enviar software a la velocidad que se espera en el mundo actual es difícil de hacer bien, y a medida que las empresas pasan de uno o dos desarrolladores a muchos equipos de desarrolladores, la carga de la comunicación en torno al envío de nuevas versiones se hace mucho más pesada y difícil de gestionar. Los desarrolladores tienen que comprender una gran complejidad del entorno al que van a enviar el software, y los equipos de operaciones de producción tienen que comprender cada vez mejor el funcionamiento interno del software que envían. En general, es bueno trabajar en todas estas habilidades, porque conducen a una mejor comprensión del entorno en su conjunto y, por tanto, fomentan el diseño de software robusto, pero estas mismas habilidades son muy difíciles de escalar eficazmente a medida que se acelera el crecimiento de una organización.

Los detalles del entorno de cada empresa suelen requerir mucha comunicación que no genera directamente valor para los equipos implicados. Por ejemplo, exigir a los desarrolladores que pidan a un equipo de operaciones la versión 1.2.1 de una biblioteca concreta les ralentiza y no aporta ningún valor empresarial directo a la empresa. Si los desarrolladores pudieran simplemente actualizar la versión de la biblioteca que utilizan, escribir su código, probar con la nueva versión y enviarla, el plazo de entrega se acortaría considerablemente, y la implementación del cambio conllevaría menos riesgos. Si los ingenieros de operaciones pudieran actualizar el software en el sistema anfitrión sin tener que coordinarse con varios equipos de desarrolladores de aplicaciones, podrían avanzar más rápidamente. Docker ayuda a construir una capa de aislamiento en el software que reduce la carga de la comunicación en el mundo de los humanos.

Más allá de ayudar con los problemas de comunicación, Docker opina sobre la arquitectura del software de un modo que fomenta la creación de aplicaciones más robustas. Su filosofía arquitectónica se centra en contenedores atómicos o desechables. Durante la implementación, todo el entorno de ejecución de la antigua aplicación se desecha con ella. Nada en el entorno de la aplicación vivirá más que la propia aplicación, y esa es una idea simple con grandes repercusiones. Significa que no es probable que las aplicaciones dependan accidentalmente de artefactos dejados por una versión anterior. Significa que es menos probable que los cambios efímeros de depuración perduren en futuras versiones que los hayan recogido del sistema de archivos local. Y significa que las aplicaciones son altamente portables entre servidores porque todo el estado debe incluirse directamente en el artefacto de implementación y ser inmutable, o enviarse a una dependencia externa como una base de datos, una caché o un servidor de archivos.

Todo esto conduce a aplicaciones que no sólo son más escalables, sino también más fiables. Las instancias del contenedor de la aplicación pueden ir y venir con escaso impacto en el tiempo de actividad del sitio frontend. Se trata de opciones arquitectónicas probadas que han tenido éxito en aplicaciones no Docker, pero las opciones de diseño impuestas por Docker significan que las aplicaciones en contenedor están obligadas a seguir estas buenas prácticas. Y eso es muy bueno.

Ventajas del flujo de trabajo Docker

Es difícil clasificar cohesivamente en todas las cosas que aporta Docker. Cuando se implementa bien, beneficia a organizaciones, equipos, desarrolladores e ingenieros de operaciones de múltiples maneras. Simplifica las decisiones arquitectónicas, porque todas las aplicaciones tienen esencialmente el mismo aspecto exterior desde la perspectiva del sistema de alojamiento. Hace que las herramientas sean más fáciles de escribir y compartir entre aplicaciones. Nada en este mundo viene con beneficios y sin retos, pero Docker está sorprendentemente sesgado hacia los beneficios. He aquí algunas más de las ventajas que obtienes con Docker y los contenedores Linux:

Empaquetar el software de forma que se aprovechen las habilidades que ya tienen los desarrolladores

Muchas empresas han tenido que crear puestos de ingenieros de lanzamiento y construcción para gestionar todos los conocimientos y herramientas necesarios para crear paquetes de software para sus plataformas compatibles. Las herramientas de Linux como rpm, mock, dpkg y pbuilder pueden ser complicadas de usar, y cada una debe aprenderse de forma independiente. Docker reúne todos sus requisitos en un formato de empaquetado, conocido como el estándar Open Container Initiative (OCI).

Agrupar el software de aplicación y los sistemas de archivos del SO necesarios en un único formato de imagenestandarizado

En el pasado, normalmente necesitabas empaquetar no sólo tu aplicación, sino también muchas de las dependencias de las que dependía, incluidas bibliotecas y demonios. Sin embargo, nunca podías garantizar que el 100% del entorno de ejecución fuera idéntico. Para el código compilado de forma nativa, esto significaba que tu sistema de compilación debía tener exactamente las mismas versiones de bibliotecas compartidas que tu entorno de producción. Todo esto hacía que el empaquetado fuera difícil de dominar, y que a muchas empresas les costara conseguirlo de forma fiable. A menudo, alguien que ejecutaba Scientific Linux recurría a intentar implementar un paquete de la comunidad probado en Red Hat Enterprise Linux, con la esperanza de que el paquete se acercara lo suficiente a lo que necesitaba. Con Docker, despliegas tu aplicación junto con todos y cada uno de los archivos necesarios para ejecutarla. Las imágenes en capas de Docker hacen que éste sea un proceso eficiente que garantiza que tu aplicación se ejecute en el entorno esperado.

Utilizar artefactos empaquetados para probar y entregar exactamente el mismo artefacto a todos los sistemas entodos los entornos.

Cuando los desarrolladores introducen cambios en un sistema de control de versiones, se puede crear una nueva imagen Docker, que puede pasar por todo el proceso de pruebas y desplegarse en producción sin tener que recompilarla ni volver a empaquetarla en ningún paso del proceso, a menos que se desee específicamente.

Abstraer las aplicaciones de software del hardware sin sacrificar recursos

Las soluciones tradicionales de virtualización empresarial, como VMware, suelen utilizarse cuando alguien necesita crear una capa de abstracción entre el hardware físico y las aplicaciones de software que se ejecutan en él, a costa de recursos. Los hipervisores que gestionan las máquinas virtuales y el núcleo de ejecución de cada una de ellas utilizan un porcentaje de los recursos del sistema de hardware, que dejan de estar disponibles para las aplicaciones alojadas. Un contenedor, en cambio, no es más que otro proceso que suele hablar directamente con el núcleo Linux subyacente y, por tanto, puede utilizar más recursos, hasta que se alcancen los límites del sistema o basados en cuotas.

Cuando se lanzó por primera vez Docker, los contenedores Linux ya existían desde hacía bastantes años, y muchas de las otras tecnologías en las que se basa Docker no son totalmente nuevas. Sin embargo, la mezcla única de Docker de sólidas opciones arquitectónicas y de flujo de trabajo se combina en un todo que es mucho más potente que la suma de sus partes. Docker ha conseguido por sí solo que los contenedores de Linux, disponibles públicamente desde 2008, sean accesibles y útiles para todos los ingenieros informáticos. Docker adapta los contenedores con relativa facilidad al flujo de trabajo y a los procesos existentes en las empresas reales. Y los problemas comentados anteriormente han sido percibidos por tanta gente que el interés por el proyecto Docker se aceleró mucho más rápido de lo que nadie podría haber esperado razonablemente.

Desde sus comienzos en 2013, Docker ha experimentado una rápida iteración y ahora cuenta con un enorme conjunto de funciones y está implementado en un gran número de infraestructuras de producción de todo el planeta. Se ha convertido en una de las capas básicas de cualquier sistema distribuido moderno y ha inspirado a muchos otros a ampliar el enfoque. Un gran número de empresas aprovechan ahora los contenedores Docker y Linux como solución a algunos de los graves problemas de complejidad a los que se enfrentan en sus procesos de entrega de aplicaciones.

Qué no es Docker

Docker puede utilizarse para resolver una amplia gama de retos para cuya solución se han alistado tradicionalmente otras categorías de herramientas; sin embargo, la amplitud de características de Docker a menudo significa que carece de profundidad en funcionalidades específicas. Por ejemplo, algunas organizaciones descubrirán que pueden eliminar por completo su herramienta de gestión de la configuración cuando migren a Docker, pero el verdadero poder de Docker es que, aunque puede sustituir algunos aspectos de herramientas más tradicionales, también suele ser compatible con ellas o incluso mejorar en combinación con ellas. En la siguiente lista, exploramos algunas de las categorías de herramientas que Docker no sustituye directamente, pero que a menudo pueden utilizarse conjuntamente para obtener grandes resultados:

Plataforma de virtualización empresarial (VMware, KVM, etc.)

Un contenedor no es una máquina virtual en el sentido tradicional. Las máquinas virtuales contienen un sistema operativo completo, que se ejecuta sobre un hipervisor gestionado por el sistema operativo anfitrión subyacente. Los hipervisores crean capas de hardware virtual que permiten ejecutar sistemas operativos adicionales sobre un único sistema informático físico. Esto hace que sea muy fácil ejecutar muchas máquinas virtuales con sistemas operativos radicalmente distintos en un único host. Con los contenedores, tanto el host como los contenedores comparten el mismo núcleo. Esto significa que los contenedores utilizan menos recursos del sistema, pero deben basarse en el mismo sistema operativo subyacente (por ejemplo, Linux).

Plataforma en la nube (OpenStack, CloudStack, etc.)

Al igual que la virtualización empresarial, el flujo de trabajo de los contenedores comparte muchas similitudes -en apariencia- con las plataformas de nube más tradicionales. Ambas se aprovechan tradicionalmente para permitir que las aplicaciones se escalen horizontalmente en respuesta a una demanda cambiante. Sin embargo, Docker no es una plataforma en la nube. Sólo se ocupa de la implementación, ejecución y gestión de contenedores en hosts Docker preexistentes. No te permite crear nuevos sistemas anfitriones (instancias), almacenes de objetos, almacenamiento de bloques y los muchos otros recursos que suelen gestionarse con una plataforma en la nube. Dicho esto, cuando empieces a ampliar tus herramientas Docker, deberías empezar a experimentar cada vez más las ventajas que tradicionalmente se asocian a la nube.

Gestión de la configuración (Puppet, Chef, etc.)

Aunque Docker puede mejorar significativamente la capacidad de una organización para gestionar aplicaciones y sus dependencias, no sustituye directamente a la gestión de configuración más tradicional. Los archivos Docker se utilizan para definir el aspecto que debe tener un contenedor en el momento de la compilación, pero no gestionan el estado continuo del contenedor y no pueden utilizarse para gestionar el sistema anfitrión Docker. Sin embargo, Docker puede reducir significativamente la necesidad de un complejo código de gestión de la configuración. A medida que más y más servidores se convierten simplemente en hosts Docker, la base de código de gestión de la configuración que utiliza una empresa puede reducirse mucho, y Docker puede utilizarse para enviar los requisitos de las aplicaciones más complejas dentro de imágenes OCI estandarizadas.

Marco de Implementación (Capistrano, Fabric, etc.)

Docker facilita muchos aspectos de la implementación mediante la creación de imágenes de contenedores que encapsulan todas las dependencias de una aplicación de forma que puedan implementarse en todos los entornos sin cambios. Sin embargo, Docker no puede utilizarse para automatizar por sí solo un proceso de implementación complejo. Normalmente siguen siendo necesarias otras herramientas para coser el flujo de trabajo más amplio. Dicho esto, como Docker y otros conjuntos de herramientas de contenedores Linux, como Kubernetes (k8s), proporcionan una interfaz bien definida para la implementación, el método necesario para implementar contenedores será coherente en todos los hosts, y un único flujo de trabajo de implementación debería bastar para la mayoría, si no todas, tus aplicaciones basadas en Docker.

Entorno de desarrollo (Vagrant, etc.)

Vagrant es una herramienta de gestión de máquinas virtuales para desarrolladores que se utiliza a menudo para simular pilas de servidores que se asemejan mucho al entorno de producción en el que se implementará una aplicación. Entre otras cosas, Vagrant facilita la ejecución de software Linux en estaciones de trabajo basadas en macOS y Windows. Las máquinas virtuales gestionadas por herramientas como Vagrant ayudan a los desarrolladores a tratar de evitar el escenario común de "funcionó en mi máquina" que se produce cuando el software funciona bien para el desarrollador pero no funciona correctamente en otro lugar. Sin embargo, como en muchos de los ejemplos anteriores, cuando empiezas a utilizar Docker plenamente, hay mucha menos necesidad de imitar una amplia variedad de sistemas de producción en el desarrollo, ya que la mayoría de los sistemas de producción serán simplemente servidores de contenedores Linux, que pueden reproducirse fácilmente a nivel local.

Herramienta de gestión de la carga de trabajo (Mesos, Kubernetes, Swarm, etc.)

Debe utilizarse una capa de orquestación (incluido el modo Swarm incorporado) para coordinar el trabajo en un conjunto de hosts de contenedores Linux, realizar un seguimiento del estado actual de todos los hosts y sus recursos, y mantener un inventario de los contenedores en ejecución. Estos sistemas están diseñados para automatizar las tareas habituales necesarias para mantener en buen estado un clúster de producción, al tiempo que proporcionan herramientas que ayudan a que la naturaleza altamente dinámica de las cargas de trabajo en contenedores sea más fácil de manejar para los seres humanos.

Cada una de estas secciones señala una función importante que Docker y los contenedores Linux alteraron y mejoraron. Los contenedores Linux proporcionan una forma de ejecutar software en un entorno controlado y aislado, mientras que las herramientas de interfaz de línea de comandos (CLI) fáciles de usar y el estándar de imagen de contenedor que introdujo Docker facilitaron mucho el trabajo con contenedores y garantizaron que hubiera una forma repetible de crear software en toda la flota.

Terminología importante

He aquí algunos términos que seguiremos utilizando a lo largo del libro y con cuyo significado deberías familiarizarte:

Cliente Docker

Este es el comando docker utilizado para controlar la mayor parte del flujo de trabajo de Docker y hablar con servidores Docker remotos.

Servidor Docker

Este es el comando dockerd que se utiliza para iniciar el proceso del servidor Docker que construye y lanza contenedores a través de un cliente.

Imágenes Docker u OCI

Las imágenes Docker y OCI consisten en de una o más capas del sistema de archivos y algunos metadatos importantes que representan todos los archivos necesarios para ejecutar una aplicación en contenedores. Una sola imagen puede copiarse en numerosos hosts. Una imagen suele tener una dirección de repositorio, un nombre y una etiqueta. La etiqueta se utiliza generalmente para identificar una versión concreta de una imagen (por ejemplo, docker.io/superorbital/wordchain:v1.0.1). Una imagen Docker es cualquier imagen compatible con el conjunto de herramientas Docker, mientras que una imagen OCI es específicamente una imagen que cumple la norma Open Container Initiative y que está garantizada para funcionar con cualquier herramienta compatible con OCI.

Contenedor Linux

Se trata de un contenedor que se ha instanciado a partir de una imagen Docker u OCI. Un contenedor específico sólo puede existir una vez; sin embargo, puedes crear fácilmente varios contenedores a partir de la misma imagen. El término contenedor Docker es un término equivocado, ya que Docker simplemente aprovecha la funcionalidad de contenedor del sistema operativo.

Anfitrión atómico o inmutable

Un host atómico o inmutable es una imagen de SO pequeña y afinada, como Fedora CoreOS, que admite el alojamiento de contenedores y las actualizaciones atómicas del SO.

Recapitulación

Entender completamente Docker puede ser un reto cuando te acercas a él sin un marco de referencia sólido. En el próximo capítulo, daremos una visión general de Docker: qué es, cómo se pretende que se utilice y qué ventajas aporta cuando se implementa teniendo todo esto en cuenta.

Get Docker: Up & Running, 3ª Edición now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.