TL;DR — Resumo Rápido

Domine HashiCorp Consul para service discovery e service mesh: arquitetura, health checks, ACLs, proxies Envoy sidecar e federação multi-datacenter.

HashiCorp Consul é uma plataforma de rede de serviços distribuída e de alta disponibilidade que resolve um dos problemas mais difíceis dos microsserviços: como os serviços se encontram, verificam a saúde uns dos outros e se comunicam com segurança em uma infraestrutura dinâmica onde endereços IP mudam constantemente? O Consul responde as três perguntas através de um plano de controle unificado que combina service discovery, health checking, armazenamento KV e um service mesh completo com aplicação de TLS mútuo. Este guia cobre todas as principais capacidades do Consul, desde a configuração de um cluster de três nós até proxies sidecar Envoy e federação multi-datacenter.

Pré-requisitos

Antes de prosseguir, certifique-se de que os seguintes recursos estejam disponíveis:

  • Host Linux ou macOS — o Consul funciona em qualquer sistema tipo Unix e Windows; os exemplos usam Linux.
  • Docker 24+ — para o exemplo de produção com Docker Compose ao final deste guia.
  • curl e dig — para testar respostas DNS e da API HTTP.
  • Compreensão básica de microsserviços — familiaridade com conceitos como balanceamento de carga, health checks e TLS.
  • Binário Consul 1.17+ — instale via repositório APT/YUM da HashiCorp ou baixe em releases.hashicorp.com.

Instalação no Ubuntu/Debian:

wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install consul
consul version
# Consul v1.20.2

Arquitetura do Consul

Agentes: Servidores vs Clientes

Cada nó em um cluster Consul executa um agente Consul em um de dois modos:

Os agentes servidor formam o plano de controle. Participam no algoritmo de consenso Raft para eleger um líder, armazenam o estado autorizado do cluster e replicam esse estado. Use sempre um número ímpar: 3 servidores toleram 1 falha; 5 servidores toleram 2 falhas.

Os agentes cliente executam em cada nó não servidor. Registram serviços e health checks locais, encaminham consultas aos servidores e participam na rede gossip. Clientes são leves — não armazenam estado do cluster.

Protocolo Gossip (Serf)

O Consul usa Serf, uma implementação do protocolo gossip SWIM, para associação ao cluster e detecção de falhas. Todos os agentes participam em dois pools gossip:

  • Pool gossip LAN — agentes dentro do mesmo datacenter.
  • Pool gossip WAN — servidores entre datacenters. Habilita a federação multi-datacenter.

Consenso Raft

O Raft é usado apenas entre servidores do Consul para consistência forte do estado do cluster. O líder aceita todas as operações de escrita e replica as entradas de log nos seguidores antes de confirmar.

Modelo de Datacenter

Um datacenter Consul é uma unidade isolada: um conjunto de servidores compartilhando um pool gossip LAN. Múltiplos datacenters se comunicam via gossip WAN ou mesh gateways.

Métodos de Instalação

Instalação do Binário

CONSUL_VERSION="1.20.2"
wget "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip"
unzip consul_${CONSUL_VERSION}_linux_amd64.zip
sudo install consul /usr/local/bin/
consul version

Docker

docker run -d \
  --name consul-dev \
  -p 8500:8500 \
  -p 8600:8600/udp \
  hashicorp/consul:1.20 agent -dev -client=0.0.0.0

Helm Chart para Kubernetes

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install consul hashicorp/consul \
  --namespace consul \
  --create-namespace \
  --values consul-values.yaml

consul-values.yaml mínimo:

global:
  name: consul
  datacenter: dc1
  tls:
    enabled: true
  acls:
    manageSystemACLs: true
server:
  replicas: 3
  bootstrapExpect: 3
connectInject:
  enabled: true

Configuração do Cluster de Servidores

Crie /etc/consul.d/consul.hcl em cada nó servidor:

datacenter  = "dc1"
data_dir    = "/opt/consul"
log_level   = "INFO"
node_name   = "consul-server-01"
server      = true
bootstrap_expect = 3

