Curso de Docker (Básico - Medio - Avanzado)

Iniciado por DarkDante, Mayo 12, 2020, 08:23:34 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Mayo 12, 2020, 08:23:34 PM Ultima modificación: Julio 01, 2020, 03:38:45 PM por DarkDante

Muy buenas underc0ders!, en este post vamos a hacer un curso de docker, orientado a la automatización. Así que sin mas texto, vamos a repasar el temario que vamos a ver

1- Introducción a Docker, ¿Que es?, ¿Para que nos sirve en automation?
2- Instalación de Docker en Windows y Linux
3- Docker images
4- Docker containers y ejemplo de automatización
5- Docker compose
6- DockerFile
7- Docker volumes


CitarIMPORTANTE: Adicionalmente, si quieres seguir al pie de la letra este curso, te recomiendo descargar Java SDK (Versión 11.0.7 Recomendada), Maven (Versión 3.6.3) y VNC Viewer (Es una herramienta gratuita para monitoreo de VM y containers de docker, esta para todos los SO). Utilizaremos estas herramientas para ejecutar un proyecto y poder ver las pruebas nosotros mismos, pero si solo quieres aprender sin ejecutarlo, no lo descargues.

LINKS:

Java SDK: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Maven: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
VNC Viewer: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

CitarDISCLAIMER: En el momento de crear este curso, se utiliza un proyecto propio para ejecutar código automatizado y ver como trabajan las pruebas con docker, utilizando la web de No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Sin embargo, estas webs estan en constante cambio, es por eso, que en un futuro no muy lejano, es probable que este proyecto de errores a la hora de encontrar elementos, ya que como explique anteriormente, los elementos de la web es mas que seguro que van a cambiar. Si esto sucede, no te preocupes, el objetivo del curso va a cumplirse igualmente, solamente las pruebas van a fallar, pero, va a cumplir su propósito.


Bueno, vamos a comenzar por el principio:

1- Introducción

¿Qué es docker?

CitarLa idea detrás de Docker es crear contenedores ligeros y portables para las aplicaciones software que puedan ejecutarse en cualquier máquina con Docker instalado, independientemente del sistema operativo que la máquina tenga por debajo, facilitando así también los despliegues

Esa es la traducción literal de la web oficial de docker

Pero esto suena de algo, ¿verdad?. Si, se asemeja mucho a una maquina virtual.
Entonces, si ya existen las maquinas virtuales, ¿cual es el objetivo de docker?, es muy simple: Crear contenedores con las funciones básicas de un sistema operativo, donde vamos a montar SOLAMENTE lo que necesitamos, y ese contenedor se podrá crear y reproducir en cualquier sistema operativo, gracias a que el contenido de dicho container, estará dado por una imagen de docker ya pre creada y configurada. Esto nos da la posibilidad de crear imágenes personalizadas, y compartirlas con alguien, para que al montarla en un container, tenga todo lo que necesita para hacer funcionar determinado servicio, o programa.

Bien, aclarado esto. ¿Cómo podemos aplicar docker en automation?

Imaginen levantar un contenedor, que a su vez, contenga muchas instancias de, por ejemplo, un navegador. Puede ser Google Chrome, Firefox, Opera, Edge o el que queramos... y no solo de uno mismo, podría tener muchas instancias de muchos navegadores al mismo tiempo corriendo pruebas en tiempo real, para que todo esto sea gestionado desde un Jenkins ya pre-configurado y listo para manejar branches y entregar resultados. Y todo esto, sin la necesidad de instalar nada mas que docker, ni contaminar nuestra PC con programas o cosas que son demasiado dolor de cabeza a veces, instalar, configurar y lograr correr correctamente.

2- Instalación de Docker


Windows:

Requisitos para instalar Docker:


       
  • Windows 10 Pro o Enterprice (Docker no funciona en Windows home, para otros Windows como 8, instalar Docker tools)
  • Compilación igual o superior a 14393.222
  • Updates críticos para Windows Containers
  • Virtualización activada en nuestro equipo
(Básicamente, ir a Windows update e instalar todas las actualizaciones)

Para instalar Docker en Windows, solo nos dirigimos a la web de docker No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.


Pasos:



       
  • Elegimos la opción "Download for Windows" e inmediatamente comenzara la descarga de Docker Desktop. Una vez tenemos el archivo, lo instalamos como administrador. Next next next... y reiniciamos. Si al reiniciar te sale un error de que no esta activada la virtualización, vamos al paso 2
  • Para este paso tenemos que reiniciar nuestra PC e ingresar a la BIOS- Esto ya depende de sus computadoras y fabricantes, pero casi siempre se ingresa a la BIOS apretando Sup, o F2, o F9, o F12. Una vez dentro, hay que buscar dentro de las opciones del procesador y activar la virtualización. Es diferente el nombre si tienes un procesador Inte, o AMD. A continuación de dejo una guía para activar la virtualización según tu procesador:


    Activar Virtualización: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Linux:
Requisitos para instalar Docker:


       
  • Virtualización activada en nuestro equipo

Instalar docker en linux es sumamente sencillo. Para este curso utilizamos la distro de Kubuntu, pero funciona en la mayoría de distros. Para instalarlo primero:



  • Necesitamos activar la virtualización de nuestro procesador antes de instalar nada. Para este paso tenemos que reiniciar nuestra PC e ingresar a la BIOS- Esto ya depende de sus computadoras y fabricantes, pero casi siempre se ingresa a la BIOS apretando Sup, o F2, o F9, o F12. Una vez dentro, hay que buscar dentro de las opciones del procesador y activar la virtualización. Es diferente el nombre si tienes un procesador Inte, o AMD. A continuación de dejo una guía para activar la virtualización según tu procesador:

    Activar Virtualización: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

    Una vez activada la virtualización, abrimos nuestra terminal y ejecutamos los siguientes comandos:
