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.