retry_join = [
  "10.0.1.11",
  "10.0.1.12",
  "10.0.1.13"
]

encrypt = "CHAVE_GOSSIP_BASE64_AQUI"

ui_config {
  enabled = true
}
client_addr    = "0.0.0.0"
bind_addr      = "{{ GetPrivateIP }}"
advertise_addr = "{{ GetPrivateIP }}"

Gere a chave gossip uma vez e use em todos os nós:

consul keygen
# Saída: j5Y3fIFjQKs2b9s9rG2ufA==

Inicie o cluster:

sudo systemctl enable consul && sudo systemctl start consul
consul members
consul operator raft list-peers

Registro de Serviços

Arquivos de Definição de Serviço

Crie um arquivo JSON em /etc/consul.d/ no agente cliente:

{
  "service": {
    "id":   "web-01",
    "name": "web",
    "port": 8080,
    "tags": ["v2", "primary"],
    "check": {
      "http":     "http://localhost:8080/health",
      "interval": "10s",
      "timeout":  "3s",
      "deregister_critical_service_after": "90s"
    }
  }
}

Registro via API HTTP

curl -s -X PUT http://localhost:8500/v1/agent/service/register \
  -H "Content-Type: application/json" \
  -d '{
    "ID":   "api-01",
    "Name": "api",
    "Port": 3000,
    "Check": {
      "HTTP":     "http://localhost:3000/healthz",
      "Interval": "15s",
      "Timeout":  "5s"
    }
  }'

Catálogo vs Agente

