Site icon Soul & Shell Blog

富人用 L4 Switch,窮人用 Linux HAProxy!

關於負載平衡 (Load Balance)HAProxy-diagram

現在很多網路服務都需要服務大量使用者,以前可以砸錢擴充機器硬體設施,但隨著網路服務的用量暴增,增加伺服器硬體設備已經無法解決問題。為了可以擴充服務,負載平衡成為主流的技術,這幾年雖然雲端與分散式儲存運算技術火紅,但是除非有特別的使用需求,不然在技術上 Load Balancing 算是比較容易達成與掌握的技術。負載平衡除了分流能力之外,有另一個很大的好處就是可以提供 High Availability,也就是傳說中的 HA 架構,好讓你一台機器掛了其他伺服器可以繼續服務,降低斷線率。

目前還使有很多大型網站都是使用典型的 Load Balance 架構,就像右圖由一台 Switch 或 Proxy 接收來自 Internet 的連線請求,然後分散給後端的 Cluster Server,藉此提高單個 IP 能夠服務與處理的連線量。除了上述的典型架構之外,也可透過 DNS 的搭配來分散流量,整提來說還算是好管理的架構。

這裡的典型架構最重要的就是 Load Balance 這台前端的 Gateway 了,如果購買 L4/L7 Switch 差不多要準備個 100W,設定也相當複雜。還好 Open Source 力量大,有 HAProxy 可以用,快來介紹如何使用吧!

Linux 安裝 HAProxy

以下介紹「套件安裝」與「編譯安裝」兩種安裝方式,由於稍等我們會介紹到如何設定 SSL 連線,因此請務必安裝 1.5 以上的版本 (SSL 是 1.5 之後才提供的的 Feature)。

套件安裝

Debian 可透過 apt 直接安裝,以下範例是在 Ubuntu Server 環境中操作
sudo apt-get install software-properties-common python-software-properties
sudo apt-add-repository ppa:vbernat/haproxy-1.5
sudo apt-get update
sudo apt-get install haproxy

編譯安裝 (RedHat 或 CentOS 皆適用)

請到「HAProxy 官方網站」下載 Source Code 並解壓縮,以下範例版本是 1.5.3。
wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.3.tar.gz
tar -zxvf haproxy-1.5.3.tar.gz
cd haproxy-1.5.3/
開始編譯 HAProxy,假設 linux 核心為 2.6.x 可以用使用 TARGET=linux26 參數進行最佳化,如果真的不知道可以用 TARGET=generic 即可,如下:
make clean
make TARGET=linux26 USE_OPENSSL=1 ADDLIB=-lz
sudo make PREFIX=/usr/local/haprox

設定 HAProxy

修改設定檔 /etc/haproxy/haproxy.cfg (如果是編譯安裝會在 /etc/haproxy.cfg),設定如下:

global
    log /dev/log    local0
    log /dev/log    local1 notice
    maxconn 1024
    user  haproxy
    group haproxy
    daemon
    nbproc 1
    pidfile /var/run/haproxy.pid
    tune.ssl.default-dh-param  1024

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    # 以下幾個 Timeout 設定要跟後端的 PHP 配合調整
    timeout server 30s
    timeout connect 30s
    timeout client 30s
    # 如果伺服器掛了要 retry 的次數
    retries 2

# Web 服務入口
frontend switch
    bind *:80
    mode http
    option httpclose
    option forwardfor
    reqadd X-Forwarded-Proto:\ https
    default_backend web_server_cluster

# HAProxy 監控儀表板
listen stats :8080
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    # 帳號密碼
    stats auth your_username:your_password
    stats refresh 10s

# 設定 Web Cluster
backend web_server_cluster
    mode http
    balance roundrobin
    cookie SERVERID insert indirect nocache
    # Web Server Cluster
    server web1 192.168.1.10:80 check cookie s1
    server web2 192.168.1.11:80 check cookie s2

重啟 HAProxy 載入設定

sudo service haproxy restart

使用瀏覽器連線後 HAProxy 就會自動分派 HTTP Request 到後端的機器中,上述設定檔有個「cookie SERVERID insert indirect nocache」是用來記錄連線的伺服器位置,這個功能相當棒。可以讓某個瀏覽器發出的 Request 統一導向同一台機器,避免一些資料交換的問題。可以偷看一下 Chrome 收到的 Response,會被 HAProxy 偷偷加上 SERVERID 這個 Cookie,如下:

此外上述的「listen stats :8080」Section,我們還啟用了監控工具(要關掉也可以),可以即時看到 HAPRoxy 的狀態,進入時需要輸入我們指定的帳號密碼,畫面如下:

啟用 SSL 加密 + 自動轉換 HTTPS 連線

除了分流之外,我們也常用 SSL 進行 HTTPS 連線,通常都會搭配 HTTP Redirect 讓使用者打了 HTTP 網址也能自動轉換,這些都可以直接透過 HAProxy 做掉,相當方便。開始之前我們先看一下要實作的架構,如下圖:

上圖中,使用者可以連進 HTTP 80 Port 與 HTTPS 443 Port,當沒有使用 SSL 連進 80 Port 時,HAProxy 會發出 HTTP 301 Redirect 將使用者導向 HTTPS 服務。然而 HAProxy 會將 SSL 解開的封包再往後頭的 HTTP Cluster Web Server 傳送,好處是集中 SSL 加解密的動作在 HAProxy 上,後端的 Web Server 就單純多了,也好管理。相關 haproxy.cfg 設定如下:

# 自動將 HTTP 轉到 HTTPS
frontend http_redirect
    bind *:80
    redirect scheme https code 301 if !{ ssl_fc }

frontend https_switch
    bind *:443 ssl crt /etc/pki/CA/server.pem
    mode http
    option httpclose
    option forwardfor
    reqadd X-Forwarded-Proto:\ https
    default_backend web_server_cluster

如果沒有 SSL 連線憑證,您也可以透過以下命令產生(當然這會被瀏覽器判斷為未認可):

sudo mkdir -p /etc/pki/CA/
sudo mkdir -p /etc/pki/CA/certs/
sudo mkdir -p /etc/pki/CA/private/
sudo openssl genrsa -out /etc/pki/CA/private/ca.key 2048
sudo openssl req -new -key /etc/pki/CA/private/ca.key -out /etc/pki/CA/certs/ssl.csr
sudo openssl x509 -req -days 3650 -in /etc/pki/CA/certs/ssl.csr -signkey /etc/pki/CA/private/ca.key -out /etc/pki/CA/certs/ssl.crt

漏講一個重要的概念,由於 HAProxy 是採用 HTTP Proxy 機制,因此後端收到的連線都是由 HAProxy 這台機器發出,如果想要抓到原始發送端的 IP Address 必須透過「X-Forwarded-Proto」這個 HTTP Header 來取得,可別忘了。

HAProxy 除了 HTTP 分流,也可以做到最基本的 TCP/IP 分流,大致上常用到的功能都有了,未來有機會我再來介紹更複雜的設定與應用,今天先到這裡,下台一鞠躬!

Exit mobile version