# HAProxy & Keepalived deployment 本文件說明如何在 Ubuntu 環境下為k8s及postgres部署本機的 HAProxy(負載平衡)與 Keepalived(VIP) --- ## 0. 規劃與前置準備 #### **K8s cluster規劃**: | Hostname | Role | IP Address | 備註 | |:----------------|:-------|:-----------|:-----------------| | **doris-f01** | Master | `10.10.0.85` | Control Plane #1 | | **doris-f02** | Master | `10.10.0.87` | Control Plane #2 | | **doris-f03** | Master | `10.10.0.89` | Control Plane #3 | | **doris-b01** | Worker | `10.10.0.93` | Worker Node | | **doris-b02** | Worker | `10.10.0.94` | Worker Node | | **doris-b03** | Worker | `10.10.0.95` | Worker Node | | **doris-b04** | Worker | `10.10.0.96` | Worker Node | #### **Postgres cluster規劃**: | 節點名稱 | PostgreSQL 角色 | Patroni API | Patroni Etcd (DCS) | 數據目錄 (Data Dir) | |:---|:---|:---|:---------------------------------------------|:-------------------------------------------------------------------------------------------------------| | **doris-f01** | Primary / Replica (動態) | Port `8008` | Port `12389` (Client)
Port `12390` (Peer) | `/var/lib/postgresql` (DB)
`/var/lib/etcd-patroni` (Etcd) | | **doris-f02** | Primary / Replica (動態) | Port `8008` | Port `12389` (Client)
Port `12390` (Peer) | `/var/lib/postgresql` (DB)
`/var/lib/etcd-patroni` (Etcd) | | **doris-f03** | Primary / Replica (動態) | Port `8008` | Port `12389` (Client)
Port `12390` (Peer) | `/var/lib/postgresql` (DB)
`/var/lib/etcd-patroni` (Etcd) | --- - 實作目標: - 節點:doris-f01, doris-f02, doris-f03 - 配置對象:k8s Control Plane cluster 與 Postgres cluster。 --- ### 0.1 允許非本地 IP 綁定 為了讓 HAProxy 能順利監聽尚未漂移過來的 VIP,需調整核心參數。 ```bash echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee -a /etc/sysctl.d/99-haproxy.conf sudo sysctl -p /etc/sysctl.d/99-haproxy.conf ``` --- ### 0.2 設定防火牆 (若有啟用 UFW) ```shell # 允許 VRRP 協定 (Keepalived 用) sudo ufw allow in proto vrrp # 允許 HAProxy 相關 Ports sudo ufw allow 6444/tcp sudo ufw allow 5000:5001/tcp sudo ufw allow 8404/tcp ``` --- ## 1. HAProxy 安裝與配置 **適用節點**:所有節點,**設定檔必須相同**。 ### 1.1 安裝 HAProxy ```bash sudo apt update sudo apt install haproxy -y ``` ### 1.2 配置 `/etc/haproxy/haproxy.cfg` 備份原設定檔,並建立新設定。 ```bash sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak sudo vi /etc/haproxy/haproxy.cfg ``` 貼上以下內容: ```haproxy global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http # --- 監控頁面 (可選) --- listen stats bind *:8404 # 監控頁面 Port stats enable stats uri /stats # 網址路徑 stats refresh 10s # 刷新頻率 stats auth admin:password # 登入帳號:密碼 (自行修改) #==========k8s========== # --- 前端配置 --- frontend kubernetes-api bind *:6444 mode tcp option tcplog default_backend k8s_masters # --- 後端配置 --- backend k8s_masters mode tcp option tcp-check balance roundrobin # 若要更 aggressive 的健康檢查,可加: # tcp-check connect port 6443 server master-A 10.10.0.85:6443 check fall 3 rise 2 server master-B 10.10.0.87:6443 check fall 3 rise 2 server master-C 10.10.0.89:6443 check fall 3 rise 2 #==========postgres========== # --- 讀寫埠前端配置 --- frontend postgres_rw bind *:5000 mode tcp default_backend backend_rw # --- 讀寫埠後端配置 --- backend backend_rw mode tcp option httpchk GET /primary http-check expect status 200 server f01 10.10.0.85:5432 check port 8008 server f02 10.10.0.87:5432 check port 8008 server f03 10.10.0.89:5432 check port 8008 # --- 唯讀埠前端配置 --- frontend postgres_ro bind *:5001 mode tcp default_backend backend_ro # --- 唯讀埠後端配置 --- backend backend_ro mode tcp balance roundrobin # 使用 API 檢查,確保節點不僅活著,而且狀態健康 (不包含初始化中或損壞的節點) option httpchk GET /read-only http-check expect status 200 server f01 10.10.0.85:5432 check port 8008 server f02 10.10.0.87:5432 check port 8008 server f03 10.10.0.89:5432 check port 8008 ``` ### 1.3 啟動與檢查 ```bash # 檢查語法 sudo haproxy -c -f /etc/haproxy/haproxy.cfg # 啟動服務 sudo systemctl restart haproxy sudo systemctl enable haproxy ``` 使用瀏覽器連線至http://10.10.0.85:8404/stats,登入查看狀態 - 預期結果: - K8s API Server (Port 6444): K8s 的 Master 是Active-Active 架構,三台都應該全是綠色 (UP) - postgres_rw (Port 5000): 應該只有 一行是綠色 (UP) (那是目前的 Primary)。 其他兩行應該是 紅色 (DOWN) (因為它們是 Replica,回應 503,這是正常的)。 - postgres_ro (Port 5001): 應該 三行全是綠色 (UP) (除非有節點掛了)。 --- ## 2. Keepalived 安裝與配置 **適用節點**:所有節點,但**設定檔內容依角色不同**。 ### 2.1 安裝 Keepalived ```bash sudo apt install keepalived -y ``` ### 2.2 配置 `/etc/keepalived/keepalived.conf` ```bash sudo vi /etc/keepalived/keepalived.conf ``` #### **通用配置 (請依照節點修改 `state` 與 `priority`)** * **Master (f01)**: `state MASTER`, `priority 100` * **Backup (f02)**: `state BACKUP`, `priority 90` * **Backup (f03)**: `state BACKUP`, `priority 80` ``` global_defs { # 當上 Master 後,延遲 5 秒發送 GARP (有些 switch 反應慢) garp_master_delay 5 # 之後每 1 秒發一次 (確保大家都有更新) garp_master_refresh 1 # 指定腳本執行使用者 (依照您的環境設定) script_user gjadmin enable_script_security } # 定義檢查腳本 vrrp_script check_haproxy { script "/usr/bin/pgrep haproxy" interval 2 weight -20 } # 定義虛擬路由 vrrp_instance VI_1 { # --- 節點差異設定 --- state MASTER # f01: MASTER, f02/f03: BACKUP priority 100 # f01: 100, f02: 90, f03: 80 # ------------------ interface enp1s0 # 請確認網卡名稱 (用 ip a 查看) virtual_router_id 51 # 所有節點需一致 advert_int 1 authentication { auth_type PASS auth_pass 1111 # 所有節點需一致 } virtual_ipaddress { 10.10.0.83 # 宣告 VIP (需確認沒有被使用) } track_script { check_haproxy } } ``` ### 2.3 啟動與檢查 ```bash # 啟動服務 sudo systemctl restart keepalived sudo systemctl enable keepalived ``` ```shell # 初始狀態檢查 # 除了本機ip外,應該還會看到VIP(10.10.0.83) ip a ``` ```shell # 模擬故障轉移 sudo systemctl stop keepalived ``` 接著在 Backup (doris-f02) 上執行 `ip a`查看。 - 預期結果: - Master (doris-f01): VIP (10.10.0.83) 應該 立即消失。 - Backup (doris-f02): VIP (10.10.0.83) 應該 自動漂移並出現 在此節點 (因為 Priority 90 > 80)。 - 服務連通性: 此時從外部 Ping VIP 或連線 HAProxy,服務應短暫中斷 (約 1 秒) 後恢復正常 --- ## 3. 整合驗證高可用性 (HA) ### 3.1 檢查 VIP 是否生效 在 Master (f01) 上執行: ```bash ip a ``` 應看到設定的 VIP(10.10.0.83) 出現在列表中。 ### 3.2 模擬故障轉移 (Failover) 1. 在 Master (f01) 停止 HAProxy: ```bash sudo systemctl stop haproxy ``` 2. 在 f01 查看 VIP 是否消失。 3. 在 Backup (f02) 執行 `ip a`,確認 VIP 是否漂移過來。 4. 恢復 f01 的 HAProxy: ```bash sudo systemctl start haproxy ``` 5. 確認 VIP 是否搶回 f01 (因為 f01 權重較高)。