March 17, 2024

Aprenda a crear e implementar sus aplicaciones distribuidas fácilmente en la nube con Docker-1

Logotipo de Docker para principiantes

Escrito y desarrollado por Prakhar Srivastav

INTRODUCCIÓN

¿Qué es Docker?

Wikipedia define Docker como

un proyecto de código abierto que automatiza la implementación de aplicaciones de software dentro de contenedores al proporcionar una capa adicional de abstracción y automatización de la virtualización a nivel del sistema operativo en Linux.

¡Guau! Eso es un bocado. En palabras más simples, Docker es una herramienta que permite a los desarrolladores, administradores de sistemas, etc. implementar fácilmente sus aplicaciones en un entorno limitado (llamado contenedores ) para ejecutarlas en el sistema operativo host, es decir, Linux. El beneficio clave de Docker es que permite a los usuarios empaquetar una aplicación con todas sus dependencias en una unidad estandarizada para el desarrollo de software. A diferencia de las máquinas virtuales, los contenedores no tienen una sobrecarga elevada y, por lo tanto, permiten un uso más eficiente del sistema y los recursos subyacentes.

¿Qué son los contenedores?

El estándar de la industria actual es utilizar máquinas virtuales (VM) para ejecutar aplicaciones de software. Las máquinas virtuales ejecutan aplicaciones dentro de un sistema operativo invitado, que se ejecuta en hardware virtual impulsado por el sistema operativo host del servidor.

Las máquinas virtuales son excelentes para proporcionar un aislamiento total del proceso de las aplicaciones: hay muy pocas formas en que un problema en el sistema operativo anfitrión pueda afectar el software que se ejecuta en el sistema operativo invitado, y viceversa. Pero este aislamiento tiene un gran costo: la sobrecarga computacional gastada en virtualizar el hardware para que lo utilice un sistema operativo invitado es sustancial.

Los contenedores adoptan un enfoque diferente: al aprovechar la mecánica de bajo nivel del sistema operativo host, los contenedores proporcionan la mayor parte del aislamiento de las máquinas virtuales con una fracción de la potencia informática.

¿Por qué utilizar contenedores?

Los contenedores ofrecen un mecanismo de empaquetado lógico en el que las aplicaciones pueden abstraerse del entorno en el que realmente se ejecutan. Este desacoplamiento permite implementar aplicaciones basadas en contenedores de manera fácil y consistente, independientemente de si el entorno de destino es un centro de datos privado, la nube pública o incluso la computadora portátil personal de un desarrollador. Esto brinda a los desarrolladores la capacidad de crear entornos predecibles que están aislados del resto de las aplicaciones y pueden ejecutarse en cualquier lugar.

Desde el punto de vista de las operaciones, además de la portabilidad, los contenedores también brindan un control más granular sobre los recursos, lo que brinda a su infraestructura una mayor eficiencia, lo que puede resultar en una mejor utilización de sus recursos informáticos.

Interés de Docker a lo largo del tiempo

Tendencias de Google para Docker

Debido a estos beneficios, los contenedores (y Docker) han experimentado una adopción generalizada. Empresas como Google, Facebook, Netflix y Salesforce aprovechan los contenedores para hacer que los grandes equipos de ingeniería sean más productivos y mejorar la utilización de los recursos informáticos. De hecho, Google le dio crédito a los contenedores por eliminar la necesidad de un centro de datos completo.

¿Qué me enseñará este tutorial?

Este tutorial pretende ser la ventanilla única para ensuciarse las manos con Docker. Además de desmitificar el panorama de Docker, le brindará experiencia práctica en la creación e implementación de sus propias aplicaciones web en la nube. Usaremos Amazon Web Services para implementar un sitio web estático y dos aplicaciones web dinámicas en EC2 usando Elastic Beanstalk y Elastic Container Service . Incluso si no tiene experiencia previa con implementaciones, este tutorial debería ser todo lo que necesita para comenzar.


EMPEZANDO

Este documento contiene una serie de varias secciones, cada una de las cuales explica un aspecto particular de Docker. En cada sección, escribiremos comandos (o escribiremos código). Todo el código utilizado en el tutorial está disponible en el repositorio de Github .