Código: php
sudo apt update
sudo apt upgrade
sudo apt install docker-ce


Listo, ya tenemos docker instalado. Para ver la versión y que este funcionando correctamente, ejecutamos el siguiente comando


Código: php
sudo docker version



    Veremos en consola los datos de docker, comandos, etc.


3- Docker images

Bueno, en este punto ya deberíamos tener instalado docker en nuestras PC. Ahora, vamos a ver que es una imagen, para que sirve y como obtenerlas.

¿Qué es una imagen?

Seguramente muchos ya saben lo que es una imagen, pero vamos a explicarlo de todas formas.
Una imagen de docker, es como una plantilla de un container ya creado, como un snapshot o una captura de estado, por decirlo de alguna forma.
Les voy a poner un ejemplo: Estamos en una "maquina virtual" haciendo cosas, y queremos que esa maquina virtual tenga deteminados programas y servicios. Bueno, se los instalamos, y luego, pasamos a generar una imagen de esa maquina virtual. Entonces, una vez montamos esa imagen en un container, volvemos a tener la "maquina virtual" tal cual la dejamos anteriormente.

Ahora, ¿como obtenemos imágenes?

Es muy simple: Solamente debemos dirigirnos a la web de Docker Hub: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Aquí, en la sección de "Explore" encontraremos todas TODAS las imagenes que hay para que nosotros podamos descargarlas y usarlas en nuestras PC

CitarNOTA: Docker Hub es como un GitHub de imágenes de docker, les recomiendo que se creen una cuenta en este sitio para poder subir sus propias imágenes

Bueno, ya hemos dejado claro que es, y para que sirve una imagen de docker. Ahora, vamos a descargar algunas imagenes

CitarNOTA: Si quieres seguir este curso al pie de la letra, te recomiendo descargar las siguientes imágenes que se verán a continuación

Pasos para descargar imagenes de docker

NOTA: Todos los comandos se escribirán para Windows, pero, si estas en Linux es exactamente lo mismo, solamente agrega un "sudo" antes de cualquier comando


  • Abrimos la consola de comando (Win + R y escribir cmd + Enter)
  • Escribimos el siguiente comando
Código: php
docker images 
    [/li]

  • Este comando nos lista todas las imagenes de docker que tenemos en nuestra PC, seguramente no les aparezca ninguna en este momento
  • Ahora, vamos a usar el comando pull para bajar imágenes desde docker hub
  • Vamos a Docker Hub/Explore y e el buscador vamos a escribir "Selenium"
  • Clickeamos la imagen llamada selenium/hub que suele ser la primera en la lista (Me encantaría poder colocar imagenes :( )
  • A la derecha, vamos a ver un recuadro con el titulo de "Docker Pull Command", abajo podemos ver el comando para descargar la imagen
  • En la consola que abrimos anteriormente, escribimos el comando que nos indica ahí mismo:
Código: php
docker pull selenium/hub


Y este es el proceso para descargar imagenes de docker, hagan el mismo proceso para las imagenes que deseen descargar. Ahora, vamos a listar las imagenes que necesitaremos para este curso.

Ejecuten los siguientes comandos (Recuerden colocar "sudo" antes de cada comando en Linux):

Código: php
docker pull selenium/hub

Código: php
docker pull selenium/node-chrome-debug

Código: php
docker pull selenium/node-firefox-debug

Código: php
docker pull jenkins/jenkins (Sólo para ver Volúmenes mas adelante)


Esto va a tardar algunos minutos según su conexión, Algunas imágenes pesan entre 300 MB hasta casi 1GB. Tengan paciencia ;)

Ahora, por ultimo, vamos a ver las imágenes que hemos descargado. Para eso, ejecutamos el comando que vimos al principio para listar las imágenes descargadas en nuestra PC. ¿Lo recuerdan?, exactamente, es este:

Código: php
docker images


Ahora en la grilla que se forma en nuestra consola, deberían aparecer las 3 imagenes que descargamos en los pasos de arriba. Ahora bien, ¿Cómo utilizamos estas imágenes y para que sirve cada una?

Lo que hemos descargado es Selenium Grid y 2 nodos de navegadores, que luego vamos a "linkear" a nuestro Selenium Grid. Entonces, en nuestro Selenium Grid podremos tener 2 navegadores corriendo al mismo tiempo, uno de Google Chrome, y otro de Mozilla Firefox (En realidad podemos correr mas de un nodo, pero lo vamos a ver mas adelante)

4- Docker containers

Bueno, hasta ahora sabemos que es docker, como instalarlo y como descargar imagenes de docker. Perfecto pero, ¿cómo usamos esas imagenes?, la respuesta es: "Contenedores"

¿Recuerdan que mas arriba tocamos el tema de maquinas virtuales?, bueno, un contenedor, o container de docker, es basicamente eso, una maquina virtual. PERO!, es una maquina virtual con una configuración mínima para funcionar, ya preestablecida por un DockerFile (Del cual hablaremos mas adelante) que nos permite el funcionamiento de un servicio (o programa) especifico. En otras palabras, podemos decir que un container es una maquina virtual, con las necesidades mínimas de un SO para que corra el contenido que nosotros necesitemos.

Ya sabemos que es un container, ¡Perfecto!, ¿y esto como se relaciona con las imagenes de docker?, bueno, en ese container es donde vamos a montar la imagen de docker que descargamos previamente.

