↓ Lewati ke konten utama
  1. Posts/

High Availability Traefik dengan Sinkronisasi GitHub (Tanpa Consul, Lebih Simpel)

Noor Khafidzin
Penulis
Noor Khafidzin
Seorang homelab enthusiast yang terobsesi pada efisiensi sistem dan seni pemecahan masalah (troubleshooting).
Daftar isi
Traefik High Availability - Artikel ini merupakan bagian dari sebuah seri.
Bagian : Artikel ini

Pendahuluan
#

Beberapa waktu lalu saya menulis panduan High Availability Traefik dengan Consul KV & Keepalived. Setup itu berjalan dengan sangat baik — tetapi ia juga meminta Anda menjalankan klaster Consul tiga node hanya untuk menyimpan beberapa aturan routing.

Kalau tujuan Anda cuma satu — “reverse proxy saya harus tetap hidup walau satu node mati” — maka itu terlalu banyak “mesin” untuk pekerjaan yang sederhana. Consul menambah quorum yang harus dijaga, satu agent Go di tiap host, dan model mental kedua (key-value) di atas YAML milik Traefik.

Karena itu saya menyederhanakannya. Di artikel ini saya membangun ulang klaster HA yang sama persis — tiga host yang sama, VIP Keepalived yang sama — tapi sumber kebenaran tunggalnya sekarang adalah repositori GitHub privat, bukan Consul KV. Setiap node men-clone repo tersebut, Traefik membaca konfigurasi dari file lokal, dan sebuah script push kecil menjaga semua node tetap sinkron.

Inti idenya dalam satu kalimat: simpan semua konfigurasi Traefik di Git, biarkan setiap node membaca file yang sama, dan biarkan Keepalived memindahkan Virtual IP di antara mereka. Git yang mendistribusikan, Keepalived yang melakukan failover.

Kenapa Tinggalkan Consul?
#

Consul adalah alat yang hebat, tetapi ia ditujukan untuk service discovery berskala besar. Untuk homelab atau klaster production kecil, sebuah repositori Git sudah memberikan semua yang tadinya dilakukan Consul KV untuk kasus ini: version control, satu salinan kanonik, dan kemudahan meninjau perubahan.

Aspek Pendekatan Consul KV Pendekatan Sinkronisasi GitHub
Penyimpanan dynamic config Klaster Consul KV (3 node untuk quorum) File di repo Git privat
Agent tambahan per host Agent Consul di setiap node Tidak ada — cukup Git
Alur perubahan Perintah consul kv put ... Edit file, commit, push
Riwayat / rollback Snapshot Consul Riwayat Git native (git log, git revert)
Mode kegagalan Kehilangan quorum → config berhenti diperbarui Commit terakhir yang di-pull tetap aktif
Shared storage (NFS) Tidak perlu Tidak perlu

Ada satu trade-off yang jujur: dengan Consul, perubahan konfigurasi menyebar seketika ke semua node. Dengan Git, sebuah node baru melihat perubahan setelah ia melakukan pull. Untuk kebanyakan orang, satu langkah tambahan itu sepadan dengan hilangnya satu basis data terdistribusi dari tumpukan.

Lebih suka jalur Consul? Tidak ada yang salah dengan panduan lama itu. Saya menyimpan kedua artikel sebagai dua desain yang sama-sama valid untuk masalah yang sama — pilih sesuai cara Anda beroperasi. Baca versi Consul di High Availability Traefik dengan Consul KV & Keepalived.

Gambaran Arsitektur
#

