Lewati ke konten utama
  1. Posts/

High Availability Traefik dengan Consul KV & Keepalived

Noor Khafidzin
Penulis
Noor Khafidzin
Seorang homelab enthusiast yang terobsesi pada efisiensi sistem dan seni pemecahan masalah (troubleshooting).
Daftar isi

Pendahuluan
#

Pernahkah reverse proxy di server Anda mati, lalu tiba-tiba semua service dan website ikutan down? Memiliki satu single point of failure tentu sangat berisiko, terutama jika Anda menjalankan service yang kritis.

Di artikel ini, kita akan membahas cara membangun arsitektur High Availability (HA) untuk Traefik menggunakan Consul KV sebagai dynamic configuration backend, acme.sh untuk manajemen sertifikat SSL wildcard, dan Keepalived untuk Virtual IP failover.

Dengan setup ini, jika satu node Traefik mati, trafik secara otomatis akan dialihkan ke node lain tanpa ada downtime yang signifikan.

1. Arsitektur Overview
#

Prinsip utama dari arsitektur HA ini adalah menghindari shared storage tradisional (seperti NFS) yang lambat dan rawan masalah. Sebagai gantinya, kita memisahkan state (konfigurasi) ke tempat yang tepat:

Prinsip Utama Arsitektur:

  • Config Statis (traefik.yaml): Diletakkan secara lokal di setiap host dengan isi yang identik.
  • Dynamic Config (Routers/Services): Disimpan di Consul KV, sehingga setiap penambahan router otomatis dibaca oleh semua node Traefik.
  • SSL Certificates: Di-generate menggunakan DNS-01 challenge (acme.sh) pada satu host utama, lalu disinkronkan ke host lain via rsync.

Kelebihan dan Kekurangan
#

Arsitektur ini sangat cocok untuk skala homelab maupun production menengah, karena memiliki karakteristik berikut:

Kelebihan:

  • Lebih Ringan dari Kubernetes/Swarm: Tidak perlu overhead dari orkestrator kontainer yang berat. Kontainer cukup berjalan dengan Docker Compose standar.
  • Tanpa Shared Storage (NFS): Kita tidak perlu setup NFS server yang lambat dan sering kali rawan macet (stale file handle). Konfigurasi dynamic murni dikontrol lewat Consul KV.
  • Sangat Resilient: Setiap node Traefik berjalan mandiri, membaca konfigurasi yang disinkronkan secara global.
  • Dynamic Configuration: Menambah routing baru bisa dilakukan cukup dengan push konfigurasi ke Consul KV tanpa me-restart Traefik.

Kelemahan:

  • Masih mengandalkan rsync untuk sinkronisasi file sertifikat fisik antar host.
  • Memerlukan instalasi agent Consul di setiap node untuk membentuk klaster yang sehat (quorum minimal 3 node).

Topologi Jaringan
#

Kita akan menggunakan 3 node untuk memastikan Consul dapat mencapai konsensus (quorum):

  • Host 1 (10.1.1.22): Primary node, menjalankan acme.sh dan mayoritas backend container.
  • Host 2 (10.1.1.200): Replica node, hanya menjalankan Traefik dan Consul.
  • Host 3 (10.1.1.11): Replica node, menjalankan Traefik, Consul, dan beberapa backend.

Semua node ini tergabung dalam klaster Consul.

2. Setup Klaster Consul
#

Consul bertugas menyimpan definisi router, service, dan middleware Traefik. Berikut adalah contoh konfigurasi compose.yml untuk Host 1:

version: "3.8"
services:
  consul:
    image: hashicorp/consul:1.19
    container_name: consul
    restart: unless-stopped
    network_mode: host
    volumes:
      - consul-data:/consul/data
    command: >
      consul agent -server
        -bootstrap-expect=3
        -ui
        -data-dir=/consul/data
        -bind=10.1.1.22
        -advertise=10.1.1.22
        -client=0.0.0.0
        -node=consul-node1
        -datacenter=dc1
        -retry-join=10.1.1.22
        -retry-join=10.1.1.200
        -retry-join=10.1.1.11

Catatan: Untuk Host 2 dan Host 3, sesuaikan parameter -bind, -advertise, dan -node dengan IP masing-masing.

3. Konfigurasi Traefik
#

Semua host menggunakan file statis traefik.yaml yang sama:

global:
  checkNewVersion: true
  sendAnonymousUsage: false
log:
  level: INFO
api:
  dashboard: true
  insecure: true
entryPoints:
  web:
     address: :80
     http:
       redirections:
         entryPoint:
           to: websecure
           scheme: https
           permanent: true
  websecure:
     address: :443
     forwardedHeaders:
       insecure: true
       trustedIPs:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
providers:
  providersThrottleDuration: 2s
  docker:
    endpoint: "unix://var/run/docker.sock"
    exposedByDefault: false
  consul:
    endpoints:
      - "consul:8500"
    rootKey: traefik
  file:
    directory: /etc/traefik/dynamic
    watch: true

Bagian terpenting ada di providers.consul. Traefik akan otomatis membaca setiap perubahan key-value di Consul dengan prefix traefik/. Selain itu, providers.file.watch: true sangat krusial agar Traefik me-reload sertifikat SSL baru secara instan tanpa restart.

4. Manajemen Sertifikat SSL (acme.sh)
#

Traefik versi open-source tidak mendukung KV Store (seperti Consul) sebagai storage ACME Let’s Encrypt. Solusinya, kita menggunakan acme.sh pada Host 1 untuk DNS-01 challenge (via Cloudflare) dan mendistribusikannya ke host lain.

Generate sertifikat untuk domain noorkhafidzin.com:

