RousselTMLEARNING

TP · Docker : del descubrimiento al nivel experto

Proyecto 1 con corrección

La corrección está integrada en el TP (Ver los recuadros verdes)

Lo que vas a aprender en este TP
  • Instalar Docker
  • Activar el modo SWARM de Docker
  • Crear un archivo Dockerfile
  • Modificar y/o anular un archivo docker compose existente
  • Crear un archivo Docker compose a partir de una necesidad
  • Desplegar un archivo docker compose
  • Crear una pila/servicio docker con un archivo docker compose
  • Monitorear su infraestructura con Prometheus/Grafana
  • Desplegar un registro privado con Harbor
  • Desplegar un registro Harbor
  • Importar una imagen en un registro
  • Buscar vulnerabilidades en una imagen
  • Configurar la sobreescritura de un archivo docker compose
  • Uso avanzado de etiquetas (labels) (Implementación en el Proyecto 2)

Introducción #

Lo que vas a aprender en esta sección
  • Instalar Docker
  • Activar el modo SWARM de Docker
  • Crear un archivo Dockerfile
  • Modificar y/o anular un archivo docker compose existente
  • Crear un archivo Docker compose a partir de una necesidad
  • Desplegar un archivo docker compose
  • Crear una pila/servicio docker con un archivo docker compose
  • Monitorear su infraestructura con Prometheus/Grafana
  • Desplegar un registro privado con Harbor
El objetivo de este proyecto es hacerle manipular diferentes nociones en torno a Docker y sobre todo combinarlas para alcanzar un objetivo. Para esto, instalaremos y configuraremos un clúster de Docker con SWARM activado y desplegaremos en él diferentes subproyectos en forma de stack (pila). El objetivo es configurar esta arquitectura: Una configuración de hardware recomendada es de 16 GB de RAM.

Entorno de prueba #

Para realizar este TP, necesitará un entorno Ubuntu (pero el TP se puede hacer con otros sistemas operativos/distribuciones). En esta máquina, crearemos 3 máquinas virtuales con las siguientes características:
  • Máquina virtual 1 :
    • Nombre : manager
    • vCPU : mínimo 2
    • RAM : mínimo 2 GB
    • IP : 192.168.56.2
  • Máquina virtual 2 :
    • Nombre : worker1
    • vCPU : mínimo 2
    • RAM : mínimo 2 GB
    • IP : 192.168.56.3
  • Máquina virtual 3 :
    • Nombre : worker1
    • vCPU : mínimo 2
    • RAM : mínimo 2 GB
    • IP : 192.168.56.4
Para ayudarle a configurar este entorno, hemos puesto a su disposición un repositorio con una configuración Vagrant/Virtualbox lista para usar.

RECORDATORIO: Este TP está dedicado a la configuración de Docker, pero dado que es un TP avanzado, necesitará nociones y conocimientos de DevOps que no son exclusivos de Docker pero que se utilizarán en sus configuraciones. Necesitará las siguientes habilidades que puede aprender gratis: Obviamente, pondremos a su disposición el máximo de información para que avance incluso sin estos requisitos previos.

Para esto, necesita instalar Vagrant y Virtualbox en su máquina. Una vez hecho esto, solo necesita ejecutar los siguientes comandos:
git clone https://github.com/RousselTM/docker-formation
cd docker-formation/tp/6_projet
vagrant up

Preconfiguración #