Y entonces, si ya existen las maquinas virtuales, ¿Por que usar docker?. Con lo que te comente mas arriba seguramente ya lo habras adivinado, y si, la razón es el poder crear un container con los minimos recursos, sin tener que pasar por una ardua y larga instalación, configuración, y sacrificio de recursos para solamente instalar un programa, o servicio.
Piensen que a la hora de crear una VM hay que asignarle disco virtual, procesador, ram, y a eso, instalar el SO, para recién poder instalar lo que necesitemos dentro de ella. Esto como mínimo podría ocuparnos 2 o 3 GB de disco (Sin contar los recursos consumidos de la maquina real). Con docker y sus containers, podemos hacer todo eso, en muchísimo menos espacio (Hasta 3 MB) y podemos levantar muchos MUCHOS containers. Lo que significa, que si en una maquina real, podemos levantar un máximo de 10 VM, con docker, posiblemente podamos levantar 50 containers que hacen lo mismo, y ahorramos recursos (Por poner un ejemplo).

Perfecto, ahora, vamos a ver como crear un container, y vamos a explicar el paso a paso de como construir uno

Si bajaron las imágenes de docker que puse en la sección 3, vamos a crear un container que contenga dentro solamente un Selenium Grid (La imagen llamada selenium/hub).

Vamos a ejecutar el siguiente comando en su consola (Recuerda el sudo si estas en linux):

Código: php
docker run -p 4444:4444 --name selenium-hub selenium/hub


Bien, ahora vamos a explicar paso a paso que significa este código y por que esta compuesto:

Código: php
docke run
Este es el comando que se encarga de crear y levantar un container nuevo de docker. Siempre se coloca al principio.

Código: php
-p 4444:4444
Estos son los puertos que estamos abriendo de comunicación entre nuestra PC y el container, lo primero es el puerto de nuestra PC y el segundo el del container (Si colocamos -P en mayúscula, este asignara un puerto automáticamente libre)

Código: php
--name selenium-hub
Este comando nos permite ponerle un nombre a nuestro container, es importante conocer este nombre, para posteriormente "linkearlo" a otros containers, si no colocamos un nombre, docker le asignara un nombre random a nuestro container

Código: php
selenium/hub
Por ultimo, el nombre de la imagen que se va a montar en ese container.

Al ejecutar esto, seguramente van a aparecer varias lineas en su consola de comandos

Veremos algo así como esto:

Código: php
{
  "host": "0.0.0.0",
  "port": 4444,
  "role": "hub",
  "maxSession": 5,
  "newSessionWaitTimeout": -1,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "jettyMaxThreads": -1,
  "cleanUpCycle": 5000,
  "browserTimeout": 0,
  "timeout": 1800,
  "debug": false
}


Esto es la información de nuestro container recién creado y ya corriendo.

CitarNOTA: NO cierren esta ventana de consola, o nuestro container morirá, cada vez que necesiten ejecutar alguna acción como las que veremos a continuación, las haremos en una terminal nueva.

¿Como comprobamos que tenemos un container levantado?, solo ejecutamos el siguiente comando en una nueva terminal

Código: php
docker ps


Veremos la siguiente grilla, donde podemos ver la ID de nuestro container, la imagen que tiene montada, cuando fue creado, el estado, los puertos y el nombre. Esto significa que el container se creo y esta corriendo en este momento.

Código: php
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
4c880423a20e        selenium/hub        "/opt/bin/entry_poin..."   2 minutes ago       Up 2 minutes        0.0.0.0:4444->4444/tcp   selenium-hub


Si llegaste hasta aquí ¡Felicidades!, has creado tu primer (tal vez) container de docker.
Ahora, ¿de que sirve o como vemos lo que acabamos de crear?
Muy facil, abre tu navegador favorito, y en la barra de direcciones escribe el puerto que le colocamos a nuestro container, en este caso, el 4444. Pero, si no sabemos cual es, basta con usar el siguiente comando:

Código: php
docker port selenium-hub


Nos saldrá la siguiente información

Código: php
4444/tcp -> 0.0.0.0:4444


Entonces, esto significa que el container esta corriendo en la IP 0.0.0.0 (O sea, local host) en el puerto 4444 (Que le definimos mas arriba al container)

En nuestro navegador escribimos:

Citarlocalhost:4444

Enter, y voala, ya estamos viendo nuestro Selenium Grid corriendo perfectamente. Y sin la necesidad de instalar nada mas que docker y su imagen.

Ahora, si revisan dentro de lo primero que vemos en Selenium Grid, veremos una parte que dice:

CitarFor more information about Selenium Grid Hub please see the docs and/or visit the wiki. Or perhaps you are looking for the Selenium Grid Hub console.

Happy Testing!

Bien, ahora si clickeamos en la palabra "console", o simplemente agregamos "/grid/console" en nuestra ruta de navegación (Quedando No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) Se nos abrira la consola de nuestro Selenium Grid, pero se vera todo vacío. Y esta perfecto. No cierres esta pestaña del navegador, porque vamos a volver pronto.

Si quieres frenar este container, basta con escribir el siguiente comando

Código: php
docker stop selenium-hub


y si queremos volver a levantarlo, basta con ejecutar este otro comando

Código: php
docker start selenium-hub


Y si necesitamos eliminarlo, el comando es el siguiente:

Código: php
docker rm selenium-hub


CitarNOTA: Recordemos que selenium-hub es el nombre de nuestro container recién creado, por eso, se utiliza al final de cada comando como stop, start o rm para indicarle a cual nos referimos

