利用keepalived和haproxy配置mysql的高可用负载均衡
实验系统:CentOS 7.5
实验前提:防火墙和selinux都关闭
实验说明:本实验共有4台主机,IP分配如拓扑
实验软件:keepalived haproxy-1.5.19 mysql-8.0.12
实验拓扑:
一:安装MySql8.0.12(在两个mysql节点上都配置)
1:解压
[root@localhost ~]# tar zxvf mysql-8.0.12-el7-x86_64.tar.gz
[root@localhost ~]# mv mysql-8.0.12-el7-x86_64 /usr/local/mysql
建议:不要安装到其它目录,否则数据库初始化的时候会报cannot change dir的错
3:卸载系统自带mysql
查看:
[root@localhost ~]# rpm -qa | grep mariadb
卸载:
[root@localhost ~]# rpm -e --nodeps mariadb-libs
4:创建用户组和用户
创建用户:
[root@localhost ~]# useradd mysql
5:给mysql目录指定专有用户和用户组
首先创建data目录:
[root@localhost ~]# mkdir /usr/local/mysql/data
指定用户和用户组:
[root@localhost ~]# chown -R mysql:mysql /usr/local/mysql/
6:初始化mysql
[root@localhost ~]# cd /usr/local/mysql/bin
[root@localhost bin]# ./mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
记住生成的临时密码
如果忘记密码或者想重新初始化,可以先将mysql/data目录中文件删除,然后再执行初始化命令
7:配置my.cnf
从5.7.17后mysql就没有默认的my_default.cnf文件,需要手动创建
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data/
8:设为系统服务并开机启动
[root@localhost ~]# ln -s /usr/local/mysql/bin/* /usr/local/bin/
[root@localhost ~]# cd /usr/local/mysql/support-files/
[root@localhost support-files]# cp mysql.server /etc/init.d/mysqld
[root@localhost support-files]# vi /etc/init.d/mysqld
添加mysql目录:
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data/
授权:
[root@localhost ~]#chmod +x /etc/init.d/mysqld
设为开机启动:
[root@localhost ~]#chkconfig --add mysqld
(1)service启动
重启服务:service mysqld restart
停止服务:service mysqld stop
启动服务:service mysqld start
查看服务:service mysqld status
9:登录mysql修改密码授权远程登录
(1)登录:
[root@localhost ~]# mysql -u root -p 输入临时密码
(2)修改root密码:
mysql> alter user 'root'@'localhost' identified by 'pwd123';
(3)远程登录授权:
mysql> create user 'root'@'192.168.1.%' identified by 'pwd123';
mysql> ALTER USER 'root'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'pwd123';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.%';
mysql> flush privileges;
可使用navicat等工具进行登录,注意关闭防火墙或开放3306端口
二:mysql8.0.12配置双主复制
1:节点1配置
修改 Master 的配置文件/etc/my.cnf
vi /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
log-slave-updates=true
2:节点2配置
vi /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=2
log-slave-updates=true
重启mysql服务
[root@localhost ~]#systemctl restart mysqld
3:在两个节点上获取主节点当前binary log文件名和位置(position)
节点01:192.168.10.101
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
节点02:192.168.10.102
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
4:
(1) 节点一(192.168.10.101)
在mysql02上创建用于复制操作的用户
创建用户并授权
mysql> create user 'zhangsan'@'192.168.1.%' identified by 'pwd123';
mysql> ALTER USER 'zhangsan'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'pwd123';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'zhangsan'@'192.168.1.%';
刷新授权表信息
mysql> flush privileges;
)
mysql> change master to master_host='192.168.10.102',master_user='zhangsan',master_password='pwd123',master_log_file='mysql-bin.000002',master_log_pos=155;
master_host:指定对端IP
master_log_file:指定对端的文件ID
master_log_pos:指定对端的位置
开启从节点
mysql> start slave;
(2)节点二(192.168.10.102)
在mysql01上创建用于复制操作的用户
创建用户并授权
mysql> create user 'zhangsan'@'192.168.1.%' identified by 'pwd123';
mysql> ALTER USER 'zhangsan'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'pwd123';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'zhangsan'@'192.168.1.%';
刷新授权表信息
mysql> flush privileges;
mysql> change master to master_host='192.168.10.101',master_user='zhangsan',master_password='pwd123',master_log_file='mysql-bin.000001',master_log_pos=155;
开启从节点
mysql> start slave;
6:查看主从同步状态
mysql> show slave statusG;
二、编译安装haproxy
1:在10.103和10.104上编译安装haproxy:
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install pcre-devel bzip2-devel gcc*
[root@localhost ~]# tar zxvf haproxy-1.5.19.tar.gz
[root@localhost ~]# cd haproxy-1.5.19/
[root@localhost haproxy-1.5.19]# make TARGET=linux2628
[root@localhost haproxy-1.5.19]# make install
2:建立haproxy配置文件
[root@localhost haproxy-1.5.19]# mkdir /etc/haproxy
[root@localhost haproxy-1.5.19]# cp examples/haproxy.cfg /etc/haproxy/
3:修改配置文件:
[root@localhost ~]# mkdir /usr/share/haproxy
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
# chroot /usr/share/haproxy
uid 99
gid 99
daemon
#debug
#quiet
defaults
log global
mode tcp
option httplog
option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen stats
mode http
bind :6677
stats enable
stats hide-version
stats uri /admin
stats realm haproxy
stats auth admin:admin
stats admin if TRUE
frontend main *:3306
default_backend mysql
backend mysql
balance leastconn
server m1 192.168.10.101:3306 check port 3306 maxconn 300
server m2 192.168.10.102:3306 check port 3306 maxconn 300
注释:
frontend main *:3306
default_backend mysql
backend mysql
balance leastconn
server m1 192.168.10.101:3306 check port 3306 maxconn 300
server m2 192.168.10.102:3306 check port 3306 maxconn 300
此部分可以写成
listen mysql 0.0.0.0:3306
balance leastconn
server m1 192.168.10.101:3306 check port 3306 maxconn 300
server m2 192.168.10.102:3306 check port 3306 maxconn 300
注释:
listen stats ##配置haproxy状态页
mode http
bind :6677 ##找一个比较特殊的端口
stats enable
stats hide-version ##隐藏haproxy版本号
stats uri /haproxyadmin?stats ##用于打开状态页的uri
stats realm Haproxy Statistics ##输入账户密码时的提示文字
stats auth admin:admin ##用户名:密码
stats admin if TRUE ##开启状态页的管理功能
frontend main *:3306 ##这里为了实验方便,使用3306端口
default_backend mysql ##后端服务器组名
backend mysql
balance leastconn ##使用最少连接方式调度
4:创建启动脚本
[root@localhost haproxy-1.5.19]# cp examples/haproxy.init /etc/init.d/haproxy
[root@localhost haproxy-1.5.19]# ln -s /usr/local/sbin/haproxy /usr/sbin/haproxy
[root@localhost haproxy-1.5.19]# chmod +x /etc/init.d/haproxy
[root@localhost haproxy-1.5.19]# /etc/init.d/haproxy start
5:启动测试haproxy:
service haproxy start
netstat -tnlp
6:按照上述步骤部署第二台haproxy
三:在客户机上测试haproxy的代理功能
1:在mysql01上创建测试用的账号,并授权
mysql> create user lisi@'192.168.1.%' identified by '123456';
mysql> ALTER USER lisi@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY '123456';
mysql> GRANT ALL PRIVILEGES ON *.* TO lisi@'192.168.1.%';
mysql> FLUSH PRIVILEGES;
2:在客户端分别登录两个mysql,若都能连接成功则继续往下:
yum -y install mysql ##如果没有mysql客户端则运行此命令
mysql -ulisi -p123456 -h192.168.10.103
mysql -ulisi -p123456 -h192.168.10.104
四、安装keepalived
1.在10.103和10.104上安装keepalived:
[root@localhost ~]# systemctl stop NetworkManager
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# yum -y install keepalived ipvsadm
[root@localhost ~]# systemctl enable keepalived
2.在10.103上配置keepalived:
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_01
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk.sh" ##检查haproxy的脚本
interval 2 ##每两秒检查一次
weight -5 #脚本结果导致优先级变更,检测失败则优先级减5
fall 2 #检测连续2次失败才算是真失败
rise 1 #检测1次就算成功,但不修改优先级
}
vrrp_instance VI_1 {
state BACKUP ##定义为BACKUP节点
nopreempt ##开启不抢占
interface ens33
virtual_router_id 51
priority 100 ##开启了不抢占,所以此处优先级必须高于另一台
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100 ##配置VIP
}
track_script {
chk_haproxy ##调用检查脚本
}
}
3.在10.104上配置keepalived:
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_01
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk.sh" ##检查haproxy的脚本
interval 2 ##每两秒检查一次
weight -5 #脚本结果导致优先级变更,检测失败则优先级减5
fall 2 #检测连续2次失败才算是真失败
rise 1 #检测1次就算成功,但不修改优先级
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.100
}
track_script {
chk_haproxy
}
}
4.在两台机器上创建chk.sh文件:
[root@localhost ~]# vim /etc/keepalived/chk.sh
#!/bin/bash
#
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
systemctl stop keepalived
fi
[root@localhost ~]# chmod +x /etc/keepalived/chk.sh
5.在10.103和10.104上进行测试:
[root@localhost ~]# service keepalived start
此处两台主机均配置为BACKUP,因此哪台先运行keepalived,VIP就在哪台上。我这里刚开始VIP运行在10.103上,然后进行连接测试:
mysql -ulisi -p123456 -h192.168.10.100
CREATE DATABASE test;
后端数据库服务器抓包:
停掉10.103的keepalived服务,让VIP转移到10.104上,再进行测试:
[root@localhost ~]# service keepalived stop ##停掉10.103的keepalived服务
mysql -ujason -p123456 -h192.168.10.100
------------------------------------------->
SHOW DATABASES;
后端数据库服务器抓包:
6.在浏览器打开http:##192.168.19.150:6677/admin,打开haproxy状态页:
在10.101上关闭mysql服务,可以看到haproxy对于后端服务器的检测是很迅速的:
[root@localhost ~]# service mysqld stop
7.额外说明:
继续之前的实验,将10.103上的keepalived服务再次启动,可以发现,VIP仍然在10.104上,这就是之前为什么要配置不抢占的原因。如果按照正常的配置,将10.103配置为MASTER,当它重启keepalived服务后,则一定会将VIP抢回。但实际上我们并不希望这样,因为10.104仍在正常工作,10.103没有理由去抢夺资源,造成没必要的资源切换。实验演示就到这里,谢谢大家!