Se necesitan las siguientes acciones para preparar su entorno de prueba.

  1. Los dominios

    Debe declarar los siguientes dominios en su máquina (en el archivo hosts). Se utilizarán para acceder a los diferentes subproyectos y deben apuntar a 127.0.0.1 (En el siguiente TP introduciremos Traefik para optimizar la gestión de puertos):
    • tp.elearning.rousseltm.fr: Para acceder a las aplicaciones. Por ejemplo, para acceder a la aplicación 1, usaremos la dirección http://tp.elearning.rousseltm.fr/app1
    • registry.tp.elearning.rousseltm.fr : para acceder a Harbor
    • grafana.tp.elearning.rousseltm.fr : para acceder a Grafana
    • prometheus.tp.elearning.rousseltm.fr : para acceder a Prometheus
    En la empresa, debe utilizar un servidor DNS.
    Debe agregar esta información al archivo hosts. La ruta para acceder al archivo variará dependiendo de su SO anfitrión:
    • /etc/hosts : Linux
    • C:\Windows\System32\drivers\etc : Windows
    También necesitará derechos de administrador.
  2. Instalación de Docker

    Puede verificar si sus máquinas se han iniciado correctamente con el siguiente comando:
    vagrant status
    Si se iniciaron correctamente (status running), puede conectarse a la máquina manager con el siguiente comando:
    vagrant ssh manager
    Ahora solo tiene que instalar Docker en todas las máquinas virtuales. Una vez realizada la instalación, debe iniciar el servicio y configurarlo para que se inicie automáticamente.
    Encuentre todos los procedimientos de instalación de docker en esta página Instalación de Docker.

    Para nuestro TP, seguiremos el procedimiento para el SO Ubuntu. Se deben privilegiar los procedimientos que se basan en el administrador de paquetes: apt, dnf, yum.

    Puede pedirle a Vagrant que realice la instalación automáticamente:
    Solo necesita definir la variable de entorno ROUSSELTM_DEPLOY_DOCKER en 'true' al momento de crear las máquinas y la configuración de Vagrant instalará Docker
    ROUSSELTM_DEPLOY_DOCKER=true vagrant up
    Debe ejecutar los siguientes comandos para iniciar y habilitar el inicio automático de Docker respectivamente
    sudo systemctl start docker
    sudo systemctl enable docker
    Vagrant también puede configurar automáticamente su clúster Docker SWARM:
    ROUSSELTM_DEPLOY_SWARM=true vagrant up
    Obviamente, en una empresa, debería utilizar su solución de configuración como código (Ansible, proyecto Salt, ...).
  3. Modo SWARM

    Debe configurar el clúster de Docker con el modo SWARM activado. La máquina 'manager' debe ser el administrador del clúster y las máquinas 'workerX' deben ser los trabajadores del clúster. Como las máquinas tienen varias direcciones IP, usaremos la IP 192.168.56.2 como dirección de gestión del plano de control.
    RECORDATORIO: En todas las máquinas creadas por Vagrant hay una carpeta /vagrant que corresponde al montaje de la carpeta donde se encuentra el archivo Vagrantfile: es decir, el contenido de la carpeta 6_projet. Por lo tanto, puede utilizar esta carpeta para compartir archivos entre las máquinas. Por ejemplo, el archivo que contiene los tokens para unirse al clúster. Obviamente en Producción, deberá utilizar una solución más segura.
    Debe proporcionar el comando de Docker que permitirá almacenar en /vagrant/swarm-token-worker el token para unirse al clúster como trabajador (worker).
    Debe inicializar el modo swarm en una máquina destinada a ser el manager, por lo que en nuestro caso en la máquina 'manager' con el siguiente comando:
    docker swarm init --advertise-addr 192.168.56.2 --listen-addr 192.168.56.2
    También puede usar el nombre de la interfaz de red en lugar de la IP (método recomendado).

    Para generar y compartir el token que se usará en los nodos trabajadores (worker):
    docker swarm join-token -q worker > /vagrant/swarm-token-worker
    En los nodos trabajadores, puede unirlos con el siguiente comando:
    docker swarm join --advertise-addr 192.168.56.2 --listen-addr 192.168.56.2 --token `cat /vagrant/swarm-token-worker` 192.168.56.2:2377
  4. Red compartida

    Debe crear las siguientes redes:
    • common-proxy: para la comunicación entre contenedores a través del proxy. Se usará completamente en el siguiente TP con el uso de Traefik.
    • common-observability: para la comunicación entre los contenedores de observabilidad
    Realizaremos una implementación mixta para manipular la comunicación entre los subproyectos implementados con el modo SWARM y aquellos sin el modo SWARM. Por lo tanto, es necesario configurar el parámetro correcto en la red 'common-proxy' durante su creación.
    En una máquina con el estado de administrador (en nuestro caso es la máquina llamada manager), puede hacerlo con los siguientes comandos:
    docker network create --driver overlay --attachable common-proxy
    docker network create --driver overlay common-observability
    El hecho de usar el controlador overlay activa automáticamente el 'alcance' (scope) SWARM.

Subproyecto 1 #

Lo que vas a aprender en esta sección
  • Desplegar un registro Harbor
  • Importar una imagen en un registro
  • Buscar vulnerabilidades en una imagen
  • Configurar la sobreescritura de un archivo docker compose
  • Uso avanzado de etiquetas (labels) (Implementación en el Proyecto 2)
