Ignora la alharaca: 5 ideas erróneas sobre Docker que los desarrolladores Java deben tener claras

 ● 17th May 2015

11 min read

¿Cómo lograr un enfoque pragmático de Docker y ver más allá de los bombos y los platillos?

Recientemente, se ha generado una gran alharaca en torno a Docker, y es fácil entender por qué. El empaquetado y la distribución de código representan un desafío. La tecnología de los contenedores ha sido tradicionalmente muy desorganizada, con muchos requisitos y plantillas. Docker te brinda una manera sencilla de crear contenedores de forma repetible. En general, es más rápido, cómodo y fácil de usar y entender que otros contenedores y métodos de empaquetado y distribución de código. ¡De ahí tanta alharaca! Pero junto con la alharaca también vienen los malentendidos y las confusiones. Como siempre, no te dejes llevar por las olas. Mantener una perspectiva pragmática sobre Docker te va a permitir entender si se ajusta a lo que tú necesitas.
En este artículo, analizaremos cinco ideas erróneas sobre Docker, y veremos a este último desde el ángulo de Java. Pero primero, vamos a ponernos en contexto. Para averiguar más, nada mejor que hablar con alguien que tenga una vasta experiencia con Docker, así que organizamos una charla con Avishai Ish-Shalom, de Fewbytes, quien también es organizador de la conferencia DevOps Days. Aprovechamos sus conocimientos y experiencia con Docker para elaborar esta lista de confusiones comunes junto con él.

Las principales ideas erróneas

1: Docker es una máquina virtual (VM) liviana

Esta es una confusión primaria de las personas que buscan abreviar y obtener un entendimiento de alto nivel de Docker. Y es comprensible: Docker se parece mucho a una VM. Hasta hacen una comparación entre Docker y las VM en el sitio web de Docker. De todos modos, Docker es más conocido como una evolución de los contenedores Linux (LXC), antes que como una VM ligera. Ambos son diferentes animales, así que tratar a los contenedores Docker como si fueran VM livianas únicamente traerá problemas.
worst-cat
El peor gato
Hay varias diferencias cruciales entre los contenedores Docker y las VM que deberás entender antes de usar Docker.
Aislamiento de recursos: Docker no ofrece el mismo nivel de aislamiento de recursos que las máquinas virtuales. Mientras que estas últimas brindan grandes niveles de aislamiento de recursos, Docker tiene, por su diseño, varios tipos de recursos compartidos que no puede aislar ni proteger, tales como la caché de páginas y los recolectores de entropía. (Un comentario al margen: los recolectores de entropía son realmente interesantes. Si no te suenan conocidos, básicamente ellos se dedican a juntar y almacenar bits aleatorios generados por acciones del sistema. Esta recolección es usada por el computador cada vez que la aleatoriedad es necesaria, como en el caso de la criptografía.) En el caso que un contenedor de Docker consuma todos los recursos compartidos, otros procesos tendrán que esperar a que los primeros sean liberados y recargados.
Overhead: Es sabido que las máquinas virtuales brindan un desempeño casi nativo de CPU y de RAM, pero también vienen con mucho overhead E/S. Gracias a que Docker no cuenta con el SO invitado que ofrecen las máquinas virtuales, logra ofrecer paquetes de menor tamaño y menor overhead de almacenamiento que ellas. Esto no significa que Docker sea completamente inmune a cualquier problema de overhead. Existe suficiente overhead E/S con los contenedores de Docker como para que les prestes atención, aunque no tanta como con las máquinas virtuales.
Uso del kernel: Los contenedores de Docker y las máquinas virtuales hacen usos muy distintos de los kernels. Las máquinas virtuales usan un kernel para cada una de ellas. Los contenedores de Docker, en cambio, comparten un kernel para todos. Compartir un kernel genera cierta eficiencia, pero únicamente a costa de una alta fiabilidad y redundancia. Si sufres un kernel panic con tus máquinas virtuales, únicamente la que se encuentra en ese kernel morirá. Un kernel panic en los contenedores de Docker significa que fallen todos tus contenedores.

