Como Integrar API Gateway e Consul?

Fei Han

February 25, 2022

Ecosystem

Informações de Fundo

O Consul é uma solução de malha de serviços. Um de seus núcleos, o Consul KV, é um banco de dados distribuído de chave-valor cujo principal propósito é armazenar parâmetros de configuração e metadados, além de permitir que os usuários armazenem objetos indexados.

No modelo de arquitetura de microsserviços, quando os serviços upstream mudam devido a expansão de capacidade, falhas de hardware, etc., a maneira de manter as informações do serviço upstream por meio da escrita manual da configuração pode levar a um aumento significativo no custo de manutenção. Em resposta, o Apache APISIX fornece um registro de descoberta de serviços para obter dinamicamente as informações mais recentes das instâncias de serviço, reduzindo o custo de manutenção para os usuários.

Atualmente, o Apache APISIX suporta o registro de descoberta de serviços baseado no Consul KV com o módulo consul_kv contribuído pela comunidade.

Como Funciona

O Apache APISIX aproveita o módulo consul_kv da capacidade de armazenamento distribuído de chave-valor do Consul KV para desacoplar o provedor e o consumidor de um serviço e implementar as duas funções principais de um registro de descoberta de serviços.

  1. Registro de Serviço: Os provedores de serviços registram seus serviços no registro.
  2. Descoberta de Serviço: Os consumidores de serviços encontram as informações de roteamento dos provedores de serviços através do registro.

Com base nisso, o Apache APISIX será mais flexível e adaptável às arquiteturas de microsserviços existentes, atendendo melhor às necessidades dos usuários.

arquiteturas do consul

Como Habilitar o Consul no Apache APISIX

Os ambientes de teste deste artigo são construídos no Docker usando docker-compose.

  1. Baixe o Apache APISIX.

    # Clone o repositório Git do apisix-docker
    git clone https://github.com/apache/apisix-docker.git
    
  2. Crie a pasta do Consul e os arquivos de configuração.

    # Crie a pasta do Consul
    mkdir -p ~/docker-things/consul/ && cd $_
    # Crie os arquivos de configuração
    touch docker-compose.yml server1.json
    
  3. Edite o arquivo 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. Edite o arquivo server1.json.

    {
    node_name: consul-server1,
    server: true,
    addresses: {
    http: 0.0.0.0
    }
    }
    
  5. Adicione as informações de configuração relacionadas ao Consul ao arquivo de configuração do Apache APISIX apisix_conf/config.yaml.

    # config.yml
    # ...outras configurações
    discovery:
    consul_kv:
    servers:
      - http://consul-server1:8500
    prefix: upstreams
    
  6. Inicie o Apache APISIX e o Consul.

    # Vá para a pasta example, consul, e inicie o APISIX e o Consul
    docker-compose up -d
    
  7. Registre o serviço de teste no Consul. O exemplo contém dois serviços web que você pode usar diretamente para teste.

    # Verifique o docker-compose.yml do exemplo
    # Você verá dois serviços Web
    $ cat docker-compose.yml | grep web
    # Saídas
    web1:
    - ./upstream/web1.conf:/etc/nginx/nginx.conf
    web2:
    - ./upstream/web2.conf:/etc/nginx/nginx.conf
    
  8. Confirme os endereços IP desses serviços Web.

    $ sudo docker inspect -f='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq) | grep web
    # Saídas
    /example-web1-1 - 172.26.0.7
    /example-web2-1 - 172.26.0.2
    
  9. Faça uma requisição à API HTTP do Consul no terminal para registrar o serviço de teste.

    # Registre com o IP correspondente
    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
    

    O caminho após /v1/kv/ segue o formato {Prefix}/{Service Name}/{IP}:{Port}.

    {Prefix} é o prefixo escrito ao configurar o Consul no APISIX, enquanto {Service Name} e {IP}:{Port} precisam ser determinados pelo usuário de acordo com o serviço upstream.

    O formato dos dados é {"weight": , "max_fails": , "fail_timeout": }.

  10. Verifique se o serviço de teste foi registrado com sucesso.

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

    A seguinte mensagem de retorno indica registro bem-sucedido.

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

Crie uma Rota e Habilite o Consul

Adicione o Consul à rota usando a API Admin fornecida pelo Apache APISIX.

O X-API-KEY e o upstream.service_name precisam ser determinados antes de adicioná-los.

  • X-API-KEY: Para o token de acesso à API Admin, neste exemplo, usamos o padrão edd1c9f034335f136f87ad84b625c8f1.
  • upstream.service_name: O nome do serviço upstream, que especifica o serviço em um registro que será vinculado a uma rota, deve ser definido como a URL usada para registrar o serviço de teste ao usar o Consul, e a parte {IP}:{Port} deve ser removida no final. Também podemos usar a API Memory Dump fornecida pelo Apache APISIX para obter a URL do serviço e confirmar se o serviço upstream foi descoberto corretamente.
$ curl http://127.0.0.1:9092/v1/discovery/consul_kv/dump | jq
# Saída
{
  "services": {
    # Esta chave é a URL necessária
    "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": {
    # ...configurações
  }
}

Adicione uma Rota

Aqui, a requisição com a URL /consul/* é roteada para http://consul-server1:8500/v1/kv/upstreams/webpages/. Além disso, o discovery_type deve ser definido como consul_kv para iniciar o módulo correspondente.

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"
    }
}'

Teste e Verifique o Resultado

Os resultados da requisição mostram que a nova rota no Apache APISIX foi capaz de encontrar o endereço correto do serviço através do Consul e solicitá-lo a ambos os nós com base na política de balanceamento de carga.

# a primeira requisição
curl -s http://127.0.0.1:9080/consul/
# Saída
hello web1%

# a segunda requisição
curl -s http://127.0.0.1:9080/consul/
# Saída
hello web2%

# Nota: Também é possível que ambas as requisições retornem
#       o mesmo resultado, seja web1 ou web2.
#       Isso é causado pela natureza do balanceamento de carga e
#       você pode tentar fazer mais requisições.

Resumo

A primeira metade deste artigo descreve como o Apache APISIX funciona com o Consul para implementar o registro de descoberta de serviços baseado no Consul KV, resolvendo o problema de gerenciamento e manutenção de informações de serviços. A segunda metade do artigo se concentra em como usar o Apache APISIX no Docker com o Consul. Claro, a aplicação em cenários reais precisa ser analisada de acordo com o cenário de negócios e a arquitetura do sistema existente.

Mais instruções sobre o uso do registro do Consul no Apache APISIX podem ser encontradas na documentação oficial.

O Apache APISIX também está trabalhando atualmente em plugins adicionais para suportar a integração de serviços adicionais, então, se você estiver interessado, sinta-se à vontade para iniciar uma discussão no GitHub Discussion, ou via lista de e-mails para se comunicar.

Tags: