概述:
lvs負載均衡是一個虛擬服務器集羣項目,無論是哪一種lvs結構都需要一個前端的調度器,讓原本應該直接訪問真實服務器的網絡請求經過該調度器,讓該調度器去決定該請求應該由誰處理。根據調度器將網絡請求分配到真正服務器的不同方式,基本分成了三種模式--nat,tun,dr,還有一種需要對內核添加功能的模式是fullnat,但這次我們先不介紹這個模式。
1.三種模式的介紹
nat模式,這種模式十分好理解,也很好配置,顧名思義nat(Network Address Translation)地址轉換的意思,調度器收到客戶端請求後將這個請求的ip頭部中的目的地址轉換成爲調度器內網的某臺真實主機(選擇哪臺主機與調度算法有關)。
優點:只要調度器擁有真實ip即可,真正的服務器可以設置爲內網的任意ip。
缺點:擴展性不好,因爲所有的真實服務都必須和調度器在一個局域網內,而且必須以調度器作爲網關,所以所有的網絡請求都要經過調度器進來,也要經過調度器出去,當真實服務擴展時,調度器的瓶頸將會越來越明顯。
tun模式,該模式是在ip包外再添加一個ip包頭也就是ip隧道技術,真實服務也可以接受這樣的數據包,解析後去和真實的客戶端通信。
優點:現在調度器只是一個添加ip包頭的作用,調度器的性能不再成爲系統的瓶頸。而且由於使用的是隧道技術,真實服務器可以在公網上佈置。
缺點:網絡上對數據包的大小是有規定的,包過大將會被拆分,而且每臺真實服務都要有公網上的合法ip。
dr模式,與前兩種不同的是,這個模式修改的是以太網包的頭部的目的mac地址,將數據包轉發到不同mac地址的主機,之後真實服務器將和客戶端進行通信。
優點:和tun一樣,不會讓調度器成爲系統的瓶頸,而且不需要ip隧道技術。
缺點:調度器和真實服務都需要配置上虛擬ip,而且爲了防止局域網內的mac地址混淆,需要關閉掉真實服務器對局域網內對尋找虛擬ip主機的mac地址廣播的迴應。
2.配置DR模式
首先安裝lvs的支持軟件
[root@dp1 ~]# yum install ipvsadm
設置虛擬ip和提供的服務,[root@dp1 ~]# ipvsadm -A -t 172.25.9.100:80 -s rr
-A添加一個虛擬服務,-t添加tcp服務,-s lvs的算法
[root@dp1 ~]# ipvsadm -a -t 172.25.9.100:80 -r 172.25.9.42 -g
[root@dp1 ~]# ipvsadm -a -t 172.25.9.100:80 -r 172.25.9.43 -g
添加真實服務的節點,-a 添加一個真實服務的虛擬ip,-r定義real service的地址,-g使用直接路由方式(DR)。
[root@dp1 ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.9.100:http rr
-> rs1.mo.com:http Route 1 0 0
-> rs2.mo.com:http Route 1 0 0
查看lvs的狀態此時給dp1添加虛擬ip。
[root@rs1 ~]# ip addr add 172.25.9.100/24 dev eth0
在真實服務器上架設http服務
[root@rs1 html]# /etc/init.d/httpd start
Starting httpd: [ OK ]
[root@rs1 html]# ls
index.html
[root@rs2 html]# ls
index.html
rs1和rs2上是不同的內容,爲了一會的實驗結果明顯
dp1,rs1,rs2在同一網段內,但是他們都具有172.25.9.100的ip,我們希望外界認爲172.25.9.100是dp1,所以需要屏蔽掉rs1,rs2對172.25.9.100這個ip查詢mac時的迴應。我們採用arptables,一個基於二層的防火牆,使用方法類似iptables。
[root@rs1 html]# yum install arptables_jf.x86_64
[root@rs1 html]# arptables -A IN -d 172.25.9.100 -j DROP
[root@rs1 html]# arptables -A OUT -s 172.25.9.100 -j mangle --mangle-ip-s 172.25.9.42
[root@rs1 html]# /etc/init.d/arptables_jf save
第一條策略是當有找172.25.9.100的arp包時候,這臺機器不做迴應,第二條是當發出查找其他ip對應的mac的時候的源頭地址應該是172.25.9.42也就是本機的獨有ip。
rs2同理。
rs1,rs2都開啓arptables的服務。
現在測試lvs是否成功
[root@foundation9 0220]# curl 172.25.9.100
rs1
[root@foundation9 0220]# curl 172.25.9.100
rs1
發現沒有成功,這時如果我們理解原理,就能知道,既然一直訪問的是rs1,說明172.25.9.100的ip地址一定綁定在了
rs1上,查看一下
[root@foundation9 0220]# arp -an 172.25.9.100
? (172.25.9.100) at 52:54:00:ce:44:70 [ether] on br0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:ce:44:70 brd ff:ff:ff:ff:ff:ff
inet 172.25.9.42/24 brd 172.25.9.255 scope global eth0
inet 172.25.9.100/24 scope global secondary eth0
發現確實如此,所以清除客戶機的arp緩存。[root@foundation9 0220]# arp -d 172.25.9.100
[root@foundation9 0220]# curl 172.25.9.100
rs2
[root@foundation9 0220]# curl 172.25.9.100
rs1
現在重新測試,已經成功符合了負載均衡的結果。3.添加lvs的健康檢查
現在我們做一個測試,將rs1的http服務關閉。
[root@foundation9 0220]# curl 172.25.9.100
rs2
[root@foundation9 0220]# curl 172.25.9.100
curl: (7) Failed connect to 172.25.9.100:80; Connection refused
發現lvs並沒有發現rs1壞掉了,仍然會切換到壞掉的rs1上,在真實環境中,這明顯不是我們想要的結果,應該是當檢測到rs1壞掉後,就不會再跳到rs1上。使用現有的東西我們無法完成,所以需要添加一個監控服務健康的服務。就是
ldirectord,用於監控在lvs集羣的真實服務。ldirectord是和heartbeat相結合的一個服務,可以作爲heartbeat的一個啓動服務。所以之前要安裝好heartbeat,而且配置好,再將ldrectord的配置文件複製到/etc/ha.d下,因爲默認沒有放到裏面。
[root@dp2 ha.d]# rpm -ql ldirectord
/etc/ha.d/resource.d
/etc/ha.d/resource.d/ldirectord
/etc/init.d/ldirectord
/etc/logrotate.d/ldirectord
/sbin/rcldirectord
/usr/sbin/ldirectord
/usr/share/doc/packages/ldirectord
/usr/share/doc/packages/ldirectord/ldirectord.cf
/usr/share/man/man8/ldirectord.8.gz
ldirectord.cf就是配置文件。
編輯配置文件。
checktimeout=3
checkinterval=1
autoreload=yes
quiescent=no
virtual=172.25.9.100:80
real=172.25.9.42:80 gate
real=172.25.9.43:80 gate
fallback=127.0.0.1:80 gate
service=http
scheduler=rr
#persistent=600
#netmask=255.255.255.255
protocol=tcp
checktype=negotiate
checkport=80
request="index.html"
# receive="Test Page"
# virtualhost=www.x.y.z
配置如上,通過virtual來定義vip,接下來是定義real service的節點,fallback是當所有real掛掉後,本機衝上去,一般這個頁面顯示服務器正在維護等界面。service表示;調度的服務,scheduler是調度算法,protocol是定義協議,checktype是檢查類型爲協商,checkport就是檢查的端口,也就是健康檢查。request代表你的/var/www/html一定要有index的html。接下來啓動服務lvs就會自己開啓,而且ip也會自己佈置。
但是啓動ldirectord模塊的時候出現了問題
[root@dp1 ha.d]# /etc/init.d/ldirectord start
Starting ldirectord... Can't locate IO/Socket/INET6.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/ldirectord line 3061.
BEGIN failed--compilation aborted at /usr/sbin/ldirectord line 3061.
failure
這就是perl模塊的問題,我們安裝一下perl模塊就好了。
[root@dp1 ha.d]# yum install -y perl-IO-Socket-INET6
安裝成功後就啓動成功了。
[root@dp1 html]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.9.100:http rr
-> rs1.mo.com:http Route 1 0 2
-> rs2.mo.com:http Route 1 0 1
[root@foundation9 0220]# curl 172.25.9.100
rs2
[root@foundation9 0220]# curl 172.25.9.100
rs1
負載均衡成功。現在關掉rs1的http服務
[root@foundation9 0220]# curl 172.25.9.100
rs2
[root@foundation9 0220]# curl 172.25.9.100
rs2
發現不會出現切到壞掉的服務器上了。
問題發現:
ldirectord是對perl的一個包有依賴的,所以當你啓動的時候遇到問題不要驚慌。
如下:
Starting ldirectord... Can't locate IO/Socket/INET6.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/ldirectord line 3061.
BEGIN failed--compilation aborted at /usr/sbin/ldirectord line 3061.
failure
這就是缺少那個perl包了
perl-IO-Socket-INET6.noarch : Perl Object interface for AF_INET|AF_INET6 domain sockets
安裝之後就可以解決了4.將ldirectord加入heartbeat集羣。
首先配置好heartbeat,對heartbeat還不太瞭解的小夥伴可以看一下上一篇博客,如下是ha.cf
logfacility local0
keepalive 2
deadtime 30
warntime 10
initdead 60
udpport 10005
bcast eth0 # Linux
auto_failback on
node ha1.mo.com
node ha2.mo.com
ping 192.168.5.1
respawn hacluster /usr/lib64/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
authkeys文件
auth 1
1 crc
haresource文件
ha1.mo.com IPaddr::192.168.5.100/24/eth0 ldirectord
現在啓動heartbeat服務,但是我發現我heartbeat啓動後沒有任何的輸出信息,甚至連日誌一行都不輸出,仔細搜索後發現這竟然是官網的一個小bug。
273 vim /usr/lib/ocf/resource.d/heartbeat/.ocf-directories
${HA_BIN:=/usr/libxec/heartbeat}
將上面這行的libxec修改成lib64你就會發現一切都正常了。
現在我們的基礎結構就成了有ha1,ha2作爲lvs雙機備份的調度節點,rs1,rs2作爲真實服務。
5.keepalive+lvs
首先安裝keepalived的源碼包
[root@ha1 keepalived-1.2.24]# ls
aclocal.m4 bin_install configure COPYING genhash keepalived Makefile.am README
ar-lib ChangeLog configure.ac depcomp INSTALL keepalived.spec.in Makefile.in TODO
AUTHOR compile CONTRIBUTORS doc install-sh lib missing
源碼包的內容如上所示,沒有喜聞樂見的spec結尾,也就是可以生成rpm包。
[root@ha1 keepalived-1.2.24]# ./configure
configure: error: in `/root/keepalived-1.2.24':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
日常執行configure,發現沒有c compiler。configure: error:
!!! OpenSSL is not properly installed on your system. !!!
!!! Can not include OpenSSL headers files. !!
openssl沒有繼續下載,切記是openssl-devel。因爲這是屬於編譯階段,缺少的都是devel。
編譯成功進入make階段,但是這裏給大家一個建議,由於這個源代碼包無法生成rpm,爲了之後遷移到另一個節點考慮的話,我們應該將keepalive安裝到一個獨立的目錄中方便遷移。
[root@ha1 keepalived-1.2.24]# ./configure --prefix=/usr/local/keepalived
將keepalived的根目錄放置到/usr/local下。之後在進行make和make install
[root@ha1 keepalived]# pwd
/usr/local/keepalived
[root@ha1 keepalived]# ls
bin etc lib sbin share
現在已經將keepalived的根目錄仿真到了/usr/local下。
現在將keepalived的配置文件,啓動腳本等放置到操作系統的相應目錄下,使用軟鏈接即可。
[root@ha1 ~]# ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
[root@ha1 ~]# /etc/init.d/keepalived start
/etc/init.d/keepalived: line 15: /etc/sysconfig/keepalived: No such file or directory
只將keepalived啓動腳本連接好就是如上結果,將sysconfig文件也放置好
[root@ha1 ~]# ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@ha1 ~]# /etc/init.d/keepalived start
Starting keepalived: /bin/bash: keepalived: command not found
[FAILED]
將sysconfig下文件放置好後仍然報錯,發現找不到命令,也就是缺少/sbin下的二進制命令,我們繼續連接,將啓動的二進制文件連接到/sbin下。[root@ha1 ~]# ln -s /usr/local/keepalived/sbin/keepalived /sbin/
[root@ha1 ~]# /etc/init.d/keepalived start
Starting keepalived: [ OK ]
測試啓動,發現已經打開了。但是現在先關閉keepalived服務,因爲配置文件還沒有寫好,到這裏發現還需要連接etc下的配置文件。[root@ha1 ~]# ln -s /usr/local/keepalived/etc/keepalived /etc/
現在將ha2上也佈置好keepalived服務,我們將/usr/local/keepalived發送到ha2下。做和一上相同的軟連接。
修改配置文件。
ha1上的配置文件如下:
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost #接收報警的email地址
}
notification_email_from [email protected] #警告郵件在哪裏發出,注意這裏在MASTER和BACKUP上是不一樣的
smtp_server 127.0.0.1 #設置smtp服務地址,一般爲本地
smtp_connect_timeout 30
router_id LVS_DEVEL #load balancer的標誌id
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER #節點的標誌,MASTER爲主節點,BACKUP爲從節點
interface eth0 #監測的網絡端口
virtual_router_id 51 #MASTER和BACKUP的id必須相同
priority 100 #優先級,MASTER一定要高於BACKUP
advert_int 1 #主備之間通告的間隔秒數
authentication {
auth_type PASS #設置驗證類型,有PASS和AUTH
auth_pass 1111
}
virtual_ipaddress { #設置虛擬IP地址
192.168.5.100
}
}
virtual_server 192.168.5.100 80 { #定義虛擬服務
delay_loop 6
lb_algo rr #定義lvs的調度算法,這裏使用的是輪詢
lb_kind DR #定義lvs模式,這裏是DR
#persistence_timeout 50 #這裏是保持連接時間,對動態頁面有很大作用
protocol TCP #定義轉發協議的類型
real_server 192.168.5.13 80 { #真正提供服務節點的配置
weight 1 #節點權重,數值越大,所承受的負載越大
TCP_CHECK {
connect_timeout 3 #3秒無響應超時
nb_get_retry 3 #重試次數
delay_before_retry 3 #重試間隔
}
}
real_server 192.168.5.14 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
將這個配置文件發送到ha2上進行,再把所有與ha1和MASTER相關的修改成ha2和BACKUP,在上面的配置文件內容中已經標出。
現在兩邊重啓服務即可。
觀察一下ip有沒有掛上去,負載均衡是否工作正常。
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:f4:26:bf brd ff:ff:ff:ff:ff:ff
inet 192.168.5.11/24 brd 192.168.5.255 scope global eth0
inet 192.168.5.100/32 scope global eth0
inet6 fe80::20c:29ff:fef4:26bf/64 scope link
valid_lft forever preferred_lft forever
[root@ha1 ~]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.5.100:http rr
-> rs1.mo.com:http Route 1 0 0
-> rs2.mo.com:http Route 1 0 0