¿Cómo integrar API Gateway y Consul?

Fei Han

February 25, 2022

Ecosystem

Información de fondo

Consul es una solución de malla de servicios. Uno de sus núcleos, Consul KV, es una base de datos distribuida de clave-valor cuyo propósito principal es almacenar parámetros de configuración y metadatos, mientras que también permite a los usuarios almacenar objetos indexados.

En el modelo de arquitectura de microservicios, cuando los servicios upstream cambian debido a la expansión de capacidad, fallas de hardware, etc., la forma de mantener la información del servicio upstream mediante la escritura manual de la configuración puede llevar a un aumento significativo en el costo de mantenimiento. En respuesta, Apache APISIX proporciona un registro de descubrimiento de servicios para obtener dinámicamente la información más reciente de las instancias de servicio y reducir el costo de mantenimiento para los usuarios.

Actualmente, Apache APISIX admite el registro de descubrimiento de servicios basado en Consul KV con el módulo consul_kv contribuido por la comunidad.

Cómo funciona

Apache APISIX aprovecha el módulo consul_kv de la capacidad de almacenamiento distribuido de clave-valor de Consul KV para desacoplar el proveedor y el consumidor de un servicio e implementar las dos funciones principales de un registro de descubrimiento de servicios.

  1. Registro de servicios: Los proveedores de servicios registran sus servicios en el registro.
  2. Descubrimiento de servicios: Los consumidores de servicios encuentran la información de enrutamiento de los proveedores de servicios a través del registro.

Sobre esta base, Apache APISIX será más flexible y adaptable a las arquitecturas de microservicios existentes para satisfacer mejor las necesidades de los usuarios.

arquitecturas de consul

Cómo habilitar Consul en Apache APISIX

Los entornos de prueba en este artículo se construyen en Docker utilizando docker-compose.

  1. Descargar Apache APISIX.

    # Clonar el repositorio Git de apisix-docker
    git clone https://github.com/apache/apisix-docker.git
    
  2. Crear la carpeta y archivos de configuración de Consul.

    # Crear la carpeta de Consul
    mkdir -p ~/docker-things/consul/ && cd $_
    # Crear archivos de configuración
    touch docker-compose.yml server1.json
    
  3. Editar el archivo docker-compose.yml.

    version: '3.8'
    
    services:
    consul-server1:
    image: consul:1.9.3
    container_name: consul-server1
    restart: always
    volumes:
      - ./server1.json:/consul/config/server1.json:ro
    networks:
      - apisix
    ports:
      - '8500:8500'
    command: 'agent -bootstrap-expect=1'
    
    networks:
    apisix:
    external: true
    name: example_apisix
    
  4. Editar el archivo server1.json.

    {
    node_name: consul-server1,
    server: true,
    addresses: {
    http: 0.0.0.0
    }
    }
    
  5. Agregar la información de configuración relacionada con Consul al archivo de configuración de Apache APISIX apisix_conf/config.yaml.

    # config.yml
    # ...otras configuraciones
    discovery:
    consul_kv:
    servers:
      - http://consul-server1:8500
    prefix: upstreams
    
  6. Iniciar Apache APISIX y Consul.

    # Ir a la carpeta de ejemplo, carpeta consul, iniciar APISIX y Consul
    docker-compose up -d
    
  7. Registrar el servicio de prueba en Consul. El ejemplo contiene dos servicios web que puedes usar directamente para probar.

    # Revisar el docker-compose.yml del ejemplo
    # Puedes ver dos servicios web
    $ cat docker-compose.yml | grep web
    # Salidas
    web1:
    - ./upstream/web1.conf:/etc/nginx/nginx.conf
    web2:
    - ./upstream/web2.conf:/etc/nginx/nginx.conf
    
  8. Confirmar las direcciones IP de estos servicios web.

    $ sudo docker inspect -f='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq) | grep web
    # Salidas
    /example-web1-1 - 172.26.0.7
    /example-web2-1 - 172.26.0.2
    
  9. Hacer una solicitud a la API HTTP de Consul en la terminal para registrar el servicio de prueba.

    # Registrar con la IP correspondiente
    curl \
    -X PUT \
    -d ' {weight: 1, max_fails: 2, fail_timeout: 1}' \
    http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.7:80
    
    curl \
    -X PUT \
    -d ' {weight: 1, max_fails: 2, fail_timeout: 1}' \
    http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.2:80
    

    La ruta después de /v1/kv/ sigue el formato {Prefijo}/{Nombre del Servicio}/{IP}:{Puerto}.

    {Prefijo} es el prefijo escrito al configurar Consul en APISIX, mientras que {Nombre del Servicio} y {IP}:{Puerto} deben ser determinados por el usuario según el servicio upstream.

    El formato de los datos es {"weight": , "max_fails": , "fail_timeout": }.

  10. Verificar si el servicio de prueba se registró correctamente.

    curl http://127.0.0.1:8500/v1/kv/upstreams/webpages?keys
    

    El siguiente mensaje de retorno indica un registro exitoso.

    [upstreams/webpages/172.26.0.2:80,upstreams/webpages/172.26.0.7:80]%
    

