網上沒找到合適的圖片,自己畫一張簡單的架構圖吧
想單獨講一個keepalived是因為不止可以實現MYSQL主備的切換,包括nginx、proxysql等需要高可用架構的場景,都可以實現。
這是部署完成之后的架構圖,服務器A會多一個虛擬IP地址。192.168.150.100
應用程序都會訪問這個虛擬IP,
同時兩台服務器上的keepalived軟件會保持心跳,檢測對方是否存在。
下面是當服務器A或MySQL 實例A掛跳之后的架構。可以看到,虛擬IP 192.168.150.100 已經飄移到了服務器B,這對應用側是透明的,應用側不需要修改數據庫連接地址,還能正常訪問到數據庫
如果服務器A 或MySQL實例A修復好之后,虛擬IP還用飄移到服務器A嗎,如果沒有特殊需求,是不用的,畢竟MySQL實例A和MySQL實例B數據是一樣的。
兩台機器都要安裝
下載地址:
https://www.keepalived.org/download.html
Keepalived for Linux - Version 2.0.20
wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz tar xvf keepalived-2.0.20.tar.gz cd keepalived-2.0.20/ yum install gcc openssl-devel libnl3-devel pcre-devel -y ./configure --prefix=/usr/local/keepalived make && make install mkdir /etc/keepalived/ cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ cp /root/keepalived-2.0.20/keepalived/keepalived.service /etc/systemd/system/ ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/ ll /usr/sbin/k* cp /root/keepalived-2.0.20/keepalived/etc/init.d/keepalived /etc/init.d/ chmod 755 /etc/init.d/keepalived systemctl enable keepalived.service systemctl start keepalived.service [root@localhost ~]# ps -ef|grep keep gdm 8380 8099 0 06:45 ? 00:00:00 /usr/libexec/gsd-housekeeping root 13572 1 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13573 13572 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13574 13572 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13593 8592 0 07:33 pts/0 00:00:00 grep --color=auto keep [root@localhost ~]# tail -f /var/log/messages May 18 07:33:35 localhost Keepalived_vrrp[13574]: Sending gratuitous ARP on eth0 for 192.168.200.18 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: HTTP_CHECK on service [192.168.201.100]:tcp:443 failed after 3 retry. May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Removing service [192.168.201.100]:tcp:443 to VS [192.168.200.100]:tcp:443 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Lost quorum 1-0=1 > 0 for VS [192.168.200.100]:tcp:443 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Remote SMTP server [192.168.200.1]:25 connected. May 18 07:34:00 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:01 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:03 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:04 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:06 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. #Keepalived已經正常啟動了,現在先停掉服務 [root@localhost ~]# systemctl stop keepalived.service
[root@localhost ~]# service mysql stop
繼續在兩台服務器做相同配置
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak vi /etc/keepalived/keepalived.conf global_defs { router_id MySQL-HA #標識,只是一個名字 } vrrp_script check_run { script "/usr/local/mysql/mysql_check.sh" #檢測腳本地址 interval 60 #健康檢查周期 } vrrp_instance VI_1 { state BACKUP #狀態為BACKUP interface eth0 #綁定的網卡 virtual_router_id 50 #主備服務器必須在一個id內, priority 100 #權重設置 advert_int 1 #心跳間隔 nopreempt #非搶占模式 authentication { auth_type PASS #用戶名 主備要配置為一樣 auth_pass 1234 #密碼 主備要配置為一樣 } track_script { check_run #執行的檢測腳本 } virtual_ipaddress { 192.168.150.100 #虛擬IP } }
[root@localhost ~]# vi /usr/local/mysql/mysql_check.sh #! /bin/bash host=127.0.0.1 user=root passwd=123456 /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 -P 3306 -e "select 1" >/dev/null 2>/dev/nul if [ $? != 0 ] ; then systemctl stop keepalived.service fi [root@localhost ~]# chmod +x /usr/local/mysql/mysql_check.sh
配置完畢,
1、啟動兩個實例的mysql
[root@localhost ~]# service mysql start Redirecting to /bin/systemctl start mysql.service [root@localhost ~]#
2、啟動兩個實例的keepalived
[root@localhost ~]# service keepalived start
Starting keepalived (via systemctl): [ OK ]
[root@localhost ~]#
3、先啟動keepalived的服務器會先拿到虛擬IP,服務器A先啟動的,在服務器A看下
[root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:cd:3f:f3 brd ff:ff:ff:ff:ff:ff inet 192.168.150.101/24 brd 192.168.150.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 192.168.150.100/32 scope global eth0 ###可以看到已經有192.168.150.100這個IP了 valid_lft forever preferred_lft forever inet6 fe80::9aea:2ec6:c21c:9e85/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::6b3:ad64:3e31:9979/64 scope link noprefixroute valid_lft forever preferred_lft forever inet6 fe80::e204:ab19:4112:354e/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff [root@localhost ~]#
模擬一下服務器A數據庫宕機的場景,連接服務器A,執行
[root@host101 ~]# service mysql stop
Redirecting to /bin/systemctl stop mysql.service
keepalived的檢測腳本會發現,mysql已經無法訪問了,會觸執行一條命令:
systemctl stop keepalived.service
也就是將機的keepalived程序停掉,
1、服務器A的keepalived程序停掉后,無法與服務器B的keepalived程序保持心跳狀態,同時也會刪掉本機的虛擬IP
2、服務器B與服務器A的心跳中斷之后,會認為服務器A已經宕機了,所以虛擬IP需要由自己來接管。
3、在服務器B執行,ip a 會發現IP已經在服務器B上邊了
[root@host102 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:80:76:e0 brd ff:ff:ff:ff:ff:ff inet 192.168.150.102/24 brd 192.168.150.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 192.168.150.100/32 scope global eth0 ###192.168.150.100已經在服務器B上了 valid_lft forever preferred_lft forever inet6 fe80::9aea:2ec6:c21c:9e85/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff [root@host102 ~]#
如果此時在服務器A執行
service mysql start
service keepalived start
虛擬IP並不會再搶回來,根據之前keepalived.conf配置文件中,
state BACKUP
不會發生搶虛擬IP的行為,只有感知到另一方掛掉之后才會接管虛擬IP。
如果服務器B的mysql進程掛掉后,192.168.150.100會瓢移到服務器A上邊來。