A API do agente (/v1/agent/service/*) gerencia serviços registrados no agente local. A API do catálogo (/v1/catalog/service/*) consulta o registro global de todos os agentes:

curl http://localhost:8500/v1/agent/services | jq .
curl http://localhost:8500/v1/catalog/service/web | jq '[.[] | {no: .Node, end: .ServiceAddress, porta: .ServicePort}]'

Health Checks

O Consul suporta seis tipos de health checks, todos com parâmetros interval, timeout e deregister_critical_service_after.

HTTP — O Consul executa um GET HTTP; 2xx = passing, 429 = warning, qualquer outro = critical.

TCP — Abre uma conexão TCP ao host:porta especificado.

Script — Executa um comando shell; código de saída 0 = passing, 1 = warning, outro = critical.

TTL — A própria aplicação deve chamar a API do Consul para atualizar seu estado de saúde.

gRPC — Para serviços que implementam o protocolo de saúde gRPC.

Exemplo de check TTL:

curl -X PUT http://localhost:8500/v1/agent/check/pass/service:worker-01 \
  -d "Processando fila normalmente"

Sempre defina deregister_critical_service_after para remover automaticamente serviços com falhas contínuas:

"deregister_critical_service_after": "90s"

Interface DNS

O Consul executa um servidor DNS na porta 8600. Os serviços são resolvidos em <serviço>.service.<datacenter>.consul.

# Resolver todas as instâncias saudáveis de "web"
dig @127.0.0.1 -p 8600 web.service.consul A

# Com registro SRV (inclui porta)
dig @127.0.0.1 -p 8600 web.service.consul SRV

# Por tag
dig @127.0.0.1 -p 8600 primary.web.service.consul A

Encaminhamento DNS com systemd-resolved

# /etc/systemd/resolved.conf.d/consul.conf
[Resolve]
DNS=127.0.0.1:8600
Domains=~consul
sudo systemctl restart systemd-resolved
# Agora você pode usar: curl http://web.service.consul:8080/

Prepared Queries com Failover

curl -X POST http://localhost:8500/v1/query \
  -d '{
    "Name": "web",
    "Service": {
      "Service":     "web",
      "OnlyPassing": true,
      "Failover": {
        "NearestN":    2,
        "Datacenters": ["dc2", "dc3"]
      }
    }
  }'

dig @127.0.0.1 -p 8600 web.query.consul A

Service Mesh / Connect

O Consul Connect usa Envoy como proxy sidecar e emite certificados TLS de curta duração para TLS mútuo entre serviços.

Registro do Sidecar

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "sidecar_service": {
        "port": 21000,
        "proxy": {
          "upstreams": [
            {
              "destination_name": "api",
              "local_bind_port":  9191
            }
          ]
        }
      }
    }
  }
}
consul connect envoy -sidecar-for web &

Intenções

# Permitir que web alcance api
consul intention create web api

# Negar uma rota específica
consul intention create -deny payments logging

# Listar todas as intenções
consul intention list

Armazenamento KV

# Escrever um valor
consul kv put config/app/log_level info

# Ler um valor
consul kv get config/app/log_level

# Listar chaves sob um prefixo
consul kv list config/app/

# Excluir uma árvore
consul kv delete -recurse config/app/

consul-template

wget https://releases.hashicorp.com/consul-template/0.39.0/consul-template_0.39.0_linux_amd64.zip
unzip consul-template_0.39.0_linux_amd64.zip
sudo install consul-template /usr/local/bin/

Template nginx.conf.ctmpl:

upstream web_backend {
  {{ range service "web" }}
  server {{ .Address }}:{{ .Port }};
  {{ end }}
}
consul-template \
  -template "nginx.conf.ctmpl:/etc/nginx/conf.d/web.conf:nginx -s reload" \
  -once

Sistema ACL

cat >> /etc/consul.d/consul.hcl <<EOF
acl {
  enabled                  = true
  default_policy           = "deny"
  enable_token_persistence = true
}
EOF

consul acl bootstrap
# SecretID: db14c...   ← este é seu token bootstrap (root)

export CONSUL_HTTP_TOKEN="db14c..."

consul acl policy create \
  -name "leitura-servico-web" \
  -rules 'service "web" { policy = "read" }
node_prefix "" { policy = "read" }'

consul acl token create \
  -description "Token leitura serviço web" \
  -policy-name "leitura-servico-web"

Interface de Usuário do Consul

A UI web do Consul está disponível em http://localhost:8500/ui quando ui_config { enabled = true } está configurado. Seções principais:

  • Serviços — todos os serviços registrados com estado de saúde, tags e contagem de instâncias.
  • Nós — todos os agentes com estado de saúde e serviços registrados.
  • Key/Value — navegador do armazenamento KV com suporte para criar, editar e excluir.
  • Intenções — visualize e gerencie regras de autorização entre serviços.
  • Controles de Acesso — gerencie tokens, políticas e funções.

Federação Multi-Datacenter

Gossip WAN

# Nos servidores do dc2, juntar ao pool WAN do dc1
consul join -wan 10.0.1.11

# Consultar o serviço web no dc2
dig @127.0.0.1 -p 8600 web.service.dc2.consul A
curl "http://localhost:8500/v1/catalog/service/web?dc=dc2"

Mesh Gateways

Mesh gateways são a abordagem moderna — fazem proxy do tráfego entre datacenters sem expor serviços internos à WAN:

consul connect envoy -gateway=mesh -register -address $(hostname -I | awk '{print $1}'):8443

Comparação: Consul vs Alternativas

RecursoConsuletcdZooKeeperEurekaIstioLinkerd
Service DiscoveryDNS + API HTTPApenas APIApenas APIAPI HTTPVia KubernetesVia Kubernetes
Health ChecksIntegrado (6 tipos)Nenhum nativoNenhum nativoHeartbeat clienteProbes KubernetesProbes Kubernetes
Service MeshSim (Connect)NãoNãoNãoSim (Envoy)Sim (proxy2)
Armazenamento KVSimSim (uso primário)SimNãoNãoNão
Sistema ACLSim (rico)BásicoSASL/ACLNãoRBACRBAC
Multi-datacenterNativoNãoNãoPeers replicadosNãoNão
Sem KubernetesSimSimSimSimNãoNão

Implantação em Produção com Docker Compose

name: consul-cluster

services:
  consul-server-1:
    image: hashicorp/consul:1.20
    command: >
      agent -server
      -node=server-1
      -bootstrap-expect=3
      -datacenter=dc1
      -data-dir=/consul/data
      -bind=0.0.0.0
      -client=0.0.0.0
      -retry-join=consul-server-2
      -retry-join=consul-server-3
      -ui
    volumes:
      - consul-server-1-data:/consul/data
      - ./consul-config:/consul/config:ro
    ports:
      - "8500:8500"
      - "8600:8600/udp"
    networks:
      - consul-net
    restart: unless-stopped

  consul-server-2:
    image: hashicorp/consul:1.20
    command: >
      agent -server
      -node=server-2
      -bootstrap-expect=3
      -datacenter=dc1
      -data-dir=/consul/data
      -bind=0.0.0.0
      -client=0.0.0.0
      -retry-join=consul-server-1
      -retry-join=consul-server-3
    volumes:
      - consul-server-2-data:/consul/data
      - ./consul-config:/consul/config:ro
    networks:
      - consul-net
    restart: unless-stopped

  consul-server-3:
    image: hashicorp/consul:1.20
    command: >
      agent -server
      -node=server-3
      -bootstrap-expect=3
      -datacenter=dc1
      -data-dir=/consul/data
      -bind=0.0.0.0
      -client=0.0.0.0
      -retry-join=consul-server-1
      -retry-join=consul-server-2
    volumes:
      - consul-server-3-data:/consul/data
      - ./consul-config:/consul/config:ro
    networks:
      - consul-net
    restart: unless-stopped

  consul-client:
    image: hashicorp/consul:1.20
    command: >
      agent
      -node=client-1
      -datacenter=dc1
      -data-dir=/consul/data
      -bind=0.0.0.0
      -client=0.0.0.0
      -retry-join=consul-server-1
    volumes:
      - consul-client-data:/consul/data
      - ./consul-config:/consul/config:ro
      - ./services:/consul/services:ro
    networks:
      - consul-net
    restart: unless-stopped

volumes:
  consul-server-1-data:
  consul-server-2-data:
  consul-server-3-data:
  consul-client-data:

networks:
  consul-net:
    driver: bridge
GOSSIP_KEY=$(docker run --rm hashicorp/consul:1.20 keygen)
echo "encrypt = \"${GOSSIP_KEY}\"" > consul-config/encryption.hcl
docker compose up -d
sleep 5
docker compose exec consul-server-1 consul members

Armadilhas e Casos Especiais

  • bootstrap_expect inconsistente — todos os servidores devem ter o mesmo valor; uma discrepância impede a formação do cluster.
  • Rotação de chave gossip — use consul keyring para rotacionar; todos os nós devem completar a rotação antes de remover a chave antiga.
  • Distribuição de tokens ACL — evite tokens em arquivos de configuração; use o motor de segredos Consul do Vault ou secrets do Kubernetes.
  • Compatibilidade de versão do Envoy — sempre alinhe a versão do Envoy com a matriz de compatibilidade do Consul.
  • Timeouts de health checks — defina timeout menor que interval para evitar execuções de checks sobrepostas.

Resumo

  • Três ou cinco servidores com consenso Raft formam o plano de controle; use número ímpar para tolerância de quorum.
  • Gossip (Serf) lida com associação ao cluster e detecção de falhas em escala O(log N) em LAN e WAN.
  • Definições de serviço registram serviços com health checks ricos que removem automaticamente instâncias não saudáveis do DNS.
  • A interface DNS na porta 8600 permite resolver serviço.service.consul sem alterações de código.
  • Consul Connect adiciona mTLS entre serviços via sidecars Envoy; intenções aplicam autorização sem tocar no código da aplicação.
  • Prepared queries fornecem failover em nível DNS entre datacenters para alta disponibilidade.
  • O armazenamento KV combinado com consul-template permite gerenciamento dinâmico de configuração.
  • ACLs com default_policy = deny bloqueiam o cluster; use auth methods para emissão de tokens sem segredos.

Artigos Relacionados