TL;DR — Kurzzusammenfassung

HashiCorp Consul meistern: Architektur, Health Checks, ACLs, Envoy-Sidecar-Proxies und Multi-Datacenter-Verbund für Service Discovery und Service Mesh.

HashiCorp Consul ist eine verteilte, hochverfügbare Service-Networking-Plattform, die eines der schwierigsten Probleme von Microservices löst: Wie finden sich Dienste gegenseitig, überprüfen ihre Gesundheit und kommunizieren sicher in einer dynamischen Infrastruktur, in der sich IP-Adressen ständig ändern? Consul beantwortet alle drei Fragen über eine einheitliche Steuerungsebene, die Service Discovery, Health Checking, KV-Speicher und ein vollständiges Service Mesh mit gegenseitiger TLS-Durchsetzung kombiniert. Dieser Leitfaden deckt alle wichtigen Consul-Funktionen ab – von der Einrichtung eines Drei-Knoten-Clusters über Envoy-Sidecar-Proxies bis zur Multi-Datacenter-Verbundbildung.

Voraussetzungen

Stellen Sie vor dem Fortfahren sicher, dass Folgendes verfügbar ist:

  • Linux- oder macOS-Host — Consul läuft auf jedem Unix-ähnlichen System und Windows; die Beispiele verwenden Linux.
  • Docker 24+ — für das Produktionsbeispiel mit Docker Compose am Ende dieses Leitfadens.
  • curl und dig — zum Testen von DNS- und HTTP-API-Antworten.
  • Grundlegendes Verständnis von Microservices — Vertrautheit mit Load Balancing, Health Checks und TLS.
  • Consul-Binärdatei 1.17+ — installieren Sie über das HashiCorp APT/YUM-Repository oder laden Sie von releases.hashicorp.com herunter.

Installation unter 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

Consul-Architektur

Agenten: Server vs. Clients

Jeder Knoten in einem Consul-Cluster betreibt einen Consul-Agenten in einem von zwei Modi:

Server-Agenten bilden die Steuerungsebene. Sie nehmen am Raft-Konsensalgorithmus teil, um einen Leader zu wählen, speichern den autoritativen Cluster-Zustand und replizieren diesen Zustand. Verwenden Sie immer eine ungerade Anzahl: 3 Server tolerieren 1 Ausfall; 5 Server tolerieren 2 Ausfälle.

Client-Agenten laufen auf jedem Nicht-Server-Knoten. Sie registrieren lokale Dienste und Health Checks, leiten Abfragen an Server weiter und nehmen am Gossip-Netzwerk teil. Clients sind leichtgewichtig — sie speichern keinen Cluster-Zustand.

Gossip-Protokoll (Serf)

Consul verwendet Serf, eine Implementierung des SWIM-Gossip-Protokolls, für die Cluster-Mitgliedschaft und Fehlerkennung. Alle Agenten nehmen an zwei Gossip-Pools teil:

  • LAN-Gossip-Pool — Agenten innerhalb desselben Datencenters.
  • WAN-Gossip-Pool — Server zwischen Datencentern. Ermöglicht Multi-Datacenter-Verbund.

Raft-Konsens

Raft wird nur zwischen Consul-Servern für die starke Konsistenz des Cluster-Zustands verwendet. Der Leader akzeptiert alle Schreibvorgänge und repliziert Log-Einträge auf Follower, bevor er bestätigt.

Datacenter-Modell

Ein Consul-Datacenter ist eine isolierte Einheit: eine Gruppe von Servern, die einen LAN-Gossip-Pool teilen. Mehrere Datacenter kommunizieren über WAN-Gossip oder Mesh-Gateways.

Installationsmethoden

Binäre Installation

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 für 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

Minimales consul-values.yaml:

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

Server-Cluster-Konfiguration

Erstellen Sie /etc/consul.d/consul.hcl auf jedem Server-Knoten:

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 = "GOSSIP_SCHLUESSEL_BASE64_HIER"

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

Generieren Sie den Gossip-Schlüssel einmalig und verwenden Sie ihn auf allen Knoten:

consul keygen
# Ausgabe: j5Y3fIFjQKs2b9s9rG2ufA==

Cluster starten:

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

Dienst-Registrierung

Dienstdefinitionsdateien

Erstellen Sie eine JSON-Datei in /etc/consul.d/ auf dem Client-Agenten:

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

Registrierung über HTTP-API

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

Katalog vs. Agent

