Cómo Docker puede hacer su vida más fácil como desarrollador

Docker es una tecnología que le permite crear y ejecutar contenedores para sus aplicaciones. Los contenedores son entornos aislados que ejecutan una aplicación e inc...

¿Qué es Docker?

Docker es una tecnología que le permite crear y ejecutar contenedores para sus aplicaciones. Los contenedores son entornos aislados que ejecutan una aplicación e incluyen sus dependencias. Por lo general, son mínimos, e incluyen solo lo que necesita para ejecutar su aplicación y nada más.

Los contenedores no están destinados a almacenar datos permanentes. Se espera que su contenedor se destruya y se vuelva a crear en cualquier momento, por lo que se perderán todos los datos guardados dentro del contenedor. Solo debe contener los archivos binarios y el código necesarios para que su aplicación se ejecute, con cualquier dato permanente almacenado externamente, por ejemplo, en volúmenes montados o una base de datos en la nube.

Hay una serie de ventajas de usar contenedores para desarrollar e implementar su aplicación:

  1. Sin errores humanos: tiene un entorno predecible cada vez que implementa. En lugar de que el administrador de su sistema ejecute comandos a través de SSH en un servidor virtual, ahora tiene un script documentado en su código fuente de lo que se implementa en su contenedor.

  2. Entornos reproducibles: puede ejecutar un sistema que está muy cerca de la producción en su máquina de desarrollo. Esto hace que encontrar errores sea mucho más fácil. Es mucho menos probable que se introduzca un error porque alguien olvidó ejecutar un comando en producción. O como dice la vieja excusa: "Funcionó en mi máquina".

  3. Herramientas de administración de infraestructura: puede aprovechar las herramientas y tecnologías que manejan el aprovisionamiento, las redes, el equilibrio de carga y el escalado de contenedores como Docker Swarm o Kubernetes.

  4. Administración de dependencias: si tiene dos servicios que necesitan diferentes versiones de Python, por ejemplo, puede ejecutar ambos servicios en la misma máquina virtual pero en diferentes contenedores y sus dependencias no interferirán entre sí.

  5. Nuevos miembros del equipo: las empresas suelen tener un documento gigante, incorrecto e incompleto sobre cómo configurar la máquina de un desarrollador que frustra enormemente a los nuevos miembros del equipo. Los contenedores pueden ayudarte a mejorar esto. Su entorno de desarrollo se puede configurar completamente con un script bash.

