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.
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.
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/, dancompose.yaml. - Keepalived memindahkan Virtual IP
10.1.1.111agar klien selalu mengenai node yang sehat. - Sertifikat Let’s Encrypt disimpan di
acme.jsonpada tiap node — tanparsync, tanpa direktori sertifikat bersama.
Prasyarat #
- Tiga host Linux (Debian/Ubuntu/Armbian) dengan Docker dan plugin Compose terpasang.
gitterpasang 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.pubTambahkan 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/homelabUji 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-haMemakai 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: falsePoin penting:
providers.file.watch: true— Traefik me-reload otomatis saat file berubah, tanpa restart (inilah yang “ditumpangi” olehgit pulldi script Anda).certificatesResolvers.cloudflare— Traefik kini menerbitkan dan memperbarui sertifikat sendiri lewat DNS-01 challenge Cloudflare. Tidak perluacme.sh, tidak perlursync.forwardedHeaders.trustedIPs— memastikan IP klien asli diteruskan ke backend.
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.
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/certsnetwork_mode: host— Traefik mengikat port 80/443 langsung dan API-nya bisa diakses dilocalhost:8080, yang akan dicek sehat oleh Keepalived../traefik/certsadalah bind mount yang menyimpanacme.jsondi 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.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.jsonKarena .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:
- Meminta sertifikat ke Let’s Encrypt memakai DNS-01 challenge.
- Memakai
CF_DNS_API_TOKENAnda untuk membuat record TXT_acme-challengedi Cloudflare. - 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.jsonLangkah 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.111Terakhir, arahkan record wildcard DNS Anda (*.noorkhafidzin.com) ke VIP 10.1.1.111.
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 && ./pushOpsional: 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>&1Operasi 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 -fTroubleshooting #
| 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?