CitarNOTA: Si necesitamos eliminar un container, primero hay que pararlo con docker stop, ya que no se pueden eliminar containers en ejecución. Pueden eliminarse con el comando docker rm selenium-hub -f o kill, pero lo estaríamos forzando y perderíamos la información que se maneja dentro del container, por tanto, es una mala practica que no recomiendo para nada, pero, es bueno saberlo

Bien!, ya sabemos como crear containers, incluso hemos creado uno con Selenium Grid funcionando perfectamente, ahora, vamos a crear containers con nodos de Google Chrome y Mozilla Firefox (Imagenes que descargamos en el capitulo 3)

Para esto, ejecutamos los siguientes comandos cada uno en una terminal nueva, recuerden eso:

Código: php
docker run -P --link selenium-hub:hub selenium/node-chrome-debug

Código: php
docker run -P --link selenium-hub:hub selenium/node-firefox-debug


Este código solo tiene una diferencia con el anterior, y es que lo estamos linkeando directamente con el primer container que creamos con el siguiente parámetro:

Código: php
--link selenium-hub:hub

Este es el link que se crea entre ambos containers, y esta conexión se llamara hub

Perfecto, ha llegado el momento de regresar a la pestaña que abrimos al principio, o sino, solo ve a
CitarNo tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Y ahí llevas los dos nodos que levantamos en nuestros containers, uno de Chrome y otro de Firefox

Hermoso, hasta ahora, hemos creado 3 containers. Uno con Selenium Grid, y 2 con nodos de navegadores, que hemos linkeado a nuestro Selenium Grid.

¡Perfecto!, ahora, vamos a usar un pequeño ejemplo para ver como funcionan.

Entramos en el siguiente repositorio de GitHub y bajamos el siguiente proyecto (No olvides dejar una estrellita :P) Puedes clonarlo usando git clone, o bajarlo como un zip. Como tu prefieras

CitarNo tienes permitido ver los links. Registrarse o Entrar a mi cuenta

¿Que acabamos de descargar?
Es un pequeño proyecto de automatización que cree utilizando Java y Maven, el cual se conectara a través de un RemoteWebDriver para hacer las pruebas automatizadas en los containers que acabamos de crear

CitarNOTA: Recuerden tener instalado JAVA (Versión 11.0.7 recomendada) y Maven (Versión 3.6.3), a partir de aquí se da por sentado que estan instalados y saben como hacerlo. En este curso no se enseña a instalar otras tecnologías

CitarNOTA: Recuerden tener instalado VNC Viewer, pues vamos a utilizarlo a continuación

Bueno, en este momento vamos a hacer uso de Maven, por eso, era uno de los requisitos necesarios si querías ejecutar este proyecto, junto con Java y VNC Viewer.

¿Que procede ahora?, espero que no hayas cerrado ninguno de los 3 containers que creamos y levantamos. Si lo hiciste, repite los pasos mas arriba y vuelve a crear los 3 contenedores necesarios.

Ahora, una vez levantados los 3 containers, vamos a nuestra aplicación VNC Viewer

Esta aplicación nos permite monitorear maquinas virtuales, y como no, containers de docker

Abrimos nuestro VNC Viewer y arriba, tenemos una barra de direcciónes, ahi vamos a copiar la dirección IP y puerto del container de uno de los nodos.

¿Como averiguamos el puerto de los nodos de navegadores?, ¿lo recuerdan?, se los mencione mas arriba, pero vamos a hacerlo desde el principio, de paso, les enseñare a buscar por ID

CitarNOTA: Los datos que se verán resultado de los próximos comandos ejecutados aquí, serán exclusivamente de mi PC, y no de las suyas, a lo que me refiero, es que ustedes tendrán distintos IDs y nombres en sus containers. No copien los míos, porque no les funcionara.

Bien, para empezar, vamos a ejecutar el comando:

Código: php
docker ps


Eran algo como lo siguiente, pero, con distintos nombres en los nodos de chrome-debug y firefox debug y, lógicamente, con distintos IDs

Código: php
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                     NAMES
1e65731aca1d        selenium/node-firefox-debug   "/opt/bin/entry_poin..."   45 minutes ago      Up 45 minutes       0.0.0.0:32769->5900/tcp   busy_sanderson
0b0eb8b8feb5        selenium/node-chrome-debug    "/opt/bin/entry_poin..."   47 minutes ago      Up 47 minutes       0.0.0.0:32768->5900/tcp   keen_khayyam
4c880423a20e        selenium/hub                  "/opt/bin/entry_poin..."   About an hour ago   Up 57 minutes       0.0.0.0:4444->4444/tcp    selenium-hub


Ahora, necesitamos averiguar el puerto e Ip de los containers que necesitamos, en este caso, son los de selenium/node-firefox-debug y selenium/node-chrome-debug. Si vemos la información que nos arrojo el comando docker ps anteriormente, veremos la ID de cada container.

Cada uno de los comandos puede ejecutarse, ya sea con el ID o el nombre del container

Entonces, vamos a averiguar el puerto del nodo de chrome-debug con la ID de mi container que de todas formas ya se ve con el docker ps, pero quiero que aprendan el comando

Código: php
docker port 0b0eb8b8feb5


Mis resultados fueron estos:

Código: php
5900/tcp -> 0.0.0.0:32768


Bien, como aprendimos a hacer esto para ver el puerto de nuestro Selenium Grid, ahora lo hacemos para ver el puerto de nuestro nodo, pero, utilizando la ID del container en vez del nombre. Los resultados son los mismos.

Ahora, es el turno del nodo de firefox. Simplemente repetimos lo anterior:

Código: php
docker port 1e65731aca1d


Resultado:

Código: php
5900/tcp -> 0.0.0.0:32769


