JavaRush /Blog Java /Random-ES /Primer contacto con Docker
Viacheslav
Nivel 3

Primer contacto con Docker

Publicado en el grupo Random-ES
La contenedorización es un mecanismo que se utiliza a menudo en la práctica. Por ejemplo, cuando busca en headhunter, encontrará 477 vacantes a día de hoy que mencionan Docker. Por tanto, no sería mala idea familiarizarse con lo que es. Espero que esta breve reseña ayude a formarse una primera idea. Bueno, lo respaldará con materiales adicionales, como cursos en Udemy. Primera introducción a Docker - 1

Introducción

En esta breve reseña me gustaría tocar un tema como la contenedorización. Y es necesario empezar por comprender qué es realmente la contenedorización. Según Wikipedia, la " contenedorización " es la virtualización a nivel del sistema operativo (es decir, NO de hardware) en la que el núcleo del sistema operativo mantiene múltiples instancias aisladas de espacio de usuario en lugar de solo una. El " espacio de usuario " es el espacio de direcciones de memoria virtual del sistema operativo reservado para los programas de usuario. Las instancias de espacio de usuario (comúnmente llamadas contenedores) son completamente idénticas a una única instancia de sistema operativo desde el punto de vista del usuario. El kernel garantiza un aislamiento completo del contenedor, por lo que los programas de diferentes contenedores no pueden afectarse entre sí. Resulta que la contenedorización es virtualización de software, es decir, virtualización a nivel del sistema operativo, de la cual es responsable el núcleo del sistema operativo. Uno de los rasgos característicos de este enfoque es que todos los contenedores utilizan un kernel común, el mismo que el sistema operativo anfitrión (es decir, aquel en el que se encuentran los contenedores). Esto le permite deshacerse de la sobrecarga de emular hardware virtual y ejecutar una instancia completa del sistema operativo. Podemos decir que se trata de una virtualización “ligera”. El kernel es la parte central del sistema operativo que proporciona a las aplicaciones acceso coordinado a los recursos de la computadora, como el tiempo del procesador, la memoria, el hardware externo y los dispositivos externos de entrada y salida. El kernel también suele proporcionar servicios de protocolo de red y sistema de archivos. En general, este es el corazón de todo el sistema. Para información adicional puede resultar útil revisar el material " Información general sobre contenedores ". Y unas palabras más para completar la introducción. Ahora entendemos que un sistema operativo tiene un núcleo. Proporciona aislamiento para instancias de espacio de usuario. En este contexto, es posible que se encuentre con el término " cgroups ". Este es el nombre del mecanismo del kernel de Linux que le permite lograr esto. Por tanto, podemos decir que el camino de la contenerización comenzó con los sistemas Linux. Sin embargo, a partir de Windows 10, también apareció la compatibilidad con la contenedorización. Para trabajar con virtualización, necesita configurar el soporte de virtualización en el BIOS de su computadora. Cómo hacer esto depende de la computadora. Por ejemplo, podría verse así:
Primera introducción a Docker - 2
En Windows puedes comprobar esto de diferentes maneras. Por ejemplo, puede descargar una utilidad especial del sitio web de Microsoft: Herramienta de detección de virtualización asistida por hardware . Bueno, vale la pena mencionar otro concepto importante: el hipervisor. Hypervisor es un monitor de máquina virtual, un programa para garantizar la ejecución paralela de varios sistemas operativos en la misma computadora. El hipervisor garantiza que los sistemas operativos estén aislados entre sí y comparta recursos entre los sistemas operativos en ejecución. Uno de esos hipervisores es Oracle VirtualBox .
Primera introducción a Docker - 3

Estibador

Entonces, qué es la virtualización está claro. ¿Pero cómo usarlo? Y aquí Docker viene en nuestra ayuda. Docker es un software para automatizar la implementación y gestión de aplicaciones en entornos en contenedores. Vale la pena comenzar con el hecho de que Docker está representado por un concepto como Docker Enginge. Y deberías comenzar con el sitio web oficial de Docker y la sección " Descripción general de Docker ".
Primera introducción a Docker - 4
La documentación dice que Docker consta de:
  • El servidor Docker se llama proceso Docker Daemon (dockerd).
  • Interfaz de línea de comando, también conocida como CLI (docker).
  • Una API REST que describe cómo los programas pueden "hablar" con el demonio y decirle qué hacer.
Antes de profundizar más, instalemos Docker, es decir, instalemos el demonio de Docker. El sitio web de Docker tiene instrucciones para instalar " Docker para Windows ". Curiosamente, Docker tiene sus propios requisitos de sistema. Y si usted, como yo, tiene un Windows antiguo, por ejemplo Windows 7, entonces necesita usar Docker Toolbox.
Primera introducción a Docker - 5

