高可用(keepalived)部署方案

2023-04-10 12:01:02

前言:為了減少三維資料中心視覺化管理系統的停工時間,保持其服務的高度可用性。同時部署多套同樣的三維視覺化系統,讓三維資料中心視覺化系統同時部署並執行到多個伺服器上。同時提供一個虛擬IP,然後外面通過這個虛擬IP來存取三維視覺化管理系統,當一臺實體伺服器掛掉時會自動的切到另一條伺服器,但是這個虛擬IP依然能提供服務。

要實現高可用性,需要保證資料的一致,因此需要保證這幾臺伺服器上的資料庫中的資料一致;同時還需要保證上傳的檔案資訊一致。最後需要通過軟體監聽程式來監聽並且掛掉時進行自動切換。

一、什麼是高可用?

高可用HA(High Availability)是分散式系統架構設計中必須考慮的因素之一,它通常是指,通過設計減少系統不能提供服務的時間。

假設系統一直能夠提供服務,我們說系統的可用性是100%。

如果系統每執行100個時間單位,會有1個時間單位無法提供服務,我們說系統的可用性是99%。

很多公司的高可用目標是4個9,也就是99.99%,這就意味著,系統的年停機時間為8.76個小時。

百度的搜尋首頁,是業內公認高可用保障非常出色的系統,甚至人們會通過www.baidu.com 能不能存取來判斷「網路的連通性」,百度高可用的服務讓人留下啦「網路通暢,百度就能存取」,「百度打不開,應該是網路連不上」的印象,這其實是對百度HA最高的褒獎。-----摘選自知乎

二、如何保障系統的高可用

我們都知道,單點是系統高可用的大敵,單點往往是系統高可用最大的風險和敵人,應該儘量在系統設計的過程中避免單點。方法論上,高可用保證的原則是「叢集化」,或者叫「冗餘」:只有一個單點,掛了服務會受影響;如果有冗餘備份,掛了還有其他backup能夠頂上。

保證系統高可用,架構設計的核心準則是:冗餘。

有了冗餘之後,還不夠,每次出現故障需要人工介入恢復勢必會增加系統的不可服務實踐。所以,又往往是通過「自動故障轉移」來實現系統的高可用。-----摘選自知乎

人話:兩臺伺服器啟動著相同的服務,如果有一臺故障,另一臺自動接管,我們將這個稱之為高可用;

類似伺服器:冗餘,類似伺服器有2-4個電源,但是比較貴

上圖:

安裝keepalived:

離線安裝方法:因為我們的大部分客戶都是屬於資料中心,並不會連線外網,所以採取離線安裝的方式比較多,線上安裝的方法非常簡單,如下命令即可,在安裝keepalived之前確保安裝了攝像頭的那一套東西,因為這裡涉及到需要安裝openssl的模組,如果沒有裝請先裝nginx攝像頭相應的軟體

keepalived的執行模式:

準備條件:

需要三個ip,並且保證是區域網,相互之間ping的通,前面兩個ip好理解,兩臺伺服器,第三個ip就是一個虛擬ip,就是空餘ip沒被啟用的即可,我們存取系統的話就是通過這個虛擬ip存取

優先順序

VRRP根據優先順序來確定虛擬路由器中每臺路由器的地位;

非搶佔方式

如果Backup路由器工作在非搶佔方式下,則只要Master路由器沒有出現故障Backup路由器即使隨後被設定了更高的優先順序也不會成為Master路由器;

搶佔方式

如果Backup路由器工作在搶佔方式下,當它收到VRRP報文後,會將自己的優先順序與通告報文中的優先順序進行比較。如果自己的優先順序比當前的Master路由器的優先順序高,就會主動搶佔成為Master路由器;否則,將保持Backup狀態.

yum install keepalived-y

1.上傳檔案

1.首先把檔案傳到opt下面

2.解壓安裝

cd /opt   
tar -zxvf keepalived-2.0.20.tar.gz

3.編譯

cd  keepalived-2.0.20

./configure --prefix=/usr/local/keepalived

會發現有一個報錯

4.報錯資訊然後安裝

cd /opt
rpm -ivh libnl-1.1.4-3.el7.x86_64.rpm --force --nodeps
rpm -ivh libnl-devel-1.1.4-3.el7.x86_64.rpm --force --nodeps
cd keepalived-2.0.20
./configure --prefix=/usr/local/keepalived

沒有報錯了,繼續往下執行

 make && make install

輸入上面的命令會報以下錯誤

解決:

cd /usr/local/lib64
export LIBRARY_PATH=/usr/local/lib64
cd /opt/keepalived-2.0.20
./configure --prefix=/usr/local/keepalived
 make && make install

執行完之後也報錯了

5.初始化keepalived

 cp /opt/keepalived-2.0.20/keepalived/etc/init.d/keepalived /etc/init.d/
 cp /opt/keepalived-2.0.20/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
mkdir -p /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
chmod +x /etc/init.d/keepalived

6.新增keepalived到開機啟動

chkconfig —add keepalived 

chkconfig keepalived on 

7.啟動、關閉、重啟

service keepalived start  //啟動
service keepalived stop   //停止
service keepalived restart   //重啟

當我們啟動使用 service keepalived start 啟動的時候會報錯

解決:

ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1

在輸入命令啟動

service keepalived start

以上的1-7步驟在備機上也需要裝一下,請注意

8.設定keepalived

主機:192.168.10.51

備機:192.168.10.65

虛擬ip:192.168.10.77

在主機下操作:

vi /etc/keepalived/keepalived.conf

以下就是我們需要修改的內容

填完直接 :wq!儲存退出即可

上面圖裡面說的網路卡名稱查詢方法:

ip addr

然後重啟keepalived

service keepalived restart

service keepalived status     //檢視keepalived的狀態,下圖表示已經啟動

在備機下操作:

vi /etc/keepalived/keepalived.conf

以下就是我們需要修改的內容

填完直接 :wq!儲存退出即可

然後重啟keepalived

service keepalived restart

service keepalived status     //檢視keepalived的狀態,下圖表示已經啟動

9.驗證

啟動後看對應的虛擬IP地址是否生成,當主機關掉或者其對應的keepalived掛掉後備機是否生成對應的虛擬IP,以及主機重啟工作時虛擬IP是否重新漂移到主機上。

我們可以相互ping一下,可以看見是通的

上面我們講過,預設存取就是主機,主機掛了就是切換到備機,我們只需要檢視主機上面的ip,上面很明顯有兩個ip,其中有一個就是虛擬機器器ip

當我們把主機關掉或者主機的keepalived服務關掉之後看能否重新漂移回來呢?

我們再看看ip addr,很明顯已經沒有了虛擬ip

我們已經成功關掉了主機的keepalived服務,我們看下備機上能夠看到虛擬ip嗎

我們在備機上操作,我們可以看到虛擬ip跑到了這上面,看到這裡你是不是對keepalived的工作模式有了一個淺顯的認識,接下來我們開啟主機的keepalived服務,能夠在跳過去嘛.這就是模擬當主機已經恢復服務了,看能否自動跳轉過去

啟動主機的keepalived服務:

service keepalived start
service keepalived status

檢視ip,很明顯已經切換回來了,自此已經設定完成了keepalived服務

mysql主主備份:

保證各伺服器上的資料庫中的資料一致,因此需要開啟資料庫同步機制。由於是一整套系統,並且系統內含資料庫。由於任何一臺伺服器都有可能被選中,因此要讓所有的資料庫上的資料都是最新的,任何一個伺服器上的資料發生變化時都要自動的同步到其他的伺服器上。

三維視覺化管理系統使用的時Mysql資料庫,這裡採用的時主-主備份機制進行同步的。

主一資料庫:192.168.10.51

主二資料庫:192.168.10.65

主資料庫1:

編輯資料庫

vi /etc/my.cnf
# 開啟二進位制同步
log-bin=mysql-bin

# 設定ID,不能重複,可以使用IP最後一位數位 
server-id=129

# 需要同步的資料名稱,多個資料庫則要重複設定: bin-do-db,bin-ignore-db為互斥關係, 只需設定其中一項即可
replicate-do-db=itv

# 自增長欄位初始值為1
auto-increment-offset=1

# 自增長欄位增量值
auto-increment-increment=2

# 跳過所有複製的錯誤
slave-skip-errors=all

systemctl restart mysqld   //重啟mysql服務

主資料庫2:

編輯資料庫

vi /etc/my.cnf
# 開啟二進位制同步
log-bin=mysql-bin

# 設定ID,不能重複,可以使用IP最後一位數位 
server-id=128

# 需要同步的資料名稱,多個資料庫則要重複設定: bin-do-db,bin-ignore-db為互斥關係, 只需設定其中一項即可
replicate-do-db=itv

# 自增長欄位初始值為1
auto-increment-offset=1

# 自增長欄位增量值
auto-increment-increment=2

# 跳過所有複製的錯誤
slave-skip-errors=all

systemctl restart mysqld   //重啟mysql服務

建立mysql複製賬戶:

在主一資料庫操作:

為主二的所在的ip建立一個賬號密碼為root1,這樣就能夠允許遠端存取本機資料庫了

登入mysql:

mysql -uroot -proot   //登入mysql
grant replication slave on *.* to root1@'192.168.10.68' identified by 'root1';

賦予許可權:如果就這樣連線的話雖然能存取但還是看不了資料的,所以需要賦予root1許可權

update user set `Select_priv` = 'Y',`Insert_priv` = 'Y',`Update_priv` = 'Y',`Delete_priv` = 'Y',`Create_priv` = 'Y',`Drop_priv` = 'Y',
`Reload_priv` = 'Y',`Shutdown_priv` = 'Y',`Process_priv` = 'Y',`File_priv` = 'Y',`Grant_priv` = 'Y',`References_priv` = 'Y',
`Index_priv` = 'Y',`Alter_priv` = 'Y',`Show_db_priv` = 'Y',`Super_priv` = 'Y',`Create_tmp_table_priv` = 'Y',
`Lock_tables_priv` = 'Y',`Execute_priv` = 'Y',`Repl_slave_priv` = 'Y',`Repl_client_priv` = 'Y',`Create_view_priv` = 'Y',
`Show_view_priv` = 'Y',`Create_routine_priv` = 'Y',`Alter_routine_priv` = 'Y',`Create_user_priv` = 'Y',`Event_priv` = 'Y',
`Trigger_priv` = 'Y',`Create_tablespace_priv` = 'Y'
where user='root1';

立即生效:

flush privileges;

在主二資料庫操作:

為主一的所在的ip建立一個賬號密碼為root1,這樣就能夠允許遠端存取本機資料庫了

登入mysql:

mysql -uroot -proot   //登入mysql
grant replication slave on *.* to root1@'192.168.10.67' identified by 'root1';

賦予許可權:如果就這樣連線的話雖然能存取但還是看不了資料的,所以需要賦予root1許可權

update user set `Select_priv` = 'Y',`Insert_priv` = 'Y',`Update_priv` = 'Y',`Delete_priv` = 'Y',`Create_priv` = 'Y',`Drop_priv` = 'Y',
`Reload_priv` = 'Y',`Shutdown_priv` = 'Y',`Process_priv` = 'Y',`File_priv` = 'Y',`Grant_priv` = 'Y',`References_priv` = 'Y',
`Index_priv` = 'Y',`Alter_priv` = 'Y',`Show_db_priv` = 'Y',`Super_priv` = 'Y',`Create_tmp_table_priv` = 'Y',
`Lock_tables_priv` = 'Y',`Execute_priv` = 'Y',`Repl_slave_priv` = 'Y',`Repl_client_priv` = 'Y',`Create_view_priv` = 'Y',
`Show_view_priv` = 'Y',`Create_routine_priv` = 'Y',`Alter_routine_priv` = 'Y',`Create_user_priv` = 'Y',`Event_priv` = 'Y',
`Trigger_priv` = 'Y',`Create_tablespace_priv` = 'Y'
where user='root1';

立即生效:

flush privileges;

測試能否存取:

在主一登入主二的資料庫:

mysql -h192.168.10.65 -uroot1 -p    //登入主二的資料庫

發現連線失敗

我們檢視3306埠發現被佔用,我們開啟3306埠,我們在主備機都需要開放此埠

應該是防火牆的原因,

firewall-cmd --zone=public --add-port=3306/tcp --permanent

然後重啟防火牆

systemctl restart firewalld.service

繼續連線,發現可以連線成功,並且可以檢視資料

show databases;  //檢視資料庫

同理,在主二的資料庫可以存取主一的資料庫看下:

mysql -h192.168.10.51 -uroot1 -p    //登入主一的資料庫
show databases;  //檢視資料庫

重啟資料庫

主資料庫1: systemctl restart mysqld
主資料庫2: systemctl restart mysqld 

互告bin-log資訊

主主同步還有主從同步都是基於binlog的原理進行,相當於我們開啟了這個開關,每次運算元據庫都會產生一個binlog紀錄檔,然後把binlog紀錄檔進行發給對方進行執行,這樣資料就保持同步了

首先進入MySQL命令列:

主資料庫1:

檢視紀錄檔: show master status;

設定同步:

change master to master_host = '192.168.10.65',master_user='root1',master_password='root1',master_port=3306,master_log_file='mysql-bin.000002',master_log_pos=154;

備註: master_log_file與File值一致, master_log_pos與Position值一致

開始同步: start slave;

檢視同步情況:

show slave status\G;

當看到了兩個yes,即:Slave_IO_Running: Yes

Slave_SQL_Running: Yes

說明已經設定成功了,但是這裡有一個顯示為no,明顯有問題

解決辦法:

stop slave;
reset slave;
start slave;

然後我們繼續檢視同步情況;

show slave status\G;

灰常完美

主資料庫2:

這裡其實跟上面的主數庫一是一樣的操作

show master status;

change master to master_host = '192.168.10.51',master_user='root1',master_password='root1',master_port=3306,master_log_file='mysql-bin.000002',master_log_pos=154;

備註: master_log_file與File值一致, master_log_pos與Position值一致

開始同步:

  start slave;

檢視同步情況:

 show slave status\G;

當看到了兩個yes,即:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

說明已經設定成功了,如果這裡的slave_io_Running顯示no依然採用上面的辦法操作即可

開啟專案測試:

在主一和主二機器上分別部署專案,並且匯入相同的資料庫,然後用forever啟動,這個在之前的部署環境就有講過,此處不再贅述,我們開啟專案

在主機上開啟機房:

在備機上也開啟機房:

然後我們開始存取這兩個專案(注意此時的防火牆,把8081埠開啟):

我們發現兩個專案都可以順利的開啟,這時候我們就使用虛擬ip進行存取,因為實際我們也是通過這個虛擬ip進行存取的,我們的虛擬ip是192.168.10.77,一i就那個可以順利存取了,現在我們就關掉主機的機房程式,看他能不能存取

關掉主機服務:

forever stopall

我們還需要吧keepalived的服務關了,因為keepalived並不知道我們的機房程式已經掛了,所以要時刻監聽8081埠的狀態,如果8081埠監聽不到那麼就停止keepalived這個服務,以下是sheel指令碼,然後我們設定監聽一分鐘即可

A=`netstat -lnp | grep 8081 | wc -l`

if [ $A -eq 0 ]; then
    # echo "keepalived 應該關閉了"
    /usr/sbin/service keepalived stop
fi

然後關掉keepalived的服務:

service keepalived stop

現在我們繼續存取主機的程式,然後在存取虛擬ip

可以看到,主機程式已經存取不到,那麼虛擬ip呢(這裡注意虛擬ip機大的防火牆一定要關閉或者是開放8081埠)

可以看到,虛擬ip已經飄到備用伺服器上了,這時候備機上面已經有了虛擬ip

如果現在主機重新上線,虛擬ip還會從備機飄到主機上,這時候就會產生一個現象,就是腦裂

我們啟動主機的機房並且啟動keepalived