Vamos a crear un registro de docker con Harbor en la máquina manager. Lo haremos funcionar en el dominio registry.tp.elearning.rousseltm.fr. Para este primer proyecto, lo implementaremos en HTTP en el puerto 5000 (puerto predeterminado de los registros Docker en HTTP).
RECORDATORIO: El sitio oficial de Harbor https://goharbor.io/ y puede revisar el video de presentación de Harbor en esta dirección: Presentación y despliegue de Harbor
  1. Despliegue

    Debe instalar Harbor con el servicio trivy en el puerto 5000. Si todo está bien, debería poder acceder a Harbor desde la máquina anfitriona en la dirección
    http://registry.tp.elearning.rousseltm.fr:5000
    INFORMACIÓN: En la carpeta 6_projet, tiene una carpeta llamada 'projects' cuyo contenido se montará automáticamente en /opt/projects en todas las máquinas virtuales. Así que puede usarla para gestionar los archivos de sus subproyectos. Recomendamos 1 carpeta por subproyecto.
    Debe seguir el procedimiento descrito en el sitio web de Harbor para descargarlo e instalarlo
    https://goharbor.io/docs/2.11.0/install-config/download-installer/
  2. Personalización

    El script install.sh generó un archivo docker-compose.yml por lo que si deseamos modificar parámetros deberemos editar este archivo. Pero perderemos todas nuestras modificaciones en cada ejecución del script.

    Debe proponer una solución para evitar esto sabiendo que queremos que el contenedor 'proxy' se conecte a la red 'common-proxy' y que tenga la etiqueta (label) dt.owner (Explicación de esta etiqueta Dynatrace) con el valor 'equipe1'. Al mismo tiempo, agregue una etiqueta para decirle a Filebeat que no tome en cuenta sus registros (logs).

    Inicialmente lo desplegaremos simplemente con 'docker compose' para probar y posteriormente en forma de stack 'docker stack'.

    ATENCIÓN: La sobreescritura también debe ser tomada en cuenta por el script install.sh
    Como el script no tiene la opción -f para pasar un archivo de sobreescritura (override), es necesario utilizar el archivo de sobreescritura predeterminado
    compose.override.yml
    con el siguiente contenido

