¿En qué se diferencia Docker de una máquina virtual

docker containers virtual-machine virtualization


Sigo releyendo la documentación de Docker para tratar de comprender la diferencia entre Docker y una máquina virtual completa. ¿Cómo se las arregla para proporcionar un sistema de archivos completo, un entorno de red aislado, etc. sin ser tan pesado?

¿Por qué es más fácil desplegar el software en una imagen Docker (si ese es el término correcto)que simplemente desplegarlo en un entorno de producción consistente?





Answer 1 Ken Cochrane


Docker originalmente utilizó LinuX Containers (LXC), pero luego cambió a runC (anteriormente conocido como libcontainer ), que se ejecuta en el mismo sistema operativo que su host. Esto le permite compartir muchos de los recursos del sistema operativo host. Además, utiliza un sistema de archivos en capas ( AuFS ) y administra las redes.

El AuFS es un sistema de archivos por capas,por lo que puedes tener una parte de sólo lectura y otra de escritura que se fusionan entre sí.Uno podría tener las partes comunes del sistema operativo como de sólo lectura (y compartidas entre todos sus contenedores)y luego darle a cada contenedor su propia montura para la escritura.

Entonces, supongamos que tiene una imagen de contenedor de 1 GB; Si desea utilizar una máquina virtual completa, necesitaría tener 1 GB x número de máquinas virtuales que desea. Con Docker y AuFS, puede compartir la mayor parte de 1 GB entre todos los contenedores y si tiene 1000 contenedores, es posible que solo tenga un poco más de 1 GB de espacio para el sistema operativo de contenedores (suponiendo que todos estén ejecutando la misma imagen del sistema operativo) .

Un sistema totalmente virtualizado obtiene su propio conjunto de recursos asignados a él,y hace un mínimo intercambio.Obtienes más aislamiento,pero es mucho más pesado (requiere más recursos).Con Docker se obtiene menos aislamiento,pero los contenedores son ligeros (requieren menos recursos).Por lo tanto,podrías hacer funcionar fácilmente miles de contenedores en un anfitrión,y ni siquiera parpadeará.Intenta hacerlo con Xen,y a menos que tengas un huésped realmente grande,no creo que sea posible.

Un sistema virtualizado completo suele tardar minutos en iniciarse,mientras que los contenedores DockerLXCrunC tardan segundos,y a menudo incluso menos de un segundo.

Hay pros y contras para cada tipo de sistema virtualizado.Si quieres un aislamiento completo con recursos garantizados,un VM completo es el camino a seguir.Si sólo quiere aislar los procesos entre sí y quiere ejecutar una tonelada de ellos en un host de tamaño razonable,entonces DockerLXCrunC parece ser el camino a seguir.

Para obtener más información, consulte este conjunto de publicaciones de blog que explican cómo funciona LXC.

¿Por qué es más fácil desplegar software a una imagen docker (si ese es el término correcto)que simplemente desplegarlo a un entorno de producción consistente?

Implementar un entorno de producción consistente es más fácil decirlo que hacerlo. Incluso si usa herramientas como Chef y Puppet , siempre hay actualizaciones del sistema operativo y otras cosas que cambian entre hosts y entornos.

Docker te da la posibilidad de capturar el sistema operativo en una imagen compartida,y facilita la implementación en otros hosts Docker.Localmente,dev,qa,prod,etc.:todos con la misma imagen.Seguro que puedes hacer esto con otras herramientas,pero no tan fácil o rápido.

Esto es genial para probar; supongamos que tiene miles de pruebas que necesitan conectarse a una base de datos, y cada prueba necesita una copia prístina de la base de datos y realizará cambios en los datos. El enfoque clásico para esto es restablecer la base de datos después de cada prueba, ya sea con código personalizado o con herramientas como Flyway ; esto puede llevar mucho tiempo y significa que las pruebas deben ejecutarse en serie. Sin embargo, con Docker podría crear una imagen de su base de datos y ejecutar una instancia por prueba, y luego ejecutar todas las pruebas en paralelo, ya que sabe que todas se ejecutarán en la misma instantánea de la base de datos. Dado que las pruebas se ejecutan en paralelo y en contenedores Docker, podrían ejecutarse todas en la misma caja al mismo tiempo y deberían terminar mucho más rápido. Intenta hacerlo con una máquina virtual completa.