Caja de herramientas acoplable

Instalar Docker en máquinas antiguas que no cumplen con los requisitos del sistema. El sitio web lo dice: "Solución de escritorio heredada". Vayamos a la página " Docker Toolbox " y descárguela. Este conjunto pesa unos 211 megas. Lo instalaremos por defecto, es decir, simplemente aceptaremos dócilmente todo sin reorganizar las banderas. Tras la instalación comprobaremos que todo está bien. En el futuro, nuestro campo de batalla será la línea de mando. Recomiendo no utilizar la línea de comandos de Windows, porque puede haber problemas no obvios con ella. Es mejor usar bash shell. En Windows, la forma más recomendada de conseguirlo es instalar el sistema de control de versiones git , igual te resultará útil. Porque "incluido" estará el bash que necesitamos. Para esta revisión usaré git bash. También puedes instalar bash con CYGWIN . Iniciemos bash o git bash. Asegurémonos de tener instalada Docker Machine, también conocida como Docker Machine: ¿ docker-machine -version Qué es esta Docker Machine? Docker Machine es una utilidad para administrar hosts dockerizados (estos son hosts en los que está instalado Docker Engine). Si inmediatamente después de instalar Docket Toolbox vemos las máquinas acoplables usando el comando docker-machine ls, veremos una lista vacía:
Primera introducción a Docker - 6
Creemos una nueva máquina. Para hacer esto, necesitamos ejecutar el comando crear : docker-machine create -- driver virtualbox javarushVeremos el registro de creación de la máquina acoplable:
Primera introducción a Docker - 7
Lo que aquí nos interesa es lo siguiente. ¿Qué es Boot2Docker? Esta es una distribución de Linux minimalista para ejecutar Docker Engine (entendemos que Docker funciona gracias a las herramientas de virtualización de Linux, y en Windows el mecanismo necesario apareció solo a partir de Windows 10). Esta distribución está basada en la distribución " Tiny Core Linux ". También se mencionó sobre VirtualBox VM. Esto se debe a que especificamos --driver virtualbox. Se creó una nueva máquina virtual en VirtualBox a partir de la imagen de Boot2Docker. Después de la creación, podemos iniciar VirtualBox (ya que VirtualBox se instala con Docker Toolbox) y ver la máquina virtual creada para la máquina Docker:
Primera introducción a Docker-8
Después de la creación, se nos pedirá que ejecutemos el comando " docker-machine env " para obtener las variables de entorno que deben configurarse para conectarse a la máquina acoplable:
Primera introducción a Docker - 9
Después de ejecutar este comando usando docker-machine, nos conectamos a un host dockerizado remoto (en este caso, uno virtual alojado en Virtual Box) y podemos ejecutar comandos de docker localmente como si los estuviéramos ejecutando en un host remoto. Para comprobarlo, podemos ejecutar el comando " docker info ". Si no se establece la conexión con la máquina acoplable, recibiremos un error. Y si todo está bien, información sobre la ventana acoplable en la máquina acoplable. Ahora es el momento de comprender cómo funciona Docker en general y cómo utilizarlo.
Primera introducción a Docker - 10

Contenedores acoplables