Finalmente, vale la pena mencionar que aunque Docker es casi sinónimo de contenedores, existen otras tecnologías de contenedores, como [rkt] (https://coreos.com/rkt/). Nos centraremos en Docker en este artículo, pero es bueno saber que hay otras opciones.

Docker también es una empresa que vende soluciones empresariales para contenedores. Sin embargo, el motor Docker y los productos de escritorio Docker son de uso gratuito. El motor Docker usa contenedor, que es de código abierto.

Instalación de Docker {#instalación de Docker}

Puede instalar Docker Desktop en Windows y Mac. Esto viene con un montón de herramientas útiles, incluido Docker Compose:

Puede instalar Docker Server en Linux. Y también puede instalar otras herramientas por separado, como Docker Compose:

Creación de una imagen basada en Alpine Linux

Una imagen de Docker es un archivo binario que contiene los archivos necesarios para iniciar y ejecutar un contenedor de Docker. Las imágenes de Docker se construyen usando una serie de comandos en un archivo llamado Dockerfile. Estos comandos configuran la imagen y le indican a Docker qué comando ejecutar cuando se inicia el contenedor.

Alpine Linux es una distribución ligera de Linux que es popular para contenedores debido a su pequeño tamaño y mínimo equipaje. Las distribuciones pequeñas son populares porque reducen el tiempo de creación de la imagen y brindan un control más preciso sobre las dependencias que instala.

Aquí hay un ejemplo de un Dockerfile, que es tan simple como podría ser:

1
2
FROM alpine:3.9
CMD echo "hello world"

El primer comando usa la imagen Docker alpine:3.9 como base. Tomará la imagen para esto y luego ejecutará el resto de los comandos contra ella. De manera predeterminada, Docker obtendrá estas imágenes del Registro acoplable, pero eso se puede cambiar si es necesario.

El segundo comando es el comando a ejecutar para iniciar el contenedor. Aquí solo estamos ejecutando echo, por lo que esto generará Hello World en la consola. El contenedor solo permanecerá activo mientras se ejecute este comando, por lo que en este caso saldrá inmediatamente y apagará el contenedor.

Para los contenedores que deben ejecutarse continuamente, el comando final normalmente iniciaría un proceso que nunca se detiene, como un servidor web o un motor de base de datos.

Ejecutar un contenedor desde su imagen

Ejecute el siguiente comando en el mismo directorio que Dockerfile para crear la imagen del contenedor y etiquételo con la etiqueta "myimage":

1
$ docker build -t myimage .

El resultado de ejecutar esto es algo como esto:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:3.9
3.9: Pulling from library/alpine
bdf0201b3a05: Pull complete
Digest: sha256:28ef97b8686a0b5399129e9b763d5b7e5ff03576aa5580d6f4182a49c5fe1913
Status: Downloaded newer image for alpine:3.9
 ---> cdf98d1859c1
Step 2/2 : CMD echo "hello world"
 ---> Running in db62be8c00ca
Removing intermediate container db62be8c00ca
 ---> d351cb9614ec
Successfully built d351cb9614ec
Successfully tagged myimage:latest

Luego, usando la etiqueta como referencia, podemos ejecutar el contenedor:

1
$ docker run -t myimage

El resultado:

1
hello world

Los archivos Docker pueden hacer mucho más. Por ejemplo, pueden copiar archivos del sistema de archivos a la imagen y cambiar las imágenes base para que se use una imagen diferente como base para ejecutar el contenedor. Veremos un ejemplo de estas características en la siguiente sección.

Caso de uso: ejecutar un proyecto de código abierto con un Dockerfile

Hoy en día es cada vez más común que un proyecto de código abierto exponga un Dockerfile para facilitar la configuración y ver la aplicación en ejecución. Puede ayudar a los recién llegados a ejecutar el proyecto sin perder tiempo instalando innumerables dependencias en su computadora.

Si escribe software de código abierto, podría considerar exponer un Dockerfile, el proyecto tiene una serie de dependencias. Para un proyecto simple de Node.js, puede que no valga la pena, pero para algo que ejecute Node, Ruby y MySQL, puede hacer esto para facilitar un poco la vida de las personas que aún no los tienen instalados.

En este ejemplo, vamos a tomar una aplicación de código abierto escrita en el marco .NET Core de Microsoft y ejecutarla en Docker. La aplicación es un ejemplo hecho especialmente para Docker y se puede encontrar en el siguiente enlace:

https://github.com/dotnet/dotnet-docker-samples/tree/master/aspnetapp

El primer paso es clonar este repositorio para que lo tengamos localmente:

1
$ git clone https://github.com/dotnet/dotnet-docker-samples

Si no has usado Git antes, puedes instalarlo de aquí. No es importante que tenga mucho conocimiento de git ya que solo lo estamos usando para descargar el código fuente.

Una vez clonado, abra la carpeta dotnet-docker-samples/aspnetapp, eche un vistazo a los archivos y observe que hay un Dockerfile. Que al momento de escribir se ve así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Este Dockerfile se basa en una imagen de Microsoft para construir aplicaciones ASP.NET y procede a emitir comandos para copiar los archivos y compilarlos. Luego cambia las imágenes a una de Microsoft para ejecutar una aplicación ASP.NET, procede a copiar los archivos creados en el directorio actual y luego ejecuta el tiempo de ejecución de ASP.NET contra ellos.

Si nunca ha usado ASP.NET antes, pronto podrá decir que creó, instaló y ejecutó una aplicación ASP.NET. ¡Todo lo que habría hecho es escribir un par de comandos de Docker!

Para construir la imagen, ejecute los siguientes comandos desde la línea de comandos:

1
2
3
$ cd dotnet-docker-samples/aspnetapp
$ docker build -t aspnetapp .
$ docker run -it --rm -p 8000:80 aspnetapp

Esto creará la imagen y luego iniciará un contenedor usando esa imagen, asignando el puerto 8000 en su computadora al puerto 80 dentro de la imagen. Ahora puede visitar http://localhost:8000 para ver esta aplicación ejecutándose.

Debería ver algo como esto:

aspnet container application in browser{.img-responsive}

Componer Docker

Un problema que encontrará rápidamente al ejecutar un solo contenedor es que no es fácil configurar un contenedor para hacer un montón de cosas diferentes, como procesar archivos PHP, alojar una base de datos MySQL y actuar como un servidor web usando NGINX.

También es innecesario porque los contenedores son muy livianos (a diferencia de las máquinas virtuales), lo que significa que no hay problema en tener varios de ellos ejecutándose en la misma máquina haciendo cosas diferentes.

La ventaja de múltiples contenedores e imágenes es que le brinda la oportunidad de dividirlos en diferentes máquinas virtuales o máquinas físicas e incluso crear múltiples contenedores a partir de la misma imagen en todas las máquinas para manejar la carga adicional de la aplicación.

El desafío con varios contenedores es cómo configurarlos para que sepan cómo comunicarse entre sí a través de la red, con la seguridad adecuada y cómo conectar el almacenamiento a esos contenedores. Afortunadamente, hay varias opciones diferentes para resolver este problema de "orquestar" los contenedores.

Quizás la forma más fácil de comenzar es con Componer ventana acoplable.

Docker Compose usa un archivo que describe qué componentes se necesitan para que un sistema funcione. Esto puede incluir contenedores, sistemas de archivos, puertos de red a exponer, etc.

Aquí hay un ejemplo de archivo docker-compose.yml que describe una configuración de este tipo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
version: '3'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

En el archivo Docker Compose que se muestra arriba, ejecutamos dos contenedores. Uno se crea a partir de la carpeta local y el otro usa la imagen de Redis. Hay información sobre qué volumen montar, por ejemplo, la carpeta actual está asignada a /code dentro del contenedor web, y la carpeta logvolume01 está asignada a /var/log dentro del contenedor.

El comando docker-compose up se usa para iniciar los contenedores y montar los volúmenes y poner en funcionamiento todo lo que ha descrito en el archivo docker-compose.yml. Puede usar esto para entornos de desarrollo y producción.

Kubernetes

Docker Compose es una excelente herramienta para comenzar a unir contenedores, pero tiene una funcionalidad limitada para entornos de producción y se limita a ejecutarse en un solo host. Necesitará una tecnología diferente para ejecutarse en varias máquinas y manejar la tolerancia a fallas, el monitoreo y el escalado.

Kubernetes es una arquitectura de contenedor de código abierto. Orquesta contenedores y tiene una amplia gama de características, que incluyen la creación dinámica de contenedores, el escalado, la tolerancia a fallas, el sondeo de contenedores en busca de signos de vida y el equilibrio de carga. El nombre proviene del griego κυβερνήτης que significa timonel. A veces se abrevia como K8s, aunque no estoy seguro de por qué, ya que, para empezar, no es un nombre muy largo.

Kubernetes se puede instalar directamente en máquinas virtuales o físicas. Alternativamente, los principales proveedores de la nube, incluidos Google, AWS, Azure y Digital Ocean, brindan servicios de Kubernetes administrados que simplificarán la puesta en marcha de un clúster.

Familiarizarse con Kubernetes requiere algo de estudio. No tendrá mucho sentido si solo pirateas sin algún conocimiento básico. Hay un curso edx gratis básico sobre esto, que he usado para ayudarme a comenzar con esto en el trabajo.

Kubernetes no es la única tecnología para orquestar contenedores: también están Docker Swarm, Vagrant, Monad, Openshift y muchas más. Siento que Kubernetes ofrece una “apuesta segura” en términos de soporte en el futuro a partir de 2019. Todos los principales proveedores de la nube lo admiten, y recientemente Microsoft anunció que sacarán su propio servicio de contenedores de la mezcla, a favor. de Kubernetes.

Conclusión

Docker puede hacer que su vida sea más cómoda como desarrollador de software. Se puede usar para ejecutar diferentes entornos de manera predecible en su máquina de desarrollador. También se usa en producción, generalmente con un sistema de orquestación como Kubernetes, para brindar implementaciones predecibles de sus aplicaciones en los servidores. Si aún no has probado Docker, te animo a que lo hagas.