/home/el/.acme.sh/acme.sh --issue --dns dns_cf \
  -d '*.noorkhafidzin.com' \
  --server letsencrypt

/home/el/.acme.sh/acme.sh --install-cert -d '*.noorkhafidzin.com' \
  --fullchain-file /home/el/traefik-config/certs/wildcard.noorkhafidzin.com.crt \
  --key-file /home/el/traefik-config/certs/wildcard.noorkhafidzin.com.key \
  --reloadcmd "/home/el/.hermes/traefik-renew-hook.sh"

Script Sinkronisasi (Renewal Hook)
#

Buat script traefik-renew-hook.sh yang akan dieksekusi otomatis oleh acme.sh setiap kali sertifikat diperbarui:

#!/bin/bash
CERT_DIR="/home/el/traefik-config/certs"
DYNAMIC_DIR="/home/el/traefik-config/dynamic"
HOSTS="10.1.1.200 10.1.1.11"

echo "Syncing certs to replica hosts..."

for host in $HOSTS; do
  rsync -avz --delete "$CERT_DIR/" "el@$host:$CERT_DIR/"
  rsync -avz "$DYNAMIC_DIR/" "el@$host:$DYNAMIC_DIR/"
done

# Touch tls.yaml untuk trigger reload Traefik tanpa restart
touch "$DYNAMIC_DIR/tls.yaml"
ssh [email protected] "touch /home/el/traefik-config/dynamic/tls.yaml"
ssh [email protected] "touch /home/el/traefik-config/dynamic/tls.yaml"

File tls.yaml kita cukup mendefinisikan path sertifikat:

tls:
  certificates:
    - certFile: /var/traefik/certs/wildcard.noorkhafidzin.com.crt
      keyFile: /var/traefik/certs/wildcard.noorkhafidzin.com.key

Bantu Jawab: Menyimpan Sertifikat Langsung ke Consul KV

Saat ini, setup sertifikat masih mengandalkan sinkronisasi file mentah acme.json atau file .crt / .key antar host menggunakan rsync. Saya sudah mencoba beberapa konfigurasi agar Traefik bisa menggunakan Consul KV sebagai ACME storage secara native, namun belum menemukan config yang pas.

Jika Anda pernah berhasil melakukan setup Let’s Encrypt ACME storage langsung ke Consul KV (tanpa versi Enterprise), silakan bagikan caranya di kolom komentar!

5. Dynamic Configuration via Consul KV
#

Dengan Consul, kita tidak perlu mengedit file YAML setiap kali menambah domain atau aplikasi baru. Semua perintah dilakukan via KV store.

Misalnya, menambah konfigurasi untuk app.noorkhafidzin.com:

# 1. Definisikan Service (Backend URL)
docker exec consul consul kv put \
  traefik/http/services/app-svc/loadBalancer/servers/0/url \
  "http://10.1.1.50:8080"

# 2. Definisikan Router (Domain)
docker exec consul consul kv put \
  traefik/http/routers/app-rtr/rule "Host(\`app.noorkhafidzin.com\`)"
docker exec consul consul kv put \
  traefik/http/routers/app-rtr/entryPoints/0 "websecure"
docker exec consul consul kv put \
  traefik/http/routers/app-rtr/service "app-svc"

# 3. WAJIB: Aktifkan TLS
docker exec consul consul kv put \
  traefik/http/routers/app-rtr/tls "true"

Dalam hitungan 2 detik, semua Traefik di semua host akan siap melayani trafik untuk app.noorkhafidzin.com!

Pastikan URL backend menggunakan IP Address, bukan nama container Docker. Nama container hanya dikenali di dalam host lokal tempat ia berjalan.

6. High Availability via Keepalived (VRRP)
#

Agar pengunjung selalu diarahkan ke node yang hidup, kita akan membuat sebuah Virtual IP (VIP) misal 10.1.1.111. VIP ini akan otomatis berpindah jika host utamanya mati.

Di DNS Cloudflare, kita cukup mengarahkan *.noorkhafidzin.com ke IP 10.1.1.111.

Instal Keepalived di Host 1 dan atur konfigurasinya (/etc/keepalived/keepalived.conf):

global_defs {
    router_id TRAEFIK_HA
}

# Mengecek apakah Traefik API merespons
vrrp_script check_traefik {
    script "/bin/bash -c 'curl -sf http://localhost:8080/api/version > /dev/null 2>&1'"
    interval 3
    timeout 2
    rise 2
    fall 3
}

vrrp_instance VI_TRAEFIK {
    state BACKUP
    interface eth0
    virtual_router_id 111
    priority 150        # Host lain diset ke priority yang lebih rendah (misal 130 dan 110)
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass traefikHA
    }
    virtual_ipaddress {
        10.1.1.111/24 dev eth0
    }
    track_script {
        check_traefik
    }
}

Script health check check_traefik memastikan bahwa Keepalived hanya menahan VIP selama container Traefik benar-benar berjalan dan merespons. Jika Traefik mati, priority turun, dan VIP pindah ke Host lain secara instan.

Penutup / Kesimpulan
#

Dengan memisahkan lapisan load balancer (Traefik), state storage (Consul), cert management (acme.sh), dan failover IP (Keepalived), kita mendapatkan arsitektur infrastruktur yang super tangguh (High Availability).

Tidak ada lagi rasa khawatir saat harus me-restart server atau melakukan pembaruan sistem operasi. Server mati satu? Tidak masalah, trafik otomatis dialihkan.

Punya pengalaman serupa dalam men-setup HA untuk Traefik? Atau ada kendala saat mencobanya? Jangan ragu untuk berdiskusi di komentar di bawah!

Terkait


Muat Komentar