Tiga node, satu Virtual IP, satu repositori Git:

                    ┌──────────────────────────────┐
                    │   GitHub (repo privat)       │
                    │   traefik-ha.git             │
                    │   • traefik.yaml             │
                    │   • dynamic-config/*.yaml    │
                    │   • compose.yaml             │
                    └───────────────┬──────────────┘
                       clone / pull │
        ┌───────────────────────────┼───────────────────────────┐
        ▼                           ▼                           ▼
  ┌───────────┐               ┌───────────┐               ┌───────────┐
  │  Host 22  │               │  Host 11  │               │ Host 200  │
  │ MASTER    │               │ BACKUP    │               │ BACKUP    │
  │ prio 150  │               │ prio 130  │               │ prio 110  │
  │  🏆 VIP   │               │           │               │  (wlan0)  │
  ├───────────┤               ├───────────┤               ├───────────┤
  │ traefik-ha│               │ traefik-ha│               │ traefik-ha│
  │ acme.json │               │ acme.json │               │ acme.json │
  └───────────┘               └───────────┘               └───────────┘
        └───────────── VRRP (224.0.0.18) ─────────────┘
                    DNS: *.noorkhafidzin.com → 10.1.1.111 (VIP)
Node IP Peran Prioritas Keepalived Interface
Host 22 10.1.1.22 MASTER 150 eth0
Host 11 10.1.1.11 BACKUP 130 eth0
Host 200 10.1.1.200 BACKUP 110 wlan0
  • Traefik berjalan sebagai kontainer Docker (traefik-ha) di ketiga node, membaca konfigurasi dari File Provider (/etc/traefik/dynamic-config).
  • GitHub menyimpan sumber kebenaran tunggal untuk traefik.yaml, dynamic-config/, dan compose.yaml.
  • Keepalived memindahkan Virtual IP 10.1.1.111 agar klien selalu mengenai node yang sehat.
  • Sertifikat Let’s Encrypt disimpan di acme.json pada tiap node — tanpa rsync, tanpa direktori sertifikat bersama.

Prasyarat
#

  • Tiga host Linux (Debian/Ubuntu/Armbian) dengan Docker dan plugin Compose terpasang.
  • git terpasang di semua host dan akses root/sudo.
  • Repositori GitHub privat yang kosong (misalnya traefik-ha).
  • Multicast VRRP (tujuan 224.0.0.18) diizinkan antar host.
  • Akun Cloudflare dengan zone untuk domain Anda dan API token berizin Zone → DNS → Edit.

Langkah 1 — Membuat SSH Key Khusus Deploy
#

Git perlu autentikasi tanpa password. Buat satu key di host utama lalu salin ke host lain.

# Di Host 22 (10.1.1.22)
ssh-keygen -t ed25519 -f ~/.ssh/homelab -N "" -C "homelab"
cat ~/.ssh/homelab.pub

Tambahkan public key di GitHub → Settings → SSH and GPG keys (atau sebagai deploy key pada repositori). Lalu salin private key ke dua node backup:

scp ~/.ssh/homelab [email protected]:~/.ssh/homelab
scp ~/.ssh/homelab [email protected]:~/.ssh/homelab
ssh [email protected]  'chmod 600 ~/.ssh/homelab'
ssh [email protected] 'chmod 600 ~/.ssh/homelab'

Langkah 2 — Mengatur Alias SSH dan Clone
#

Buat ~/.ssh/config di setiap host agar Git selalu memakai key yang benar:

Host github-homelab
    HostName github.com
    User git
    IdentityFile ~/.ssh/homelab

Uji koneksinya, lalu clone repositori ke path yang sama di ketiga node:

ssh -T git@github-homelab
# → Hi zarvelionzynji! You've successfully authenticated...

# Di setiap host (22, 11, 200)
git clone git@github-homelab:zarvelionzynji/traefik-ha.git /home/el/traefik-ha

Memakai path yang identik (/home/el/traefik-ha) di setiap node membuat script dan file Compose bisa disalin-tempel tanpa perubahan.

Langkah 3 — Konfigurasi Statis (traefik.yaml)
#

Berbeda dengan setup Consul, di sini tidak ada provider Consul. Semua routing hidup dalam file di dalam repo, dan TLS ditangani langsung oleh klien ACME bawaan Traefik.

/home/el/traefik-ha/traefik/config/traefik.yaml:

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
  file:
    directory: /etc/traefik/dynamic-config
    watch: true
certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]
      storage: /var/traefik/certs/acme.json
      dnsChallenge:
        provider: cloudflare
        propagation:
          disableChecks: false

Poin penting:

  • providers.file.watch: true — Traefik me-reload otomatis saat file berubah, tanpa restart (inilah yang “ditumpangi” oleh git pull di script Anda).
  • certificatesResolvers.cloudflare — Traefik kini menerbitkan dan memperbarui sertifikat sendiri lewat DNS-01 challenge Cloudflare. Tidak perlu acme.sh, tidak perlu rsync.
  • forwardedHeaders.trustedIPs — memastikan IP klien asli diteruskan ke backend.
Hanya File Provider. Saya sengaja tidak memakai Docker provider agar seluruh tabel routing hidup di Git. Kalau Anda tetap ingin mengekspos sebagian kontainer lewat label, tambahkan providers.docker — tapi ingat, konfigurasi Anda lalu hidup di dua tempat.

Langkah 4 — Konfigurasi Dinamis (Router & Service)
#

Setiap rute adalah file YAML biasa di traefik/config/dynamic-config/. Berikut satu file, routes.yaml, yang mengarahkan sebuah domain ke backend:

http:
  routers:
    app-rtr:
      rule: "Host(`app.noorkhafidzin.com`)"
      entryPoints:
        - websecure
      service: app-svc
      tls:
        certResolver: cloudflare

  services:
    app-svc:
      loadBalancer:
        servers:
          - url: "http://10.1.1.50:8080"

Untuk menambah aplikasi lain, tambahkan pasangan router/service baru, commit, dan push. Karena tls.certResolver bernilai cloudflare, Traefik akan meminta sertifikat secara otomatis saat domain pertama kali diakses — Anda tidak perlu mengatur tls: true atau mengurus file sertifikat secara manual.

Selalu pakai alamat IP backend, jangan pernah nama kontainer Docker. Nama kontainer hanya bisa di-resolve di host tempat kontainer itu berjalan, sehingga akan langsung rusak begitu trafik mendarat di node lain.

Langkah 5 — Docker Compose
#

/home/el/traefik-ha/compose.yaml:

services:
  traefik:
    image: traefik:v3.6.8
    container_name: traefik-ha
    restart: unless-stopped
    network_mode: host
    env_file:
      - .env
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/config/traefik.yaml:/etc/traefik/traefik.yaml:ro
      - ./traefik/config/dynamic-config:/etc/traefik/dynamic-config:ro
      - ./traefik/certs:/var/traefik/certs
  • network_mode: host — Traefik mengikat port 80/443 langsung dan API-nya bisa diakses di localhost:8080, yang akan dicek sehat oleh Keepalived.
  • ./traefik/certs adalah bind mount yang menyimpan acme.json di antara restart.
  • Mount Docker socket bersifat opsional jika Anda tidak memakai Docker provider.

Langkah 6 — Secret dan .gitignore
#

Token API Cloudflare disimpan di file .env:

# /home/el/traefik-ha/.env
CF_DNS_API_TOKEN=token_cloudflare_anda
Jangan pernah men-commit secret. Jaga .env dan acme.json tetap di luar Git. .gitignore di bawah melindungi Anda walaupun script push menjalankan git add ..

/home/el/traefik-ha/.gitignore:

.env
traefik/certs/acme.json

Karena .env tidak di-commit, buat file itu sekali di tiap host (salin lewat SSH). Sisanya didistribusikan otomatis oleh Git.

Langkah 7 — Sertifikat SSL
#

Tidak ada yang perlu dipasang. Saat permintaan pertama tiba untuk domain dengan certResolver: cloudflare, Traefik akan:

  1. Meminta sertifikat ke Let’s Encrypt memakai DNS-01 challenge.
  2. Memakai CF_DNS_API_TOKEN Anda untuk membuat record TXT _acme-challenge di Cloudflare.
  3. Menyimpan sertifikat hasilnya di /var/traefik/certs/acme.json.

Setiap node menyimpan acme.json miliknya sendiri, jadi tidak ada langkah sinkronisasi sertifikat sama sekali. Pastikan saja file-nya terlindungi:

chmod 600 /home/el/traefik-ha/traefik/certs/acme.json

Langkah 8 — Failover VIP dengan Keepalived
#

Pasang Keepalived di ketiga host:

sudo apt-get update && sudo apt-get install -y keepalived

/etc/keepalived/keepalived.conf di Host 22 (MASTER):

global_defs { router_id TRAEFIK_HA }

# Hanya tahan VIP selama API Traefik benar-benar 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 MASTER
    interface eth0
    virtual_router_id 111
    priority 150
    advert_int 1
    authentication { auth_type PASS; auth_pass traefikHA }
    virtual_ipaddress { 10.1.1.111/24 dev eth0 }
    track_script { check_traefik }
}

Di Host 11 gunakan state BACKUP, priority 130, interface eth0. Di Host 200 gunakan state BACKUP, priority 110, interface wlan0, dan letakkan VIP di wlan0 juga.

Lalu restart Keepalived di tiap host dan pastikan VIP muncul:

sudo systemctl restart keepalived
ip addr show eth0 | grep 10.1.1.111

Terakhir, arahkan record wildcard DNS Anda (*.noorkhafidzin.com) ke VIP 10.1.1.111.

Kenapa host 200 tetap paling rendah: ia memakai Wi-Fi, jadi seharusnya hanya mengambil alih ketika kedua node kabel sudah mati. Prioritas lebih rendah = pilihan terakhir, dan itu memang yang Anda inginkan.

Langkah 9 — Script Push
#

Mengedit konfigurasi manual di tiga mesin adalah awal dari drift. Sebagai gantinya, letakkan script kecil di dalam repo yang akan men-commit, push, dan menyuruh node backup untuk pull.

/home/el/traefik-ha/push:

#!/bin/bash
REPO_DIR="/home/el/traefik-ha"
HOSTS=("10.1.1.11" "10.1.1.200")
SSH_KEY="/home/el/.ssh/homelab"

echo "🚀 Starting sync process..."
cd "$REPO_DIR" || { echo "❌ Repo not found"; exit 1; }

git add .
git commit -m "Auto-sync: $(date '+%Y-%m-%d %H:%M:%S')"
if git push origin main; then
    echo "✅ Push successful!"
else
    echo "❌ Push failed"; exit 1
fi

for HOST in "${HOSTS[@]}"; do
    echo "🔄 Pulling on $HOST..."
    ssh -i "$SSH_KEY" "el@$HOST" "cd $REPO_DIR && git pull origin main && docker compose restart traefik"
    echo "✅ $HOST updated"
done
echo "🎉 All hosts synchronized!"

Jadikan executable dan pakai setiap kali habis mengedit:

chmod +x /home/el/traefik-ha/push
cd /home/el/traefik-ha && ./push

Opsional: Pull Otomatis dengan Cron
#

Jika Anda lebih suka tidak push manual, biarkan tiap node backup melakukan pull terjadwal:

# Di host 11 dan 200
crontab -e
# Tambahkan:
*/5 * * * * cd /home/el/traefik-ha && git pull origin main && docker compose restart traefik >> /var/log/traefik-sync.log 2>&1

Operasi Harian
#

# Status container
docker compose -f /home/el/traefik-ha/compose.yaml ps

# Ikuti log
docker logs -f traefik-ha

# Node mana yang sedang memegang VIP?
ip addr show | grep 10.1.1.111

# Lihat failover secara langsung
sudo systemctl stop keepalived      # di MASTER, lalu perhatikan VIP berpindah
journalctl -u keepalived -f

Troubleshooting
#

Gejala Yang perlu dicek
Kontainer Traefik terus restart docker logs traefik-ha — cari error config (mis. field tak dikenal di bawah propagation).
Sertifikat tidak terbit Scope token Cloudflare (Zone → DNS → Edit); zone harus ada; cek log untuk error dns01 challenge.
VIP tidak pernah failover Multicast VRRP 224.0.0.18 diblokir firewall, atau interface salah (eth0 vs wlan0).
git push gagal Uji ssh -T git@github-homelab; pastikan key termuat dan alias benar.
acme.json permission denied chmod 600 .../traefik/certs/acme.json dan pastikan dimiliki oleh root.
Routing hanya jalan di satu node URL backend kemungkinan memakai nama kontainer, bukan alamat IP.

Penutup / Kesimpulan
#

Anda sekarang punya setup Traefik yang sama tangguhnya dengan versi Consul, tapi dengan lebih sedikit komponen bergerak: Git mendistribusikan konfigurasi, File Provider Traefik membacanya secara lokal, klien ACME bawaan menangani sertifikat, dan Keepalived menjaga satu Virtual IP tetap mengarah ke node yang sehat.

Model mentalnya sangat ringkas — kalau satu node mati, VIP berpindah, dan node yang bertahan sudah punya konfigurasi yang sama karena ia menariknya dari repo yang sama. Anda bisa men-patch dan me-reboot host satu per satu, dan pengguna tidak akan menyadarinya.

Jika Anda datang dari versi Consul, kedua desain ini layak untuk diketahui: High Availability Traefik dengan Consul KV & Keepalived untuk distribusi KV yang instan, dan setup berbasis Git ini untuk kesederhanaan maksimal.

Menurut Anda, mana yang lebih cocok untuk homelab Anda? Ceritakan di kolom komentar — dan bagaimana Anda menangani sinkronisasi sertifikat atau distribusi konfigurasi di klaster Anda sendiri?

Traefik High Availability - Artikel ini merupakan bagian dari sebuah seri.
Bagian : Artikel ini

Terkait


Muat Komentar