De los comentarios...

¡Interesante! Supongo que todavía estoy confundido por la noción de "instantánea del sistema operativo".¿Cómo se hace eso sin,bueno,hacer una imagen del sistema operativo?

Bueno, veamos si puedo explicarlo. Comienza con una imagen base, y luego realiza los cambios, y los confirma utilizando Docker, y se crea una imagen. Esta imagen contiene solo las diferencias de la base. Cuando desea ejecutar su imagen, también necesita la base, y coloca su imagen en la parte superior de la base usando un sistema de archivos en capas: como se mencionó anteriormente, Docker usa AuFS. AuFS combina las diferentes capas y obtienes lo que deseas; solo necesitas ejecutarlo. Puede seguir agregando más y más imágenes (capas) y continuará guardando solo las diferencias. Dado que Docker generalmente se basa en imágenes preparadas de un registro , rara vez tiene que "capturar" todo el sistema operativo usted mismo.




Answer 2 manu97


Buenas respuestas.Sólo para obtener una representación de la imagen del contenedor contra el VM,eche un vistazo a la siguiente.

enter image description here

Source




Answer 3 Shital Shah


Podría ser útil comprender cómo funcionan la virtualización y los contenedores a bajo nivel.Eso aclarará muchas cosas.

Nota:Estoy simplificando un poco al describir a continuación.Vea las referencias para más información.

¿Cómo funciona la virtualización a bajo nivel?

En este caso, VM Manager se hace cargo del anillo de CPU 0 (o el "modo raíz" en las CPU más nuevas) e intercepta todas las llamadas privilegiadas realizadas por el SO huésped para crear la ilusión de que el SO huésped tiene su propio hardware. Dato curioso: antes de 1998 se pensaba que era imposible lograr esto en la arquitectura x86 porque no había forma de hacer este tipo de intercepción. La gente de VMWare fue la primera que tuvo la idea de reescribir los bytes ejecutables en la memoria para llamadas privilegiadas del sistema operativo invitado para lograr esto.

El efecto neto es que la virtualización permite ejecutar dos sistemas operativos completamente diferentes en el mismo hardware.Cada sistema operativo invitado pasa por todo el proceso de bootstrapping,carga de kernel,etc.Puedes tener una seguridad muy estricta,por ejemplo,el SO invitado no puede tener acceso total al SO anfitrión o a otros invitados y estropear las cosas.

¿Cómo funcionan los contenedores a bajo nivel?

Alrededor de 2006 , las personas, incluidos algunos de los empleados de Google, implementaron una nueva función de nivel de núcleo llamada espacios de nombres (sin embargo, la idea existía mucho antes en FreeBSD ). Una función del sistema operativo es permitir compartir recursos globales como la red y el disco con los procesos. ¿Qué sucede si estos recursos globales se envuelven en espacios de nombres para que sean visibles solo para aquellos procesos que se ejecutan en el mismo espacio de nombres? Digamos que puede obtener un trozo de disco y ponerlo en el espacio de nombres X y luego los procesos que se ejecutan en el espacio de nombres Y no pueden verlo ni acceder a él. Del mismo modo, los procesos en el espacio de nombres X no pueden acceder a nada en la memoria asignada al espacio de nombres Y. Por supuesto, los procesos en X no pueden ver ni hablar con los procesos en el espacio de nombres Y. Esto proporciona un tipo de virtualización y aislamiento para los recursos globales. Así es como funciona Docker: cada contenedor se ejecuta en su propio espacio de nombres pero usa exactamente el mismo núcleo que todos los demás contenedores. El aislamiento ocurre porque el kernel conoce el espacio de nombres asignado al proceso y durante las llamadas a la API se asegura de que el proceso solo pueda acceder a los recursos en su propio espacio de nombres.

