Registro y descubrimiento de servicios en contenedores de Docker con Consul y Registrator

Escrito por el .
planeta-codigo programacion software
Comentarios

En los microservicios se hace necesario un servicio de registro y descubrimiento como Eureka o Consul que permita conocer la ubicación de las instancias en cada momento. Las instancias de los servicios se pueden registrar ellas mismas o esta tarea se puede delegar en una en otro servicio. Al usar contenedores de Docker una herramienta que permite delegar el registro y desregistro en Consul de los servicios es GliderLabs Registrator.

Consul
Docker

El registro y descubrimiento de servicios permite a los servicios registrase y a los clientes descubrir la ubicación de otros servicios, la ubicación consiste en la dirección IP y el puerto en el que contactarles. Dado la naturaleza efímera de los servicios donde nuevas instancias de servicios se inician y se detienen en diferentes máquinas y puertos el servicio de descubrimiento es esencial.

La funcionalidad de registro y descubrimiento consiste en dos partes, por un lado cuando se inicia una instancia de un servicio se registra su ubicación en el servicio de registro y descubrimiento y por otro lado los clientes cuando requieren una instancia de un servicio la buscan en el servicio de descubrimiento.

El registro en el servicio de descubrimiento puede hacerse de dos formas, que sea el propio servicio el que se registra en el servicio de descubrimiento o que se sea otro servicio el que lo registra. Para el primer caso escribí un artículo con Consul como servicio de descubrimiento en una aplicación de Spring Boot que se registra al iniciarse. La ventaja es que es autosuficiente pero adquiere la tarea de autoregistrarse. Por el contrario delegar la trea de registro permite extraerla de los servicios y ofrecer esa funcionalidad por un servicio con esa misión específicamente.

En este artículo se usa GliderLabs Registrator como servicio que se encarga de registrar en un servicio de descubrimiento como Consul los servicios que se inicien en Docker, aunque soporta otros como etcd.

Registrator es un contenedor de Docker, su funcionamiento es escuchar los eventos del demonio de Docker y monitorizar cuando se inician nuevos contenedores o cuando se paran. La monitorización la hace a través del socket del servicio de Docker, para lo que hay que montar un volumen en este contenedor con el archivo /var/run/docker.sock del host.

Primero se inicia el servicio de Consul.

1
$ consul agent -dev

Luego se inicia el contenedor Registrator indicando la ubicación con dirección IP y puerto del servicio de Consul.

1
$ docker run --rm --name=registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest consul://localhost:8500

Iniciados estos dos servicios en la interfaz de estado de Consul se observa que no hay ningún servicio pero cuando se inicie un nuevo contenedor será registrado en Consul por Registrator.

En este caso se utiliza como servicio una base de datos PostgreSQL. Dado que el puerto en el que esté disponible el servicio de PostgreSQL es indiferente al utilizar un servicio de registro y descubrimiento se indica el -p sin indicar el puerto del host, de este modo Docker le asigna un puerto público aleatorio.

1
$ docker run --rm --name postgres -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password -e POSTGRES_DB=database -p 5432 postgres:alpine
1
2
3
4
$ docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED              STATUS              PORTS                     NAMES
cb7602605725        postgres:alpine                 "docker-entrypoint.s…"   54 seconds ago       Up 53 seconds       0.0.0.0:32777->5432/tcp   postgres
d286341148cb        gliderlabs/registrator:latest   "/bin/registrator co…"   About a minute ago   Up About a minute                             registrator

En la salida del contenedor de Registrator se emite una traza indicando que el servicio de postgres ha sido registrado en Consul.

1
2
3
4
5
6
7
8
2019/05/26 11:05:29 Starting registrator v7 ...
2019/05/26 11:05:29 Using consul adapter: consul://localhost:8500
2019/05/26 11:05:29 Connecting to backend (0/0)
2019/05/26 11:05:29 consul: current leader  127.0.0.1:8300
2019/05/26 11:05:29 Listening for Docker events ...
2019/05/26 11:05:29 Syncing services on 1 containers
2019/05/26 11:05:29 ignored: d286341148cb no published ports
2019/05/26 11:05:50 added: cb7602605725 archlinux:postgres:5432

Una vez iniciado el servicio de postgres en la consola de Consul se muestra con su dirección y puerto en el que se encuentra, en el contenedor utiliza su puerto por defecto 5432 pero hacia el exterior en este caso al no haber especificado uno Docker le asigna un puerto aleatorio en este caso el 32777. Este puerto aleatorio es con el que los clientes acceden a la base de datos.

Servicio de postgres registrado en Consul por Registrator

En vez de iniciar los servicios individualmente con comandos de Docker creando un archivo de Docker Compose con la definición de todos los contenedores se facilita iniciar todos los contenedores con un comando.

1
$ docker-compose up
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: "3.7"
services:
  consul:
    image: consul:latest
    container_name: consul
    network_mode: "host"
    command: ["consul", "agent", "-dev", "-ui"]
  registrator:
    image: gliderlabs/registrator:latest
    container_name: registrator
    network_mode: "host"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    entrypoint: /bin/registrator consul://localhost:8500
    depends_on:
      - consul
  postgres:
    image: postgres:alpine
    container_name: postgres
    ports:
        - "5432"
    environment:
        - POSTGRES_USER=user
        - POSTGRES_PASSWORD=password
        - POSTGRES_DB=database
    depends_on:
      - registrator

El proyecto de Spring Cloud ofrece soporte para ambas tareas de registrar y descubrir servicios, aunque perfectamente la tarea de registro se puede delegar como en este caso a Registrator y utilizar en los servicios de Spring Boot únicamente la parte de descubrimiento.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./docker-compose-up.sh.

Este artículo forma parte de la serie docker:

  1. Introducción y características de Docker
  2. Inicio básico de Docker
  3. Cómo crear una imagen para Docker usando un Dockerfile
  4. Integración entre Ansible y Docker
  5. Aplicaciones multicontenedor con Docker Compose
  6. Crear y usar un repositorio en Docker Hub
  7. Usar docker con Docker Machine en Linux, Windows o Mac
  8. Cambiar la ruta raíz del entorno de Docker
  9. Introducción y ejemplo de cluster de contenedores con Docker Swarm
  10. Iniciar un stack de servicios en un cluster de Docker Swarm
  11. Escalar y actualizar un servicio de un cluster de Docker Swarm
  12. Contenedores en Docker Swarm con volúmenes de datos persistentes usando REX-Ray y VirtualBox
  13. Información sensible en los contenedores con Docker Secrets
  14. Imágenes de Docker con Alpine Linux
  15. Registro y descubrimiento de servicios en contenedores de Docker con Consul y Registrator

Este artículo forma parte de la serie hashicorp:

  1. Introducción a Nomad para gestionar aplicaciones y microservicios
  2. Estrategias de despliegue para microservicios con Nomad
  3. Servicios con persistencia en el orquestador de microservicos Nomad
  4. Crear de forma sencilla y rápida máquinas virtuales de VirtualBox con Vagrant
  5. Registro y descubrimiento de servicios en contenedores de Docker con Consul y Registrator
  6. Administrar secretos y proteger datos sensibles con Vault
  7. Generar credenciales de conexión a base de datos bajo demanda con Vault
  8. Utilizar credenciales de conexión a la base de datos generadas por Vault en una aplicación de Spring
  9. Microservicios con Spring Cloud, Consul, Nomad y Traefik