CitarNOTA: Los puertos pueden variar, ya que el comando -P que usamos cuando creamos los containers, asigna un puerto aleatorio disponible. Si no es igual que el que se ve aquí, no te preocupes.



Bueno, ahora es el turno del ya muchas veces mencionado VNC Viewer.

Lo abrimos, y en la barra de direcciónes copiamos la IP y puerto que obtuvimos anteriormente.
En mi caso, la de chrome fue 0.0.0.0:32768 y la de firefox fue 0.0.0.0:32768.

Recordamos que 0.0.0.0 es nuestro local host, entonces, en la barra de direcciónes del VNC Viewer, escribimos lo siguiente

Citarlocalhost:32768

Enter

Nos pedirá una contraseña, esa contraseña es: secret

Ahora, debemos estar viendo una pantalla negra con el logo de Ubuntu de fondo, esta perfecto, estamos dentro de la maquina virtual que contiene el nodo de chrome.

Repetimos el mismo proceso para el nodo de firefox-debug

Sin cerrar la nueva ventana que se nos abrió de VNC Viewer, vamos al VNC Viewer y escribimos la direxión del nodo de firefox, en mi caso:

Citarlocalhost:32769

Password: secert

Y estaremos viendo otra panralla en negro con el logo de ubuntu, esto esta perfecto.

¿Qué estamos viendo en estas pantallas?, pues literalmente estamos mirando dentro de los containers que creamos, el de chrome y el de firefox espesificamente, en tiempo real.

Entonces ahora, vamos a la carpeta del proyecto que descargamos de GitHub. Abrimos una consola en la ubicación de esa carpeta, y ejecutamos el siguiente comando de maven, pero antes de hacerlo, no pierdan de vista las ventanas de VNC Viewer que abrimos anteriormente. Pónganlas a la par la una de la otra. Una vez hecho esto, vamos a la nueva consola en la ubicación de la carpeta del proyecto descargado y ejecutamos el siguiente comando de maven:

Código: php
mvn test


Comenzara la instalación, compilación y ejecución de las dependencias de maven, en ese momento, deben mirar los containers con las ventanas de VNC Viewer.

Para este entonces, ya debieron ver como se abren automáticamente ventanas de Youtube, tanto en el nodo de Chrome como en el de Firefox y ejecutan pruebas al mismo tiempo. (Sin necesidad de haber instalado Chrome, o Firefox en nuestra PC)

¡Increíble! ¿verdad?, ahora, imaginen crear 40 nodos y correr las pruebas simultáneamente. Si quieren, los invito a hacerlos y vean el potencial que tiene docker con la automatización

CitarNOTA: Es muy posible que las pruebas hayan fallado, ya que cambian los elementos de la web, y puede que no los haya encontrado. Pero eso no importa, lo importante, es ver como abre en los distintos navegadores, la web de youtube. Los resultados de los test nos tienen sin cuidado.

5- Docker compose


CitarNOTA: No borren el proyecto que bajamos antes de GitHub, vamos a volver a utilizarlo.

Bien, ahora viene la parte interesante de todo esto. ¿Recuerdan lo visto en el capitulo anterior? (Capitulo 3 - containers), ¿Que dirían si les digo que TODO eso que hicimos, podemos hacerlo completamente en un solo paso? y levantar todos los containers ya configurados listos para usarse, ejecutando solamente un solo comando?, bueno, aquí viene la magia del docker-compose:

Antes que nada, debemos instalarlo:

Windows:

Si estas en windows, tienes suerte, ya que docker-compose viene instalado dentro de Docker desktop, por tanto, tu no tienes que hacer nada

Linux

Desde la consola de comando, ejecutar lo siguiente en orden:

Revisaremos la versión actual y, si es necesario, la actualizaremos en el comando que se muestra a continuación:

Código: php
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose


Luego, configuraremos los permisos:

Código: php
sudo chmod +x /usr/local/bin/docker-compose


A continuación, comprobaremos que la instalación se haya realizado de forma correcta revisando la versión

Código: php
docker-compose --version


Con esto se imprimirá la versión que instalamos:

Salida de Consola:
Código: php
docker-compose version 1.21.2, build a133471


Perfecto, a esta altura, ya tenemos instalado docker-compose, entonces, ¿Que es docker-compose?

Al igual que el Dockerfile (Que veremos en el capitulo siguiente), un archivo docker-compose, es una especie de plantilla, o receta, donde nosotros vamos a definir un conjunto de containers a crearse, definiendo las imagens que van a tener, los puertos y redes de las mismas, asi como los nombres y variables de entorno. Entonces, vamos a crear nuestro primer docker-compose.

Antes de seguir, vamos a eliminar todos los containers que creamos en el capitulo anterior.

Para eso ejecutamos los siguientes comandos:

Código: php
docker container ls


Este comando nos enseña todos los containers que tenemos corriendo, y los que no. Bueno, ahora vamos a eliminarlos a todos, sin antes pararlos.

Para eso, vamos a correr el comando docker stop, seguido de las 3 ID de nuestros containers, unos atras de otro, de la siguiente forma:

Código: php
docker stop 1e65731aca1d 0b0eb8b8feb5 4c880423a20e


Y una vez ya estan detenidos, vamos a eliminarlos:

Código: php
docker rm1e65731aca1d 0b0eb8b8feb5 4c880423a20e


Bueno, ahora si ejecutamos el comando docker container ls, no deberíamos tener ningún container

Ahora, vamos a ver como es la estructura de un docker-compose:

