前言
目前生產環境的配置越來越多的使用雲服務了,同時負載均衡也基本轉向了雲廠商提供的服務,但對於絕大多數應用來說,自建叢集可能在費用上要更便宜一些,這篇文章也是之前整理的,再次新瓶裝舊酒分享給各位。此示例演示在不使用docker的情況下配置負載均衡,內容keepalived+nginx+tomcat的基礎配置示例,某些特定配置此例中不會出現,在示例中會用到三個虛擬機器:兩個純命令列用於模擬服務端配置,一個帶桌面環境的用於模擬客戶端訪問,這樣三臺虛擬機器使用NAT模式連線的時候是在同一個虛擬網路中,更符合伺服器的實際使用場景,虛擬機器軟體為VMPlayer,這個對於個人可以免費使用,用起來來不錯,推薦一下。
本例項中是模擬使用場景,機器效能有限,所有nginx和Tomcat就放到一個機器上了,實際場景中如果可以儘量分開,防止nginx所在伺服器出問題時跟著宕掉一個或多個Tomcat。
建立虛擬機器
此部分是為了照顧對於虛擬機器安裝不熟悉的同學,如果已經熟悉了虛擬機器的安裝或有實體機環境等,可以跳過此步驟。
建立伺服器虛擬機器(mini安裝)
- 開啟VMPlayer,然後介面如下,點選建立新虛擬機器
- 彈出頁面後選擇最後一項,稍後安裝作業系統,這裡一定要選擇這個,因為如果選擇其他直接安裝的話會使用簡易安裝,預設安裝完是帶桌面的
- 下一步,然後選擇Centos 64位的作業系統,這個需要針對映象來選擇,我這裡選這個是因為我有現成的64位映象。
- 下一步,這裡設定下虛擬機器的名字和安裝地址,便於區分。
- 下一步,然後需要設定硬碟,大小隨意(虛擬機器建立之後硬碟大小隻能增大不能減小了,所以這裡可以設定的小一點,親測配置完成後也就才2G,這裡設定5G應該就足夠了),下邊兩項也是二選一隨意。
- 下一步,介面如下,這裡我們需要點選“自定義硬體”來配置系統的光碟機,如果實體機的配置低的話可以在這裡降低下虛擬機器的CPU和記憶體等,命令列模式下的CentOS並不需要多高的配置(單核512M可以無壓力執行)
- 在開啟的介面中選擇光碟機,然後選擇使用ISO映象,點選瀏覽選擇映象即可,這個映象可以從CentOS官網下載。
- 之後點選關閉,再點選完成即可,此時的介面如下:
- 此時虛擬機器的硬體已經準備完畢,接下來我們點選播放虛擬機器配置系統,點選後介面如下,選擇第一項Install。
- 接下來稍等片刻會進入圖形化介面,這裡不用擔心,這個只是安裝的圖形介面,與之後系統沒關係,如下:
- 因為是要最小化安裝,所以語言預設英文即可,點選Continue,跳轉後的介面為配置介面,我們僅需要修改下圖中紅框的部分,其他的預設即可。
-
第一項是配置系統的硬碟,這裡我們不需要進行任何配置,點選進入之後直接點選左上角的Done按鈕即可。
-
第二項是配置系統的網路,預設不連線,所以我們需要點選進入配置頁面,然後將右上角的OFF置成ON,然後點選DONE,之後會跳轉回一開始的設定頁,我們就可以開始系統的安裝了,點選Begin Installation,接下來需要設定使用者。
- ROOT使用者的密碼是必須要建立的,其他使用者可以根據需要進行建立,這裡我只設定了ROOT使用者的密碼,方便後續的操作,不用考慮許可權問題,實際應用中是要用其他使用者操作的,後續的操作可視情況賦予許可權即可。還有需要注意的是如果使用者的密碼強度很低,需要點選兩次DONE來確定。
- 接下來就是等待結束重啟即可,至此CentOS就安裝完成了。
建立客戶端虛擬機器(簡易安裝安裝)
在這個例項中客戶端有兩個用處,一是透過瀏覽器測試服務端的服務是否好用;二是透過FTP向服務端上傳幾個原始碼包。其實上傳原始碼包這個功能大部分情況下實體機也是可以操作的,但在NAT網路下實體機的瀏覽器在預設是無法訪問服務端的服務的。
客戶端虛擬機器對作業系統無限制,只要可以執行瀏覽器即可,其實命令列模式下的linux也是可以訪問的,不過不太直觀,如果想用實體機進行訪問的話也可以,不過需要將虛擬機器的網路連線模式改為橋接模式,而且對網路有要求,需要支援DHCP才可以。
安裝過程和服務端的很類似,只有第二部有所區別,伺服器需要選擇稍後安裝作業系統,但客戶端的虛擬機器使用第二項選擇映象即可,之後會提示設定系統的使用者名稱和密碼,之後的步驟就一樣了,而且自定義硬體的時候不再需要設定光碟機。
配置基礎環境
-
這裡以Server01為示例,其實我們需要配置兩臺的,我使用的使用者是root使用者,實際應用中可能需要在其他使用者下進行,視情況賦予許可權即可。
-
因為我們需要向虛擬機器上傳一些用到的軟體(當然可以使用wget來下載,只不過有點麻煩),所以這裡我們實體機或者客戶端使用FTP客戶端進行連線(工具有很多,挑選自己順手的使用,這裡推薦Xftp和FileZilla,對於個人使用都是免費的),虛擬機器的IP地址可以透過ip addr進行檢視,紅框中就是當前虛擬機器的IP地址
- 接下來在FTP客戶端中輸入主機地址,需要注意的是CentOS使用的是SFTP,所以我們輸入的地址應該是sftp://192.168.59.130,輸入賬戶密碼之後點選快速連線,如果看到如下介面則表示連線成功了
- 現在系統是配置完成了,不過IP是隨機分配的,如果有需要可以將伺服器的地址改為靜態IP,不過這個IP一般不會發生變化,這裡我就先不改了,但是伺服器的話是一定會設定固定IP的。
安裝JDK
- 我們常用的SUN JDK不支援yum安裝,所以需要從JDK官網下載合適的JDK,這裡我使用的是JDK-8u111-linux-x64.rpm,透過ftp上傳到/usr/local/download下(這個位置隨意),然後分別執行以下命令進行安裝,JDK的預設安裝地址為/usr/java
cd /usr/local/download
rpm -i jdk-8u111-linux-x64.rpm
- 安裝後即可執行java -version檢視安裝的版本資訊
安裝Tomcat
- Tomcat是可以透過yum進行安裝的,不過示例中我們需要兩個Tomcat,單獨下載更方便,我這裡下載的是tomcat 7.0.72。透過FTP將tomcat上傳到/usr/local/download下,然後分別執行以下命令解壓並移動到/usr/local下,因為後續要使用兩個Tomcat,所以我們執行兩次操作
tar -xvf apache-tomcat-7.0.72.tar.gz
mv apache-tomcat-7.0.72 /usr/local/Tomcat01
tar -xvf apache-tomcat-7.0.72.tar.gz
mv apache-tomcat-7.0.72 /usr/local/Tomcat02
- 此時我們的Tomcat已經解壓完成了,接下來是修改埠號,防止兩個Tomcat埠衝突,Tomcat預設會佔用三個埠:8005,8080和8009,這裡我們修改成如下,檔案為/usr/local/Tomcat01/conf/server.xml和/usr/local/Tomcat02/conf/server.xml(這裡如果不熟悉vi編輯器的小夥伴可以將配置檔案下載到本地然後修改完成後再上傳回伺服器)
Tomcat01 8015 8081 8019
Tomcat02 8025 8082 8029
- 修改完成以後我們進入/usr/local/Tomcat01/bin目錄下執行 ./start.sh,會提示Tomcat Started,此時實體機依然是無法訪問的,因為防火牆沒有開放埠,執行以下命令開放埠,以下命令僅當前會話有效,增加--permanent可以永久保留埠開放狀態,不過我們是要做的負載均衡中nginx只會訪問本機的Tomcat,所以Tomcat的埠沒有必要一直開放,現在測試下就夠了
firewall-cmd --zone=public --add-port=8081/tcp
- 此時我們在客戶端虛擬機器中訪問 http://192.168.59.130:8081 即可看到Tomcat的歡迎頁了,此時還有一個問題,兩個Tomcat的首頁是一樣的,負載均衡成功後無法分辨來自哪個Tomcat,所以我們要加點東西區分一下,我是在每個歡迎頁的body中增加了一行標識如下,檔案位於/usr/local/Tomcat01/webapps/ROOT/index.jsp
安裝Nginx
nginx可以透過修改源的方式進行yum安裝,有需要的同學可以自行搜尋下,本例中使用原始碼安裝
- 從官網下載原始碼包後透過FTP將nginx的原始碼上傳到/usr/local/download下,然後執行以下命令解壓,我這裡使用的是1.10.2
tar -xvf nginx-1.10.2.tar.gz
- 之後我們就要用到gcc來編譯nginx的原始碼了,需要先安裝gcc
yum install gcc
- 之後分別執行以下命令,--prefix是指定軟體的安裝位置
cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx
- 執行之後我們會的到以下錯誤,我們需要去下載PCRE的原始碼,然後透過FTP上傳到/usr/local/download下,我這裡用的是8.39
- 解壓縮pcre的原始碼,命令和以前的一樣,解壓後不需要進行其他操作
tar -xvf pcre-8.39.tar.gz
- 然後我們再次編譯nginx,根據上次的提示我們追加上pcre的原始碼位置
cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx --with-pcre=/usr/local/download/pcre-8.39
- 恭喜,又報錯了,這次提示換成了這個,所以我們又需要下載zlib的原始碼,老辦法上傳到老地方,然後解壓,這裡命令就不詳細說了,跟之前一樣,我下載的版本是1.2.8
- 解壓完成後,我們根據提示追加zlib命令,是的,就追加這兩個,不需要再追加了
cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx --with-pcre=/usr/local/download/pcre-8.39 --with-zlib=/usr/local/download/zlib-1.2.8
- 編譯完成了,執行安裝,命令如下
make && make install && make clean
- 本來以為可以愉快的結束了的,結果。。。。。。
- 好吧,只能繼續安裝了
yum install gcc-c++
- 現在執行前一步的make命令安裝就可以了,接下來進入/usr/local/nginx/sbin目錄下執行./nginx啟動nginx,然後分別執行以下命令開放80埠(永久開放的埠在設定後必須執行reload,本次有效的不需要執行,執行reload後本次有效的埠也將失效)
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
- 之後我們可以在客戶端的瀏覽器中輸入 http://192.168.59.130 進行測試,如果出現如下頁面表示nginx啟動成功了
- nginx是可以做成系統服務的,實際應用中大多也是這麼做的,不過這裡只是個示例,就不做成服務了,如果有需要的可以自行百度,當然如果使用yum安裝的話安裝完成就已經註冊服務了。
配置負載均衡
- 之前Tomcat我們已經做好了配置,接下來只需要在nginx中配置即可,配置檔案為/usr/local/nginx/conf/nginx.conf,如下圖新增upstream部分,將localtion部分更改為圖中部分即可,server可以是其他伺服器上的服務,weight越高越容易被分發請求,這裡我暫時寫本機的,另外實際使用中upstream第一行要加入ip_hash來保證同一使用者一次只能訪問同一臺伺服器,解決session跨伺服器丟失的問題,如果系統內使用其他方法處理了session的共享問題就不要加了,這個例項中我們就不加入了,因為加入了以後重新整理瀏覽器頁面不會變化。
- 接下來就可以進行負載均衡的測試了,因為修改過nginx的配置檔案所以我們需要重啟一下nginx,然後開啟兩個Tomcat,命令如下:
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx
/usr/local/Tomcat01/bin/start.sh
/usr/local/Tomcat02/bin/start.sh
- 接下來可以在實體機的瀏覽器進行測試了,連續訪問虛擬機器的nginx,這時Tomcat歡迎頁就會在01和02之間來回切換,至此負載均衡配置結束,然後大家可以回過頭去再建立一個Server02重新配置一遍了,因為keepalived就需要根據機器分主次了,配置檔案是不一樣的,配置完成的話server01的nginx也可以設定將請求分發到server02的tomcat上,不過這裡為了演示就不新增了,後續好區分請求由哪臺機器響應。
配置keepalived
-
keepalived推薦使用yum安裝,原始碼安裝之後的配置挺複雜的
yum install keepalived
- 安裝完成後需要配置keepalived的配置檔案,檔案位於/etc/keepalived/keepalived.conf,下圖中為需要修改的部分,預設的配置檔案中在其後還有很多內容,本例項只是簡單的DEMO,所以那些內容暫時用不上,可以全部刪除,核心配置說明如下:
vrrp_instance VI_1 {
# 主伺服器為MASTER,其他伺服器均為BACKUP
state MASTER
# 通訊用的網路卡,在之前檢視IP時可以看到
interface eno16777736
# 主從伺服器此ID必須一致
virtual_router_id 51
# 優先順序,主伺服器必須大於其他伺服器,數值越大優先順序越高
priority 100
# 主從伺服器必須一致
authentication {
auth_type PASS
auth_pass 1111
}
# 虛擬IP地址,主從伺服器必須一致,此IP為客戶端訪問時使用的IP
virtual_ipaddress {
192.168.59.100
}
}
- 配置完此檔案後儲存退出,然後重啟keepalived服務,此時透過ip addr檢視發現主從伺服器上都有192.168.59.100的虛擬IP,原因是防火牆阻止了伺服器之間的vrrp通訊,分別執行以下命令,需要針對自己電腦進行修改的只有interface後的網路卡,其他的照抄即可
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eno16777736 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface eno16777736 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
-
至此Keepalived的配置也完成了,透過ip addr檢視可發現主服務上帶有192.168.59.100的虛擬IP而從伺服器上沒有,關閉主伺服器的keepalived,虛擬IP則會轉移到從伺服器上來,測試伺服器透過瀏覽器訪問 http://192.168.59.100 可看到虛擬IP轉移的效果,頁面會從主伺服器的頁面轉換為從伺服器的頁面,這裡就不上圖片了
-
完成上述步驟之後keepalived已經可以實現虛擬IP轉移了,但是實際應用當中我們需要的是自動進行虛擬IP的轉移,所以我們還需要配置keepalived的指令碼,使其能夠在某一個nginx無法提供服務的時候自動將虛擬IP轉移到備用伺服器,以下指令碼來自於上邊提供的連結,原理是透過curl訪問某一個連結,如果連續兩次三秒沒有響應則降低伺服器的優先順序,我們在/etc/keepalived目錄下建立一個名為check_status.sh的檔案,然後鍵入以下內容
#!/bin/bash
count=0
for (( k=0; k<2; k++ ))
do
check_code=$( curl --connect-timeout 3 -sL -w "%{http_code}\\n" http://localhost/login.html -o /dev/null )
if [ "$check_code" != "200" ]; then
count=$(expr $count + 1)
sleep 3
continue
else
count=0
break
fi
done
if [ "$count" != "0" ]; then
exit 1
else
exit 0
fi
- 因為指令碼後續是需要執行的,所以我們需要賦予可執行的許可權,此指令碼是我們自定義的,沒有什麼安全問題,此項操作需要在root使用者下執行,程式碼如下(這裡感謝 程式人生0407 的提醒)
chmod +x check_status.sh
- 之後我們在keepalived.conf中配置指令碼,配置內容如下
vrrp_script check_status {
script "/etc/keepalived/check_status.sh"
interval 5
weight -5
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.59.100
}
track_script {
check_status
}
}
-
配置完成後重啟keepavlied即可,此時如果關閉本機的nginx的話可以看到在5秒後虛擬IP會漂移到備用伺服器上去,這裡因為演示的話圖片太多了,就不上圖片了,nginx退出可以執行nginx -s stop命令,如果是使用yum安裝的nginx可以透過systemctl來停止nginx服務
-
實際使用當中經常使用到的還有在切換伺服器時傳送郵件用以提醒運維人員主伺服器異常,方法有很多種,此例中就不再贅述,有興趣的可以自行查詢相關資料
本示例到此結束,如果各位有什麼意見或建議,歡迎留言指教,轉載請註明源地址
另說明,markdown文件中的程式碼由於未知原因傳上來以後格式有點混亂,大家使用的時候注意下格式,不要少個括號之類的。