Subproyecto 2 #

  1. Build de la imagen

    Debe crear un Dockerfile para construir una imagen para la siguiente aplicación GO que se llamará simple-app y tendrá la etiqueta 1.0: Esta aplicación debe generar un binario '/app/simple-app' y usar '/app' como directorio de trabajo.
    Aquí hay un ejemplo de Dockerfile: Atención, se debe hacer una compilación multi-etapa (multi-stage) para evitar terminar con herramientas de desarrollo (DEV) en la imagen final. Puede compilar (build) la imagen con el siguiente comando:

    docker build -t simple-app:1.0 .
  2. Adición de la imagen al registro Harbor

    Debe enviar esta imagen al proyecto (Explicación sobre el concepto de proyecto en Harbor) 'library' en Harbor. Elegimos 'library' porque es el proyecto público predeterminado. Así, la imagen podrá ser utilizada en otros proyectos (Ver el siguiente TP). Para recordar, tras su instalación, Harbor está disponible en la dirección
    http://registry.tp.elearning.rousseltm.fr:5000
    Como nuestro registro está en HTTP, se debe indicar a Docker que haga una conexión HTTP en lugar de HTTPS predeterminado. Por lo tanto, hay que agregar esta configuración en el archivo '/etc/docker/daemon.json':
    {
    	...
    	"insecure-registries" : ["registry.tp.elearning.rousseltm.fr:5000"],
    	...
    }
    Aquí están los comandos para enviar la imagen al registro privado
    docker login registry.tp.elearning.rousseltm.fr:5000
    docker tag simple-app:1.0 registry.tp.elearning.rousseltm.fr:5000/library/simple-app:1.0
    docker push registry.tp.elearning.rousseltm.fr:5000/library/simple-app:1.0
  3. Análisis de vulnerabilidades (Scan)

    Debe escanear la imagen importada para verificar sus vulnerabilidades contra las fallas CVE.

    En la consola Harbor (http://registry.tp.elearning.rousseltm.fr:5000), debe seguir los siguientes pasos:
    1. Haga clic en el menú 'Projects' a la izquierda (abierto por defecto al conectarse a Harbor)
    2. Haga clic en el proyecto. En nuestro caso 'library'
    3. Haga clic en la imagen. En nuestro caso 'library/simple-app'
    4. Seleccione la imagen y las etiquetas (artefactos) a escanear. En nuestro caso la que tiene la etiqueta '1.0'
    5. Haga clic en el botón 'SCAN VULNERABILITY'
  4. Despliegue Docker

    La configuración a construir debe satisfacer estas necesidades:
    • Aplicación 2-tier: go y redis
    • Los servicios solo deben ejecutarse en los workers. Esta configuración debe ser externalizada para permitir compartirla con otras aplicaciones en el mismo caso.
    • Los servicios deben usar las últimas versiones (en producción use versiones fijas) de las imágenes oficiales y la aplicación GO usar la imagen construida anteriormente y disponible en Harbor.
    • 1 instancia de cada servicio
    • El servicio GO debe exportar la variable de entorno APP='APP1'
    • El servicio GO debe exportar la variable de entorno TASK_SLOT donde debe poner el número de réplica del contenedor (Las plantillas (templates)).
    • El servicio de la aplicación go debe estar conectado a la red 'common-proxy'
    Aquí hay un ejemplo del contenido del archivo docker compose
  5. Balanceo de carga (Load balancing)

    Debe verificar que cuando llame a la URL de la aplicación (http://tp.elearning.rousseltm.fr) realmente devuelve esta página y que los campos resaltados cambian cuando actualiza la página, alternando bien entre los dos contenedores:
    Dado que es una URL en HTTP, es posible que su navegador lo redirija automáticamente a HTTPS. Puede desactivar esta opción en el navegador, pero le recomendamos que use el modo de 'navegación privada' (debe reabrir la página para ver el balanceo de carga). También puede verificar esto en la línea de comandos con el comando curl:
    curl http://tp.elearning.rousseltm.fr/

Subproyecto 3 #

Subproyecto de observabilidad que consta de Prometheus, Grafana, Node exporter y cAdvisor. Este subproyecto es el de observabilidad y, por tanto, nos permitirá tener visibilidad sobre todo nuestro proyecto.

  1. Despliegue Docker

    La configuración a construir debe satisfacer estas necesidades:
    • Hacer accesible Grafana en el puerto 3000
    • Hacer accesible Prometheus en el puerto 9090
    Puede referirse a los comandos del subproyecto 2 para todo lo relacionado con el comando de ejecución. Si todo está en orden, su configuración debería parecerse a esta configuración: Atención a la parametrización de cAdvisor y Node exporter. Deben configurarse de forma que se cree un contenedor en cada nodo.
  2. Configuración de los servicios

    La configuración a construir debe satisfacer estas necesidades:
    • Importar automáticamente a Grafana la fuente de datos (datasource) de Prometheus y Elasticsearch
    • Importar los paneles (dashboards) con el ID: 609
    • Recopilar métricas de Traefik
    • Recopilar métricas de todos los nodos del clúster
    • Recopilar métricas de todos los contenedores
    Como se indica en el archivo compose.yaml, necesitamos:
    • Un archivo config/grafana/provisioning/datasources/datasource.yml: aquí hay un ejemplo de contenido

    • Un archivo config/prometheus/prometheus.yml: aquí hay un ejemplo de contenido Tenemos dos tipos de configuración:
      • static_configs : utilizado para instancias fijas
      • dns_sd_configs : utilizado para instancias dinámicas.

Nivel de dificultad : ●●●○○ (3/5)

Glossaire de la formation

Microservicios

Arquitectura donde una aplicación se divide en varios servicios pequeños e independientes, a menudo desplegados en la nube.

Docker

Herramienta que permite virtualizar y empaquetar aplicaciones dentro de contenedores ligeros para un despliegue óptimo.Ejemplo de despliegue de un con...

Prometheus

Sistema de monitorización y alertas de código abierto, particularmente adaptado para la recopilación de métricas en entornos dinámicos (como Kubernete...

Kubernetes

Plataforma de código abierto de orquestación de contenedores que permite automatizar el despliegue, el escalado y la gestión de aplicaciones en conten...

CI/CD

Integración Continua y Despliegue Continuo. Prácticas DevOps destinadas a automatizar las pruebas y el despliegue de aplicaciones para entregar de for...

Terraform

Herramienta de Infraestructura como Código (IaC) que permite definir y aprovisionar recursos de infraestructura en la nube y on-premise a través de ar...

Métricas

Medidas numéricas recopiladas a intervalos regulares (ej: CPU, RAM, tiempo de respuesta) utilizadas para evaluar el estado de salud general de un sist...

DevOps

Cultura, movimiento y prácticas destinadas a unificar el desarrollo de software (Dev) y la administración de infraestructuras informáticas (Ops).

API Gateway

Pasarela que sirve de punto de entrada único para todas las solicitudes hacia arquitecturas de microservicios. Gestiona el enrutamiento, la seguridad ...

Arquitectura

Diseño global y estructural de un sistema informático, definiendo sus diferentes componentes, sus relaciones y los principios que guían su evolución.

Artefacto (Artifact)

Resultado final de un proceso de compilación o construcción de software (build), como un archivo .jar, un archivo zip o una imagen de Docker, listo pa...

Repositorio (Repository)

Depósito de almacenamiento centralizado. Puede referirse a un repositorio de código fuente (ej: Git) o a un repositorio de artefactos y binarios (ej: ...

Ansible

Herramienta de automatización informática de código abierto (IaC) que permite la gestión de configuraciones, el despliegue de aplicaciones y la orques...