Nota: este tutorial utiliza la versión 18.05.0-ce de Docker. Si encuentra que alguna parte del tutorial es incompatible con una versión futura, plantee un problema . ¡Gracias!

Requisitos previos

No se necesitan habilidades específicas para este tutorial más allá de un conocimiento básico con la línea de comandos y el uso de un editor de texto. Este tutorial utiliza git clonepara clonar el repositorio localmente. Si no tiene Git instalado en su sistema, instálelo o recuerde descargar manualmente los archivos zip desde Github. La experiencia previa en el desarrollo de aplicaciones web será útil, pero no es obligatoria. A medida que avancemos en el tutorial, utilizaremos algunos servicios en la nube. Si está interesado en seguirnos, cree una cuenta en cada uno de estos sitios web:

Configurando tu computadora

Configurar todas las herramientas en su computadora puede ser una tarea desalentadora, pero afortunadamente, a medida que Docker se ha estabilizado, ponerlo en funcionamiento en su sistema operativo favorito se ha vuelto muy fácil.

Hasta hace algunos lanzamientos, ejecutar Docker en OSX y Windows era bastante complicado. Sin embargo, últimamente, Docker ha invertido significativamente en mejorar la experiencia de incorporación para sus usuarios en estos sistemas operativos, por lo que ejecutar Docker ahora es pan comido. La guía de introducción a Docker tiene instrucciones detalladas para configurar Docker en Mac , Linux y Windows .

Una vez que haya terminado de instalar Docker, pruebe su instalación de Docker ejecutando lo siguiente:

$ docker run hello-world

Hello from Docker.
This message shows that your installation appears to be working correctly.
...

HOLA MUNDO

Jugando con Busybox

Ahora que tenemos todo configurado, es hora de ensuciarnos las manos. En esta sección, ejecutaremos un contenedor Busybox en nuestro sistema y probaremos el docker runcomando.

Para comenzar, ejecutemos lo siguiente en nuestra terminal:

$ docker pull busybox
Nota: Dependiendo de cómo haya instalado Docker en su sistema, es posible que vea un permission deniederror después de ejecutar el comando anterior. Si estás en una Mac, asegúrate de que el motor Docker esté ejecutándose. Si estás en Linux, antepone tus dockercomandos con sudo. Alternativamente, puede crear un grupo acoplable para solucionar este problema.

El pullcomando recupera la imagen de Busybox del registro de Docker y la guarda en nuestro sistema. Puede usar el docker imagescomando para ver una lista de todas las imágenes en su sistema.

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
busybox                 latest              c51f86c28340        4 weeks ago         1.109 MB

Ejecución de ventana acoplable

¡Excelente! Ahora ejecutemos un contenedor Docker basado en esta imagen. Para hacer eso vamos a usar el docker runcomando todopoderoso.

$ docker run busybox
$

Espera, ¡no pasó nada! ¿Es eso un error? Bueno no. Detrás de escena sucedieron muchas cosas. Cuando llamas run, el cliente Docker encuentra la imagen (Busybox en este caso), carga el contenedor y luego ejecuta un comando en ese contenedor. Cuando ejecutamos docker run busybox, no proporcionamos un comando, por lo que el contenedor arrancó, ejecutó un comando vacío y luego salió. Bueno, sí, una especie de fastidio. Probemos algo más emocionante.

$ docker run busybox echo "hello from busybox"
hello from busybox

Bien, finalmente vemos algunos resultados. En este caso, el cliente Docker ejecutó diligentemente el echocomando en nuestro contenedor de Busybox y luego salió de él. Si te has dado cuenta, todo eso sucedió bastante rápido. Imagínese iniciar una máquina virtual, ejecutar un comando y luego eliminarla. ¡Ahora ya sabes por qué dicen que los contenedores son rápidos! Ok, ahora es el momento de ver el docker pscomando. El docker pscomando le muestra todos los contenedores que se están ejecutando actualmente.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Como no se está ejecutando ningún contenedor, vemos una línea en blanco. Probemos una variante más útil:docker ps -a

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
305297d7a235        busybox             "uptime"            11 minutes ago      Exited (0) 11 minutes ago                       distracted_goldstine
ff0a5c3750b9        busybox             "sh"                12 minutes ago      Exited (0) 12 minutes ago                       elated_ramanujan
14e5bd11d164        hello-world         "/hello"            2 minutes ago       Exited (0) 2 minutes ago                        thirsty_euclid

