Actividad: Introducción a Docker
Objetivos
- Parte 1: Introducción a la arquitectura de microservicios y contenedores.
- Parte 2: Topología y Preparación del Entorno.
- Parte 3: Instalación de mi primer contenedor en Docker.
- Parte 4: Aislamiento y exposición de servicios (Port Forwarding).
- Parte 5: Orquestación básica con Docker Compose.
Escenario
En esta última década, el desarrollo de cloud nos ha planteado una serie de nuevos desafíos que poco a poco se van solucionando con innovadoras soluciones. Entre estos se encuentra un gran reto que es el empaquetado, despliegue y distribución de aplicaciones. Es en este contexto que aparece la arquitectura de microservicios, ofreciendo un nuevo enfoque en el desarrollo del software.
Este desarrollo está basado en potenciar la autonomía de cada servicio o funcionalidad, lo cual implica el hecho de “dividir” la aplicación en componentes más pequeños, llamados servicios, para que estos puedan ser mantenidos, ejecutados y distribuidos de forma totalmente independiente. Diferenciándose de la tradicional arquitectura monolítica donde se integran todas esas funcionalidades en un único componente.
Las aplicaciones tradicionales escalan de manera vertical, en cambio los microservicios son independientes y se comunican entre sí mediante APIs o recursos HTTP, lo cual nos permite escalar de manera horizontal y de forma aislada. Los microservicios están íntimamente relacionados al concepto de contenedores, ya que estos nos permiten empaquetar todo lo necesario para que un servicio se ejecute de manera encapsulada dentro de una sola imagen, la cual es independiente del equipo donde se ejecute.
Existen varias soluciones de contenerización en el mercado, pero sin dudas la más extendida y la que utilizaremos en el curso es Docker.

![[virtualization-vs-containers.png]]
Parte 1: Introducción a la arquitectura de microservicios
Para entender el contexto de la contenerización, es fundamental conocer su definición y evolución. Según Red Hat, un contenedor es: “Conjunto de uno o más procesos separados del resto del sistema. Todos los archivos que se necesitan para ejecutarlos provienen de una imagen diferente, lo cual significa que los contenedores de Linux son portátiles y uniformes durante todas las etapas: desarrollo, prueba y producción.”
No es una tecnología nueva, ya que en el año 2000 se implementó FreeBSD Jail, lo que en esencia era un contenedor, permitiendo generar un entorno aislado compartiendo el kernel del sistema operativo host. No tardó tanto, ya que en el año siguiente Linux incorporó el entorno aislado en su kernel mediante el proyecto Vserver.
Contexto de la contenerización:
En el año 2015 se creó el OCI (Open Container Initiative) un proyecto de Linux Foundation para diseñar un estándar abierto para la contenerización y cuyo objetivo es que las plataformas de contenedores no estén vinculadas a ninguna empresa o proyecto concreto.

![[oci.png]]
Pero no fue hasta el año 2008 que apareció Docker, incorporando una serie de conceptos y herramientas como:
* CLI sencilla: Para ejecutar y diseñar imágenes nuevas basadas en capas.
* Un daemon de servidor: Encargado de gestionar los objetos de Docker.
* Una biblioteca de imágenes: Concepto de servidor de registros e imágenes prediseñadas.

![[docker-arch.png]]
Parte 2: Topología y Preparación del Entorno
En esta etapa, prepararemos la infraestructura base sobre la cual desplegaremos nuestros servicios. Es fundamental mantener la consistencia entre la infraestructura física/virtual y nuestra "Fuente de Verdad" (Source of Truth).
1. Despliegue de la Maquina Virtual:
Debe desplegar una máquina virtual vía cloud-init en su computadora anfitriona (host) con las siguientes especificaciones:
* Hostname: FLAGLSR01
* Segmento de Red: SERVIDORES (VLAN 1)
* OVA: https://cloud-images.ubuntu.com/noble/current/

![[unidades/unidad-2/hands-on/assets/topologia_red|900]]
2. Documentación en NetBox: Antes de proceder con la configuración técnica, registre toda la información correspondiente en NetBox. Asegúrese de ubicar los activos dentro del Tenant asignado a su usuario, incluyendo:
- Creación del prefijo de red para el segmento
SERVIDORES. - Registro del dispositivo (Virtual Machine) con su respectiva interfaz y dirección IP.
3. Configuración de Red e Internet:
Una vez realizado el despliegue de la VM, aplique las configuraciones necesarias en su entorno de virtualización para que el equipo tenga salida a Internet a través de su router de borde FLAGLRO01. Verifique la conectividad desde FLAGLSR01 mediante:
ping -c 4 google.com
Cuando tenga respuesta exitosa, continué a la siguiente sección.
4. Instalación de Docker Engine: Con la conectividad validada, procederemos a transformar nuestra VM en un nodo de contenedores. Realice la instalación de Docker siguiendo como referencia la documentación oficial para sistemas basados en Debian/Ubuntu:
Referencia: https://docs.docker.com/engine/install/ubuntu/
Al finalizar, se debe agregar el usuario al grupo docker , de lo contrario se denegara el acceso al comunicarse con docker engine mediante docker cli:

![[docker-ps.png]] Desde el contexto de superusuario:
sudo usermod -aG docker $USER
Para que el cambio sea global (y desde las sesiones remotas reconozcan que ya se tiene permiso de Docker), lo ideal es cerrar la sesión del usuario y volver a iniciar.
Parte 3: Instalación de mi primer contenedor en Docker
Luego de verificar que nuestro entorno es el adecuado, comenzaremos con el despliegue práctico. Utilizaremos una imagen oficial de Nginx, un servidor web de alto rendimiento.
Para listar las imágenes disponibles localmente utilizaremos el comando: docker images
![[docker-images.png]]
Para descargar e iniciar nuestro primer contenedor, ejecutaremos:
docker run -d --name mi-servidor-web nginx
Explicación de los parámetros:
- -d: Ejecuta el contenedor en segundo plano (detached).
- --name: Asigna un nombre específico para identificarlo fácilmente.
![[docker-run.png]]
Podemos ver el contenedor en ejecución con: docker ps

![[docker-ps-2.png]]
Como no configuramos ningún modo de red específico, el contenedor está aislado a nivel de networking con nuestra VM. Por lo tanto, necesitamos utilizar la IP interna de la red de Docker para obtener el contenido del servidor nginx mediante el cliente curl:
curl http://172.17.0.2

![[curl.png]]
Parte 4: Aislamiento y exposición de servicios (Port Forwarding)
En un entorno de producción, necesitamos que los servicios sean accesibles desde el exterior de la VM (por ejemplo, desde nuestra red de gestión o VLANs específicas). Para esto, utilizaremos el concepto de Port Forwarding, indicando qué puerto de nuestra VM se redireccionará a qué puerto dentro del contenedor.
- Despliegue con mapeo de puertos:
docker run -d -p 3000:80 --name web-puerto-3000 nginx
De esta forma, todo request HTTP que se realice a nuestra VM al puerto indicado (3000 en nuestro caso) se redireccionará hacia dentro del contenedor al puerto 80, donde está el proceso de nginx atendiendo las peticiones.
- Uso de aplicaciones en ReactJS: Una vez que finalicemos el contenedor anterior, podemos iniciar otro utilizando la imagen docker/getting-started, la cual se compone de una guía interactiva sobre el uso de Docker:
docker run -d -p 80:80 docker/getting-started

![[docker-run-2.png]]
Parte 5: Orquestación básica con Docker Compose
A medida que nuestras aplicaciones crecen, gestionar cada contenedor manualmente con docker run se vuelve ineficiente. Para solucionar esto, utilizamos Docker Compose.
Docker Compose es una herramienta que permite definir y ejecutar aplicaciones multi-contenedor. Mediante un archivo de configuración en formato YAML, podemos definir los servicios, redes y volúmenes necesarios para que nuestra aplicación funcione como una sola unidad.
1. Creación del archivo de configuración:
Cree un directorio para su proyecto y dentro un archivo llamado docker-compose.yml:
services:
web-nginx:
image: nginx
ports:
- "4000:80"
restart: always
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./data:/app/data
ports:
- "4001:3001"
2. Despliegue de la pila de servicios:
Para iniciar todos los servicios definidos en el archivo, utilice el comando: docker compose up

![[docker-compose.png]] Como podemos observar, el stack de contenedores desplegados vía docker compose queda asociada a esa terminal (foreground). Para finalizar la ejecución de los mismos, se puede usar la combinación de teclas Control + C.
3. Ejecución en modo Detach:
En entornos de servidor, necesitamos que los servicios continúen funcionando aunque cerremos nuestra terminal. Para esto, utilizamos el parámetro -d (detach), que envía la ejecución al segundo plano:
docker compose up -d

![[docker-compose-dettach.png]]
4. Gestión del ciclo de vida:
-
Ver estado de los servicios del proyecto:
docker compose ps -
Detener y eliminar los contenedores y redes:
docker compose down