Entonces tenemos Docker. ¿Qué es este acoplador de todos modos? La documentación de Docker y la sección " Comenzar " nos ayudarán a comprender esto . La parte introductoria de esta sección presenta Docker Concepts . Afirma que Docker es una plataforma para desarrollar, depurar y ejecutar aplicaciones en contenedores. Por tanto, lo principal para Docker son los contenedores. Incluso si miras el logo de Docker, es una ballena que sostiene contenedores en su espalda. Pero ¿qué es un contenedor? A continuación, en la sección " Imágenes y contenedores ", dice que un contenedor es una instancia en ejecución de Imagen. Y Image es un "paquete" que contiene todo lo necesario para la aplicación (código, entorno, bibliotecas, configuraciones, etc.). Ahora intentémoslo nosotros mismos. El sitio web de Docker tiene una sección llamada " Muestras de Docker " que incluye " Docker para principiantes ". Los ejemplos de aquí me parecen más interesantes. Entonces, de repente quisimos familiarizarnos con Alpine Linux y podemos hacerlo usando contenedores Docker. Para obtener una imagen, debemos "tirarla" o "sacarla". Por tanto, ejecutamos el comando docker pull :docker pull apline
Primera introducción a Docker-11
Como podemos ver, estamos descargando desde algún lugar. De forma predeterminada, Docker busca en su repositorio en la red https://hub.docker.com . Después de recuperar con éxito la imagen, podemos verificar la lista de imágenes disponibles ejecutando el comando Docker Images :
Primera introducción a Docker - 12
Ahora tenemos una imagen aplina. Dado que el contenedor es una instancia de imagen en ejecución, iniciemos esta misma imagen. Iniciemos el contenedor usando el comando docker run alpine. Como vemos, no pasó nada. Si ejecutamos el comando docker pspara mostrar todos los contenedores activos, tampoco obtendremos nada. Pero si ejecutamos, docker ps -averemos todos los contenedores:
Primer contacto con Docker - 13
El caso es que no iniciamos Docker en modo interactivo. Por lo tanto, ejecutó la orden y se detuvo. El comando era abrir la terminal. Hagamos lo mismo, pero en modo interactivo (con el indicador -it ):
Primera introducción a Docker - 14
Como puede ver, después de superar un error y usar la pista, ¡llegamos al contenedor y podemos trabajar en él! Para salir del contenedor sin detener su funcionamiento, puede presionar Ctrl + p + q. Si ejecutamos ahora docker ps, veremos un contenedor activo. Para ingresar a un contenedor que ya se está ejecutando, ejecute el comando docker exec :
Primer contacto con Docker - 15
Recomiendo leer la descripción del ejemplo de Docker para obtener una excelente descripción de cómo sucede todo esto: " 1.0 Ejecutando su primer contenedor ". Me gusta porque allí está todo escrito de forma muy accesible y comprensible. Para reformularlo brevemente, estamos conectados mediante Docker-machine a una máquina virtual que ejecuta Docker Daemon. Usando la CLI sobre la API REST, solicitamos iniciar la imagen alpina. Docker lo encuentra y por tanto no lo descarga. Docker crea un nuevo contenedor y ejecuta el comando que especificamos en este contenedor. Y todo esto, por supuesto, es bueno. Pero ¿por qué necesitamos todo esto? Y aquí tenemos que descubrir cómo Docker crea una imagen. Y los crea basándose en el archivo acoplable.
Primera introducción a Docker - 16

archivo acoplable

