天天看點

haproxy的高可用

一、簡介

軟體負載均衡一般通過兩種方式來實作:基于作業系統的軟負載實作和基于第三方應用的軟負載實作。

LVS 就是基于 Linux 作業系統實作的一種軟負載,HAProxy就是開源的并且基于第三應用實作的軟負載。HAProxy 相比 LVS 的使用要簡單很多,功能方面也很豐富。目前,HAProxy 支援兩種主要的代理模式:"tcp"即 4 層(大多用于郵件伺服器、内部協定通信伺服器等)和 7 層(HTTP)在 4 層模式下, HAproxy僅在用戶端和伺服器之間轉發雙向流量。 7 層模式下, HAProxy 會分析協定,并且能通過允許、拒絕、交換、增加、修改或者删除請求(request)或者回應(response)裡指定内容來控制協定,這種操作要基于特定規則。

詳情可以HAProxy 官方網站(http://haproxy.1wt.eu)可以下載下傳配置說明文檔(configuration.txt)和架構檔案(architecture.txt)作為參考。

二、拓撲圖

三、 配置過程

注:

OS:Centos 6.5x86_64

己經安裝的包組 :

1

<code>#yum groupinstall -y </code><code>"Development tools"</code> <code>"Server Platform Development"</code>

前提:

HAproxy A與B要做到

主機名解析

時間同步

無密鑰登入

1、HAproxy A配置

安裝keepalived、haproxy

<code>#yum install -y keepalived haproxy</code>

配置keepalived

編輯/etc/keepalived/keepalived.conf

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

<code>!  Configuration File </code><code>for</code> <code>keepalived</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             </code> 

<code>global_defs {</code>

<code>   </code><code>notification_email {</code>

<code>         </code><code>root@localhost</code>

<code>         </code><code>essuninfo@localhost</code>

<code>   </code><code>}</code>

<code>   </code><code>notification_email_from essuninfo@localhost</code>

<code>   </code><code>smtp_connect_timeout 3</code>

<code>   </code><code>smtp_server 127.0.0.1</code>

<code>   </code><code>router_id LVS_DEVEL</code>

<code>}</code>

<code>vrrp_script chk_haproxy {</code>

<code>    </code><code>script </code><code>"killall -0 haproxy"</code>

<code>    </code><code>interval 1</code>

<code>    </code><code>weight 2</code>

<code>vrrp_instance VI_1 {</code>

<code>    </code><code>interface eth0</code>

<code>    </code><code>state MASTER</code>

<code>    </code><code>priority 201</code>

<code>    </code><code>virtual_router_id 109</code>

<code>    </code><code>garp_master_delay 1</code>

<code>    </code><code>authentication {</code>

<code>        </code><code>auth_type PASS</code>

<code>        </code><code>auth_pass password</code>

<code>    </code><code>}</code>

<code>    </code><code>track_interface {</code>

<code>       </code><code>eth0</code>

<code>    </code><code>virtual_ipaddress {</code>

<code>        </code><code>172.16.1.103</code><code>/16</code> <code>dev eth0 label eth0:0</code>

<code>    </code><code>track_script {</code>

<code>        </code><code>chk_haproxy</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               </code> 

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              </code> 

<code>    </code><code>notify_master </code><code>"/etc/keepalived/notify.sh master"</code>  

<code>    </code><code>notify_backup </code><code>"/etc/keepalived/notify.sh backup"</code>

<code>    </code><code>notify_fault </code><code>"/etc/keepalived/notify.sh fault"</code>

<code>vrrp_instance VI_2 {</code>

<code>    </code><code>state BACKUP</code>

<code>    </code><code>priority 99</code>

<code>    </code><code>virtual_router_id 52</code>

<code>        </code><code>172.16.1.109</code><code>/16</code> <code>dev eth0 label eth0:1</code>

通知腳本

<code>#!/bin/bash</code>

<code># description: An example of notify script</code>

<code>#</code>

<code>vip=172.16.1.103</code>

<code>contact=</code><code>'root@localhost'</code>

<code>notify() {</code>

<code>    </code><code>mailsubject=</code><code>"`hostname` to be $1: $vip floating"</code>

<code>    </code><code>mailbody=</code><code>"`date '+%F\ %T'`: vrrp transition, `hostname` changed to be $1"</code>

<code>    </code><code>echo</code> <code>$mailbody | mail -s </code><code>"$mailsubject"</code> <code>$contact</code>

<code>case</code> <code>"$1"</code> <code>in</code>

<code>    </code><code>master)</code>

<code>        </code><code>notify master</code>

<code>        </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/haproxy</code> <code>start</code>

<code>        </code><code>exit</code> <code>0</code>

<code>    </code><code>;;</code>

<code>    </code><code>backup)</code>

<code>        </code><code>notify backup</code>

<code>        </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/haproxy</code> <code>stop</code>

<code>    </code><code>fault)</code>

<code>        </code><code>notify fault</code>

<code>    </code><code>*)</code>

<code>        </code><code>echo</code> <code>'Usage: `basename $0` {master|backup|fault}'</code>

<code>        </code><code>exit</code> <code>1</code>

<code>esac</code>

<code>#chmod +x /etc/keepalived/notify.sh</code>

配置haproxy 

編輯配置檔案 /etc/haproxy/haproxy.cfg

65

66

67

68

69

70

71

72

73

74

75

76

77

78

<code>#---------------------------------------------------------------------</code>

<code># Example configuration for a possible web application.  See the</code>

<code># full configuration options online.</code>

<code>#   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt</code>

<code># Global settings</code>

<code>global </code><code>#全局配置區域</code>

<code>    </code><code>log         127.0.0.1 local2  </code><code>#日志将通過rsyslog進行歸檔記錄</code>

<code>    </code><code>chroot      </code><code>/var/lib/haproxy</code> <code>#運作的安裝路徑</code>

<code>    </code><code>pidfile     </code><code>/var/run/haproxy</code><code>.pid </code><code>#pid檔案存放的位置</code>

<code>    </code><code>maxconn     4000  </code><code>#最大連接配接</code>

<code>    </code><code>user        haproxy  </code><code>#運作haproxy的使用者</code>

<code>    </code><code>group       haproxy  </code><code>#運作haprixy的組</code>

<code>    </code><code>daemon     </code><code>#以背景模式運作haproxy</code>

<code>    </code><code># turn on stats unix socket</code>

<code>    </code><code>stats socket </code><code>/var/lib/haproxy/stats</code>

<code># common defaults that all the 'listen' and 'backend' sections will</code>

<code># use if not designated in their block</code>

<code>defaults</code>

<code>    </code><code>mode                    http  </code><code>#工作模式</code>

<code>    </code><code>log                     global </code><code>#記錄日志</code>

<code>    </code><code>option                  httplog</code>

<code>    </code><code>option                  dontlognull </code><code>#不記錄健康檢查的日志資訊</code>

<code>    </code><code>option http-server-close  </code><code>#啟用伺服器端主動關閉</code>

<code>    </code><code>option forwardfor       except 127.0.0.0</code><code>/8</code> <code>#傳遞用戶端IP</code>

<code>    </code><code>option                  redispatch </code><code>#當後端伺服器組中的某一台主機故障後,能夠自動将請求重定向到組内的其它主機</code>

<code>    </code><code>retries                 3 </code><code>#請求重試次數</code>

<code>    </code><code>timeout http-request    10s </code><code>#http請求逾時時間</code>

<code>    </code><code>timeout queue           1m </code><code>#一個請求在隊列裡的逾時時間</code>

<code>    </code><code>timeout connect         10s </code><code>#連接配接伺服器逾時時間</code>

<code>    </code><code>timeout client          1m </code><code>#用戶端逾時時間</code>

<code>    </code><code>timeout server          1m </code><code>#用戶端逾時時間</code>

<code>    </code><code>timeout http-keep-alive 10s</code>

<code>    </code><code>timeout check           10s </code><code>#心跳檢測逾時時間</code>

<code>    </code><code>maxconn                 3000 </code><code>#最大連接配接數</code>

<code># main frontend which proxys to the backends</code>

<code>frontend  proxy *:80</code>

<code>    </code><code>acl url_static       path_beg       -i </code><code>/static</code> <code>/images</code> <code>/javascript</code> <code>/stylesheets</code>

<code>    </code><code>acl url_static       path_end       -i .jpg .gif .png .css .js</code>

<code>    </code><code>use_backend static          </code><code>if</code> <code>url_static</code>

<code>    </code><code>default_backend             dynamic</code>

<code># static backend for serving up images, stylesheets and such</code>

<code>backend static  </code><code>#後端排程</code>

<code>    </code><code>balance     roundrobin </code><code>#排程算法</code>

<code>    </code><code>server      web2 192.168.1.108:80 inter 1500 rise 2 fall 3  check maxconn 5000</code>

<code>#----------------------------------------</code>

<code>listen statistics</code>

<code>    </code><code>mode http  </code><code># http 7 層模式</code>

<code>    </code><code>bind *:8080 </code><code>#監聽位址</code>

<code>    </code><code>stats </code><code>enable</code> <code>#啟用狀态監控</code>

<code>    </code><code>stats auth admin:essun </code><code>#驗證的使用者與密碼</code>

<code>    </code><code>stats uri </code><code>/admin</code><code>?status </code><code>#通路路徑</code>

<code>    </code><code>stats admin </code><code>if</code> <code>TRUE </code><code>#如果驗證通過了就允許登入</code>

<code>    </code><code>stats refresh 6s </code><code>#每6秒重新整理一次</code>

<code>    </code><code>acl allow src 172.16.1.0</code><code>/24</code> <code>#允許的IP位址</code>

<code>    </code><code>tcp-request content accept </code><code>if</code> <code>allow </code><code>#如果允許的位址段就允許通路</code>

<code>    </code><code>tcp-request content reject </code><code>#拒絕非法連接配接</code>

<code># round robin balancing between the various backends</code>

<code>backend dynamic</code>

<code>    </code><code>balance     roundrobin</code>

<code>    </code><code>server      web2 192.168.1.40:80 check inter 1500 rise 2 fall 3   maxconn 5000</code>

<code>#伺服器定義,serverid為web2,check inter 1500是檢測心跳頻率</code>

<code>#rise 2是2次正确認為伺服器可用</code>

<code>#fall 3是3次失敗認為伺服器不可用</code>

<code>#最大連接配接資料為5000</code>

<code>server  web3 192.168.1.104:80 check inter 1500 rise 2 fall 3   maxconn 5000</code>

将此檔案同時也複制到HAproxy B上一份

2、HAproxy B的配置

修改keepalived在配置檔案(/etc/keepalived/keepalived.conf)

<code>! Configuration File </code><code>for</code> <code>keepalived</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        </code> 

<code>    </code><code>priority 200</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          </code> 

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       </code> 

<code>    </code><code>priority 100</code>

修改通知腳本

<code>vip=</code><code>172.16</code><code>.</code><code>1.109</code>

<code>    </code><code>echo $mailbody | mail -s </code><code>"$mailsubject"</code> <code>$contact</code>

<code>        </code><code>/etc/rc.d/init.d/haproxy start</code>

<code>        </code><code>exit </code><code>0</code>

<code>        </code><code>/etc/rc.d/init.d/haproxy stop</code>

<code>        </code><code>echo </code><code>'Usage: `basename $0` {master|backup|fault}'</code>

<code>        </code><code>exit </code><code>1</code>

由于HAproxy A中的haporxy配置與HAporxy B 的配置檔案相同從HAproxy A中發過來一份放在同一目錄下即可

<code>#scp -p /etc/haproxy/haproxy.cnf </code><code>192.168</code><code>.</code><code>1.109</code><code>:/etc/haproxy/</code>

3、測試一下keepalived功能

HAproxy B 上面的ip位址

<a href="http://s3.51cto.com/wyfs02/M00/25/8F/wKiom1Nkc9bA-JzsAAQbqKtLbzM402.jpg" target="_blank"></a>

将ha2上的keepalived停止後,ip位址己經轉移到了ha1上了

<a href="http://s3.51cto.com/wyfs02/M00/25/8F/wKioL1Nkc_izz9NBAARTu0RtDks122.jpg" target="_blank"></a>

當ha2啟動後,172.16.1.109還是會回到ha2上面。

4、安裝後端的web服務

web1 靜态頁面 (192.168.1.108)

<code>#yum install -y httpd</code>

<code>[root@essun ~]# cd /</code><code>var</code><code>/www/html/</code>

<code>[root@essun html]# echo </code><code>"&lt;h1&gt;這是一個靜态頁面,位址為192.168.1.108&lt;/h1&gt;"</code> <code>&gt; index.html</code>

<code>[root@essun html]# ll</code>

<code>total </code><code>4</code>

<code>-rw-r--r-- </code><code>1</code> <code>root root </code><code>59</code> <code>May  </code><code>3</code> <code>12</code><code>:</code><code>50</code> <code>index.html</code>

<code>[root@essun html]# cat index.html</code>

<code>&lt;h1&gt;這是一個靜态頁面,位址為</code><code>192.168</code><code>.</code><code>1.108</code><code>&lt;/h1&gt;</code>

<code>[root@essun html]# service httpd start</code>

<code>Starting httpd: httpd: apr_sockaddr_info_get() failed </code><code>for</code> <code>essun.node3.com</code>

<code>httpd: Could not reliably determine the server's fully qualified domain name, using </code><code>127.0</code><code>.</code><code>0.1</code> <code>for</code> <code>ServerName</code>

<code>                                                           </code><code>[  OK  ]</code>

<code>[root@essun html]# curl http:</code><code>//192.168.1.108</code>

在/var/www/html中放一張圖檔,僅供測試

web2 動态頁面 (192.168.1.40)

<code>[root@essun yum.repos.d]</code><code># yum install -y  httpd php php-mysql mysql-server mysql-devel</code>

<code>[root@essun yum.repos.d]</code><code># cd /var/www/html/</code>

<code>[root@essun html]</code><code># vim index.php</code>

<code>[root@essun html]</code><code># service httpd restart</code>

<code>Stopping httpd:                                            [FAILED]</code>

<code>Starting httpd: httpd: apr_sockaddr_info_get() failed </code><code>for</code> <code>essun.node4.com</code>

<code>httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 </code><code>for</code> <code>ServerName</code>

<code>[root@essun html]</code><code># cat index.php</code>

<code>&lt;h1&gt;我是動态頁面,位址是192.168.1.40&lt;</code><code>/h1</code><code>&gt;</code>

<code>&lt;?php</code>

<code>    </code><code>phpinfo();</code>

<code>?&gt;</code>

<code>[root@essun html]</code><code># curl  -I http://192.168.1.40/index.php</code>

<code>HTTP</code><code>/1</code><code>.1 200 OK</code>

<code>Date: Sat, 03 May 2014 05:11:47 GMT</code>

<code>Server: Apache</code><code>/2</code><code>.2.15 (CentOS)</code>

<code>X-Powered-By: PHP</code><code>/5</code><code>.3.3</code>

<code>Connection: close</code>

<code>Content-Type: text</code><code>/html</code><code>; charset=UTF-8</code>

web3 動态頁面(192.168.1.104)

<code>[root@essun yum.repos.d]</code><code># service httpd restart</code>

<code>Starting httpd:                                            [  OK  ]</code>

<code>&lt;h1&gt;我也是動态頁面,位址是192.168.1.104&lt;</code><code>/h1</code><code>&gt;</code>

<code>[root@essun yum.repos.d]</code><code># curl -I http://192.168.1.104</code>

<code>Date: Sat, 03 May 2014 05:14:22 GMT</code>

四、測試

1、利用兩個vip任意一個測試一下

靜态頁面測試

<a href="http://s3.51cto.com/wyfs02/M00/25/90/wKiom1NkkzrSxJ6AAAHNA-t0B4Y260.jpg" target="_blank"></a>

動态頁面測試 web3 (192.168.1.104)

<a href="http://s3.51cto.com/wyfs02/M00/25/90/wKiom1Nkk5Sxs60uAAKQX7mpE4I883.jpg" target="_blank"></a>

監控頁面,驗證使用者身份

<a href="http://s3.51cto.com/wyfs02/M00/25/90/wKioL1NklOGCK9cEAAEkEELQ1Uw160.jpg" target="_blank"></a>

驗證通過後

<a href="http://s3.51cto.com/wyfs02/M02/25/90/wKiom1NklUuCdLbOAAaZ205nWuA099.jpg" target="_blank"></a>

其中一個keepalived當機後完不會影響到服務的正常的運作

<a href="http://s3.51cto.com/wyfs02/M01/25/90/wKioL1Nklx3S74OGAAV06sAYa1k937.jpg" target="_blank"></a>

本文轉自 jinlinger 51CTO部落格,原文連結:http://blog.51cto.com/essun/1405893,如需轉載請自行聯系原作者