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
| Recurso | Consul | etcd | ZooKeeper | Eureka | Istio | Linkerd |
|---|---|---|---|---|---|---|
| Service Discovery | DNS + API HTTP | Apenas API | Apenas API | API HTTP | Via Kubernetes | Via Kubernetes |
| Health Checks | Integrado (6 tipos) | Nenhum nativo | Nenhum nativo | Heartbeat cliente | Probes Kubernetes | Probes Kubernetes |
| Service Mesh | Sim (Connect) | Não | Não | Não | Sim (Envoy) | Sim (proxy2) |
| Armazenamento KV | Sim | Sim (uso primário) | Sim | Não | Não | Não |
| Sistema ACL | Sim (rico) | Básico | SASL/ACL | Não | RBAC | RBAC |
| Multi-datacenter | Nativo | Não | Não | Peers replicados | Não | Não |
| Sem Kubernetes | Sim | Sim | Sim | Sim | Não | Nã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_expectinconsistente — todos os servidores devem ter o mesmo valor; uma discrepância impede a formação do cluster.- Rotação de chave gossip — use
consul keyringpara 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
timeoutmenor queintervalpara 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.consulsem 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 = denybloqueiam o cluster; use auth methods para emissão de tokens sem segredos.