Como se indica en la referencia de Dockerfile , un dockerfile es un archivo de texto que contiene todos los comandos para obtener una imagen. De hecho, todas las imágenes que recibimos (incluso Alpine, del ejemplo anterior) se crearon a partir de un archivo acoplable. Construyamos nuestra imagen con una aplicación Java. Y primero necesitamos esta aplicación Java. Sugiero usar el sistema de compilación Gradle, sobre el cual puedes leer más en esta breve reseña: " Una breve introducción a Gradle ". Nos ayudará a crear el proyecto " Complemento de inicio de Gradle Build ". Creemos una nueva aplicación Java usando Gradle: gradle init --type java-application este comando crea una plantilla de proyecto Java. Esta es una aplicación independiente, pero nos gustaría crear una aplicación web. Eliminemos las clases App y AppTest (fueron generadas automáticamente por el complemento Gradle Build Init). Para crear rápidamente una aplicación web, usaremos el tutorial de Gradle: " Creación de aplicaciones web Java ". Según el tutorial, hagamos: Hay que tener cuidado aquí. Como siempre, puede haber errores en los ejemplos. Aquí lo tienes:
Primera introducción a Docker - 17
Ahora, para probarlo, agreguemos el complemento gretty a build.gradle, como se indica en la sección " Agregar el complemento gretty y ejecutar la aplicación ":
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
Es interesante que Gretty no ve el error HelloServletdescrito anteriormente. Esto demuestra que una aplicación puede comportarse de manera diferente en diferentes entornos. Gretty puede funcionar donde un servidor independiente normal arrojaría un error. Ya sólo queda comprobar que la aplicación funciona correctamente. Hagamos:gradle appRun
Primer contacto con Docker - 18
Si todo está bien, utilice el comando gradle warpara recopilar un archivo con la extensión war (archivo web). De forma predeterminada, gradle lo compila en formato \build\libs. Ahora estamos listos para escribir nuestro archivo acoplable. Usando la " referencia de Dockerfile " crearemos un Dockerfile. Creemos un archivo llamado "Dockerfile" en la raíz de nuestro proyecto Java (en el mismo lugar que el script de compilación). Abrámoslo para editarlo. Este archivo tiene su propio formato, que se describe en la sección " Referencia de Dockerfile: Formato ". Cualquier dockerfile comienza con una declaración FROM, que indica la "imagen base". Podemos decir que esta es la imagen principal a partir de la cual creamos nuestra imagen. Es muy fácil para nosotros elegir una imagen principal. Una aplicación web necesita un servidor web. Por ejemplo, podemos utilizar el servidor web Tomcat. Nos dirigimos al repositorio oficial de Docker, que se llama docker hub . Miramos allí para ver si la imagen que necesitamos está ahí:
Primer contacto con Docker - 19
También vale la pena entender que se llama la imagen de Tomcat. Pero además del nombre tiene una etiqueta. Una etiqueta es como una versión. Las imágenes de Tomcat de diferentes versiones difieren en qué versión de Tomcat se utiliza, qué versión de jre y qué imagen base. Por ejemplo, podemos obtener una imagen docker pull tomcat:9-jre8-alpine que utilice la versión 9 de tomcat, la versión 8 de jre y una imagen alpina como base. Esto puede ser importante para reducir el tamaño de nuestra imagen:
Primera introducción a Docker - 20
Como podemos ver, la diferencia es enorme. Si construimos nuestra imagen basada en Tomcata Alpine, comenzaremos con solo 100 megabytes y no con 600. En consecuencia, agregaremos el siguiente contenido al dockerfile creado previamente:
# Базовый образ, "наследуемся" от него
FROM tomcat:9-jre8-alpine
# Копируем из Build Context'а собранный web archive в каталог томката
COPY build/libs/docker.war /usr/local/tomcat/webapps/docker.war
# Меняем рабочий каталог на томкатовский
WORKDIR /usr/local/tomcat
# Открываем порт 8080 для контейнера, т.к. его слушает томкат
EXPOSE 8080
Y ahora ejecutemos el comando para construir la imagen: docker build -t jrdocker ..
Primer contacto con Docker - 21
-t- esta es una etiqueta, es decir, cómo llamar a la imagen ensamblada. El punto al final significa que agregamos el directorio actual (el directorio donde se encuentra el archivo docker y desde donde ejecutamos el comando) a Build context. Build context- este es el contexto de aquellos archivos que están disponibles al crear un archivo acoplable. Como puede ver, gracias a esto pudimos copiar el archivo war ensamblado en nuestra imagen, en el directorio del servidor web. Ahora ejecutemos nuestra imagen:docker run -d --rm -p 8888:8080 jrdocker
Primer contacto con Docker - 22
Para saber si el servidor se ha iniciado, puede consultar el registro del contenedor. El registro se puede obtener utilizando el comando docker logs, especificando el contenedor por su ID o nombre. Por ejemplo:
Primer contacto con Docker - 23
Bueno, no olvides que siempre podemos ir a un contenedor en ejecución por su nombre con el comando: winpty docker exec -it NombreКонтейнера sh Ahora solo queda conectarnos. Anteriormente, especificamos EXPOSE , es decir, permitimos el acceso al puerto 8080 desde el interior del contenedor. Cuando iniciamos el contenedor, especificamos la etiqueta -p ( puertos entrantes ), correlacionando así el puerto 8080 en el contenedor (el servidor web Tomcat). está esperando conexiones allí) con el puerto 8888 en una máquina con un demonio acoplable. Como recordamos, no lanzamos el demonio acoplable directamente, sino a través de la máquina acoplable. Por lo tanto, pidamos una vez más datos sobre nuestras máquinas acoplables usando el comando docker-machine ls y contactemos al servidor en el contenedor:
Primera introducción a Docker - 24
Por lo tanto, usted y yo acabamos de lanzar nuestra aplicación web en un contenedor Docker. ) También me gustaría señalar lo siguiente. En caso de problemas de acceso, conviene recordar que la máquina Docker es ante todo una máquina virtual Virtual BOx. Puede haber problemas con la configuración de red de la máquina virtual. Una configuración de VMBox que funcione podría verse así:
Primer contacto con Docker - 25
Primer contacto con Docker - 26

Capas

Ya hemos descubierto que las imágenes se crean a partir de archivos acoplables y que los archivos acoplables son un conjunto de comandos. También descubrimos que un dockerfile tiene un padre. Y que el tamaño de las imágenes es diferente. Curiosamente, puedes ver el historial de cómo se creó la imagen usando el comando Docker History . Por ejemplo:
Primer contacto con Docker - 27
Es importante decir esto para entender que, en esencia, cada imagen es un conjunto de imágenes. Cada cambio de imagen (cada nuevo comando en el archivo acoplable) crea una nueva capa que tiene su propia ID. Puede leer más sobre las capas en la documentación " Docker: Imágenes y capas ". También recomiendo leer el artículo sobre Habré: “ Imágenes y contenedores de Docker en imágenes ”.

Conclusión

Espero que esta breve descripción haya sido suficiente para que se interese en la contenedorización. A continuación encontrará enlaces a material adicional que puede resultar útil: #viacheslav
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION