docker - una - maquinas virtuales contenedores
¿En qué se diferencia Docker de una máquina virtual? (19)
1. Ligero
Esta es probablemente la primera impresión para muchos aprendices de docker.
En primer lugar, las imágenes de la ventana acoplable suelen ser más pequeñas que las imágenes de VM, lo que facilita la creación, copia y uso compartido.
En segundo lugar, los contenedores Docker pueden iniciarse en varios milisegundos, mientras que la máquina virtual se inicia en segundos.
2. Sistema de archivos en capas
Esta es otra característica clave de Docker. Las imágenes tienen capas y las diferentes imágenes pueden compartir capas, lo que hace que ahorre más espacio y sea más rápido de construir.
Si todos los contenedores utilizan Ubuntu como sus imágenes base, no todas las imágenes tienen su propio sistema de archivos, sino que comparten el mismo subrayado de los archivos ubuntu, y solo difieren en sus propios datos de aplicación.
3. Kernel de SO compartido
¡Piense en los contenedores como procesos!
Todos los contenedores que se ejecutan en un host son, de hecho, un montón de procesos con diferentes sistemas de archivos. Comparten el mismo núcleo de sistema operativo, solo encapsula la biblioteca del sistema y las dependencias.
Esto es bueno para la mayoría de los casos (no se conserva el kernel del sistema operativo adicional) pero puede ser un problema si se necesitan aislamientos estrictos entre los contenedores.
¿Por qué importa?
Todas estas parecen mejoras, no revolución. Bueno, la acumulación cuantitativa conduce a la transformación cualitativa .
Piense en la implementación de la aplicación. Si queremos implementar un nuevo software (servicio) o actualizar uno, es mejor cambiar los archivos y procesos de configuración en lugar de crear una nueva máquina virtual. Porque crear una máquina virtual con servicio actualizado, probarlo (compartir entre Dev y QA), la implementación en producción lleva horas, incluso días. Si algo sale mal, tienes que empezar de nuevo, perdiendo aún más tiempo. Por lo tanto, use la herramienta de administración de configuración (títere, saltstack, chef, etc.) para instalar un nuevo software, es preferible descargar archivos nuevos.
Cuando se trata de la ventana acoplable, es imposible utilizar un contenedor de la ventana acoplable creado recientemente para reemplazar el anterior. El mantenimiento es mucho más fácil. Crear una nueva imagen, compartirla con control de calidad, probarlo, implementarlo solo toma minutos (si todo está automatizado), horas en el peor de los casos. Esto se denomina infraestructura inmutable : no mantenga el software (actualice), cree uno nuevo en su lugar.
Transforma cómo se entregan los servicios. Queremos aplicaciones, pero tenemos que mantener máquinas virtuales (lo cual es una molestia y tiene poco que ver con nuestras aplicaciones). Docker te hace enfocar en aplicaciones y suaviza todo.
Sigo releyendo la documentación de Docker para intentar 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 implementar software en una imagen de Docker (si ese es el término correcto) que simplemente implementar en un entorno de producción consistente?
A través de este post vamos a dibujar algunas líneas de diferencias entre las máquinas virtuales y los LXC. Primero definámoslos.
VM :
Una máquina virtual emula un entorno informático físico, pero las solicitudes de CPU, memoria, disco duro, red y otros recursos de hardware se administran mediante una capa de virtualización que traduce estas solicitudes al hardware físico subyacente.
En este contexto, se llama a la máquina virtual como invitado, mientras que el entorno en el que se ejecuta se denomina host.
LXC s:
Los contenedores de Linux (LXC) son capacidades de nivel de sistema operativo que hacen posible ejecutar múltiples contenedores de Linux aislados, en un host de control (el host de LXC). Los contenedores de Linux sirven como una alternativa ligera a las máquinas virtuales, ya que no requieren la presencia de hipervisores. Virtualbox, KVM, Xen, etc.
Ahora, a menos que haya sido drogado por Alan (Zach Galifianakis de la serie Hangover) y haya estado en Vegas durante el último año, será muy consciente del tremendo arrebato de interés para la tecnología de contenedores de Linux, y si soy específico, un contenedor. El proyecto que ha generado un gran revuelo en todo el mundo en los últimos meses es: Docker lleva a algunas opiniones de eco de que los entornos de computación en la nube deberían abandonar las máquinas virtuales (VM) y reemplazarlos con contenedores debido a sus menores gastos generales y, posiblemente, a un mejor rendimiento.
Pero la gran pregunta es, ¿es factible ?, ¿será sensata?
a. Los LXC están sujetos a una instancia de Linux. Podrían ser diferentes versiones de Linux (por ejemplo, un contenedor de Ubuntu en un host CentOS pero aún es Linux). De manera similar, los contenedores basados en Windows ahora tienen el alcance de una instancia de Windows. Si nos fijamos en máquinas virtuales, tienen un alcance bastante más amplio. Los hipervisores no están limitados a los sistemas operativos Linux o Windows.
segundo. Los LXC tienen bajos gastos generales y tienen un mejor rendimiento en comparación con las máquinas virtuales. Herramientas a saber. Docker, que se basa en la tecnología LXC, ha proporcionado a los desarrolladores una plataforma para ejecutar sus aplicaciones y, al mismo tiempo, ha habilitado a las personas de operaciones con una herramienta que les permitirá implementar el mismo contenedor en servidores de producción o centros de datos. Intenta hacer que la experiencia entre un desarrollador que ejecuta una aplicación, el arranque y la prueba de una aplicación y una persona de operaciones que implementa esa aplicación sea transparente, porque es ahí donde reside toda la fricción y el propósito de DevOps es romper esos silos.
Por lo tanto, el mejor enfoque es que los proveedores de infraestructura en la nube deberían abogar por un uso adecuado de las máquinas virtuales y LXC, ya que cada uno es adecuado para manejar cargas de trabajo y escenarios específicos.
Abandonar máquinas virtuales no es práctico a partir de ahora. Así que tanto las máquinas virtuales como los LXC tienen su propia existencia e importancia individual.
Ambos son muy diferentes. Docker es liviano y usa LXC / libcontainer (que se basa en el espacio de nombres del kernel y cgroups) y no tiene emulación de máquina / hardware como el hipervisor, KVM. Los xen que son pesados.
Docker y LXC están diseñados para el uso de espacios aislados, la contenedorización y el aislamiento de recursos. Utiliza la API de clonación del sistema operativo host (actualmente solo kernel de Linux) que proporciona espacios de nombres para IPC, NS (montaje), red, PID, UTS, etc.
¿Qué pasa con la memoria, E / S, CPU, etc.? Esto se controla mediante cgroups donde puede crear grupos con cierta especificación / restricción de recursos (CPU, memoria, etc.) y colocar sus procesos allí. Además de LXC, Docker proporciona un backend de almacenamiento ( http://www.projectatomic.io/docs/filesystems/ ), por ejemplo, un sistema de archivos de montaje de unión donde puede agregar capas y compartir capas entre diferentes espacios de nombres de montaje.
Esta es una característica poderosa donde las imágenes base son típicamente de solo lectura y solo cuando el contenedor modifica algo en la capa escribirá algo en la partición de lectura-escritura (también conocido como copia en escritura). También proporciona muchos otros envoltorios, como el registro y el control de versiones de las imágenes.
Con el LXC normal, debe venir con algunos rootfs o compartir los rootfs y cuando se comparte, y los cambios se reflejan en otros contenedores. Debido a muchas de estas características agregadas, Docker es más popular que LXC. LXC es popular en entornos integrados para implementar la seguridad en procesos expuestos a entidades externas como la red y la interfaz de usuario. Docker es popular en entornos de múltiples tenencias en la nube donde se espera un entorno de producción consistente.
Una VM normal (por ejemplo, VirtualBox y VMware) utiliza un hipervisor, y las tecnologías relacionadas tienen un firmware dedicado que se convierte en la primera capa para el primer sistema operativo (sistema operativo host o sistema operativo invitado 0) o un software que se ejecuta en el sistema operativo host para proporcionar emulación de hardware como CPU, USB / accesorios, memoria, red, etc., a los sistemas operativos invitados. Las máquinas virtuales siguen siendo populares (a partir de 2015) en un entorno multiusuario de alta seguridad.
Docker / LXC casi se puede ejecutar en cualquier hardware barato (menos de 1 GB de memoria también está bien, siempre y cuando tenga un kernel más nuevo) en comparación con las máquinas virtuales normales, se necesitan al menos 2 GB de memoria, etc., para hacer algo significativo. . Pero el soporte de Docker en el sistema operativo host no está disponible en sistemas operativos como Windows (a partir de noviembre de 2014), donde pueden ejecutarse tipos de máquinas virtuales en Windows, Linux y Mac.
Buenas respuestas Solo para obtener una representación de imagen de contenedor vs VM, eche un vistazo a la siguiente.
Docker encapsula una aplicación con todas sus dependencias.
Un virtualizador encapsula un sistema operativo que puede ejecutar cualquier aplicación que normalmente puede ejecutar en una máquina completa.
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 eso, Docker inicialmente estaba usando el controlador LXC, luego se movió a libcontainer, que ahora se renombra como 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 del sistema están diseñados para ejecutar múltiples procesos, como máquinas virtuales. Por lo tanto, Docker se considera una herramienta de administración de contenedores o de implementación de aplicaciones en sistemas en contenedores.
Para saber en qué se diferencia de otras virtualizaciones, pasemos por la virtualización y sus tipos. Entonces, sería más fácil entender cuál es la diferencia allí.
Virtualización
En su forma concebida, se consideró un método para dividir lógicamente los mainframes para permitir que múltiples aplicaciones se ejecuten simultáneamente. 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 se ejecuten múltiples sistemas operativos simultáneamente en un solo sistema basado en x86.
Hipervisor
El hipervisor maneja la creación del 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 invitados según sea necesario. El hipervisor se encuentra 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 invitado en las máquinas virtuales y emula la operación en el sistema operativo de la máquina host.
El rápido desarrollo de las tecnologías de virtualización, principalmente en la nube, ha impulsado el uso de la virtualización al permitir la creación de múltiples servidores virtuales en un único servidor físico con la ayuda de hipervisores, como Xen, VMware Player, KVM, etc., y 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 se puede categorizar en función de cómo imita el hardware a un sistema operativo invitado y emula el entorno operativo invitado. Principalmente, hay tres tipos de virtualización:
- Emulación
- Paravirtualización
- Virtualización basada en contenedores
Emulación
La emulación, también conocida como virtualización completa, ejecuta el kernel del sistema operativo 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 host, que es responsable de traducir el código del kernel del sistema operativo invitado a las instrucciones del software. La traducción se realiza íntegramente en software y no requiere participación de hardware. La emulación hace posible ejecutar cualquier sistema operativo no modificado que admita el entorno que se está emulando. La desventaja de este tipo de virtualización es la sobrecarga adicional de recursos del sistema que lleva a una disminución en el rendimiento en comparación con otros tipos de virtualizaciones.
Los ejemplos en esta categoría incluyen VMware Player, VirtualBox, QEMU, Bochs, Parallels, etc.
Paravirtualización
La paravirtualización, también conocida como hipervisor de Tipo 1, se ejecuta directamente en el hardware, o "sin 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 recursos extensos.
Los ejemplos en esta categoría incluyen Xen, KVM, etc.
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 kernel de sistema operativo. Tiene el mejor rendimiento y densidad posibles y cuenta con una gestión dinámica de recursos. El entorno de ejecución virtual aislado proporcionado por este tipo de virtualización se denomina contenedor y puede verse como un grupo de procesos rastreados.
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 del sistema. Se accede mediante la llamada al sistema clone () que permite crear instancias separadas de espacios de nombres previamente globales.
Los espacios de nombres se pueden usar de muchas maneras diferentes, pero el enfoque más común es crear un contenedor aislado que no tenga visibilidad o acceso a objetos fuera del contenedor. Los procesos que se ejecutan dentro del contenedor parecen estar ejecutándose en un sistema Linux normal, aunque comparten el kernel subyacente con procesos ubicados en otros espacios de nombres, lo mismo para otros tipos de objetos. Por ejemplo, cuando se usan espacios de nombres, el usuario root dentro del contenedor no se trata como root fuera del contenedor, lo que agrega seguridad adicional.
El subsistema Grupos de control de Linux (cgroups), el siguiente componente principal para habilitar la virtualización basada en contenedores, se utiliza para agrupar procesos y administrar su consumo agregado de recursos. Se usa comúnmente para limitar el consumo de memoria y CPU de los contenedores. Dado que un sistema Linux en contenedor tiene solo un kernel y el kernel tiene visibilidad completa en los contenedores, solo hay un nivel de asignación y programación de recursos.
Varias herramientas de administración están disponibles para los contenedores de Linux, incluidos 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 iniciar el núcleo del sistema operativo, por lo que los contenedores se pueden crear en menos de un segundo. Esta característica hace que la virtualización basada en contenedores sea única y deseable que otros enfoques de virtualización.
Dado que la virtualización basada en contenedores agrega poca o ninguna sobrecarga a la máquina host, la virtualización basada en contenedores tiene un rendimiento casi nativo
Para la virtualización basada en contenedores, no se requiere software adicional, a diferencia de otras virtualizaciones.
Todos los contenedores en una máquina host comparten el programador de la máquina host, lo que ahorra la necesidad de recursos adicionales.
Los estados de los contenedores (imágenes Docker o LXC) son pequeños en comparación con las imágenes de 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 realiza a través de cgroups. Cgroups no permite que los contenedores consuman más recursos que los asignados a ellos. Sin embargo, a partir de ahora, todos los recursos de la máquina host están visibles en las máquinas virtuales, pero no se pueden usar. Esto se puede realizar ejecutando top
o htop
en contenedores y la máquina host al mismo tiempo. La salida en todos los entornos se verá similar.
Actualizar:
¿Cómo ejecuta Docker los contenedores en sistemas que no son Linux?
Si los contenedores son posibles debido a las características disponibles en el kernel de Linux, entonces la pregunta obvia es cómo los sistemas que no son Linux ejecutan los contenedores. Tanto Docker para Mac como Windows usan máquinas virtuales de Linux para ejecutar los contenedores. Docker Toolbox se utiliza para ejecutar contenedores en máquinas virtuales de Virtual Box. Pero, el último Docker utiliza Hyper-V en Windows y Hypervisor.framework en Mac.
Ahora, permítanme describir cómo Docker para Mac ejecuta los contenedores en detalle.
Docker para Mac usa https://github.com/moby/hyperkit para emular las capacidades del hipervisor y 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 nombrar la red y el sistema de archivos, respectivamente.
La máquina virtual de Linux que Docker ejecuta en Mac es de solo lectura. Sin embargo, puedes golpearlo ejecutando:
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
.
Ahora, incluso podemos verificar la versión de Kernel de esta máquina virtual:
# uname -a Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux
.
Todos los contenedores se ejecutan dentro de esta máquina virtual.
Hay 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 en Windows. También están tratando de aprovechar las capacidades de Windows 10 para ejecutar sistemas Linux de forma nativa.
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 recursos del sistema operativo host. Además, utiliza un sistema de archivos en capas ( AuFS ) y administra la red.
AuFS es un sistema de archivos en capas, por lo que puede tener una parte de solo lectura y una parte de escritura que se fusionan. Uno podría tener las partes comunes del sistema operativo como solo lectura (y compartirlas entre todos sus contenedores) y luego dar a cada contenedor su propio soporte para escribir.
Entonces, digamos que tienes una imagen de contenedor de 1 GB; Si desea utilizar una máquina virtual completa, deberá tener 1 GB por x número de máquinas virtuales que desee. Con Docker y AuFS, puede compartir la mayor parte de los 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 los contenedores (asumiendo que todos ejecutan la misma imagen de sistema operativo) .
Un sistema virtualizado completo obtiene su propio conjunto de recursos asignados y hace un intercambio mínimo. Obtienes más aislamiento, pero es mucho más pesado (requiere más recursos). Con Docker usted obtiene menos aislamiento, pero los contenedores son livianos (requieren menos recursos). Por lo tanto, puede ejecutar fácilmente miles de contenedores en un host, y ni siquiera parpadeará. Intenta hacer eso con Xen, y a menos que tengas un gran anfitrión, no creo que sea posible.
Un sistema virtualizado completo suele tardar unos minutos en iniciarse, mientras que los contenedores Docker / LXC / runC tardan unos segundos y, a menudo, incluso menos de un segundo.
Hay ventajas y desventajas para cada tipo de sistema virtualizado. Si desea un aislamiento completo con recursos garantizados, una máquina virtual completa es el camino a seguir. Si solo desea aislar procesos entre sí y desea ejecutar una tonelada de ellos en un host de tamaño razonable, entonces Docker / LXC / runC parece ser el camino a seguir.
Para obtener más información, consulte este conjunto de publicaciones de blog que explican cómo funciona el LXC.
¿Por qué es más fácil implementar software en una imagen acoplable (si ese es el término correcto) que simplemente implementarlo en 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 los hosts y los entornos.
Docker le ofrece la posibilidad de hacer una instantánea del sistema operativo en una imagen compartida, y facilita la implementación en otros hosts de Docker. Localmente, dev, qa, prod, etc .: todas las mismas imágenes. Seguro que puedes hacer esto con otras herramientas, pero no tan fácil o rápido.
Esto es genial para la prueba; digamos 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 hará cambios en los datos. El enfoque clásico de esto es restablecer la base de datos después de cada prueba, ya sea con un código personalizado o con herramientas como Flyway ; esto puede llevar mucho tiempo y significa que las pruebas se deben ejecutar en serie. Sin embargo, con Docker puede 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 contra 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 hacer eso con una máquina virtual completa.
De los comentarios ...
¡Interesante! Supongo que todavía estoy confundido por la noción de "snapshot [ting] the OS". ¿Cómo se puede hacer eso sin, bueno, hacer una imagen del sistema operativo?
Bueno, vamos a ver si puedo explicar. Empieza con una imagen base, luego realiza los cambios y confirma esos cambios utilizando la ventana acoplable, y crea una imagen. Esta imagen contiene solo las diferencias de la base. Cuando desea ejecutar su imagen, también necesita la base, y esta coloca su imagen en la parte superior de la base mediante un sistema de archivos en capas: como se mencionó anteriormente, Docker usa AUFS. AUFS fusiona las diferentes capas y obtienes lo que quieres; solo necesitas ejecutarlo. Puede seguir agregando más y más imágenes (capas) y seguirá guardando solo las diferencias. Dado que Docker generalmente se basa en imágenes preparadas de un registry , rara vez tiene que hacer una instantánea de todo el sistema operativo.
La mayoría de las respuestas aquí hablan de máquinas virtuales. Le daré una respuesta de una sola línea a esta pregunta que me ha ayudado más durante los últimos dos años de uso de Docker. Es esto:
Docker es solo una forma elegante de ejecutar un proceso, no una máquina virtual.
Ahora, déjame explicarte un poco más sobre lo que eso significa. Las máquinas virtuales son su propia bestia. Siento que explicar qué es Docker lo ayudará a comprender esto más que a explicar qué es una máquina virtual. Especialmente porque hay muchas respuestas finas aquí que le dicen exactamente lo que alguien quiere decir cuando dicen "máquina virtual". Asi que...
Un contenedor de Docker es solo un proceso (y sus elementos secundarios) que se cgroups en compartimientos utilizando cgroups dentro del núcleo del sistema host del resto de los procesos. Puede ver sus procesos de contenedor Docker ejecutando ps aux
en el host. Por ejemplo, al iniciar apache2
"en un contenedor" solo se inicia apache2
como un proceso especial en el host. Simplemente se ha compartimentado de otros procesos en la máquina. Es importante tener en cuenta que sus contenedores no existen fuera de la vida útil de su proceso en contenedores. Cuando su proceso muere, su contenedor muere. Esto se debe a que Docker reemplaza pid 1
dentro de su contenedor con su aplicación ( pid 1
es normalmente el sistema init). Este último punto sobre pid 1
es muy importante.
En cuanto al sistema de archivos utilizado por cada uno de esos procesos de contenedor, Docker utiliza imágenes respaldadas por UnionFS , que es lo que está descargando cuando hace un docker pull ubuntu
. Cada "imagen" es solo una serie de capas y metadatos relacionados. El concepto de capas es muy importante aquí. Cada capa es solo un cambio de la capa debajo de ella. Por ejemplo, cuando borra un archivo en su Dockerfile mientras construye un contenedor Docker, en realidad está creando una capa en la parte superior de la última capa que dice "este archivo ha sido eliminado". Por cierto, esta es la razón por la que puede eliminar un archivo grande de su sistema de archivos, pero la imagen sigue ocupando la misma cantidad de espacio en el disco. El archivo todavía está allí, en las capas debajo de la actual. Las capas en sí son sólo archivos de archivos. Puede probar esto con la docker save --output /tmp/ubuntu.tar ubuntu
y luego cd /tmp && tar xvf ubuntu.tar
. Entonces puedes echar un vistazo alrededor. Todos esos directorios que parecen hashes largos son en realidad las capas individuales. Cada uno contiene archivos ( layer.tar
) y metadatos ( json
) con información sobre esa capa en particular. Esas capas simplemente describen cambios en el sistema de archivos que se guardan como una capa "sobre" su estado original. Cuando se leen los datos "actuales", el sistema de archivos lee los datos como si solo estuviera mirando las capas más altas de cambios. Es por eso que el archivo parece ser eliminado, a pesar de que todavía existe en las capas "anteriores", porque el sistema de archivos solo está mirando las capas más altas. Esto permite que los contenedores completamente diferentes compartan sus capas del sistema de archivos, a pesar de que pueden haber ocurrido cambios significativos en el sistema de archivos en las capas más altas de cada contenedor. Esto puede ahorrarle una tonelada de espacio en disco, cuando sus contenedores comparten sus capas de imagen base. Sin embargo, cuando monta directorios y archivos del sistema host en su contenedor mediante volúmenes, esos volúmenes "omiten" el UnionFS, por lo que los cambios no se almacenan en capas.
La red en Docker se logra mediante el uso de un puente Ethernet (denominado docker0
en el host) y las interfaces virtuales para cada contenedor en el host. Crea una subred virtual en docker0
para que sus contenedores se comuniquen "entre". Aquí hay muchas opciones para la creación de redes, incluida la creación de subredes personalizadas para sus contenedores y la capacidad de "compartir" la pila de redes de su host para que su contenedor pueda acceder directamente.
Docker se está moviendo muy rápido. Su documentación es una de las mejores que he visto. Generalmente está bien escrito, es conciso y preciso. Le recomiendo consultar la documentación disponible para obtener más información y confiar en la documentación sobre cualquier otra cosa que lea en línea, incluido el desbordamiento de pila. Si tiene preguntas específicas, le recomiendo que se una a #docker
en Freenode IRC y pregunte allí (¡incluso puede usar el webchat de Freenode para eso!).
Me gusta la respuesta de Ken Cochrane.
Pero quiero agregar un punto de vista adicional, no cubierto en detalle aquí. En mi opinión Docker se diferencia también en todo el proceso. A diferencia de las máquinas virtuales, Docker no (solo) trata de compartir recursos de hardware de manera óptima, sino que también proporciona un "sistema" para la aplicación de empaquetado (preferible, pero no un deber, 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 ops como Puppet , VMware, Xen, lo que sea ...
¿Por qué es más fácil implementar software en una imagen acoplable (si ese es el término correcto) que simplemente implementarlo en un entorno de producción consistente?
Su pregunta asume 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 no publicadas y / o gran cantidad de documentación ... En teoría, los servidores pueden ejecutarse de forma indefinida y se mantienen completamente consistentes y actualizados. La práctica no logra administrar la configuración de un servidor por completo, por lo que hay un margen considerable para el cambio de configuración y cambios inesperados en los servidores en ejecución.
Así que hay un patrón conocido para evitar esto, el llamado servidor inmutable . Pero el patrón de servidor inmutable no fue amado. Sobre todo debido a las limitaciones de las máquinas virtuales que se utilizaron antes de Docker. Tratar con varias imágenes grandes de gigabytes, mover esas imágenes grandes para cambiar algunos campos de la aplicación, fue muy laborioso. Comprensible...
Con un ecosistema de Docker, nunca tendrá que mover gigabytes en "pequeños cambios" (gracias aufs y Registry) y no tendrá que preocuparse por perder rendimiento al empaquetar aplicaciones en un contenedor de Docker en tiempo de ejecución. No tienes que preocuparte por las versiones de esa imagen.
Y, finalmente, incluso podrá reproducir entornos de producción complejos incluso en su computadora portátil Linux (no me llame si no funciona en su caso;))
Y, por supuesto, puede iniciar los contenedores Docker en máquinas virtuales (es una buena idea). Reduzca el aprovisionamiento de su servidor en el nivel de VM. Todo lo anterior podría ser gestionado por Docker.
PS Mientras tanto, Docker usa su propia implementación "libcontainer" en lugar de LXC. Pero LXC todavía es utilizable.
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 la descripción a continuación. Ver referencias para más información.
¿Cómo funciona la virtualización a bajo nivel?
En este caso, VM Manager toma el anillo de la 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 manera de hacer este tipo de intercepción. La gente de VMWare fue la primera que tuvo la idea de volver a escribir los bytes ejecutables en la memoria para las llamadas privilegiadas del sistema operativo huésped para lograr esto.
El efecto neto es que la virtualización le permite ejecutar dos sistemas operativos completamente diferentes en el mismo hardware. Cada sistema operativo invitado pasa por todo el proceso de arranque, carga del kernel, etc. Puede tener una seguridad muy estricta, por ejemplo, el sistema operativo invitado no puede tener acceso completo al sistema operativo host u otros invitados y desordenar 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 kernel llamada espacios de nombres (sin embargo, la idea long existía long antes en FreeBSD ). Una función del sistema operativo es permitir compartir recursos globales como la red y el disco a los procesos. ¿Qué pasaría si estos recursos globales se envolvieran en espacios de nombres para que fueran visibles solo para los procesos que se ejecutan en el mismo espacio de nombres? Por ejemplo, puede obtener una porción del 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. De manera similar, los procesos en el espacio de nombres X no pueden acceder a nada en la memoria que esté asignado al espacio de nombres Y. Por supuesto, los procesos en X no pueden ver o 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 la ventana acoplable: cada contenedor se ejecuta en su propio espacio de nombres, pero utiliza 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 vs VM deberían ser obvias ahora: no puede ejecutar sistemas operativos completamente diferentes en contenedores como en las máquinas virtuales. Sin embargo, puede ejecutar diferentes distribuciones de Linux porque comparten el mismo kernel. El nivel de aislamiento no es tan fuerte como en VM. De hecho, había una forma para que el contenedor "invitado" se hiciera cargo del host en las implementaciones tempranas. También puede ver que cuando carga un contenedor nuevo, la nueva copia completa del sistema operativo no se inicia como lo hace en la VM. Todos los contenedores comparten el mismo núcleo . Por eso los contenedores son ligeros. Además, a diferencia de la máquina virtual, no tiene que asignar previamente una parte significativa de la memoria a los contenedores porque no estamos ejecutando una nueva copia del sistema operativo. Esto permite ejecutar miles de contenedores en un sistema operativo al tiempo que los almacena, lo que no sería posible hacer si estuviéramos ejecutando una copia separada del sistema operativo en su propia máquina virtual.
Aquí hay muchas respuestas técnicas que discuten claramente las diferencias entre las máquinas virtuales y los contenedores, así como los orígenes de Docker.
Para mí, la diferencia fundamental entre las máquinas virtuales y Docker es cómo gestiona la promoción de su aplicación.
Con las máquinas virtuales usted promueve su aplicación y sus dependencias de una máquina virtual a la siguiente DEV a la UAT al PRD.
- A menudo, estas máquinas virtuales tendrán diferentes parches y bibliotecas.
- No es raro que varias aplicaciones compartan una máquina virtual. Esto requiere gestionar la configuración y las dependencias para todas las aplicaciones.
- El retroceso requiere deshacer los cambios en la máquina virtual. O restaurarlo si es posible.
Con Docker, la idea es que usted agrupe su aplicación dentro de su propio contenedor junto con las bibliotecas que necesita y luego promueva todo el contenedor como una sola unidad.
- Excepto por el núcleo, los parches y las bibliotecas son idénticos.
- Como regla general, solo hay una aplicación por contenedor que simplifica la configuración.
- El retroceso consiste en detener y eliminar el contenedor.
Entonces, en el nivel más fundamental con las máquinas virtuales, usted promueve la aplicación y sus dependencias como componentes discretos, mientras que con Docker usted promueve todo de una vez.
Y sí, hay problemas con los contenedores que incluyen su gestión, aunque herramientas como Kubernetes o Docker Swarm simplifican enormemente la tarea.
En relación a:-
"¿Por qué es más fácil implementar el software en una imagen acoplable que simplemente implementarlo en un entorno de producción consistente?"
La mayoría del software se implementa en muchos entornos, generalmente un mínimo de tres de los siguientes:
- Desarrollador individual PC (s)
- Entorno de desarrollador compartido
- Probador individual PC (s)
- Entorno de prueba compartido
- Ambiente de control de calidad
- Entorno UAT
- Pruebas de carga / rendimiento
- Puesta en escena en vivo
- Producción
- Archivo
También hay que considerar los siguientes factores:
- Los desarrolladores, y de hecho los probadores, tendrán configuraciones de PC sutilmente o muy diferentes, por la naturaleza del trabajo
- Los desarrolladores a menudo pueden desarrollar en PC más allá del control de las reglas de estandarización corporativas o de negocios (por ejemplo, profesionales independientes que se desarrollan en sus propias máquinas (a menudo de forma remota) o contribuyentes a proyectos de código abierto que no son "empleados" o "contratados" para configurar sus PC de una manera determinada. camino)
- Algunos entornos consistirán en un número fijo de máquinas múltiples en una configuración de carga equilibrada
- Muchos entornos de producción tendrán servidores basados en la nube de forma dinámica (o "elástica") creados y destruidos según los niveles de tráfico
Como puede ver, la cantidad total de servidores extrapolados para una organización rara vez se presenta en cifras únicas, muy a menudo en cifras triples y fácilmente puede ser significativamente mayor.
Todo esto significa que, en primer lugar, crear entornos consistentes es lo suficientemente difícil solo por su gran volumen (incluso en un escenario de campo verde), pero mantenerlos consistentes es casi imposible dado el alto número de servidores, la adición de nuevos servidores (dinámicamente o manualmente), actualizaciones automáticas de los proveedores de software, vendedores de antivirus, proveedores de navegadores y similares, instalaciones de software manuales o cambios de configuración realizados por desarrolladores o técnicos de servidores, etc. Permítanme repetirlo: es prácticamente imposible (sin intencionalidad) para mantener los entornos consistentes (bueno, para los puristas, se puede hacer, pero implica una gran cantidad de tiempo, esfuerzo y disciplina, que es precisamente la razón por la que se diseñaron máquinas virtuales y contenedores (por ejemplo, Docker) en primer lugar).
Entonces piense en su pregunta más como esto: "Dada la extrema dificultad de mantener todos los entornos consistentes, ¿es más fácil implementar software en una imagen acoplable, incluso cuando se tiene en cuenta la curva de aprendizaje? . Creo que encontrará que la respuesta será invariablemente "sí", pero solo hay una forma de averiguarlo: publique esta nueva pregunta en .
Existen tres configuraciones diferentes que proporcionan una pila para ejecutar una aplicación (esto nos ayudará a reconocer qué es un contenedor y qué lo hace tan poderoso como otras soluciones):
1) Traditional Servers(bare metal)
2) Virtual machines (VMs)
3) Containers
1) La pila de servidores tradicional consiste en un servidor físico que ejecuta un sistema operativo y su aplicación.
Ventajas:
Utilización de recursos brutos.
Aislamiento
Desventajas:
- Tiempo de despliegue muy lento
- Costoso
- Recursos desperdiciados
- Difícil de escalar
- Difícil de migrar
- Configuración compleja
2) La pila de VM consta de un servidor físico que ejecuta un sistema operativo y un hipervisor que administra su máquina virtual, recursos compartidos e interfaz de red. Cada Vm ejecuta un sistema operativo invitado, una aplicación o conjunto de aplicaciones.
Ventajas:
- Buen uso de los recursos.
- Fácil de escalar
- Fácil de hacer copias de seguridad y migrar
- Eficiencia de costo
- Flexibilidad
Desventajas:
- La asignación de recursos es problemática
- Dependencia de un proveedor
- Configuración compleja
3) La configuración del contenedor , la diferencia clave con otra pila es que la virtualización basada en el contenedor utiliza el núcleo del sistema operativo host para dividir varias instancias de invitado aisladas. Estas instancias invitadas son llamadas como contenedores. El host puede ser un servidor físico o VM.
Ventajas:
- Aislamiento
- Ligero
- Recurso efectivo
- Fácil de migrar
- Seguridad
- Gastos indirectos bajos
- Espejo de producción y entorno de desarrollo.
Desventajas:
- Misma arquitectura
- Aplicaciones pesadas de recursos
- Problemas de redes y seguridad.
Al comparar la configuración del contenedor con sus predecesores, podemos concluir que la contenedorización es la configuración más rápida, más eficaz en cuanto a recursos y más segura que conocemos hasta la fecha. Los contenedores son instancias aisladas que ejecutan su aplicación. Docker gira el contenedor de una manera, las capas obtienen la memoria en tiempo de ejecución con los controladores de almacenamiento predeterminados (controladores de superposición) que se ejecutan en segundos y se crea una capa de copia en escritura una vez que ingresamos en el contenedor, que permite la ejecución contenedoresEn el caso de máquinas virtuales, tomará alrededor de un minuto cargar todo en el entorno de virtualización. Estas instancias ligeras se pueden reemplazar, reconstruir y mover fácilmente. Esto nos permite reflejar el entorno de producción y desarrollo y es una gran ayuda en los procesos de CI / CD. Las ventajas que pueden proporcionar los contenedores son tan convincentes que definitivamente están aquí para quedarse.
Hay muchas respuestas que explican más detalladamente las diferencias, pero aquí está mi explicación muy breve.
Una diferencia importante es que las máquinas virtuales utilizan un kernel separado para ejecutar el sistema operativo . Esa es la razón por la que es pesado y toma tiempo para arrancar, ya que consume más recursos del sistema.
En Docker, los contenedores comparten el kernel con el host; Por lo tanto, es ligero y puede iniciar y detener rápidamente.
En la virtualización, los recursos se asignan al principio de la configuración y, por lo tanto, los recursos no se utilizan completamente cuando la máquina virtual está inactiva durante muchas de las veces. En Docker, los contenedores no se asignan con una cantidad fija de recursos de hardware y es libre de usar los recursos según los requisitos y, por lo tanto, es altamente escalable.
Docker utiliza el sistema de archivos UNION . Docker utiliza una tecnología de copia en escritura para reducir el espacio de memoria que consumen los contenedores. Leer más aquí
Fuente: Kubernetes en Acción.
Así es como Docker se presenta:
Docker es la compañía que impulsa el movimiento de contenedores y el único proveedor de plataformas de contenedores para abordar cada aplicación en la nube híbrida. Los negocios de hoy están bajo presión para transformarse digitalmente, pero están limitados por las aplicaciones e infraestructura existentes al mismo tiempo que racionalizan una cartera cada vez más diversa de nubes, centros de datos y arquitecturas de aplicaciones. Docker permite una verdadera independencia entre las aplicaciones y la infraestructura, y los desarrolladores y las operaciones de TI para desbloquear su potencial y crean un modelo para una mejor colaboración e innovación.
Así que Docker se basa en contenedores, lo que significa que tiene imágenes y contenedores que se pueden ejecutar en su máquina actual. No incluye el sistema operativo como VM s, sino como un paquete de diferentes paquetes de trabajo como Java, Tomcat, etc.
Si entiendes los contenedores, obtienes lo que es Docker y en qué se diferencia de VM s ...
Entonces, ¿qué es un contenedor?
Una imagen de contenedor es un paquete ejecutable, ligero y autónomo de una pieza de software que incluye todo lo necesario para ejecutarlo: código, tiempo de ejecución, herramientas del sistema, bibliotecas del sistema, configuración. Disponible para aplicaciones basadas tanto en Linux como en Windows, el software en contenedor siempre se ejecutará de la misma manera, independientemente del entorno. Los contenedores aíslan el software de su entorno, por ejemplo, las diferencias entre los entornos de desarrollo y de preparación y ayudan a reducir los conflictos entre equipos que ejecutan software diferente en la misma infraestructura.
Entonces, como se ve en la imagen de abajo, cada contenedor tiene un paquete separado y se ejecuta en una sola máquina y comparte el sistema operativo de esa máquina ... Son seguros y fáciles de enviar ...
Con una máquina virtual , tenemos un servidor, tenemos un sistema operativo host en ese servidor y luego tenemos un hipervisor. Y luego, ejecutando sobre ese hipervisor, tenemos cualquier número de sistemas operativos invitados con una aplicación y sus binarios dependientes, y bibliotecas en ese servidor. Trae todo un sistema operativo invitado con él. Es bastante pesado. También hay un límite a la cantidad que realmente puede poner en cada máquina física.
Contenedores Docker por otro lado, son ligeramente diferentes. Tenemos el servidor. Tenemos el sistema operativo host. Pero en lugar de un hipervisor , tenemos el motor Docker , en este caso. En este caso, no traemos todo un sistema operativo invitado con nosotros. Estamos trayendo una capa muy delgada del sistema operativo , y el contenedor puede hablar del sistema operativo host para llegar a la funcionalidad del núcleo allí. Y eso nos permite tener un contenedor muy ligero.
Todo lo que tiene allí es el código de la aplicación y los binarios y bibliotecas que requiere. Y esos binarios y bibliotecas pueden compartirse en diferentes contenedores si así lo desean. Y lo que esto nos permite hacer, es una serie de cosas. Tienen un tiempo de inicio mucho más rápido . No puedes soportar una sola máquina virtual en unos segundos así. E igualmente, eliminarlos tan rápido ... para que podamos escalar hacia arriba y hacia abajo muy rápidamente y lo veremos más adelante.
Cada contenedor piensa que se está ejecutando en su propia copia del sistema operativo. Tiene su propio sistema de archivos, registro propio, etc., que es una especie de mentira. En realidad se está virtualizando.
Docker, básicamente contenedores, admite la virtualización del sistema operativo, es decir, su aplicación siente que tiene una instancia completa de un sistema operativo, mientras que VM admite la virtualización de hardware . Sientes que es una máquina física en la que puedes arrancar cualquier sistema operativo.
En Docker, los contenedores que se ejecutan comparten el núcleo del sistema operativo host, mientras que en las máquinas virtuales tienen sus propios archivos de sistema operativo. El entorno (el sistema operativo) en el que desarrolla una aplicación sería el mismo cuando lo implemente en varios entornos de servicio, como "pruebas" o "producción".
Por ejemplo, si desarrolla un servidor web que se ejecuta en el puerto 4000, cuando lo implementa en su entorno de "prueba", ese puerto ya está siendo utilizado por algún otro programa, por lo que deja de funcionar. En los contenedores hay capas; todos los cambios que haya realizado en el sistema operativo se guardarán en una o más capas y esas capas serían parte de la imagen, por lo que dondequiera que vaya la imagen, las dependencias también estarán presentes.
En el ejemplo que se muestra a continuación, la máquina host tiene tres máquinas virtuales. Para proporcionar el aislamiento completo de las aplicaciones en las máquinas virtuales, cada una tiene sus propias copias de los archivos del sistema operativo, las bibliotecas y el código de la aplicación, junto con una instancia en memoria completa de un sistema operativo.Mientras que la figura de abajo muestra el mismo escenario con contenedores. Aquí, los contenedores simplemente comparten el sistema operativo host, incluido el kernel y las bibliotecas, por lo que no necesitan iniciar un sistema operativo, cargar bibliotecas o pagar un costo de memoria privada por esos archivos. El único espacio incremental que ocupan es la memoria y el espacio en disco necesarios para que la aplicación se ejecute en el contenedor. Si bien el entorno de la aplicación se siente como un sistema operativo dedicado, la aplicación se despliega como lo haría en un host dedicado. La aplicación en contenedor se inicia en segundos y muchas más instancias de la aplicación pueden encajar en la máquina que en el caso de VM.
Fuente: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/
He utilizado Docker en entornos de producción y puesta en escena mucho. Cuando se acostumbre a él, lo encontrará muy poderoso para construir un contenedor múltiple y entornos aislados.
Docker se ha desarrollado en base a LXC (contenedor de Linux) y funciona perfectamente en muchas distribuciones de Linux, especialmente Ubuntu.
Los contenedores Docker son entornos aislados. Puede verlo cuando emita el top
comando en un contenedor de Docker que se ha creado a partir de una imagen de Docker.
Además, son muy ligeros y flexibles gracias a la configuración de dockerFile.
Por ejemplo, puede crear una imagen de Docker y configurar un DockerFile y decirle que, por ejemplo, cuando se está ejecutando, entonces "wget" this ", apt-get" that ", ejecuta" algunas secuencias de comandos de shell ", configurando variables de entorno, etc.
En proyectos y arquitectura de microservicios, Docker es un activo muy viable. Puedes lograr escalabilidad, resistencia y elasticidad con Docker, Docker Swarm, Kubernetes y Docker Compose.
Otro tema importante con respecto a Docker es Docker Hub y su comunidad. Por ejemplo, implementé un ecosistema para monitorear kafka utilizando Prometheus, Grafana, Prometheus-JMX-Exporter y Dokcer.
Por eso descargué los contenedores Docker configurados para Zookeeper, Kafka, Prometheus, Grafana y jmx-collector, luego monté mi propia configuración para algunos de ellos usando archivos yml o para otros cambié algunos archivos y configuraciones en el contenedor Docker y construí un conjunto sistema para monitorear kafka utilizando Dockers de múltiples contenedores en una sola máquina con aislamiento, escalabilidad y resistencia, esta arquitectura se puede mover fácilmente a múltiples servidores.
Además del sitio de Docker Hub, hay otro sitio llamado quay.io que puede usar para tener su propio panel de control de imágenes de Docker allí y jalar / empujar hacia / desde él. Incluso puede importar imágenes de Docker desde Docker Hub al muelle y luego ejecutarlas desde el muelle en su propia máquina.
Nota: Aprender Docker en primer lugar parece complejo y difícil, pero cuando te acostumbras a él, entonces no puedes trabajar sin él.
Recuerdo los primeros días de trabajar con Docker cuando emití los comandos incorrectos o eliminé mis contenedores y todos los datos y configuraciones por error.