Harbor HA dengan External PostgreSQL dan Redis Sentinel
/ 5 min read
📑 Daftar Isi (23)
- #Arsitektur
- #Prasyarat
- #Step 1: Konfigurasi HAProxy
- #Step 2: Verifikasi HAProxy
- #Step 3: Download & Konfigurasi Harbor
- #harbor.yml — sesuaikan dengan ini:
- #Persistent volume:
- #Step 4: Install Harbor
- #harbor-01 duluan:
- #Verifikasi container:
- #Login Harbor UI:
- #Jika login gagal “read-only transaction”:
- #Step 5: Install di harbor-02 & harbor-03
- #Step 6: Docker Login & Push
- #Tambahin insecure registry (kalau belum ada SSL):
- #Test:
- #Step 7: Test Failover
- #PostgreSQL failover:
- #Harbor failover:
- #Redis failover:
- #Ringkasan Port
- #Dependencies
- #Pitfall
Stack: Harbor 2.15.2 - PostgreSQL 18.4 (Patroni) - Redis 7 (Sentinel) - HAProxy - Keepalived - 3 Node
Arsitektur
Floating IP (publik) │ ▼Port 192.168.10.200 (standalone, Floating IP attach permanen) │ ▼Keepalived VIP 192.168.10.200 (pindah antar node via VRRP unicast) │ ▼HAProxy (*:80, *:15432, *:15433, *:8404) │ ├──► Harbor (port 8080) -- 3 node, round-robin ├──► PostgreSQL (port 5432) -- 3 node, via 15432 (all) & 15433 (leader only) └──► Redis Sentinel -- direct dari Harbor (no HAProxy)| Port | Service | Keterangan |
|---|---|---|
| 80 | Harbor UI & API | Load-balanced ke 3 node Harbor |
| 15432 | PostgreSQL (all nodes) | Round-robin, bisa kena replica |
| 15433 | PostgreSQL (leader only) | Health check Patroni API, hanya Leader |
| 8404 | HAProxy Stats | Monitoring |
Prasyarat
- PostgreSQL + Patroni HA (3 node) running
- Redis + Sentinel (3 node) running
- Docker & Docker Compose terinstall di 3 node
- HAProxy + Keepalived terinstall (unicast VRRP)
- Database
registry+ userharborsudah dibuat - Port
192.168.10.200dibuat di OpenStack + allowed_address_pairs di port.21,.22,.23 - Floating IP publik attach permanen ke port
192.168.10.200
Step 1: Konfigurasi HAProxy
Di semua 3 node:
sudo tee /etc/haproxy/haproxy.cfg << 'EOF'global log /dev/log local0 maxconn 4096
defaults log global timeout connect 5s timeout client 60s timeout server 60s
frontend harbor_frontend bind *:80 mode http default_backend harbor_backend
backend harbor_backend mode http balance roundrobin option httpchk GET /api/v2.0/ping http-check send hdr Host 192.168.10.200 http-check expect status 200 server harbor01 192.168.10.21:8080 check inter 5s server harbor02 192.168.10.22:8080 check inter 5s server harbor03 192.168.10.23:8080 check inter 5s
listen postgresql bind *:15432 mode tcp option tcplog server pg01 192.168.10.21:5432 check inter 3s server pg02 192.168.10.22:5432 check inter 3s server pg03 192.168.10.23:5432 check inter 3s
listen postgresql_leader bind *:15433 mode tcp option tcplog balance first server pg01 192.168.10.21:5432 check inter 3s port 8008 server pg02 192.168.10.22:5432 check inter 3s port 8008 server pg03 192.168.10.23:5432 check inter 3s port 8008
listen stats bind *:8404 mode http stats enable stats uri /stats stats auth admin:adminEOF
sudo systemctl reload haproxyPenjelasan critical:
postgresql(15432): round-robin ke semua node PG — buat backup, monitoring, read querypostgresql_leader(15433): health check via Patroni API port 8008, cuma Leader yang terima koneksi — buat Harbor (WRITE)balance first: all traffic ke server pertama yang UP (Leader), fallback kalau matihttp-check send hdr Host 192.168.10.200: Harbor validasi Host header, harus matchhostnamediharbor.yml
Step 2: Verifikasi HAProxy
# Cek statscurl -s -u admin:admin http://192.168.10.200:8404/stats | grep -c "UP"
# Test port 15432 (all PG nodes)psql -h 192.168.10.200 -p 15432 -U postgres -c "SELECT inet_server_addr();"
# Test port 15433 (Leader only)psql -h 192.168.10.200 -p 15433 -U postgres -c "SELECT pg_is_in_recovery();"# Harus: f (false = Leader)Password PostgreSQL:
P@ssw0rdDB
Step 3: Download & Konfigurasi Harbor
Di semua 3 node:
cd ~wget -q https://github.com/goharbor/harbor/releases/download/v2.15.2/harbor-offline-installer-v2.15.2.tgztar -xzf harbor-offline-installer-v2.15.2.tgzcd harborcp harbor.yml.tmpl harbor.ymlharbor.yml — sesuaikan dengan ini:
hostname: 192.168.10.200data_volume: /dataharbor_admin_password: HarborAdmin123!
http: port: 8080
# HTTPS di-comment -- SSL di-handle Nginx Proxy Manager
# Hapus/dikomentari bagian database dan redis bawaan (embedded)
# ---- EXTERNAL BACKENDS ----
external_database: harbor: host: 192.168.10.200 port: 15433 db_name: registry username: harbor password: HarborDBPass2024 ssl_mode: disable max_idle_conns: 100 max_open_conns: 900 connect_retries: 10 connect_retry_delay: 5s
external_redis: host: 192.168.10.21:26379,192.168.10.22:26379,192.168.10.23:26379 password: RedisPass2024! sentinel_master_set: harbor-redis registry_db_index: 1 jobservice_db_index: 2 trivy_db_index: 5 idle_timeout_seconds: 30
storage_service: s3: accesskey: YOUR_ACCESS_KEY secretkey: YOUR_SECRET_KEY region: us-east-1 regionendpoint: https://s3.example.com bucket: harbor-registry secure: trueCatatan:
port: 15433= PostgreSQL leader-only via HAProxy (WRITE safe)- Redis Sentinel langsung, tidak lewat HAProxy
- Storage bisa pakai filesystem dulu kalau belum ada S3
Persistent volume:
sudo mkdir -p /datasudo chmod 777 /dataStep 4: Install Harbor
harbor-01 duluan:
cd ~/harborsudo ./install.sh --with-trivyVerifikasi container:
sudo docker compose ps# Harus semua UP: core, portal, registry, jobservice, nginx, harbor-log, trivy-adapter
sudo docker compose logs core | tail -5# Tidak ada ERROR atau FATAL
curl -s http://192.168.10.21:8080/api/v2.0/ping# Harus: PongLogin Harbor UI:
http://192.168.10.200admin / HarborAdmin123!Jika login gagal “read-only transaction”:
Pastikan harbor.yml pakai port: 15433 (bukan 15432). Re-install:
sudo docker compose downsudo ./install.sh --with-trivyStep 5: Install di harbor-02 & harbor-03
Copy harbor.yml dari harbor-01, jalankan:
cd ~/harborsudo ./install.sh --with-trivyVerifikasi:
curl -s http://192.168.10.22:8080/api/v2.0/pingcurl -s http://192.168.10.23:8080/api/v2.0/pingCek HAProxy stats — semua backend Harbor harus hijau (UP).
Step 6: Docker Login & Push
Tambahin insecure registry (kalau belum ada SSL):
sudo tee /etc/docker/daemon.json << 'EOF'{ "insecure-registries": ["192.168.10.200"]}EOFsudo systemctl restart dockerTest:
docker login 192.168.10.200# admin / HarborAdmin123!
docker pull alpine:latestdocker tag alpine:latest 192.168.10.200/library/alpine:testdocker push 192.168.10.200/library/alpine:testStep 7: Test Failover
PostgreSQL failover:
# Stop Patroni di Leadersudo systemctl stop patroni
# Cek HAProxy stats -- pg02/pg03 harus naik jadi UPcurl -s -u admin:admin http://192.168.10.200:8404/stats | grep postgresql_leader
# Test via Harbor UI -- login harus tetap bisaHarbor failover:
# Stop Harbor di satu nodecd ~/harborsudo docker compose stop
# Cek UI -- tetap bisa (LB redirect ke node lain)curl -s http://192.168.10.200/api/v2.0/ping
# Balikinsudo docker compose startRedis failover:
# Di node master Redissudo docker compose stop redis
# Cek sentinel di node lainsudo docker exec -it sentinel redis-cli -p 26379 SENTINEL master harbor-redis
# Harbor harus tetap jalan (Redis buat session/task queue)Ringkasan Port
| Port | Service | Dari | Ke |
|---|---|---|---|
| 80 | Harbor UI | Client → VIP → HAProxy | Harbor 8080 |
| 8080 | Harbor internal | HAProxy health check | Harbor container |
| 15432 | PG all nodes | Manual/admin | PG 5432 (round-robin) |
| 15433 | PG leader only | Harbor container | PG 5432 (dicek via Patroni 8008) |
| 5432 | PG instance | Patroni | PostgreSQL |
| 8008 | Patroni API | HAProxy health check | Patroni |
| 26379 | Sentinel | Harbor container | Sentinel |
| 8404 | HAProxy Stats | Admin browser | HAProxy |
Dependencies
Harbor install ──depends──► HAProxy port 15433 ready PostgreSQL Leader running Redis Sentinel quorum 2/3 Database registry + user harbor created Docker installedPitfall
| Gejala | Penyebab | Solusi |
|---|---|---|
Login gagal: read-only transaction | Harbor konek ke replica PG | Pakai port 15433 (leader-only via HAProxy) |
| HAProxy backend Harbor merah | Host header mismatch | Sesuaikan http-check send hdr Host dengan hostname di harbor.yml |
| Harbor container restart terus | Port 5432 conflict dengan PG | Pakai external_database dengan port HAProxy (15433) |
Redis sentinel: num-other-sentinels: 1 | Sentinel announce IP Docker internal | Tambah sentinel announce-ip <host_ip> di config |
Harbor prepare error: KeyError | Config YAML kurang field | Gunakan template asli harbor.yml.tmpl, jangan bikin dari nol |
data_volume kosong error | Variable $data_path tidak diset | Tambahkan data_volume: /data di harbor.yml |
📖 Artikel Terkait
Redis High Availability dengan Sentinel
Tutorial membangun Redis HA cluster menggunakan Sentinel di tiga node dengan Docker Compose, dari setup master-replica hingga uji failover otomatis.
Load Balancing PostgreSQL dengan HAProxy dan Keepalived
Tutorial setup HAProxy load balancer dengan Keepalived VRRP failover untuk PostgreSQL HA, termasuk health check Patroni API dan leader-only routing.
PostgreSQL High Availability dengan Patroni dan etcd
Tutorial lengkap membangun PostgreSQL HA cluster menggunakan Patroni dan etcd di Ubuntu 26.04, dari hasil trial-error langsung di production.
💬 Komentar
Komentar via GitHub Discussions. Login GitHub diperlukan.