Código: php
version: '2'
services:
   db:
     container_name: 'mysql-blog'
     image: 'mysql'
     ports:
      - '3306:3306'
     environment:
      - MYSQL_ROOT_PASSWORD= '12345'
      - MYSQL_DATABASE= 'blog'
      - MYSQL_USER= 'root'
     volumes:
      - ./mysql:/var/lib/mysql
   web:
     container_name: wordpress-blog
     image: wordpress:4.7.5-apache
     volumes:
       - ./code:/var/www/html
     ports:
       - '8080:80'
     links:
       - 'db:mysql'
     depends_on:
       - db


Explicación del ejemplo anterior:

Version: 2 : Esto se refiere al formato del archivo compose, dependiendo de este valor tendremos disponibles algunas propiedades y otras no.
Services: (db, web): Aqui podremos definir los docker que utilizaremos, imaginen que estamos haciendo dos docker run
db, Web: Aquí podremos pasarles parametros a cada docker por separado.
Container_name: Este será el nombre de este docker.
Image: Nombre de la imagen desde la que se creará nuestro docker.
Ports: Permite que relacionemos un puerto interno del docker con uno de nuestra maquina.
Enviroments: Estas son variables de entornos, generalmente las imagenes de docker utilizan estas variables para configuraciones iniciales por ejemplo el de mysql configura  una contraseña por defecto.
Volumes: Esta opcion nos permite relacionar una carpeta de nuestro equipo con una ubicación dentro del docker, es decir lo que el docker genere en esa carpeta lo tendremos en nuestro host y viceversa.

Lo que vimos anteriormente fue solo un ejemplo para crear un docker compose y explicar toda su composición y estructura. Ahora, vamos a crear nuestro propio docker-compose, con las imagenes de Selenium Grid, Google Chrome y Mozilla Firefox que vimos en el capitulo anterior:

Primero, vamos a cualquier parte de nuestra PC, y creamos un nuevo archivo, de extencion .yml el cual llamaremos docker-compose

Ahora, lo abrimos con nuestro editor de texto favorito y vamos a copiar y pegar lo siguiente dentro de el

Código: php
version: '3'
services:

  selenium-hub:
    container_name: selenium-hub
    image: selenium/hub
    ports:
    - "4444:4444"

  seleniumChrome:
    container_name: chrome
    image: selenium/node-chrome-debug
    ports:
      - "32769:5900"
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444

  seleniumFirefox:
    container_name: firefox
    image: selenium/node-firefox-debug
    ports:
      - "32768:5900"
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444


Lo guardamos, y ahora vamos a abrir una nueva terminal de nuestra consola en la ubicación donde creamos el archivo docker-compose.yml y ejecutaremos el siguiente comando:

Código: php
docker-compose up


Y... ¡Magia!, cuando termino de hacer lo suyo, tenemos levantados los 3 mismos containers que creamos en el capitulo 3. Solamente corriendo un comando a partir de la receta del docker-compose que armamos.

CitarNOTA: si tienes problemas para crear el archivo, dentro de la carpeta del proyecto que bajamos de GitHub, en la raiz, hay un archivo llamado docker-compose, que esta compuesto por la misma estructura que acabamos de crear aquí. Pueden usar el mismo, pero lo ideal sería que lo creen ustedes mismos

Para comprobar que todo esta funcionando, vamos a otra consola nueva, y escribimos el siguiente comando:

Código: php
docker ps


Aquí desvariamos ver los 3 containers levantados y corriendo como les enseño a continuación:

Código: php
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                     NAMES
295c07893d72        selenium/node-firefox-debug   "/opt/bin/entry_poin..."   17 seconds ago      Up 15 seconds       0.0.0.0:32768->5900/tcp   firefox
b14634d06cb0        selenium/node-chrome-debug    "/opt/bin/entry_poin..."   17 seconds ago      Up 15 seconds       0.0.0.0:32769->5900/tcp   chrome
15d2dbb2d161        selenium/hub                  "/opt/bin/entry_poin..."   20 seconds ago      Up 17 seconds       0.0.0.0:4444->4444/tcp    selenium-hub


CitarNOTA: Si les da error al crear el container llamado selenium-hub, recuerden eliminar todos los containers, ya que si encuentra uno con el mismo nombre, no podrá crearlo

Esto significa, que si vamos a nuestro navegador y escribimos en la barra de direcciónes:

CitarNo tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Vamos a ver nuestro Selenium Grid corriendo con los nodos de Chorome y Firefox

Si lo deseamos, podemos levantar una nueva terminal con la ubicación root del proyecto descargado de GitHub y ejecutar el comando de maven:

Citarmvn test

Y se ejecutara sobre los nodos que levantamos a través del docker-compose que creamos.

CitarNOTA: Pueden repetir la parte de visualizar dentro de cada container utilizando VNC Viewer como se explico en el capitulo 3

Muy bien underc0ders. Esto sería casi que lo básico y lo mediano para empezar a automatizar con docker. Si llegaron hasta aquí y siguieron bien todos los pasos, seguro que lo lograron. Ahora va a empezar la parte avanzada, que es posible que no la necesiten, pero, igual la dejare en este curso.


6- Dockerfile


Bueno, ahora vamos a pasar a lo que sería el dockerfile. ¿Que es un docker file?:

CitarUn Dockerfile es un archivo de texto plano que contiene las instrucciones necesarias para automatizar la creación de una imagen que será utilizada posteriormente para la ejecución de instancias específicas ( i.e. contenedores ).

En otras palabras, se puede decir que un DockerFile es una receta, a partir de la cual vamos a crear una imagen personalizada de docker, que posteriormente podremos montar en un container, o incluso compartirla (Veremos al final del curso)

¿Como esta compuesto un dockerfile?
Básicamente el dockefile esta compuesto de las siguientes instrucciónes, aunque no todas son obligatorias.