Entonces, lo que vemos arriba es una lista de todos los contenedores que ejecutamos. Tenga en cuenta que la STATUScolumna muestra que estos contenedores salieron hace unos minutos.

Probablemente se esté preguntando si existe alguna forma de ejecutar más de un comando en un contenedor. Intentemos eso ahora:

$ docker run -it busybox sh
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # uptime
 05:45:21 up  5:58,  0 users,  load average: 0.00, 0.01, 0.04

Ejecutar el runcomando con las -itbanderas nos adjunta a un tty interactivo en el contenedor. Ahora podemos ejecutar tantos comandos en el contenedor como queramos. Tómate un tiempo para ejecutar tus comandos favoritos.

Zona de peligro : si te sientes particularmente aventurero, puedes probar rm -rf binen el contenedor. Asegúrese de ejecutar este comando en el contenedor y no en su computadora portátil/escritorio. Hacer esto hará que cualquier otro comando como lsno uptimefuncione. Una vez que todo deja de funcionar, puede salir del contenedor (escriba exity presione Entrar) y luego reinícielo con el docker run -it busybox shcomando. Dado que Docker crea un nuevo contenedor cada vez, todo debería empezar a funcionar de nuevo.

Esto concluye un recorrido relámpago por el poderoso docker runcomando, que probablemente sea el comando que usará con más frecuencia. Tiene sentido dedicar algún tiempo a sentirse cómodo con ello. Para obtener más información sobre run, utilice docker run --helppara ver una lista de todas las banderas que admite. A medida que avancemos, veremos algunas variantes más de docker run.

Sin embargo, antes de seguir adelante, hablemos rápidamente sobre la eliminación de contenedores. Vimos arriba que todavía podemos ver restos del contenedor incluso después de haber salido ejecutando docker ps -a. A lo largo de este tutorial, lo ejecutará docker runvarias veces y dejar contenedores perdidos consumirá espacio en el disco. Por lo tanto, como regla general, limpio los contenedores una vez que termino con ellos. Para hacer eso, puede ejecutar el docker rmcomando. Simplemente copie los ID de los contenedores desde arriba y péguelos junto al comando.

$ docker rm 305297d7a235 ff0a5c3750b9
305297d7a235
ff0a5c3750b9

Al eliminarlos, debería ver que se le devuelven los ID. Si tiene un montón de contenedores para eliminar de una sola vez, copiar y pegar ID puede resultar tedioso. En ese caso, simplemente puedes ejecutar:

$ docker rm $(docker ps -a -q -f status=exited)

Este comando elimina todos los contenedores que tienen un estado de exited. En caso de que se lo pregunte, la -qbandera solo devuelve los ID numéricos y -ffiltra la salida según las condiciones proporcionadas. Una última cosa que será útil es la --rmbandera que se puede pasar y docker runque elimina automáticamente el contenedor una vez que se sale de él. Para ejecuciones únicas de Docker, --rmflag es muy útil.

En versiones posteriores de Docker, el docker container prunecomando se puede utilizar para lograr el mismo efecto.

$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
4a7f7eebae0f63178aff7eb0aa39f0627a203ab2df258c1a00b456cf20063
f98f9c2aa1eaf727e4ec9c0283bcaa4762fbdba7f26191f26c97f64090360

Total reclaimed space: 212 B

Por último, también puedes eliminar imágenes que ya no necesites ejecutando docker rmi.

Terminología

