1. Keepalived + LVS (Keepalived 和 MySQL 部署在一起)

1. 1 架构设计

具体架构如下图所示:
MySQL高可用-Keepalived-LVS.png
使用两台主机实现 MySQL 半同步主从复制并使用 Keepalived + LVS 实现 MySQL的读写分离和高可用。Keepalived 这里主要用作后端服务器的健康状态检查,提供VIP,以及故障转移;LVS 提供读负载均衡。
整体架构设计原理如下:

  1. 后端服务器 A 和 B 实现 MySQL 半同步主从复制的主库和从库。
  2. 利用 Keepalived 提供两个虚拟 IP ,Write-VIP 和 Read-VIP,前者负责写入,后者负责读取,实现读写分离。
  3. 当服务器 A 和 B 都正常工作时,LVS 通过 Write-VIP 将写请求转发到服务器 A,通过 Read-VIP 将读请求转发给 A 和 B,实现读负载均衡。
  4. 当服务器 A 即 Master 发生异常时,Write-VIP 漂移到服务器 B 上,使用脚本将 B 提升为 Master 。
  5. 当服务器 B 即 Slave 发生异常时,Read-VIP 自动将 B 剔除,其他不变。

    1.2 部署和配置

    1.2.1 服务器总体部署规划

    | 服务器 | 角色 | IP | VIP | | —- | —- | —- | —- | | A | Keepalived Write-VIP Master+
    Keepalived Read-VIP Backup+
    MySQL Master | 192.168.0.71 | Write:192.168.0.100 | | B | Keepalived Read-VIP Master+
    Keepalived Write-VIP Backup
    MySQL Slave | 192.168.0.72 | Read:192.168.0.200 |

1.2.2 部署过程

  1. 按照规划安装和配置 MySQL 的半同步主从复制,192.168.0.71 为主库,192.168.0.72 为从库。
  2. 安装 LVS 管理工具

    1. yum -y install ipvsadm
  3. 下载安装 Keepalived 。

  4. Iptables 配置

由于 Keepalived + LVS 和 MySQL 部署在同一台机器上,即 LVS 的 Director 服务器和 Real Server 为一台机器的时候,会出现两台 Director 无限循环转发的情况。为了解决该问题,需要使用 Iptables 对数据包进行标记,然后让 LVS 对 fwm 进行转发,而不是直接转发 TCP。每台 Director 都标记自己发送的数据包,ipvs 只转发这些自己标记过的包,而其他 Director 服务器发送的数据包就不再转发了,直接交给上层监听程序。
生产中建议 Keepalived 放在单独的两台机器上,则不需要进行此步操作!
具体操作如下:

  1. # 192.168.0.71 主库
  2. [root@C7-01 ~]# iptables -t mangle -I PREROUTING -d 192.168.0.100 -p tcp -m tcp --dport 3306 -m mac ! --mac-source 00:0c:29:87:7f:87 -j MARK --set-mark 0x1
  3. # 192.168.0.72 从库
  4. [root@C7-02 ~]# iptables -t mangle -I PREROUTING -d 192.168.0.100 -p tcp -m tcp --dport 3306 -m mac ! --mac-source 00:0c:29:49:f4:0b -j MARK --set-mark 0x2

其中,192.168.0.100 为Write-VIP,00:0c:29:87:7f:87 为 192.168.0.72 从库的网卡 MAC 地址,00:0c:29:49:f4:0b 为 192.168.0.71 主库的网卡 MAC 地址。
执行完上面的操作后,为了能永久保存 iptables 规则,需要将 iptables 规则保存到文件中,并开启开机自动加载:

  1. # 保存 iptables 规则
  2. iptables-save > /etc/iptables-script
  3. # 开机自动加载 iptables 规则
  4. echo '/usr/sbin/iptables-restore /etc/iptables-script' >> /etc/rc.d/rc.local
  1. Keepalived 配置。