Los Dockerfile tienen algunas instrucciones:

CitarFROM: indica la imagen base a partir de la cual crearemos la imagen que construirá el Dockerfile.
MAINTAINER: documenta el creador de la imagen.
ENV HOME: establece el directorio HOME que usarán los comandos RUN.
RUN: permite ejecutar una instrucción en el contenedor, por ejemplo, para instalar algún paquete mediante el gestor de paquetes (apt-get, yum, rpm, ...).
ADD: permite añadir un archivo al contenedor, en muchas ocasiones se utiliza para proporcionar la configuración de los servicios (ssh, mysql, ...).
VOLUME: establece puntos de montaje que al usar el contenedor se pueden proporcionar, los volúmenes son al forma de externalizar un determinado directorio y proporcionar persistencia (las imágenes de docker son de solo lectura y no almacenan datos entre diferentes ejecuciones).
EXPOSE: indica los puertos TCP/IP por los que se pueden acceder a los servicios del contenedor, los típicos son 22 (SSH), 80 (HTTP) y en este caso el puerto por defecto de mysql 3306.
CDM: establece el comando del proceso de inicio que se usará si no se indica uno al iniciar un contenedor con la imagen.

Por ejemplo, aquí voy a definir un archivo de dockerfile. Simplemente hacemos esto

Vamos a cualquier parte de nuestra PC y creamos un nuevo archivo que vamos a llamar Dockerfile-base.txt

Dentro del mismo, copiamos y pegamos lo siguiente:

Código: php
FROM phusion/baseimage:0.9.15
MAINTAINER picodotdev <[email protected]>

ENV HOME /root

RUN apt-get update -q

RUN /etc/my_init.d/00_regen_ssh_host_keys.sh

RUN echo 'root:$6$l/PahbyY$jFhqIAuvHeK/GwjfT71p4OBBkHQpnTe2FErcUWZ8GIN1ykdI7CgL05Jkk7MYW6l.0pijAlfoifkQnLpaldEJY0' | chpasswd -e

ADD bashrc /root/.bashrc
ADD timezone /etc/timezone

EXPOSE 22

CMD ["/sbin/my_init"]


Ahora, en el mismo lugar, creamos un nuevo archivo al que llamaremos Dockerfile-mysql.txt con lo siguiente:

Código: php
FROM picodotdev/base:1.0
MAINTAINER picodotdev <[email protected]>

ENV HOME /root

RUN apt-get install -y mysql-server mysql-client

ADD my.cnf /etc/mysql/my.cnf
RUN mkdir /etc/service/mysql
ADD mysql /etc/service/mysql/run
RUN chmod +x /etc/service/mysql/run

RUN rm -R /var/lib/mysql && \
mkdir /var/lib/mysql && \
    mkdir /mnt/keys

VOLUME ["/var/lib/mysql", "/mnt/keys"]

RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

EXPOSE 22 3306

CMD ["/sbin/my_init"]


El Dockerfile-base crea una imagen base que usaremos posteriormente en la imagen de mysql, configura el color del prompt, la contraseña de root y expone el puerto 22 para poder hacer ssh.

En este ejemplo en vez de usar una imagen propia de Ubuntu en la directiva FROM he usado una imagen especial, phusion/baseimage:0.9.15. La imagen phusion/baseimage proporciona un sistema init adaptado al funcionamiento de los contenedores de docker al contrario de las imágenes de ubuntu que emplean upstart. Si usásemos alguna imagen de ubuntu y quisiésemos iniciar varios procesos en el contenedor deberíamos usar un servicio como punto de entrada como supervisord, con la imagen phusion/baseimage no sería necesario ya que ya ofrece esta funcionalidad de forma más sencilla.

Con las instrucciones RUN y ADD instalamos el paquete de mysql y el cliente de mysql y añadimos la configuración de mysql en el archivo my.cnf. En /etc/service/mysql/run dejamos el comando del servicio que iniciará el proceso de mysql como espera el sistema init de la imagen phusion. Con VOLUME ["/var/lib/mysql"] establecemos un punto de montaje para poder externalizar y persistir los datos de las bases de datos de mysql.

Ahora, para poder generar nuestra imagen a partir de estas recetas, necesitamos ejecutar los siguientes comandos, que al final explicare como están compuestos, dentro del mismo directorio donde están ambos dockerfiles:

Código: php
docker build -t "picodotdev/base:1.0" docker/base
docker build -t "picodotdev/mysql:1.0" docker/mysql


Este comando nos indica que con docker build va a crear una nueva imagen utilizando el dockerfile llamado picodotdev/base:1.0, donde picodotdev es el nombre del MAINTAINER y base o mysql es el nombre del archivo, y por ultimo, el nombre de la imagen, en estos casos, la primera que creamos se llama docker/base y la segunda docker/mysql

Obtendremos por pantalla algo similar a esto (Imagen tomada desde linux)


Para probar la imagen recién creada, solo tenemos que consultar la lista de imágenes que tenemos en nuestro directorio de imágenes de docker. Para eso, ejecutamos el comando

Código: php
docker images


Ahora, para crear un container con la imagen recién creada, repetimos el paso del capitulo 4, donde creamos el container, pero, colocamos el nombre de nuestra nueva imagen generada.

CitarFUENTE: Blog Bitix
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

7- Volumes


Bueno, ahora un problema muy común que tenemos a la hora de usar docker, es que los containers que creamos, son efímeros. ¿Que quiero decir con esto?, que en el momento que muere un container muere toda la información dentro de el. Esto significa, que los containers no guardan estado... por si solos. Hay forma de guardar la información que va generando un container fuera del contenedor en nuestra maquina real. Esto es muy útil por si necesitamos matar un contenedor, que su información no muera, para posteriormente levantarlo y continuar teniendo todos los datos que trabajamos antes. Incluso para compartir datos con alguien.