2: Docker hace que tu aplicación sea escalable

Puesto que Docker facilita la implementación de tu código en varios servidores en un corto período de tiempo, sería necesario un pequeño salto más para combinar eso con la posibilidad de que Docker por sí mismo hiciera que tu aplicación sea escalable. Pero, desafortunadamente para todos nosotros, ese no es el caso. Tu aplicación es propiedad de tu código y Docker no reescribe tu código. La escalabilidad de tu aplicación sigue siendo tu responsabilidad, tal como siempre lo ha sido. El uso de Docker no hará automáticamente que tu código sea más escalable, sino simplemente más fácil de implementar a través de servidores.

3: Docker es ampliamente usado en producción

Como consecuencia de todo lo que se habla sobre Docker, puede que muchas personas asuman que debe ser una herramienta ampliamente usada en producción. Lo cierto es que tal no es el caso. ¡Algunos se olvidan de que Docker es muy nuevo! Todavía es joven y está en crecimiento, lo cual quiere decir que todavía tiene fallos bastante molestos y también que aún le faltan funcionalidades. No hay nada de malo en que la tecnología te apasione, pero mejor aún es que entiendas los sacrificios y los casos de uso adecuados que tienen lugar en ella. Hoy en día, Docker es muy fácil de adoptar para tu desarrollo. Docker simplifica la configuración de múltiples entornos diferentes (o por lo menos te da la sensación de que configuras diferentes entornos), lo cual representa un excelente beneficio para el desarrollo.
Por el lado de la producción, muchos de los problemas de crecimiento de una tecnología que todavía es joven se convierten en impedimentos que, en la mayoría de los casos, son demasiado grandes como para un uso generalizado. Por ejemplo, Docker no ofrece soporte directo para capacidades de monitoreo o conexiones en red de múltiples máquinas, todo lo cual limita su utilidad para la producción de hoy en día. De todos modos, hay mucho potencial. El beneficio de empaquetar y distribuir el mismo paquete desde el desarrollo hasta la producción es muy grande. Y hay varias funcionalidades de Docker en tiempo de ejecución que son de mucho valor en entornos de producción. Así y todo, las limitaciones superan a los beneficios en varios casos de uso de la producción actual. Eso no quiere decir que no puedas usarlo satisfactoriamente en producción, pero sí que no debes esperar que ya esté absolutamente maduro y completo al día de hoy.

4: Docker es agnóstico en cuanto a sistemas operativos

Otra confusión común reside en la creencia de que Docker funciona de forma universal en cualquier sistema operativo y entorno. Tiene sentido pensar en ello basándose en la metáfora que Docker usa de contenedores que empaquetan y distribuyen, pero la verdad es que el software y los sistemas operativos no son tan simples como los puertos en los océanos.
En realidad, Docker es una tecnología exclusiva de Linux. Y ya que algunos elementos de Docker dependen de ciertas funcionalidades del kernel en particular, vas a tener que asegurarte de tener una versión reciente del kernel instalada. Debido a las diferencias  que existen entre los variados sistemas operativos, usar funcionalidades que no estén dentro del más común denominador entre todos ellos puede acarrearte algunos problemas. Algunos de estos incidentes pueden ocurrir únicamente en un 1 % de los casos pero, cuando escales, ese 1 % se volverá mucho más significativo.
Si bien Docker corre de manera nativa exclusivamente en Linux, existen métodos para usar Docker en OS X y en Windows. Por ejemplo, boot2docker integra una máquina virtual local con Linux en tu máquina con OS X o Windows y se ocupa de la mayor parte de la configuración de Docker.

5: Docker hace que tu aplicación sea más segura

