一鍵部署MySQL8+keepalived雙主熱備高可用
概述
本次的文章會格外的長,網上大多的配置流程已經不可使用,本篇文章可以稱為保姆級教程,而且通過shell指令碼大大減少了部署mysql主從,雙主的工作量。
如上圖,VIP地址為192.168.10.100
,如果主機192.168.10.129
掛了,會自動切換到備機192.168.10.130
上,由於是雙主,資料可以進行同步恢復
部署流程大致為
- 在
192.168.10.129
伺服器上部署docker、mysql一主一叢 - 在
192.168.10.130
伺服器上部署docker、mysql一主一叢 -
192.168.10.129
的Master1資料庫和192.168.10.130
的資料庫互為主從 - 在兩臺伺服器上安裝keeplived形成高可用
部署流程
配置第一臺Master
部署Master
準備Master配置檔案my.cnf
mkdir /home/mysql_config mkdir /home/mysql_config/master1 mkdir /home/mysql_config/master1/config touch /home/mysql_config/master1/config/my.cnf chmod +x /home/mysql_config/master1/config/my.cnf cat > /home/mysql_config/master1/config/my.cnf <<EOF [mysqld] server_id=110 user=mysql character-set-server=utf8mb4 collation-server=utf8mb4_general_ci default-authentication-plugin=mysql_native_password max_connections=800 max_connect_errors=1000 log_bin=mysql_binlog_master1 slow_query_log=ON slow_query_log_file=/var/lib/mysql/slow.log log_error=/var/lib/mysql/mysql.err log_replica_updates=ON enforce_gtid_consistency=ON gtid_mode=ON plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so" #rpl_semi_sync_source_enabled=ON #rpl_semi_sync_replica_enabled=ON binlog-ignore-db=information_schema binlog-ignore-db=mysql binlog-ignore-db=sys binlog-ignore-db=performance_schema [client] default-character-set=utf8mb4 EOF
執行Master
會自動下載最新版mysql
docker run -d --name mysql_master1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/master1/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password
啟動半同步外掛
此步主要是為了將#rpl_semi_sync_source_enabled=ON
和#rpl_semi_sync_replica_enabled=ON
mysql會檢測
semisync_source.so
和semisync_replica.so
外掛的情況,如果沒有安裝就不能設定rpl_semi_sync_source_enabled
和rpl_semi_sync_replica_enabled
cat > /home/mysql_config/master1/config/my.cnf <<EOF
[mysqld]
server_id=110
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000
log_bin=mysql_binlog_master1
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log
log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON
plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=ON
rpl_semi_sync_replica_enabled=ON
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema
[client]
default-character-set=utf8mb4
EOF
重新開啟
docker restart mysql_master1
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "show variables like 'rpl_semi_sync_%';"
+---------------------------------------------+------------+
| Variable_name | Value |
+---------------------------------------------+------------+
| rpl_semi_sync_replica_enabled | ON |
| rpl_semi_sync_replica_trace_level | 32 |
| rpl_semi_sync_source_enabled | ON |
| rpl_semi_sync_source_timeout | 10000 |
| rpl_semi_sync_source_trace_level | 32 |
| rpl_semi_sync_source_wait_for_replica_count | 1 |
| rpl_semi_sync_source_wait_no_replica | ON |
| rpl_semi_sync_source_wait_point | AFTER_SYNC |
+---------------------------------------------+------------+
部署Slave
準備Slave配置檔案my.cnf
mkdir /home/mysql_config/slave1
mkdir /home/mysql_config/slave1/config
touch /home/mysql_config/slave1/config/my.cnf
chmod +x /home/mysql_config/slave1/config/my.cnf
cat > /home/mysql_config/slave1/config/my.cnf <<EOF
[mysqld]
server_id=120
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000
log_bin=mysql_binlog_master1_slave1
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log
log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema
[client]
default-character-set=utf8mb4
EOF
執行Slave
會自動下載最新版mysql
docker run -d --name mysql_master1_slave1 -p 4306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/slave1/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password
主從配置
安裝MySQL客戶端
兩臺Master都需要安裝,而且後續keepalived也需要安裝
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql
編寫指令碼檔案
touch /home/mysql_config/mysql_script.sh
chmod +x /home/mysql_config/mysql_script.sh
cat > /home/mysql_config/mysql_script.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
ALLOW_HOST=%
MASTER_HOST=192.168.10.129
MASTER_PORT=3306
SLAVE_HOST=192.168.10.129
SLAVE_PORT=4306
# master
DROP_USER_SQL="DROP USER '$MASTER_RPL_USER'@'$ALLOW_HOST';"
CREATE_USER_SQL="CREATE USER '$MASTER_RPL_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_RPL_PASSWORD';"
GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE ON *.* TO '$MASTER_RPL_USER'@'$ALLOW_HOST';"
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$GRANT_PRIVILEGES_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$FLUSH_PRIVILEGES_SQL"
# master's slave shell
RESULT=`mysql -h$MASTER_HOST -p$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`
SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF
執行指令碼並檢查
sh /home/mysql_config/mysql_script.sh
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
配置第二臺
部署Master
準備Master配置檔案my.cnf
mkdir /home/mysql_config
mkdir /home/mysql_config/master2
mkdir /home/mysql_config/master2/config
touch /home/mysql_config/master2/config/my.cnf
chmod +x /home/mysql_config/master2/config/my.cnf
cat > /home/mysql_config/master2/config/my.cnf <<EOF
[mysqld]
server_id=111
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000
log_bin=mysql_binlog_master2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log
log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON
plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
#rpl_semi_sync_source_enabled=ON
#rpl_semi_sync_replica_enabled=ON
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema
[client]
default-character-set=utf8mb4
EOF
執行Master
會自動下載最新版mysql
docker run -d --name mysql_master2 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/master2/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password
啟用半同步外掛
此步主要是為了將#rpl_semi_sync_source_enabled=ON
和#rpl_semi_sync_replica_enabled=ON
的井號去掉
mysql會檢測
semisync_source.so
和semisync_replica.so
外掛的情況,如果沒有安裝就不能設定rpl_semi_sync_source_enabled
和rpl_semi_sync_replica_enabled
cat > /home/mysql_config/master2/config/my.cnf <<EOF
[mysqld]
server_id=111
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000
log_bin=mysql_binlog_master2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log
log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON
plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=ON
rpl_semi_sync_replica_enabled=ON
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema
[client]
default-character-set=utf8mb4
EOF
重新開啟
docker restart mysql_master2
docker exec -it mysql_master2 mysql -uroot -padmin123456 -e "show variables like 'rpl_semi_sync_%';"
+---------------------------------------------+------------+
| Variable_name | Value |
+---------------------------------------------+------------+
| rpl_semi_sync_replica_enabled | ON |
| rpl_semi_sync_replica_trace_level | 32 |
| rpl_semi_sync_source_enabled | ON |
| rpl_semi_sync_source_timeout | 10000 |
| rpl_semi_sync_source_trace_level | 32 |
| rpl_semi_sync_source_wait_for_replica_count | 1 |
| rpl_semi_sync_source_wait_no_replica | ON |
| rpl_semi_sync_source_wait_point | AFTER_SYNC |
+---------------------------------------------+------------+
部署Slave
準備Slave配置檔案my.cnf
mkdir /home/mysql_config/slave2
mkdir /home/mysql_config/slave2/config
touch /home/mysql_config/slave2/config/my.cnf
chmod +x /home/mysql_config/slave2/config/my.cnf
cat > /home/mysql_config/slave2/config/my.cnf <<EOF
[mysqld]
server_id=121
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000
log_bin=mysql_binlog_master2_slave2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log
log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema
[client]
default-character-set=utf8mb4
EOF
執行Slave
會自動下載最新版mysql
docker run -d --name mysql_master2_slave2 -p 4306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/slave2/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password
主從配置
安裝MySQL客戶端
兩臺Master都需要安裝,而且後續keepalived也需要安裝
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql
編寫指令碼檔案
touch /home/mysql_config/mysql_script.sh
chmod +x /home/mysql_config/mysql_script.sh
cat > /home/mysql_config/mysql_script.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
ALLOW_HOST=%
MASTER_HOST=192.168.10.130
MASTER_PORT=3306
SLAVE_HOST=192.168.10.130
SLAVE_PORT=4306
# master
DROP_USER_SQL="DROP USER '$MASTER_RPL_USER'@'$ALLOW_HOST';"
CREATE_USER_SQL="CREATE USER '$MASTER_RPL_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_RPL_PASSWORD';"
GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE ON *.* TO '$MASTER_RPL_USER'@'$ALLOW_HOST';"
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$GRANT_PRIVILEGES_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$FLUSH_PRIVILEGES_SQL"
# master's slave shell
RESULT=`mysql -h$MASTER_HOST -p$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`
SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF
執行指令碼並檢查
sh /home/mysql_config/mysql_script.sh
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
雙主配置
Master1作為主,Master2作為備份
Master1的IP地址為:192.168.10.129
Master2的IP地址為:192.168.10.130
安裝MySQL客戶端
兩臺Master都需要安裝,而且後續keepalived也需要安裝
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql
編寫配置檔案
touch /home/mysql_config/rplShell.sh
chmod +x /home/mysql_config/rplShell.sh
cat > /home/mysql_config/rplShell.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
MASTER_HOST=192.168.10.130
MASTER_PORT=3306
BACKUP_HOST=192.168.10.129
BACKUP_PORT=3306
RESULT=`mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`
SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF
執行指令碼並檢查
sh /home/mysql_config/rplShell.sh
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Master2作為主,Master1作為備份
Master1的IP地址為:192.168.10.129
Master2的IP地址為:192.168.10.130
安裝MySQL客戶端
兩臺Master都需要安裝,而且後續keepalived也需要安裝
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql
編寫配置檔案
touch /home/mysql_config/rplShell.sh
chmod +x /home/mysql_config/rplShell.sh
cat > /home/mysql_config/rplShell.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
MASTER_HOST=192.168.10.129
MASTER_PORT=3306
BACKUP_HOST=192.168.10.130
BACKUP_PORT=3306
RESULT=`mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`
SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF
執行指令碼並檢查
sh /home/mysql_config/rplShell.sh
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
配置Keepalived
Master1主機配置
安裝keepalived
yum install -y keepalived
編寫keepalived配置檔案
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id HA-M1
script_user root
}
vrrp_script chk_mysql {
script /etc/keepalived/chk_mysql.sh
interval 3
fall 3
rise 2
}
vrrp_instance VI_MYSQL {
state MASTER
interface ens160
virtual_router_id 100
priority 100
advert_int 1
unicast_src_ip 192.168.10.129
unicast_peer {
192.168.10.130
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100/24 dev ens160 label ens160:vip
}
track_script {
chk_mysql
}
}
EOF
-
router_id
:標識,兩臺需不一樣 -
state MASTER
:表明這臺是Master角色 -
priority
:優先順序,MASTER角色比BACKUP高 -
virtual_router_id
:虛擬路由編號,兩臺需要一致,兩個節點不能一樣 -
192.168.10.100 dev ens32 label ens32:vip
:VIP地址—192.168.10.100 -
script /etc/keepalived/chk_mysql.sh
:MySQL的檢測指令碼,定時去檢測MySQL程序是否掛掉,會重啟,interval是為間隔時間(2s檢測一次)
當Keepalived從BACKUP提升為MASTER時,那麼VIP就會漂移到自己身上,這個時候我們只需要將Slave掛載在自己身上即可
MySQL狀態監測指令碼
安裝MySQL客戶端
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum module disable mysql
yum install mysql-community-client
yum module enable mysql
配置Keepalived的MySQL狀態監測指令碼
touch /etc/keepalived/chk_mysql.sh
chmod +x /etc/keepalived/chk_mysql.sh
cat > /etc/keepalived/chk_mysql.sh <<'EOF'
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.10.129
MYSQL_USER=root
MYSQL_PASSWORD=admin123456
CHECK_TIME=3
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
function check_mysql_helth (){
$MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
systemctl stop keepalived
exit 1
fi
sleep 1
done
EOF
Master2備機配置
安裝keepalived
yum install -y keepalived
編寫keepalived配置檔案
cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id HA-M2
script_user root
}
vrrp_script chk_mysql {
script /etc/keepalived/chk_mysql.sh
interval 3
fall 3
rise 2
}
vrrp_instance VI_MYSQL {
state BACKUP
interface ens160
virtual_router_id 100
nopreempt
priority 50
advert_int 1
unicast_src_ip 192.168.10.130
unicast_peer {
192.168.10.129
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100/24 dev ens160 label ens160:vip
}
track_script {
chk_mysql
}
}
EOF
注意router_id需要不一樣,state BACKUP表明是備機,virtual_router_id需要一致,priority要比MASTER低!
chk_mysql.sh內容如下,可以看到可以根據當前Keepalived的狀態分別處理,但是此處的處理都是啟動MySQL(如果MySQL程序已退出)
MySQL狀態監測指令碼
安裝MySQL客戶端
在網站查詢https://dev.mysql.com/downloads/repo/yum/
要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm
舉例
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum module disable mysql
yum install mysql-community-client
yum module enable mysql
配置Keepalived的MySQL狀態監測指令碼
touch /etc/keepalived/chk_mysql.sh
chmod +x /etc/keepalived/chk_mysql.sh
cat > /etc/keepalived/chk_mysql.sh <<'EOF'
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.10.130
MYSQL_USER=root
MYSQL_PASSWORD=admin123456
CHECK_TIME=3
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
function check_mysql_helth (){
$MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
systemctl stop keepalived
exit 1
fi
sleep 1
done
EOF
啟動Keepalived
最後在Master1和Master2分別啟動Keepalived
systemctl start keepalived
檢視Master1網路配置
ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.129 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::20c:29ff:fe23:aab2 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:23:aa:b2 txqueuelen 1000 (Ethernet)
RX packets 4797 bytes 524410 (512.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2860 bytes 332307 (324.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens160:vip: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.100 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:23:aa:b2 txqueuelen 1000 (Ethernet)
檢視Master2網路配置
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.130 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::20c:29ff:feb4:3ede prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b4:3e:de txqueuelen 1000 (Ethernet)
RX packets 4672 bytes 2048171 (1.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2703 bytes 275576 (269.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
主機上有ens160:vip
而備機上沒有vip
Keepalived可能會遇到的問題
- 主機能啟動,備機不能啟動
- 關閉防火牆
- 兩臺機器的網絡卡uuid是否衝突(如果是vm ware複製的linux,因為網絡卡uuid一致導致的)
- 主機和備機keepalived都為master,有兩種方法
- 關閉防火牆,或設定組播ip可用
- 兩端keepalived設定為單播(使用unicast_src_ip )
測試
資料同步測試
進入Master1
,建立資料庫test_db
,表test_user
,並插入一條資料。
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "CREATE DATABASE test_db;"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "CREATE TABLE test_db.test_user (id INT(11),name VARCHAR(25),age int(11) );"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "INSERT INTO test_db.test_user values (1,'zhangsan',18);"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
檢視Master1
及從庫master1_slave1
、 檢視Master2
及從庫master2_slave2
的資料同步情況
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | zhangsan | 18 |
+------+----------+------+
docker exec -it mysql_master1_slave1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | zhangsan | 18 |
+------+----------+------+
docker exec -it mysql_master2 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | zhangsan | 18 |
+------+----------+------+
docker exec -it mysql_master2_slave2 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | zhangsan | 18 |
+------+----------+------+
高可用測試
啟用備機測試
停止主機上的mysql
docker stop mysql_master1
主機上的Keepalived狀態
Keepalived[4213]: Stopping
Keepalived_vrrp[4214]: (VI_MYSQL) sent 0 priority
Keepalived_vrrp[4214]: (VI_MYSQL) removing VIPs.
備機的Keepalived狀態
Keepalived_vrrp[8986]: (VI_MYSQL) Backup received priority 0 advertisement
Keepalived_vrrp[8986]: (VI_MYSQL) Receive advertisement timeout
Keepalived_vrrp[8986]: (VI_MYSQL) Entering MASTER STATE
Keepalived_vrrp[8986]: (VI_MYSQL) setting VIPs.
Keepalived_vrrp[8986]: (VI_MYSQL) Sending/queueing gratuitous ARPs on ens160 for 192.168.10.100
注意
Master備機上做寫操作,第一次寫會發生半同步等待(10s左右),第二次寫會退化成非同步複製
主機恢復測試
啟動主機上的mysql和keepalived
docker start mysql_master1
systemctl start keepalived
主機上的Keepalived狀態
Keepalived_vrrp[5413]: (VI_MYSQL) Entering BACKUP STATE
Keepalived_vrrp[5413]: VI_MYSQL: sending gratuitous ARP for 192.168.10.129
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.129
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) Receive advertisement timeout
Keepalived_vrrp[5413]: (VI_MYSQL) Entering MASTER STATE
Keepalived_vrrp[5413]: (VI_MYSQL) setting VIPs.
Keepalived_vrrp[5413]: (VI_MYSQL) Sending/queueing gratuitous ARPs on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
備機的Keepalived狀態
Keepalived_vrrp[8986]: (VI_MYSQL) Master received advert from 192.168.10.129 with higher priority 100, ours 50
Keepalived_vrrp[8986]: (VI_MYSQL) Entering BACKUP STATE
Keepalived_vrrp[8986]: (VI_MYSQL) removing VIPs.
結論
如果殺掉主機上的mysql
- VIP會漂移到備機上,ifconfig能看到VIP資訊
- 備機的Keepalived從BACKUP狀態轉換為了MASTER狀態
- Master備機上做寫操作,第一次寫會發生半同步等待(10s左右),第二次寫會退化成非同步複製
恢復主機mysql
- ifconfig看下VIP會漂移回來,並且備機上的VIP會消失
- 剛才在Master備機上寫入的資料同步過來了
- Keepalived的狀態是從FAULT轉變為BACKUP,最後變成MASTER