Las limitaciones de los contenedores frente a la VM deberían ser obvias ahora: no puede ejecutar un sistema operativo completamente diferente en contenedores como en las máquinas virtuales. Sin embargo, puede ejecutar diferentes distribuciones de Linux porque comparten el mismo núcleo. El nivel de aislamiento no es tan fuerte como en VM. De hecho, había una manera para que el contenedor "invitado" se hiciera cargo del host en las primeras implementaciones. También puede ver que cuando carga un nuevo contenedor, la nueva copia completa del sistema operativo no se inicia como lo hace en VM. Todos los contenedores comparten el mismo núcleo . Es por eso que los contenedores son livianos. Además, a diferencia de VM, no tiene que asignar previamente una porción considerable de memoria a los contenedores porque no estamos ejecutando una nueva copia del sistema operativo. Esto permite ejecutar miles de contenedores en un sistema operativo, mientras que los sandboxing lo que podría no ser posible si estuviéramos ejecutando una copia separada del sistema operativo en su propia máquina virtual.




Answer 4 aholbreich


Me gusta la respuesta de Ken Cochrane.

Pero quiero añadir un punto de vista adicional,no cubierto en detalle aquí.En mi opinión,Docker difiere también en todo el proceso.A diferencia de los VM,Docker no se trata (sólo)de compartir óptimamente los recursos de hardware,sino que además proporciona un "sistema" para empaquetar la aplicación (preferible,pero no imprescindible,como un conjunto de microservicios).

Para mí, encaja en la brecha entre herramientas orientadas al desarrollador como rpm, paquetes Debian , Maven , npm + Git en un lado y herramientas de operaciones como Puppet , VMware, Xen, lo que sea ...

¿Por qué es más fácil desplegar software a una imagen docker (si ese es el término correcto)que simplemente desplegarlo a un entorno de producción consistente?

Su pregunta supone un entorno de producción consistente. Pero, ¿cómo mantenerlo consistente? Considere cierta cantidad (> 10) de servidores y aplicaciones, etapas en la tubería.

Para mantener esto sincronizado, comenzará a usar algo como Puppet, Chef o sus propios scripts de aprovisionamiento, reglas inéditas y / o mucha documentación ... En teoría, los servidores pueden ejecutarse indefinidamente y mantenerse completamente consistentes y actualizados. La práctica no logra administrar completamente la configuración de un servidor, por lo que hay un margen considerable para la deriva de la configuración y cambios inesperados en los servidores en ejecución.

Por lo tanto, existe un patrón conocido para evitar esto, el llamado servidor inmutable . Pero el patrón de servidor inmutable no fue amado. Principalmente debido a las limitaciones de las máquinas virtuales que se usaron antes de Docker. Tratar con imágenes grandes de varios gigabytes, mover esas imágenes grandes solo para cambiar algunos campos en la aplicación, fue muy muy laborioso. Comprensible...

Con un ecosistema Docker,nunca tendrá que moverse en gigabytes en "pequeños cambios" (gracias a aufs y a Registry)y no tendrá que preocuparse por la pérdida de rendimiento al empaquetar aplicaciones en un contenedor Docker en tiempo de ejecución.No necesitas preocuparte por las versiones de esa imagen.

Y por último,a menudo incluso podrás reproducir complejos entornos de producción incluso en tu portátil Linux (no me llames si no funciona en tu caso ;))

Y,por supuesto,puedes poner en marcha contenedores Docker en VMs (es una buena idea).Reduzca el aprovisionamiento de su servidor a nivel de VM.Todo lo anterior podría ser administrado por Docker.

PD Mientras tanto, Docker usa su propia implementación "libcontainer" en lugar de LXC. Pero LXC todavía es utilizable.




Answer 5 Ashish Bista


Docker no es una metodología de virtualización.Se basa en otras herramientas que realmente implementan la virtualización basada en contenedores o la virtualización a nivel de sistema operativo.Para ello,Docker utilizó inicialmente el controlador LXC,y luego se trasladó a libcontainer que ahora se denomina runc.Docker se centra principalmente en la automatización del despliegue de aplicaciones dentro de los contenedores de aplicaciones.Los contenedores de aplicaciones están diseñados para empaquetar y ejecutar un solo servicio,mientras que los contenedores de sistemas están diseñados para ejecutar múltiples procesos,como las máquinas virtuales.Así pues,Docker se considera una herramienta de gestión de contenedores o de despliegue de aplicaciones en sistemas en contenedores.