Bueno, vamos a empezar, y para esta parte, vamos a utilizar la imagen de docker que descargamos llama Jenkins

CitarNOTA: En este curso no aprenderemos a usar Jenkins, solo utilizaremos su imagen para generar datos dentro de volúmenes

Normalmente, para crear un container de docker, con la imagen de Jenkins, correríamos el siguiente comando (NO LO HAGAN)

Código: php
docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:


Pero, eso generaría un container efímero que moriría junto a toda nuestra información al momento de matarlo

Entonces, vamos a crear el contenedor, de la siguiente forma, reemplazando el jenkins_home que esta en negríta, por la url del destino de la carpeta donde queremos guardar la información

Código: php
docker run -p 8080:8080 -p 50000:50000 -v [b]jenkins_home[/b]:/var/jenkins_home jenkins/jenkins


Lo que hace el parámetro de -v jenkins_home:/var/jenkins_home es definir donde se va a crear la carpeta contenedora de toda la información del container de Jenkins. Hay que reemplazar la ruta en negrita por el path en nuestra pc donde nosotros queramos que se almacene la información.

Si van al directorio después de ejecutar el comando, verán una carpeta llamada jenkins_home, donde se guardaran todos los datos de nuestro Jenkins

Bueno, ahora vamos a probar si todo esto que dijimos e hicimos es verdad. Para eso vamos a nuestro navegador y escribimos:

Citarlocalhost:8080

Se abrira el Jenkins que acabamos de montar

CitarNOTA: Al principio pedirá una contraseña, la misma se puede sacar de la consola donde levantamos el contenedor, o, del archivo llamado secret que esta en la ubicación: /var/jenkins_home/secrets/initialAdminPassword

Una vez configurado, elegimos crear un usuario, o continuar como administrador, le damos en instalar con los plugins que nosotros elijamos, y desactivamos todo, para tener una instalación de Jenkins limpia.

Luego, estaremos dentro del Home de Jenkins. Si queremos, creamos un nuevo Job, y le ponemos un nombre pero no es necesario.

Ahora, vamos a una nueva consola y cerramos nuestro container y luego lo matamos usando los comandos ya aprendidos

Código: php
docker stop (nombre del container)

Código: php
docker rm (nombre del container)


Ahora, vamos a volver a crear el conainer, con la misma linea de comando que creamos al principio:

Código: php
docker run -p 8080:8080 -p 50000:50000 -v [b]jenkins_home[/b]:/var/jenkins_home jenkins/jenkins


CitarNOTA: Recuerden colocar el mismo path que usaron en el comando anterior de creación de container para Jenkins

Bien, esto hará que cuando se cree nuestro nuevo conainer, vaya a buscar los datos a esa ruta, y si no existen, los creara de nuevo

Ahora, vamos de nuevo a:

Citarlocalhost:8080

Debería pedirnos el pass de administrador, y una vez dentro, veríamos el mismo Job que creamos (De haberlo creado), ya que hemos hecho que los datos persistan. Si no crearon el Job, con el simple hecho que no les pida que coloquen el password de activación, que es el que vemos en la consola en el momento de levantar Jenkins, significa que ya ha guardado los estados.

Ahora bien, vamos a crear un volumen de datos, para asignarlo de forma mas fácil

Abrimos una nueva terminal de nuestra consola y ejecutamos el siguiente comando:

Citardocker volume create jenkins_volume

Con esto hemos creado un volumen local listo para usarse, entonces, si queremos ver todos nuestros volúmenes creados localmente, ejecutamos el siguiente comando

Código: php
docker volume ls


Deberíamos ver el volumen recién creado

Ahora, vamos a eliminar el primer container de Jenkins que creamos, y los datos generados por su ruta de volúmenes

Código: php
docker stop (Nombre del container de Jenkins)

Código: php
docker rm (Nombre del container de Jenkins)


Ahora, vamos manualmente al lugar físico donde nosotros indicamos el lugar de creación de la carpeta jenkins_home en la creación del contenedor anterior, y la eliminamos por completo

De esta forma hemos eliminado tanto el contenedor que creamos y todos sus datos

Bien, ahora, vamos a utilizar el volumen que acabamos de crear, llamado jenkins_home, en nuestro nuevo container. Para eso, ejecutamos el siguiente comando:

Código: php
docker run --name jenkins -p 8080:8000 -p 50000:50000 -v jenkins_volume:/var/jenkins_home jenkins/jenkins


Noten que hemos reemplazado el path donde nosotros indicábamos donde se generarían las carpetas, por el nombre del volumen que acabamos de crear. Entonces, ahora es mas fácil manejar toda la información, si se encuentra dentro de un volumen ya creado.

Ahora repetimos el proceso anterior de instalación de Jenkins, dirigiéndonos a la ruta de localhost:8080, realizando toda la configuración inicial, y los datos no se borraran.

Ahora, podemos crear otro container, al cual le podemos asignar el mismo volumen, y se comparta la misma información del mismo volumen entre varios contenedores.


:o  Hermano qué pedazo de curso, muchas gracias, lo compartiré con gente amiga que lo necesita. No me quedó bien en claro una cosita no más, el tema de los requisitos? Están ahí especificados a nivel software pero no sé si a nivel hardware, o sea RAM, procesador, etc... Gracias!  8) 

Tremendo el post!

Llegué sólo hasta el nivel intermedio, el avanzado no lo entendí (falta de conocimiento, claramente). Muy buen tuto, se agradece!