Die Agenten-API (/v1/agent/service/*) verwaltet lokal registrierte Dienste. Die Katalog-API (/v1/catalog/service/*) fragt das globale Register aller Agenten ab:

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

Health Checks

Consul unterstützt sechs Health-Check-Typen, alle mit Parametern interval, timeout und deregister_critical_service_after.

HTTP — Consul führt einen HTTP-GET durch; 2xx = passing, 429 = warning, alle anderen = critical.

TCP — Öffnet eine TCP-Verbindung zum angegebenen Host:Port.

Script — Führt einen Shell-Befehl aus; Exit-Code 0 = passing, 1 = warning, andere = critical.

TTL — Die Anwendung selbst muss die Consul-API aufrufen, um ihren Gesundheitsstatus zu aktualisieren.

gRPC — Für Dienste, die das gRPC-Gesundheitsprotokoll implementieren.

TTL-Check-Beispiel:

curl -X PUT http://localhost:8500/v1/agent/check/pass/service:worker-01 \
  -d "Warteschlange wird normal verarbeitet"

Setzen Sie immer deregister_critical_service_after, um dauerhaft fehlgeschlagene Dienste automatisch zu entfernen:

"deregister_critical_service_after": "90s"

DNS-Schnittstelle

Consul betreibt einen DNS-Server auf Port 8600. Dienste werden unter <dienst>.service.<datacenter>.consul aufgelöst.

# Alle gesunden Instanzen von "web" auflösen
dig @127.0.0.1 -p 8600 web.service.consul A

# Mit SRV-Eintrag (enthält Port)
dig @127.0.0.1 -p 8600 web.service.consul SRV

# Nach Tag filtern
dig @127.0.0.1 -p 8600 primary.web.service.consul A

DNS-Weiterleitung mit systemd-resolved

# /etc/systemd/resolved.conf.d/consul.conf
[Resolve]
DNS=127.0.0.1:8600
Domains=~consul
sudo systemctl restart systemd-resolved
# Jetzt können Sie verwenden: curl http://web.service.consul:8080/

Prepared Queries mit 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

Consul Connect verwendet Envoy als Sidecar-Proxy und stellt kurzlebige TLS-Zertifikate für gegenseitiges TLS zwischen Diensten aus.

Sidecar-Registrierung

{
  "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 &

Intentions

# Web erlauben, api zu erreichen
consul intention create web api

# Bestimmte Route verweigern
consul intention create -deny payments logging

# Alle Intentions auflisten
consul intention list

KV-Speicher

# Wert schreiben
consul kv put config/app/log_level info

# Wert lesen
consul kv get config/app/log_level

# Schlüssel unter einem Präfix auflisten
consul kv list config/app/

# Teilbaum löschen
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

ACL-System

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

consul acl bootstrap
# SecretID: db14c...   ← Ihr Bootstrap-Token (Root)

export CONSUL_HTTP_TOKEN="db14c..."

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

consul acl token create \
  -description "Web-Dienst Lese-Token" \
  -policy-name "web-dienst-lesen"

Consul-Benutzeroberfläche

Die Consul-Web-UI ist unter http://localhost:8500/ui verfügbar, wenn ui_config { enabled = true } konfiguriert ist. Hauptbereiche:

  • Dienste — alle registrierten Dienste mit Gesundheitsstatus, Tags und Instanzanzahl.
  • Knoten — alle Agenten mit Gesundheitsstatus und registrierten Diensten.
  • Key/Value — KV-Speicher-Browser mit Unterstützung für Erstellen, Bearbeiten und Löschen.
  • Intentions — Autorisierungsregeln zwischen Diensten visualisieren und verwalten.
  • Zugriffskontrollen — Tokens, Richtlinien und Rollen verwalten.

Multi-Datacenter-Verbund

WAN-Gossip

# Auf dc2-Servern dem WAN-Pool von dc1 beitreten
consul join -wan 10.0.1.11

# Web-Dienst in dc2 abfragen
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 sind der moderne Ansatz — sie leiten Traffic zwischen Datencentern weiter, ohne interne Dienste dem WAN auszusetzen:

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

Vergleich: Consul vs. Alternativen

MerkmalConsuletcdZooKeeperEurekaIstioLinkerd
Service DiscoveryDNS + HTTP-APINur APINur APIHTTP-APIVia KubernetesVia Kubernetes
Health ChecksIntegriert (6 Typen)Kein nativesKein nativesClient-HeartbeatKubernetes-ProbesKubernetes-Probes
Service MeshJa (Connect)NeinNeinNeinJa (Envoy)Ja (proxy2)
KV-SpeicherJaJa (Hauptnutzung)JaNeinNeinNein
ACL-SystemJa (umfangreich)GrundlegendSASL/ACLNeinRBACRBAC
Multi-DatacenterNativNeinNeinReplizierte PeersNeinNein
Ohne KubernetesJaJaJaJaNeinNein

Produktions-Deployment mit 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

Stolperfallen und Randfälle

  • Inkonsistentes bootstrap_expect — alle Server müssen denselben Wert haben; eine Abweichung verhindert die Cluster-Bildung.
  • Gossip-Schlüssel-Rotation — verwenden Sie consul keyring zur Rotation; alle Knoten müssen die Rotation abschließen, bevor der alte Schlüssel entfernt wird.
  • ACL-Token-Verteilung — vermeiden Sie Tokens in Konfigurationsdateien; verwenden Sie Vaults Consul-Secrets-Engine oder Kubernetes-Secrets.
  • Envoy-Versionskompatibilität — passen Sie die Envoy-Version immer an die Consul-Kompatibilitätsmatrix an.
  • Health-Check-Timeouts — setzen Sie timeout kleiner als interval, um überlappende Check-Ausführungen zu vermeiden.

Zusammenfassung

  • Drei oder fünf Server mit Raft-Konsens bilden die Steuerungsebene; verwenden Sie eine ungerade Anzahl für Quorum-Toleranz.
  • Gossip (Serf) verwaltet Cluster-Mitgliedschaft und Fehlererkennung in O(log N)-Skalierung über LAN und WAN.
  • Dienstdefinitionen registrieren Dienste mit umfangreichen Health Checks, die ungesunde Instanzen automatisch aus dem DNS entfernen.
  • Die DNS-Schnittstelle auf Port 8600 ermöglicht die Auflösung von dienst.service.consul ohne Codeänderungen.
  • Consul Connect fügt mTLS zwischen Diensten über Envoy-Sidecars hinzu; Intentions erzwingen Autorisierung ohne Eingriff in den Anwendungscode.
  • Prepared Queries bieten DNS-Level-Failover zwischen Datencentern für Hochverfügbarkeit.
  • Der KV-Speicher kombiniert mit consul-template ermöglicht dynamisches Konfigurationsmanagement.
  • ACLs mit default_policy = deny sperren den Cluster; verwenden Sie Auth-Methoden für geheimnisfreie Token-Ausstellung.

Verwandte Artikel