Para saber en qué se diferencia de otras virtualizaciones,pasemos a la virtualización y sus tipos.Entonces,sería más fácil entender cuál es la diferencia allí.

Virtualization

En su forma concebida,se consideraba un método de dividir lógicamente los ordenadores centrales para permitir la ejecución simultánea de múltiples aplicaciones.Sin embargo,el escenario cambió drásticamente cuando las empresas y las comunidades de código abierto pudieron proporcionar un método para manejar las instrucciones privilegiadas de una forma u otra y permitir que varios sistemas operativos se ejecutaran simultáneamente en un solo sistema basado en x86.

Hypervisor

El hipervisor se encarga de crear el entorno virtual en el que operan las máquinas virtuales invitadas.Supervisa los sistemas de los huéspedes y se asegura de que los recursos se asignen a los huéspedes según sea necesario.El hipervisor se sitúa entre la máquina física y las máquinas virtuales y proporciona servicios de virtualización a las máquinas virtuales.Para realizarlo,intercepta las operaciones del sistema operativo del huésped en las máquinas virtuales y emula la operación en el sistema operativo de la máquina anfitriona.

El rápido desarrollo de las tecnologías de virtualización,principalmente en la nube,ha impulsado aún más el uso de la virtualización al permitir la creación de múltiples servidores virtuales en un solo servidor físico con la ayuda de hipervisores,como Xen,VMware Player,KVM,etc.,y la incorporación de soporte de hardware en procesadores de productos básicos,como Intel VT y AMD-V.

Tipos de virtualización

El método de virtualización puede ser categorizado en base a cómo imita el hardware a un sistema operativo invitado y emula un entorno operativo invitado.Principalmente,hay tres tipos de virtualización:

  • Emulation
  • Paravirtualization
  • Virtualización basada en contenedores

Emulation

La emulación,también conocida como virtualización completa,ejecuta el núcleo del SO de la máquina virtual completamente en software.El hipervisor utilizado en este tipo se conoce como hipervisor Tipo 2.Se instala en la parte superior del sistema operativo del host,que es responsable de traducir el código del núcleo del SO huésped a instrucciones de software.La traducción se hace completamente en el software y no requiere ninguna participación del hardware.La emulación hace posible ejecutar cualquier sistema operativo no modificado que soporte el entorno que se está emulando.La desventaja de este tipo de virtualización es una sobrecarga adicional de recursos del sistema que conlleva una disminución del rendimiento en comparación con otros tipos de virtualización.

Emulation

Los ejemplos de esta categoría incluyen VMware Player,VirtualBox,QEMU,Bochs,Parallels,etc.

Paravirtualization

La paravirtualización, también conocida como hipervisor Tipo 1, se ejecuta directamente en el hardware o "bare metal" y proporciona servicios de virtualización directamente a las máquinas virtuales que se ejecutan en él. Ayuda al sistema operativo, al hardware virtualizado y al hardware real a colaborar para lograr un rendimiento óptimo. Estos hipervisores suelen tener una huella bastante pequeña y, por sí mismos, no requieren grandes recursos.

Los ejemplos en esta categoría incluyen Xen,KVM,etc.

Paravirtualization

Virtualización basada en contenedores

La virtualización basada en contenedores,también conocida como virtualización a nivel de sistema operativo,permite múltiples ejecuciones aisladas dentro de un solo núcleo de sistema operativo.Tiene el mejor rendimiento y densidad posibles y presenta una gestión dinámica de los recursos.El entorno de ejecución virtual aislado que proporciona este tipo de virtualización se denomina contenedor y puede considerarse como un grupo de procesos trazados.

Container-based virtualization

El concepto de contenedor es posible gracias a la función de espacios de nombres agregada a la versión 2.6.24 del kernel de Linux. El contenedor agrega su ID a cada proceso y agrega nuevas verificaciones de control de acceso a cada llamada al sistema. Se accede mediante la llamada al sistema clone () que permite crear instancias separadas de espacios de nombres previamente globales.

Los espacios de nombres pueden utilizarse de muchas maneras diferentes,pero el enfoque más común es crear un contenedor aislado que no tenga visibilidad o acceso a los objetos fuera del contenedor.Los procesos que se ejecutan dentro del contenedor parecen estar funcionando en un sistema Linux normal,aunque están compartiendo el núcleo subyacente con procesos ubicados en otros espacios de nombres,lo mismo para otros tipos de objetos.Por ejemplo,cuando se utilizan namespaces,el usuario raíz dentro del contenedor no se trata como raíz fuera del contenedor,lo que añade una seguridad adicional.

El subsistema de grupos de control de Linux (cgroups),que es el siguiente componente principal para permitir la virtualización basada en contenedores,se utiliza para agrupar procesos y gestionar su consumo de recursos agregados.Se utiliza comúnmente para limitar el consumo de memoria y de CPU de los contenedores.Dado que un sistema Linux basado en contenedores tiene un solo núcleo y el núcleo tiene plena visibilidad de los contenedores,sólo hay un nivel de asignación de recursos y de programación.

Se dispone de varias herramientas de gestión para los contenedores de Linux,entre ellas LXC,LXD,systemd-nspawn,lmctfy,Warden,Linux-VServer,OpenVZ,Docker,etc.

Contenedores vs Máquinas Virtuales

A diferencia de una máquina virtual,un contenedor no necesita arrancar el núcleo del sistema operativo,por lo que los contenedores pueden crearse en menos de un segundo.Esta característica hace que la virtualización basada en contenedores sea única y más deseable que otros enfoques de virtualización.

Dado que la virtualización basada en contenedores añade poca o ninguna sobrecarga al equipo anfitrión,la virtualización basada en contenedores tiene un rendimiento casi nativo

En el caso de la virtualización basada en contenedores,no se requiere ningún software adicional,a diferencia de otras virtualizaciones.

Todos los contenedores de una máquina anfitriona comparten el programador de la máquina anfitriona,lo que ahorra la necesidad de recursos adicionales.

Los estados de los contenedores (imágenes Docker o LXC)son de tamaño pequeño en comparación con las imágenes de las máquinas virtuales,por lo que las imágenes de los contenedores son fáciles de distribuir.

La gestión de recursos en contenedores se logra a través de cgroups. Cgroups no permite que los contenedores consuman más recursos de los asignados. Sin embargo, a partir de ahora, todos los recursos de la máquina host son visibles en las máquinas virtuales, pero no se pueden usar. Esto puede realizarse ejecutando top o htop en contenedores y máquina host al mismo tiempo. El resultado en todos los entornos será similar.

Update:

¿Cómo ejecuta Docker contenedores en sistemas que no son Linux?

Si los contenedores son posibles debido a las características disponibles en el núcleo de Linux,entonces la pregunta obvia es cómo funcionan los contenedores en los sistemas que no son de Linux.Tanto Docker para Mac como Windows usan VMs de Linux para ejecutar los contenedores.Docker Toolbox se utiliza para ejecutar contenedores en Virtual Box VMs.Pero,la última Docker usa Hyper-V en Windows e Hypervisor.framework en Mac.

Ahora,déjeme describirle en detalle cómo Docker para Mac maneja los contenedores.

Docker para Mac usa https://github.com/moby/hyperkit para emular las capacidades del hipervisor e Hyperkit usa hypervisor.framework en su núcleo. Hypervisor.framework es la solución de hipervisor nativa de Mac. Hyperkit también usa VPNKit y DataKit para la red de espacio de nombres y el sistema de archivos, respectivamente.

La VM de Linux que Docker ejecuta en Mac es de sólo lectura.Sin embargo,puedes entrar en ella corriendo:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty .

Ahora,podemos incluso comprobar la versión del núcleo de este VM:

# uname -a Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux .

Todos los contenedores corren dentro de este VM.

Existen algunas limitaciones para hypervisor.framework. Debido a eso, Docker no expone la interfaz de red docker0 en Mac. Por lo tanto, no puede acceder a los contenedores desde el host. A partir de ahora, docker0 solo está disponible dentro de la VM.

Hyper-v es el hipervisor nativo de Windows.También están tratando de aprovechar las capacidades de Windows 10 para ejecutar sistemas Linux de forma nativa.