Existe una creencia errónea de que el uso de Docker aumentará la seguridad de tu código y tus distribuciones. Una vez más, aquí posiblemente entran en juego las diferencias entre la idea de contenedores físicos y la de contenedores de software. Docker es una tecnología de empaquetado y distribución en contenedores y añade orquestación, pero los contenedores en Linux tienen muchas vulnerabilidades de seguridad que pueden recibir ataques. Docker no provee ninguna capa o parche de seguridad adicional para estas vulnerabilidades. No hay ninguna caja metálica gigante alrededor de tu aplicación.

Desde el ángulo de Java

Docker ha tenido una buena acogida entre los desarrolladores Java. Algunos elementos de Docker nos permiten crear fácilmente contextos que pueden escalar. A diferencia de un uber-jar, con Docker realmente puedes empaquetar TODAS tus dependencias (¡incluida la JVM!) juntos en una imagen lista para distribución. Este es un gran beneficio que puede hacer que valga la pena probar Docker. De cualquier manera, esto también trae sus inconvenientes. Normalmente, vas a desear interactuar con tu código de varias maneras: monitorearlo, depurarlo, conectarte a él, refinarlo… todo eso presenta preocupaciones y desafíos adicionales al trabajar con Docker.
Por ejemplo, supongamos que queremos usar jconsole, el cual depende de funcionalidades JMX que, a su vez, requieren conexión a la red, ya que usan RMI. Con Docker, no nos será posible usarlo de forma directa, sino que será necesario utilizar algunos trucos para abrir los puertos apropiados. Lo que, en un primer momento, nos puso a pensar en esto fue que cuando estábamos creando el instalador Docker de OverOps, tuvimos que encontrar una manera de tener un demonio junto a la JVM dentro del contenedor. Puedes ver la solución que construimos en GitHub.
Otro asunto de gran relevancia es que refinar el desempeño se vuelve aún más complicado con los contenedores de Docker. Cuando usas contenedores, no sabes exactamente cuánta memoria será asignada a cada uno de ellos. Si tienes, digamos, 20 contenedores, la memoria es asignada a todos ellos basándose en factores de los que puede que no estés al tanto. Esto presenta todo un desafío a la hora de ajustar el tamaño de tu heap de memoria dinámica con banderas del tipo -Xmx, ya que comunicarte con una JVM dentro de un contenedor de Docker requiere de cierta automatización para poder entender cuánta memoria te ha sido asignada a ti. No saber con cuánta memoria cuentas hace la tarea de refinar el desempeño extremadamente ardua.

Conclusión

Docker ofrece una tecnología muy interesante, con varios casos de uso válidos y auténticos. Y como buena tecnología joven que es, tiene mucho tiempo y potencial para abordar varias de las funcionalidades que le faltan y los fallos que presenta. Pero la verdad es que actualmente está recibiendo demasiados bombos y platillos. La alharaca no trae al éxito automáticamente, por supuesto, pero tampoco trae automáticamente el fracaso.
betamax
Betamax says hi
Betamax nos manda saludos
Usar Docker es una cuestión de entender qué es lo que realmente es y lo que realmente puedes hacer con él. Podemos desilusionarnos si lo tratamos como si fuera mágico. Esperamos que haber aclarado algunas de estas ideas erróneas pueda dejarte las cosas más claras con respecto a Docker, por si quieres dar una vuelta con él. Si ya lo has estado probando, ¿has notado alguna otra confusión común que yo no haya mencionado más arriba? Déjamelo saber en la sección de comentarios.
Muchas gracias a Avishai Ish-Shalom por aceptar charlar con nosotros para este artículo.

During his time at OverOps, Josh was in charge of product marketing. He wrote and maintained product documentation in addition to his contributions to the OverOps Blog. He's a big baseball fan and a small beer nerd.

Troubleshooting Apache Spark Applications with OverOps OverOps’ ability to detect precisely why something broke and to see variable state is invaluable in a distributed compute environment.
Troubleshooting Apache Spark Applications with OverOps

Next Article

The Fastest Way to Why.

Eliminate the detective work of searching logs for the Cause of critical issues. Resolve issues in minutes.
Learn More