Crear una ruta y habilitar Consul

Agregar Consul a la ruta utilizando la API de administración proporcionada por Apache APISIX.

El X-API-KEY y upstream.service_name deben determinarse antes de agregarlos.

  • X-API-KEY: Para el token de acceso a la API de administración, en este ejemplo, usamos el valor predeterminado edd1c9f034335f136f87ad84b625c8f1.
  • upstream.service_name: El nombre del servicio upstream, que especifica el servicio en un registro que se vinculará a una ruta, debe establecerse en la URL utilizada para registrar el servicio de prueba cuando se usa Consul, y la parte {IP}:{Puerto} debe eliminarse al final. También podemos usar la API de Memory Dump proporcionada por Apache APISIX para obtener la URL del servicio y confirmar si el servicio upstream se descubrió correctamente.
$ curl http://127.0.0.1:9092/v1/discovery/consul_kv/dump | jq
# Salida
{
  "services": {
    # Esta clave es la URL requerida
    "http://consul-server1:8500/v1/kv/upstreams/webpages/": [
      {
        "port": 80,
        "host": "172.26.0.7",
        "weight": 1
      },
      {
        "port": 80,
        "host": "172.26.0.2",
        "weight": 1
      }
    ]
  },
  "config": {
    # ...configuraciones
  }
}

Agregar una ruta

Aquí la solicitud con la URL /consul/* se enruta a http://consul-server1:8500/v1/kv/upstreams/webpages/. Además, el discovery_type debe establecerse en consul_kv para iniciar el módulo correspondiente.

curl http://127.0.0.1:9080/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X POST -d '
{
    "uri": "/consul/*",
    "upstream": {
        "service_name": "http://consul-server1:8500/v1/kv/upstreams/webpages/",
        "type": "roundrobin",
        "discovery_type": "consul_kv"
    }
}'

Probar y verificar el resultado

Los resultados de la solicitud muestran que la nueva ruta en Apache APISIX ha podido encontrar la dirección correcta del servicio a través de Consul y solicitarla a ambos nodos según la política de equilibrio de carga.

# la primera solicitud
curl -s http://127.0.0.1:9080/consul/
# Salida
hello web1%

# la segunda solicitud
curl -s http://127.0.0.1:9080/consul/
# Salida
hello web2%

# Nota: También es posible que ambas solicitudes devuelvan
#       el mismo resultado que web1 o web2.
#       Esto se debe a la naturaleza del equilibrio de carga y
#       puedes intentar hacer más solicitudes.

Resumen

La primera mitad de este artículo describe cómo Apache APISIX funciona con Consul para implementar el registro de descubrimiento de servicios basado en Consul KV para resolver el problema de la gestión y mantenimiento de la información de servicios. La segunda mitad de este artículo se centra en cómo usar Apache APISIX en Docker con Consul. Por supuesto, la aplicación en el escenario real debe analizarse según el escenario comercial y la arquitectura del sistema existente.

Puedes encontrar más instrucciones sobre el uso del registro de Consul en Apache APISIX en la documentación oficial.

Apache APISIX también está trabajando actualmente en complementos adicionales para admitir la integración de servicios adicionales, por lo que si estás interesado, no dudes en iniciar una discusión en GitHub Discussion, o a través de la lista de correo para comunicarte.

Tags: