(一)keepalived概述
Keepalived通過VRRP(虛擬路由冗余協議)協議實現虛擬IP的漂移。當master故障后,VIP會自動漂移到backup,這時通知下端主機刷新ARP表,如果業務是通過VIP連接到服務器的,則此時依然能夠連接到正常運行的主機,RedHat給出的VRRP工作原理如下圖:
本來對VIP漂移有一定了解的我,看了上面的圖后,越來越懵了。因此只能根據我的個人理解,來對keepalived的VIP漂移做一個解釋了,假設我現在有一套這樣的環境:
主機A的IP地址為:192.168.10.11
主機B的IP地址為:192.168.10.12
我們再單獨定義一個keepalived使用的VIP:192.168.10.10
當2台主機安裝了keepalive並正常運行時,keepalive會選擇一個節點做為主節點(這里假設為主機A,IP為192.168.10.11),由於A是主節點,所以主機A上還會生成一個IP地址192.168.10.10,即虛擬IP(Virtual IP,也稱VIP),此時我們使用192.168.10.10訪問主機,訪問到的主機是A;假如A主機上的keepalived由於某些原因(例如服務器宕機、用戶主動關閉…)關閉了,keepalived備用節點會檢查與主節點keepalived的通信是否正常,檢測到不正常,則會提升一個備節點為主節點,相應的虛擬IP也會在對應的主機上生成,從而實現高可用的目的。
(二)MySQL是如何結合keepalived實現高可用的
在MySQL中,通過搭建MySQL雙主復制,保持2台主機上的MySQL數據庫一模一樣,並在2台主機上安裝keepalived軟件,啟用VIP,用戶應用程序通過VIP訪問數據庫。當包含VIP的主機上的數據庫發生故障時,關閉keepalived,從而將VIP漂移到另一個節點,用戶依然可以正常訪問數據庫。 (這里需要注意,雖然MySQL架構雙主復制,2個節點都可以寫入數據,但是我們在使用的時候,是通過VIP訪問其中一個實例,並沒有2個數據庫實例一起使用)。這里我簡單畫了一個流程圖,來說明keepalive與MySQL實現高可用的過程:
(三)keepalived+MySQL實現高可用過程實現
基礎環境規划:
主機名 | IP地址 | 備注 | |
服務器A | hosta | 192.168.10.11 | keepalive主節點 |
服務器B | hostb | 192.168.10.12 | keepalive備節點 |
192.168.10.10 | 虛擬IP,會在keepalive啟動后分配到上面2台機器的主節點上 |
(3.1)搭建MySQL雙主復制環境
STEP1:安裝MySQL過程見:https://www.cnblogs.com/lijiaman/p/10743102.html
STEP2:配置雙主復制參數
服務器A | 服務器B |
[mysqld] server_id = 1
|
[mysqld] server_id = 2 |
STEP3:創建復制用戶,2個數據庫上都要創建
grant replication slave on *.* to 'rep'@'%' identified by '123';
STEP4:將hosta的數據拷貝到hostb,並應用
[root@hostb ~]# mysqldump -uroot -p123456 -h 192.168.10.11 --single-transaction --all-databases --master-data=2 > hosta.sql [root@hostb ~]# mysql -uroot -p123456 < hosta.sql
STEP5:hostb上開啟復制,以下腳本在hostb上執行
-- 配置復制 mysql> CHANGE MASTER TO -> master_host='192.168.10.11', -> master_port=3306, -> master_user='rep', -> master_password='123', -> MASTER_AUTO_POSITION = 1; Query OK, 0 rows affected, 2 warnings (0.01 sec) -- 開啟復制 mysql> start slave; Query OK, 0 rows affected (0.00 sec) -- 查看復制狀態 mysql> show slave status \G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.11 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 322 Relay_Log_File: hostb-relay-bin.000002 Relay_Log_Pos: 417 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
STEP6:hosta上開啟復制,以下腳本在hosta上執行
mysql> CHANGE MASTER TO -> master_host='192.168.10.12', -> master_port=3306, -> master_user='rep', -> master_password='123', -> MASTER_AUTO_POSITION = 1; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> start slave; Query OK, 0 rows affected (0.01 sec) mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.12 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 154 Relay_Log_File: hosta-relay-bin.000002 Relay_Log_Pos: 369 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
STEP7:測試雙主復制
在hosta上創建數據庫testdb,到hostb服務器上查看數據庫是否已經創建
-- hosta上創建數據庫 create database testdb; --hostb上查看數據庫,發現已經創建 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | db1 | | lijiamandb | | mysql | | performance_schema | | sbtest | | sys | | testdb | +--------------------+ 8 rows in set (0.01 sec)
在hostb的testdb數據庫上創建表t1,並插入數據,到hosta上查看是否復制過來
-- 在hostb上創建表並插入數據 mysql> use testdb Database changed mysql> create table t1(id int,name varchar(20)); Query OK, 0 rows affected (0.01 sec) mysql> insert into t1 values(1,'a'); Query OK, 1 row affected (0.01 sec) -- 在hosta上查看數據,數據已經過來 mysql> select * from testdb.t1; +------+------+ | id | name | +------+------+ | 1 | a | +------+------+ 1 row in set (0.00 sec)
到這,雙主復制已經搭建完成,接下來安裝配置keepalived。
(3.2)安裝配置keepalived
(3.2.1)keepalived的安裝與管理
keepalived可以使用源碼安裝,也可以使用yum在線安裝,這里直接使用yum在線安裝:
[root@hosta data]# yum install -y keepalived
使用如下命令查看安裝路徑:
[root@hosta data]# rpm -ql keepalived /etc/keepalived /etc/keepalived/keepalived.conf /etc/sysconfig/keepalived /usr/bin/genhash /usr/lib/systemd/system/keepalived.service /usr/libexec/keepalived /usr/sbin/keepalived /usr/share/doc/keepalived-1.3.5
… 略
使用如下命令管理keepalived
# 開啟keepalived
systemctl start keepalived 或者 service keepalived start
# 關閉keepalived
systemctl stop keepalived 或者 service keepalived stop
# 查看keepalived運行狀態
systemctl status keepalived 或者 service keepalived status
# 重新啟動keepalived
systemctl restart keepalived 或者 service keepalived restart
(3.2.2)keepalived的配置
keepalived的配置文件為:/etc/keepalived/keepalived.conf,我的配置文件如下:
【hosta主機的配置文件】
[root@hosta keepalived]# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { ops@wangshibo.cn tech@wangshibo.cn } notification_email_from ops@wangshibo.cn smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id MASTER-HA } vrrp_script chk_mysql_port { #檢測mysql服務是否在運行。有很多方式,比如進程,用腳本檢測等等 script "/mysql/chk_mysql.sh" #這里通過腳本監測 interval 2 #腳本執行間隔,每2s檢測一次 weight –5#腳本結果導致的優先級變更,檢測失敗(腳本返回非0)則優先級 -5
fall 2#檢測連續2次失敗才算確定是真失敗。會用weight減少優先級(1-255之間)
rise 1 #檢測1次成功就算成功。但不修改優先級 } vrrp_instance VI_1 { state BACKUP #這里所有節點都定義為BACKUP interface ens34 #指定虛擬ip的網卡接口 mcast_src_ip 192.168.10.11 #本地IP virtual_router_id 51 #路由器標識,MASTER和BACKUP必須是一致的 priority 101 #定義優先級,數字越大,優先級越高,在同一個vrrp_instance下,MASTER的優先級必須大於BACKUP的優先級。 advert_int 1 nopreempt #不搶占模式,在優先級高的機器上設置即可,優先級低的機器可不設置 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.10 #虛擬IP } track_script { chk_mysql_port } }
【hostb主機的配置文件】
[root@hostb keepalived]# cat keepalived.conf ! Configuration File for keepalived global_defs { notification_email { ops@wangshibo.cn tech@wangshibo.cn } notification_email_from ops@wangshibo.cn smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id MASTER-HA } vrrp_script chk_mysql_port { script "/mysql/chk_mysql.sh" interval 2 weight -5 fall 2 rise 1 } vrrp_instance VI_1 { state BACKUP interface ens34 mcast_src_ip 192.168.10.12 virtual_router_id 51 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.10 } track_script { chk_mysql_port } }
需要特別注意:nopreempt這個參數只能用於state為BACKUP的情況,所以在配置的時候要把master和backup的state都設置成BACKUP,這樣才會實現keepalived的非搶占模式!
【判斷MySQL數據庫允許狀態的文件】
[root@hosta ~]# cat /mysql/chk_mysql.sh #!/bin/bash counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l) if [ "${counter}" -eq 0 ]; then systemctl stop keepalived fi
在配置完成之后,啟動MySQL數據庫和keepalive,需要注意,先啟動MySQL,再啟動keepalive,因為keepalive啟動后會檢測MySQL的運行狀態,如果MySQL運行異常,keepalive會自動關閉。
(3.3)高可用測試
時間軸 (時間遞增) |
hosta操作 | hostb操作 |
時間1 | # 數據庫運行正常 #keepalived運行正常 # 此時虛擬IP在hosta上 |
# 數據庫運行正常 [root@hostb ~]# service mysqld status #keepalived運行正常 [root@hostb ~]# service keepalived status [root@hostb ~]# ip addr |
時間2 | # 通過VIP訪問數據庫,訪問到的都是hosta上的實例 |
# 通過VIP訪問數據庫,訪問到的都是hosta上的實例
|
時間3 | # 主節點關閉MySQL
|
|
時間4 | # keepalived檢測到MySQL關閉后,會自動關閉 # 此時VIP已經不存在 |
# hostb上的keepalived運行正常 # 發現VIP已經切換到了hostb |
時間5 | # 通過VIP訪問數據庫,訪問到的都是hosta上的實例 |
# 通過VIP訪問數據庫,訪問到的都是hosta上的實例 |
時間6 | # 重啟MySQL # 重啟keepalived # 因為使用了非搶占模式,VIP不會漂回來 |
【完】