En la última sección, utilizamos mucha jerga específica de Docker que puede resultar confusa para algunos. Entonces, antes de continuar, permítanme aclarar cierta terminología que se usa con frecuencia en el ecosistema Docker.

  • Imágenes : los planos de nuestra aplicación que forman la base de los contenedores. En la demostración anterior, usamos el docker pullcomando para descargar la imagen de Busybox .
  • Contenedores : creados a partir de imágenes de Docker y ejecutan la aplicación real. Creamos un contenedor usando docker runel cual hicimos usando la imagen de BusyBox que descargamos. Se puede ver una lista de contenedores en ejecución usando el docker pscomando.
  • Docker Daemon : el servicio en segundo plano que se ejecuta en el host y que gestiona la creación, ejecución y distribución de contenedores Docker. El demonio es el proceso que se ejecuta en el sistema operativo con el que hablan los clientes.
  • Cliente Docker : la herramienta de línea de comandos que permite al usuario interactuar con el demonio. De manera más general, también puede haber otras formas de clientes, como Kitematic , que proporciona una GUI a los usuarios.
  • Docker Hub : un registro de imágenes de Docker. Puede considerar el registro como un directorio de todas las imágenes de Docker disponibles. Si es necesario, uno puede alojar sus propios registros Docker y usarlos para extraer imágenes.

APLICACIONES WEB CON DOCKER

¡Excelente! Así que ahora hemos analizado docker run, jugado con un contenedor Docker y también hemos aprendido cierta terminología. Armados con todo este conocimiento, ahora estamos listos para pasar a lo real, es decir, implementar aplicaciones web con Docker.

Sitios estáticos

Comencemos dando pequeños pasos. Lo primero que veremos es cómo podemos ejecutar un sitio web estático muy simple. Extraeremos una imagen de Docker de Docker Hub, ejecutaremos el contenedor y veremos lo fácil que es ejecutar un servidor web.

Vamos a empezar. La imagen que vamos a utilizar es un sitio web de una sola página que ya creé para esta demostración y que está alojado en el registro . prakhar1989/static-sitePodemos descargar y ejecutar la imagen directamente de una sola vez usando docker run. Como se señaló anteriormente, la --rmbandera elimina automáticamente el contenedor cuando sale y la -itbandera especifica una terminal interactiva que hace que sea más fácil cerrar el contenedor con Ctrl+C (en Windows).

$ docker run --rm -it prakhar1989/static-site

Dado que la imagen no existe localmente, el cliente primero buscará la imagen del registro y luego la ejecutará. Si todo va bien, deberías ver un Nginx is running...mensaje en tu terminal. Bien, ahora que el servidor está funcionando, ¿cómo ver el sitio web? ¿En qué puerto se está ejecutando? Y lo que es más importante, ¿cómo accedemos al contenedor directamente desde nuestra máquina host? Presione Ctrl+C para detener el contenedor.

Bueno, en este caso, el cliente no expone ningún puerto, por lo que debemos volver a ejecutar el docker runcomando para publicar los puertos. Mientras estamos en eso, también deberíamos encontrar una manera de que nuestra terminal no esté conectada al contenedor en ejecución. De esta manera, podrás cerrar felizmente tu terminal y mantener el contenedor en funcionamiento. Esto se llama modo independiente .

$ docker run -d -P --name static-site prakhar1989/static-site
e61d12292d69556eabe2a44c16cbd54486b2527e2ce4f95438e504afb7b02810

En el comando anterior, -ddesconectará nuestro terminal, -Ppublicará todos los puertos expuestos en puertos aleatorios y finalmente --namecorresponderá a un nombre que queramos darle. Ahora podemos ver los puertos ejecutando el docker port [CONTAINER]comando

$ docker port static-site
80/tcp -> 0.0.0.0:32769
443/tcp -> 0.0.0.0:32768

Puede abrir http://localhost:32769 en su navegador.

Nota: Si está utilizando Docker-Toolbox, es posible que deba usarlo docker-machine ip defaultpara obtener la IP.

También puede especificar un puerto personalizado al que el cliente reenviará conexiones al contenedor.

$ docker run -p 8888:80 prakhar1989/static-site
Nginx is running...
sitio estático

Para detener un contenedor desconectado, ejecútelo docker stopproporcionando el ID del contenedor. En este caso, podemos usar el nombre static-siteque usamos para iniciar el contenedor.

$ docker stop static-site
static-site

Estoy seguro de que estás de acuerdo en que fue súper simple. Para implementar esto en un servidor real, solo necesitará instalar Docker y ejecutar el comando Docker anterior. Ahora que ha visto cómo ejecutar un servidor web dentro de una imagen de Docker, debe preguntarse: ¿cómo creo mi propia imagen de Docker? Esta es la pregunta que exploraremos en la siguiente sección.