192.168.0.71 Keepalived 初始状态为 Write-VIP Master,Read-VIP Backup,这样设计的目的是同时让 192.168.0.71 和 192.168.0.72 两台机器都负责 VIP 的调度,分担压力。
另外为了方便管理,这里采用了子配置文件的方式,将两个 VIP 的配置文件单独存放。
Keepalived 主配置文件内容如下:

  1. [root@c7-01 ~]# cat /etc/keepalived/keepalived.conf
  2. global_defs {
  3. router_id C7-01.wuvikr.top # keepalived 主机唯一标识,建议使用当前主机名
  4. vrrp_skip_check_adv_addr # 如果收到的通告报文和上一个报文是同一个路由,则跳过检查,默认为检查所有报文
  5. vrrp_garp_interval 0 # gratuitous ARP messages 报文发送延迟,0表示不延迟
  6. vrrp_gna_interval 0 # unsolicited NA messages (不请自来)消息发送延迟
  7. vrrp_mcast_group4 224.0.0.20 # 指定组播IP地址范围:224.0.0.0到239.255.255.255,默认值:224.0.0.18
  8. }
  9. include /etc/keepalived/conf.d/*.conf

Write-VIP 子配置文件内容如下:

  1. [root@c7-01 ~]# cat /etc/keepalived/conf.d/mysql_write.conf
  2. vrrp_script mysql_check { # 配置检测脚本
  3. script "/etc/keepalived/conf.d/mysql_check.sh" # 检测脚本路径
  4. interval 1 # 检测频率
  5. weight -30 # 权重减少值
  6. fall 3 # 连续检测失败3次后才算是真的失败
  7. rise 2 # 连续检测成功2次后才算是真的成功
  8. timeout 2 # 超时时间
  9. }
  10. vrrp_instance VIP_WRITE {
  11. state MASTER # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP
  12. interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡
  13. virtual_router_id 11 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同
  14. priority 100 # 当前物理节点在此虚拟路由器的优先级,范围:1-254
  15. advert_int 1 # vrrp通告的时间间隔,默认1s
  16. authentication { # 认证机制
  17. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
  18. auth_pass 111111 # 预共享密钥,即相互认证密码
  19. }
  20. virtual_ipaddress { # 虚拟路由IP
  21. 192.168.0.100 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32
  22. }
  23. track_script {
  24. mysql_check # 调用前面定义的脚本
  25. }
  26. # 使用单播配置
  27. unicast_src_ip 192.168.0.71 # 本机IP
  28. unicast_peer{
  29. 192.168.0.72 # 指向其他Keepalived主机IP
  30. }
  31. notify_backup "/etc/keepalived/conf.d/mysql_down.sh" # 配置触发脚本
  32. }

因为 Write-VIP 只会将请求转发到本机的 MySQL 服务,这里就没有使用 LVS 来进行转发了,简单的采用 VIP 配合检测脚本即可实现需求,检测脚本/etc/keepalived/conf.d/mysql_check.sh内容如下:

  1. [root@c7-01 ~]# cat /etc/keepalived/conf.d/mysql_check.sh
  2. #!/bin/bash
  3. #mysqladmin -uroot -p744123 ping
  4. killall -0 mysqld

另外,当主库宕机时,Write-VIP 会漂移到从库,此时会触发/etc/keepalived/conf.d/mysql_down.sh脚本文件来停止复制,重置 MySQL 实例的主从状态,该脚本内容如下:

  1. #!/bin/bash
  2. . /home/mysql/.bashrc
  3. user=root
  4. password=744123
  5. log=/home/mysql/stop_slave.log
  6. echo "date '+%T %F'" >> ${log}
  7. mysql -u${user} -p${password} -e "set global read_only=OFF;stop slave;reset master;reset slave all;" >> ${log}
  8. /bin/sed -i 's#read-only#\#read-only#' /etc/my.cnf

Read-VIP 子配置文件内容如下:

  1. [root@c7-01 ~]# cat /etc/keepalived/conf.d/mysql_read.conf
  2. vrrp_instance VIP_READ {
  3. state MASTER # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP
  4. interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡
  5. virtual_router_id 22 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同
  6. priority 120 # 当前物理节点在此虚拟路由器的优先级,范围:1-254
  7. advert_int 1 # vrrp通告的时间间隔,默认1s
  8. authentication { # 认证机制
  9. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
  10. auth_pass 222222 # 预共享密钥,即相互认证密码
  11. }
  12. virtual_ipaddress { # 虚拟路由IP
  13. 192.168.0.200 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32
  14. }
  15. # 使用单播配置
  16. unicast_src_ip 192.168.0.71 # 本机IP
  17. unicast_peer{
  18. 192.168.0.72 # 指向其他Keepalived主机IP
  19. }
  20. }
  21. virtual_server fwmark 1 { # 配置 fwmark 转发
  22. delay_loop 3 # 检查后端服务器的时间间隔
  23. lb_algo rr # 定义调度方法,rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq
  24. lb_kind DR # LVS类型,注意要大写, NAT|DR|TUN
  25. protocol TCP # 指定服务协议,一般默认为TCP,TCP|UDP|SCTP
  26. real_server 192.168.0.71 3306 { # RS的IP和PORT
  27. weight 1 # 调度权重
  28. TCP_CHECK {
  29. nb_get_retry 3 # 重新连接次数
  30. delay_before_retry 3 # 重新连接间隔时间
  31. connect_port 3306 # 向当前RS的哪个PORT发起健康状态检测请求
  32. connect_timeout 3 # 客户端请求的超时时长, 等于haproxy的timeout server
  33. }
  34. }
  35. real_server 192.168.0.72 3306 {
  36. weight 1
  37. TCP_CHECK {
  38. nb_get_retry 3
  39. delay_before_retry 3
  40. connect_port 3306
  41. connect_timeout 3
  42. }
  43. }
  44. }

192.168.0.72 Keepalived 初始状态为 Write-VIP Backup,Read-VIP Master。其配置文件与 192.168.0.71 基本一致,主要区别有只是 state 和 priority 不同,另外因为 Iptables 的设置,fwmark 也不一样。

  1. Real Server 的网络配置

在每台机器上使用下面的脚本一键配置 Real Server,并加入开机自启动。

  1. [root@c7-01 ~]# cat /etc/init.d/lvs_dr_rs.sh
  2. #!/bin/bash
  3. trap "echo -e '\e[1;36mThank you for using, goodbye !\e[0m'" EXIT
  4. vip=192.168.0.200
  5. mask=255.255.255.255
  6. #prefix=32
  7. dev=lo:1
  8. case $1 in
  9. start)
  10. # 禁用本地ARP请求,绑定回环地址。
  11. echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
  12. echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  13. echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
  14. echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
  15. # 在回环地址上绑定VIP,设置掩码,与Director服务器自身IP保持通信
  16. /sbin/ifconfig ${dev} ${vip} netmask ${mask} up
  17. route add -host ${vip} dev ${dev}
  18. #ip addr add ${vip}/${prefix} dev $dev label ${dev}
  19. #ip route add ${vip} via 0.0.0.0 scope link src ${vip} dev ${dev}
  20. echo -e '\e[1;32mLVS-DR Real Server starts successfully.\n\e[0m'
  21. ;;
  22. stop)
  23. /sbin/ifconfig $dev down
  24. #ip addr del ${vip}/${prefix} dev ${dev}
  25. echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
  26. echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  27. echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
  28. echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
  29. echo -e '\e[1;31mLVS-DR Real Server stopped.\n\e[0m'
  30. ;;
  31. *)
  32. echo "Usage: $(basename $0) start|stop"
  33. exit 1
  34. ;;
  35. esac
  36. # 添加执行权限
  37. [root@c7-01 ~]# chmod +x /etc/init.d/lvs_dr_rs.sh
  38. # 开机自启
  39. [root@c7-01 ~]# echo "/etc/init.d/lvs_dr_rs.sh start" >> /etc/rc.d/rc.local
  40. # 执行脚本
  41. [root@c7-01 ~]# /etc/init.d/lvs_dr_rs.sh start

执行完上面的脚本后会在本地 lo 回环网卡上添加一个 192.168.0.200/32 的虚拟 VIP ,用于 LVS DR 模型的 Director 转发。

  1. 重启 Keepalived 服务

    1. [root@c7-01 ~]# systemctl restart keepalived.service
    2. [root@c7-02 ~]# systemctl restart keepalived.service

    1.3 功能测试

    1.3.1 停止 MySQL 服务,查看 vip 漂移情况

    1.3.2 关闭服务器,查看 MySQL 服务情况

    2. Keepalived + LVS (Keepalived 和 MySQL 分别部署)

    2.1 架构设计

    MySQL高可用Keepalived+LVS实现架构图.png
    Keepalived + LVS 实现 MySQL 的读写分离和高可用。Keepalived 这里主要用作后端服务器的健康状态检查,提供VIP,以及故障转移;LVS 提供读负载均衡功能。
    整体架构设计原理如下:

  2. 后端服务器 MySQL-Master 和 MySQL-Slave 为主从复制的主库和从库。

  3. 利用 Keepalived-01 提供 Write-VIP(10.0.0.100),负责数据写入,Keepalived-02 提供 Read-VIP(10.0.0.200) 负责读取数据,实现读写分离。
  4. 当服务器 MySQL-Master 和 MySQL-Slave 都正常工作时,LVS 通过 Write-VIP 将写请求转发到服务器 MySQL-Master,通过 Read-VIP 将读请求转发给 MySQL-Master 和 MySQL-Slave,实现读负载均衡。
  5. 当服务器 MySQL-Master 发生异常时,Write-VIP 漂移到服务器 Keepalived-02 上,并使用脚本将 MySQL-Slave 提升为 Master 。
  6. 当服务器 MySQL-Slave 发生异常时,Read-VIP 自动将 MySQL-Slave 剔除,其他不变。

    2.2 服务部署

    2.2.1 安装 lvs 管理工具 和 MySQL 客户端

    1. yum -y install ipvsadm mysql

    2.2.2 下载安装 Keepalived

    ```bash

    安装依赖包

    [root@C7-01 ~]# yum install -y gcc openssl-devel libnl3-devel net-snmp-devel

解压

[root@C7-01 ~]# tar xvf keepalived-2.2.2.tar.gz -C /usr/local/src

编译安装

[root@C7-01 ~]# cd /usr/local/src/keepalived-2.2.2/ [root@C7-01 ~]# ./configure —prefix=/opt/app/keepalived [root@C7-01 ~]# make && make install

查看版本

[root@C7-01 ~]# /opt/app/keepalived/sbin/keepalived -v Keepalived v2.2.2 (03/05,2021)

Copyright(C) 2001-2021 Alexandre Cassen, acassen@gmail.com

Built with kernel headers for Linux 3.10.0 Running on Linux 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 Distro: CentOS Linux 7 (Core)

configure options: —prefix=/opt/app/keepalived

Config options: LVS VRRP VRRP_AUTH VRRP_VMAC OLD_CHKSUM_COMPAT INIT=systemd

System options: VSYSLOG LIBNL3 RTA_ENCAP RTA_EXPIRES RTA_PREF FRA_SUPPRESS_PREFIXLEN FRA_TUN_ID RTAX_CC_ALGO RTAX_QUICKACK RTA_VIA IFA_FLAGS NET_LINUX_IF_H_COLLISION LIBIPTC_LINUX_NET_IF_H_COLLISION LIBIPVS_NETLINK IFLA_LINK_NETNSID GLOB_BRACE GLOB_ALTDIRFUNC INET6_ADDR_GEN_MODE SO_MARK

安装完会自动生成 service 文件

[root@C7-01 ~]# cat /lib/systemd/system/keepalived.service [Unit] Description=LVS and VRRP High Availability Monitor After=network-online.target syslog.target Wants=network-online.target

[Service] Type=forking PIDFile=/run/keepalived.pid KillMode=process EnvironmentFile=-/usr/local/keepalived/etc/sysconfig/keepalived ExecStart=/usr/local/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS ExecReload=/bin/kill -HUP $MAINPID

[Install] WantedBy=multi-user.target

  1. <a name="aCFC6"></a>
  2. ### 2.2.3 Keepalived-01 配置
  3. 1. 创建配置文件目录:`mkdir /etc/keepalived`。
  4. 1. 创建主配置文件:`vim /etc/keepalived/keepalived.conf`。
  5. ```bash
  6. global_defs {
  7. router_id C7-01.wuvikr.top # keepalived 主机唯一标识,建议使用当前主机名
  8. vrrp_skip_check_adv_addr # 如果收到的通告报文和上一个报文是同一个路由,则跳过检查,默认为检查所有报文
  9. vrrp_garp_interval 0 # gratuitous ARP messages 报文发送延迟,0表示不延迟
  10. vrrp_gna_interval 0 # unsolicited NA messages (不请自来)消息发送延迟
  11. vrrp_mcast_group4 224.0.0.20 # 指定组播IP地址范围:224.0.0.0到239.255.255.255,默认值:224.0.0.18
  12. }
  13. include /etc/keepalived/mysql/*.conf
  1. 创建 mysql_write 子配置文件:vim /etc/keepalived/mysql/mysql_write.conf。 ```bash vrrp_instance VIP_WRITE { state BACKUP # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡 virtual_router_id 11 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同 priority 120 # 当前物理节点在此虚拟路由器的优先级,范围:1-254 advert_int 1 # vrrp通告的时间间隔,默认1s nopreempt # 非抢占式 authentication { # 认证机制

    1. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
    2. auth_pass 111111 # 预共享密钥,即相互认证密码

    } virtual_ipaddress { # 虚拟路由IP

    1. 10.0.0.100 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32

    }

    使用单播配置

    unicast_src_ip 10.0.0.21 # 本机IP unicast_peer {

    1. 10.0.0.22 # 指向其他Keepalived主机IP

    }

    当 MySQL 主库宕机时,将从库提升为主库

    notify_master “/etc/keepalived/conf.d/remove_slave.sh” }

virtual_server 10.0.0.100 3306 { # 虚拟路由 IP 和 PORT delay_loop 3 # 检查后端服务器的时间间隔 lb_algo rr # 定义调度方法,rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq lb_kind DR # LVS类型,注意要大写, NAT|DR|TUN protocol TCP # 指定服务协议,一般默认为TCP,TCP|UDP|SCTP

  1. real_server 10.0.0.31 3306 { # RS的IP和PORT
  2. weight 1 # 调度权重
  3. notify_down "/etc/keepalived/conf.d/mysql_down.sh" # RS下线触发脚本
  4. TCP_CHECK {
  5. nb_get_retry 3 # 重新连接次数
  6. delay_before_retry 3 # 重新连接间隔时间
  7. connect_port 3306 # 向当前RS的哪个PORT发起健康状态检测请求
  8. connect_timeout 3 # 客户端请求的超时时长, 等于haproxy的timeout server
  9. }
  10. }

}

  1. 4. 创建 mysql_read 子配置文件:`vim /etc/keepalived/mysql/mysql_read.conf`
  2. ```bash
  3. vrrp_instance VIP_READ {
  4. state BACKUP # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP
  5. interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡
  6. virtual_router_id 22 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同
  7. priority 100 # 当前物理节点在此虚拟路由器的优先级,范围:1-254
  8. advert_int 1 # vrrp通告的时间间隔,默认1s
  9. authentication { # 认证机制
  10. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
  11. auth_pass 222222 # 预共享密钥,即相互认证密码
  12. }
  13. virtual_ipaddress { # 虚拟路由IP
  14. 10.0.0.200 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32
  15. }
  16. # 使用单播配置
  17. unicast_src_ip 10.0.0.21 # 本机IP
  18. unicast_peer{
  19. 10.0.0.22 # 指向其他Keepalived主机IP
  20. }
  21. }
  22. virtual_server 10.0.0.200 3306 { # 虚拟路由 IP 和 PORT
  23. delay_loop 3 # 检查后端服务器的时间间隔
  24. lb_algo rr # 定义调度方法,rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq
  25. lb_kind DR # LVS类型,注意要大写, NAT|DR|TUN
  26. protocol TCP # 指定服务协议,一般默认为TCP,TCP|UDP|SCTP
  27. real_server 10.0.0.31 3306 { # RS的IP和PORT
  28. weight 1 # 调度权重
  29. TCP_CHECK {
  30. nb_get_retry 3 # 重新连接次数
  31. delay_before_retry 3 # 重新连接间隔时间
  32. connect_port 3306 # 向当前RS的哪个PORT发起健康状态检测请求
  33. connect_timeout 3 # 客户端请求的超时时长, 等于haproxy的timeout server
  34. }
  35. }
  36. real_server 10.0.0.32 3306 {
  37. weight 1
  38. TCP_CHECK {
  39. nb_get_retry 3
  40. delay_before_retry 3
  41. connect_port 3306
  42. connect_timeout 3
  43. }
  44. }
  45. }

2.2.4 Keepalived-02 配置

  1. 创建配置文件目录:mkdir /etc/keepalived
  2. 创建主配置文件:vim /etc/keepalived/keepalived.conf。 ```bash global_defs { router_id C7-01.wuvikr.top # keepalived 主机唯一标识,建议使用当前主机名 vrrp_skip_check_adv_addr # 如果收到的通告报文和上一个报文是同一个路由,则跳过检查,默认为检查所有报文 vrrp_garp_interval 0 # gratuitous ARP messages 报文发送延迟,0表示不延迟 vrrp_gna_interval 0 # unsolicited NA messages (不请自来)消息发送延迟 vrrp_mcast_group4 224.0.0.20 # 指定组播IP地址范围:224.0.0.0到239.255.255.255,默认值:224.0.0.18 }

include /etc/keepalived/mysql/*.conf

  1. 3. 创建 mysql_write 子配置文件:`vim /etc/keepalived/mysql/mysql_write.conf`
  2. ```bash
  3. vrrp_instance VIP_WRITE {
  4. state BACKUP # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP
  5. interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡
  6. virtual_router_id 11 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同
  7. priority 100 # 当前物理节点在此虚拟路由器的优先级,范围:1-254
  8. nopreempt # 非抢占式
  9. advert_int 1 # vrrp通告的时间间隔,默认1s
  10. authentication { # 认证机制
  11. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
  12. auth_pass 111111 # 预共享密钥,即相互认证密码
  13. }
  14. virtual_ipaddress { # 虚拟路由IP
  15. 10.0.0.100 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32
  16. }
  17. # 使用单播配置
  18. unicast_src_ip 10.0.0.22 # 本机IP
  19. unicast_peer {
  20. 10.0.0.21 # 指向其他Keepalived主机IP
  21. }
  22. # 当 MySQL 主库宕机时,将从库提升为主库
  23. notify_master "/etc/keepalived/conf.d/remove_slave.sh"
  24. }
  25. virtual_server 10.0.0.100 3306 { # 虚拟路由 IP 和 PORT
  26. delay_loop 3 # 检查后端服务器的时间间隔
  27. lb_algo rr # 定义调度方法,rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq
  28. lb_kind DR # LVS类型,注意要大写, NAT|DR|TUN
  29. protocol TCP # 指定服务协议,一般默认为TCP,TCP|UDP|SCTP
  30. real_server 10.0.0.32 3306 { # RS的IP和PORT
  31. weight 1 # 调度权重
  32. notify_down "/etc/keepalived/conf.d/mysql_down.sh" # RS下线触发脚本
  33. TCP_CHECK {
  34. nb_get_retry 3 # 重新连接次数
  35. delay_before_retry 3 # 重新连接间隔时间
  36. connect_port 3306 # 向当前RS的哪个PORT发起健康状态检测请求
  37. connect_timeout 3 # 客户端请求的超时时长, 等于haproxy的timeout server
  38. }
  39. }
  40. }
  1. 创建 mysql_read 子配置文件:vim /etc/keepalived/mysql/mysql_read.conf。 ```bash vrrp_instance VIP_READ { state MASTER # 当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP interface eth0 # 绑定当前虚拟路由器使用的物理接口,可以不和VIP在同一个网卡 virtual_router_id 22 # 每个虚拟路由器惟一标识,范围:0-255,同属一个虚拟路由器的多个 keepalived 节点此值必须相同 priority 120 # 当前物理节点在此虚拟路由器的优先级,范围:1-254 advert_int 1 # vrrp通告的时间间隔,默认1s authentication { # 认证机制
    1. auth_type PASS # 认证类型,可以是AH或PASS,AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
    2. auth_pass 222222 # 预共享密钥,即相互认证密码
    } virtual_ipaddress { # 虚拟路由IP
    1. 10.0.0.200 # 指定VIP,不指定网卡,默认eth0,注意:不指定/prefix,默认为32
    }

    使用单播配置

    unicast_src_ip 10.0.0.22 # 本机IP unicast_peer{
    1. 10.0.0.21 # 指向其他Keepalived主机IP
    } }

virtual_server 10.0.0.200 3306 { # 虚拟路由 IP 和 PORT delay_loop 3 # 检查后端服务器的时间间隔 lb_algo rr # 定义调度方法,rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq lb_kind DR # LVS类型,注意要大写, NAT|DR|TUN protocol TCP # 指定服务协议,一般默认为TCP,TCP|UDP|SCTP

  1. real_server 10.0.0.31 3306 { # RS的IP和PORT
  2. weight 1 # 调度权重
  3. TCP_CHECK {
  4. nb_get_retry 3 # 重新连接次数
  5. delay_before_retry 3 # 重新连接间隔时间
  6. connect_port 3306 # 向当前RS的哪个PORT发起健康状态检测请求
  7. connect_timeout 3 # 客户端请求的超时时长, 等于haproxy的timeout server
  8. }
  9. }
  10. real_server 10.0.0.32 3306 {
  11. weight 1
  12. TCP_CHECK {
  13. nb_get_retry 3
  14. delay_before_retry 3
  15. connect_port 3306
  16. connect_timeout 3
  17. }
  18. }

}

  1. <a name="gQQNd"></a>
  2. ### 2.2.5 配置说明
  3. 两台 Keepalived 机器的配置区别主要有以下几点:
  4. - 角色不同:Keepalived-01 为 Write-VIP 的 MASTER,Keepalived-02 为 Read-VIP 的 MASTER。
  5. - 模式不同:Write-VIP 为非抢占式,Read-VIP 为抢占式。
  6. - 单播配置:需要指定单播地址。
  7. 另外,对于 Read-VIP(10.0.0.200),两台机器的配置基本是一致的。而对于 Write-VIP(10.0.0.100),则不同。<br />正常情况下,Keepalived-01 为 MASTER 角色,当请求访问 10.0.0.100 时,都是由 Keepalive-01 调度到 MySQL-Master(10.0.0.31)进行写入操作。<br />当 MySQL-Master 服务宕机时,Keepalived-01会调用`/etc/keepalived/mysql/mysql_down.sh`脚本,将自身的 keepalived.service 进程杀死,使 Keepalived-02 成为新的 Write-VIP MASTER 角色,这时访问 10.0.0.100 ,则是由 Keepalived-02 机器调度到 MySQL-Slave(10.0.0.32)进行写入操作,当然在 Keepalived-02 成为新的 Master 时,会执行`/etc/keepalived/mysql/remove_slave.sh`脚本,这个脚本会将原本的 MySQL-Slave(10.0.0.32)提升为新的 MySQL-Master。<br />当 MySQL-Slave 服务宕机时,并不影响 Write-VIP(10.0.0.100)。<br />`/etc/keepalived/mysql/mysql_down.sh`脚本内容如下:
  8. ```bash
  9. #!/bin/bash
  10. /usr/bin/systemctl stop keepalived.service

/etc/keepalived/mysql/remove_slave.sh脚本内容如下:

  1. #!/bin/bash
  2. USER=root
  3. PASSWORD=123.com
  4. HOST=10.0.0.32
  5. LOG=/var/log/stop_slave.log
  6. DATE=`date '+%F %T'`
  7. echo "time : ${DATE}" >> ${LOG}
  8. /usr/bin/mysql -u${USER} -p${PASSWORD} -h${HOST} -e "set global read_only=OFF;stop slave;reset master;reset slave all;" >> ${LOG}

注意:

  • /etc/keepalived/mysql/remove_slave.sh脚本是由新的 keepalived MASTER 来执行的,因此两台 Keepalived 的脚本内容对应的 MySQL-Slave 机器并不一样。
  • 脚本需要加上执行权限。

    2.2.6 启动 Keepalived 服务

    由于 Write-VIP 采用了非抢占式模式,为了让 Keepalived-01 成为 MASTER,必须先启动 Keepalived-01。
    1. [root@keepalived-01 ~]# systemctl start keepalived.service
    2. [root@keepalived-02 ~]# systemctl start keepalived.service
    启动成功后,查看虚拟 ip 地址: ```bash [root@keepalived-01 ~]# ip a 1: lo: 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
    1. valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
    1. valid_lft forever preferred_lft forever
    2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:40:93:bd brd ff:ff:ff:ff:ff:ff inet 10.0.0.21/24 brd 10.0.0.255 scope global noprefixroute eth0
    1. valid_lft forever preferred_lft forever
    inet 10.0.0.100/32 scope global eth0
    1. valid_lft forever preferred_lft forever
    inet6 fe80::e988:85bf:3ffc:96d7/64 scope link tentative noprefixroute dadfailed
    1. valid_lft forever preferred_lft forever
    inet6 fe80::32d4:4c1:856d:4217/64 scope link tentative noprefixroute dadfailed
    1. valid_lft forever preferred_lft forever
    inet6 fe80::cdf8:ac2a:1900:51e4/64 scope link tentative noprefixroute dadfailed
    1. valid_lft forever preferred_lft forever

[root@keepalived-02 ~]# ip a 1: lo: 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: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:5d:91:2f brd ff:ff:ff:ff:ff:ff inet 10.0.0.22/24 brd 10.0.0.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 10.0.0.200/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::e988:85bf:3ffc:96d7/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::32d4:4c1:856d:4217/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::cdf8:ac2a:1900:51e4/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever

  1. 查看 LVS 后端服务:
  2. ```bash
  3. [root@keepalived-01 ~]# ipvsadm -L
  4. IP Virtual Server version 1.2.1 (size=4096)
  5. Prot LocalAddress:Port Scheduler Flags
  6. -> RemoteAddress:Port Forward Weight ActiveConn InActConn
  7. TCP 10.0.0.200:mysql rr
  8. -> 10.0.0.31:mysql Route 1 0 0
  9. -> 10.0.0.32:mysql Route 1 0 0
  10. TCP keepalived-01:mysql rr
  11. -> 10.0.0.31:mysql Route 1 0 0
  12. [root@keepalived-02 ~]# ipvsadm -L
  13. IP Virtual Server version 1.2.1 (size=4096)
  14. Prot LocalAddress:Port Scheduler Flags
  15. -> RemoteAddress:Port Forward Weight ActiveConn InActConn
  16. TCP keepalived-02:mysql rr
  17. -> 10.0.0.31:mysql Route 1 0 0
  18. -> 10.0.0.32:mysql Route 1 0 0
  19. TCP 10.0.0.100:mysql rr
  20. -> 10.0.0.32:mysql Route 1 0 0

MySQL Real Server 网络配置

在每台 MySQL 机器上使用下面的脚本一键配置 Real Server,并加入开机自启动。

  1. [root@c7-01 ~]# cat /etc/init.d/lvs_dr_rs.sh
  2. #!/bin/bash
  3. trap "echo -e '\e[1;36mThank you for using, goodbye !\e[0m'" EXIT
  4. write_vip=10.0.0.100
  5. read_vip=10.0.0.200
  6. mask=255.255.255.255
  7. dev=lo:1
  8. case $1 in
  9. start)
  10. # 禁用本地ARP请求,绑定回环地址。
  11. echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
  12. echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  13. echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
  14. echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
  15. # 在回环地址上绑定VIP,设置掩码,与Director服务器自身IP保持通信
  16. /sbin/ifconfig lo:1 ${write_vip} netmask ${mask} up
  17. /sbin/ifconfig lo:2 ${read_vip} netmask ${mask} up
  18. route add -host ${write_vip} dev lo:1
  19. route add -host ${read_vip} dev lo:2
  20. echo -e '\e[1;32mLVS-DR Real Server starts successfully.\n\e[0m'
  21. ;;
  22. stop)
  23. /sbin/ifconfig lo:1 down
  24. /sbin/ifconfig lo:2 down
  25. route del ${write_vip} >/dev/null 2>$1
  26. route del ${read_vip} >/dev/null 2>$1
  27. echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
  28. echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
  29. echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
  30. echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
  31. echo -e '\e[1;31mLVS-DR Real Server stopped.\n\e[0m'
  32. ;;
  33. *)
  34. echo "Usage: $(basename $0) start|stop"
  35. exit 1
  36. ;;
  37. esac
  38. # 添加执行权限
  39. [root@c7-01 ~]# chmod +x /etc/init.d/lvs_dr_rs.sh
  40. # 开机自启
  41. [root@c7-01 ~]# echo "/etc/init.d/lvs_dr_rs.sh start" >> /etc/rc.d/rc.local
  42. # 执行脚本
  43. [root@c7-01 ~]# /etc/init.d/lvs_dr_rs.sh start

执行完上面的脚本后会在本地 lo 回环网卡上添加上 10.0.0.100/32 和 10.0.0.200/32 的虚拟 VIP ,用于 LVS DR 模型的 Director 转发。

2.3 功能测试

2.3.1 停止主 MySQL 服务,查看 vip 漂移和访问情况

2.3.2 停止从 MySQL 服务,查看 vip 漂移和访问情况

3. MHA