CentOS 7上具有DRBD的主动/被动MySQL高可用性Pacemaker群集
我们将使用Pacemaker和Corosync构建两个节点的主动/被动MariaDB HA集群。
在我们开始之前
我们将使用MariaDB,这是MySQL的二进制替代版本。
MySQL不再位于CentOS的存储库中,MariaDB已成为提供的默认数据库系统。
MariaDB声称拥有MySQL中没有的许多新选项,扩展,存储引擎和错误修复。
检查此页面https://mariadb.com/kb/zh-CN/mariadb/mariadb-vs-mysql-compatibility/以获取有关MariaDB的更多信息。
无需共享存储。
在任何时间点,MariaDB服务都将在一个群集节点上处于活动状态。
本文遵循的约定是[ALL]表示需要在所有群集节点上运行的命令。
软件
本文使用的软件:
- CentOS Linux release 7.2.1511 (Core)
- kernel-3.10.0-327.4.4.el7
- pacemaker-1.1.13
- corosync-2.3.4
- pcs-0.9.143
- resource-agents-3.9.5
- drbd-8.4 (kmod-drbd84-8.4.7)
- MariaDB 5.5.44
网络,防火墙和SELinux配置
我们在VirtualBox上有两个CentOS 7虚拟机,分别名为pcmk01和pcmk02.
联网
将使用以下网络:
- 10.8.8.0/24-可以访问Internet的LAN(仅主机适配器),
- 172.16.21.0/24-用于Corosync(内部网络适配器)的不可路由的群集心跳线VLAN,
- 172.16.22.0/24-DRBD(内部网络适配器)的不可路由群集心跳线VLAN。
在“/etc/hosts”文件中定义的主机名和IP:
10.8.8.60 pcmkvip 10.8.8.61 pcmk01 10.8.8.62 pcmk02 172.16.21.11 pcmk01-cr 172.16.21.12 pcmk02-cr 172.16.22.11 pcmk01-drbd 172.16.22.12 pcmk02-drbd
我们设置了以下主机名:
[pcmk01]# hostnamectl set-hostname pcmk01 [pcmk02]# hostnamectl set-hostname pcmk02
简化的网络配置如下所示。
可以在下面看到第一个节点的网络配置,除了上面指定的IP外,第二个节点的网络配置相同。
[pcmk01]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s8 #Corosync ring0 NAME="enp0s8" DEVICE="enp0s8" IPADDR="172.16.21.11" PREFIX="24" TYPE="Ethernet" IPV4_FAILURE_FATAL="yes" IPV6INIT="no" DEFROUTE="no" PEERDNS="no" PEERROUTES="no" ONBOOT="yes"
[pcmk01]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s9 #DRBD NAME="enp0s9" DEVICE="enp0s9" IPADDR="172.16.22.11" PREFIX="24" TYPE="Ethernet" IPV4_FAILURE_FATAL="yes" IPV6INIT="no" DEFROUTE="no" PEERDNS="no" PEERROUTES="no" ONBOOT="yes"
[pcmk01]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s17 #LAN NAME="enp0s17" DEVICE="enp0s17" IPADDR="10.8.8.61" PREFIX="24" GATEWAY="10.8.8.1" DNS1="8.8.8.8" DNS2="8.8.4.4" TYPE="Ethernet" IPV4_FAILURE_FATAL="yes" IPV6INIT="no" DEFROUTE="yes" PEERDNS="yes" ONBOOT="yes"
iptables
本文使用Iptables防火墙。
请注意,CentOS 7使用FirewallD作为默认的防火墙管理工具。
我们用Iptables替换了FirewallD服务:
[ALL]# systemctl stop firewalld.service [ALL]# systemctl mask firewalld.service [ALL]# systemctl daemon-reload [ALL]# yum install -y iptables-services [ALL]# systemctl enable iptables.service [ALL]# service iptables save
这些是我们正在使用的iptables防火墙规则:
# iptables -S -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -s 10.8.8.0/24 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT -A INPUT -s 172.16.21.0/24 -d 172.16.21.0/24 -m comment --comment Corosync -j ACCEPT -A INPUT -s 172.16.22.0/24 -d 172.16.22.0/24 -m comment --comment DRBD -j ACCEPT -A INPUT -s 10.8.8.0/24 -p tcp -m tcp --dport 3306 -m state --state NEW -j ACCEPT -A INPUT -p udp -m multiport --dports 67,68 -m state --state NEW -j ACCEPT -A INPUT -p udp -m multiport --dports 137,138,139,445 -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -j LOG --log-prefix "iptables_input " -A INPUT -j DROP
我们还禁用了IPv6,打开“ /etc/sysctl.conf”进行编辑,然后放置以下内容:
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
[ALL]# sysctl -p
SELinux
SELinux设置为强制模式。
安装Pacemaker和Corosync
[ALL]# yum install -y pcs
这些个人电脑将安装起搏器,corosync和资源代理作为依赖项。
对于SELinux管理:
[ALL]# yum install -y policycoreutils-python
在RHEL 7中,我们必须为名为hacluster的pcs管理帐户设置一个密码:
[ALL]# echo "passwd" | passwd hacluster --stdin
启动并启用服务:
[ALL]# systemctl start pcsd.service [ALL]# systemctl enable pcsd.service
配置Corosync
以hacluster用户身份进行身份验证。
授权令牌存储在文件'/var/lib/pcsd/tokens'中。
[pcmk01]# pcs cluster auth pcmk01-cr pcmk02-cr -u hacluster -p passwd pcmk01-cr: Authorized pcmk02-cr: Authorized
生成并同步Corosync配置。
[pcmk01]# pcs cluster setup --name mysql_cluster pcmk01-cr pcmk02-cr
在所有节点上启动集群:
[pcmk01]# pcs cluster start --all
安装DRBD和MariaDB
DRBD安装
DRBD是指被设计为构成高可用性集群的构建块的块设备。
这可以通过分配的网络镜像整个块设备来完成。
DRBD可以理解为基于网络的RAID-1.
导入ELRepo软件包签名密钥,启用存储库并使用实用程序安装DRBD内核模块:
[ALL]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org [ALL]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm [ALL]# yum install -y kmod-drbd84 drbd84-utils
为了暂时避免SELinux出现问题,我们将免除SELinux控制中的DRBD流程:
[ALL]# semanage permissive -a drbd_t
DRBD的LVM卷
为DRBD创建一个新的1GB逻辑卷:
[pcmk01]# vgs VG #PV #LV #SN Attr VSize VFree vg_centos7 1 3 0 wz--n- 63.21g 45.97g
[ALL]# lvcreate --name lv_drbd --size 1024M vg_centos7
配置DRBD
配置DRBD,将单主模式与复制协议C配合使用。
[ALL]# cat << EOL >/etc/drbd.d/mysql01.res resource mysql01 { protocol C; meta-disk internal; device /dev/drbd0; disk /dev/vg_centos7/lv_drbd; handlers { split-brain "/usr/lib/drbd/notify-split-brain.sh root"; } net { allow-two-primaries no; after-sb-0pri discard-zero-changes; after-sb-1pri discard-secondary; after-sb-2pri disconnect; rr-conflict disconnect; } disk { on-io-error detach; } syncer { verify-alg sha1; } on pcmk01 { address 172.16.22.11:7789; } on pcmk02 { address 172.16.22.12:7789; } } EOL
我们有一个名为mysql01的资源,它使用'/dev/vg_centos7/lv_drbd'作为较低级别的设备,并配置了内部元数据。
资源使用TCP端口7789进行网络连接,并分别绑定到IP地址172.16.22.11和172.16.22.12.
如果遇到问题,我们必须确保在防火墙上为DRBD接口打开了TCP 7789端口,并且资源名称与文件名匹配。
为DRBD资源创建本地元数据:
[ALL]# drbdadm create-md mysql01
确保已加载DRBD内核模块,调出DRBD资源:
[ALL]# drbdadm up mysql01
为了保持数据一致性,请告知DRBD哪个节点应被视为具有正确的数据(可以在任何节点上运行,因为此时两个节点都具有垃圾):
[pcmk01]# drbdadm primary --force mysql01
观察同步:
[pcmk01]# drbd-overview 0:mysql01/0 SyncSource Primary/Secondary UpToDate/Inconsistent [=>..................] sync'ed: 11.8% (926656/1048508)K
在DRBD设备上创建文件系统,并根据需要进行调整:
[pcmk01]# mkfs.ext4 -m 0 -L drbd /dev/drbd0
[pcmk01]# tune2fs -c 30 -i 180d /dev/drbd0
挂载磁盘,我们将很快其中填充MariaDB内容:
[pcmk01]# mount /dev/drbd0 /mnt
MariaDB安装
[ALL]# yum install -y mariadb-server mariadb
确保MariaDB服务已禁用,因为它将由心脏起搏器管理:
[ALL]# systemctl disable mariadb.service
现在,在集群节点之一上手动启动MariaDB服务:
[pcmk01]# systemctl start mariadb
我们可以使用mysql_install_db命令安装一个新的MariaDB数据库:
[pcmk01]# mysql_install_db --datadir=/mnt --user=mysql
运行安全安装:
[pcmk01]# mysql_secure_installation
我们需要提供与MariaDB数据目录相同的SELinux策略。
mysqld策略在'/var/lib/mysql'目录下存储具有多种不同文件上下文类型的数据。
如果要将数据存储在其他目录中,可以使用semanage命令添加文件上下文。
[pcmk01]# semanage fcontext -a -t mysqld_db_t "/mnt(/.*)?" [pcmk01]# restorecon -Rv /mnt
请注意,使用chcon命令进行的更改不能在重新标记文件系统或者执行restorecon命令后继续存在。
始终使用管理功能。
至此,我们的准备工作已经完成,我们可以卸载临时挂载的文件系统并停止MariaDB服务:
[pcmk01]# umount /mnt
[pcmk01]# systemctl stop mariadb
最后要做的是,我们必须放置一些非常基本的“ my.cnf”配置:
[ALL]# cat << EOL > /etc/my.cnf [mysqld] symbolic-links=0 bind_address = 0.0.0.0 datadir = /var/lib/mysql pid_file = /var/run/mariadb/mysqld.pid socket = /var/run/mariadb/mysqld.sock [mysqld_safe] bind_address = 0.0.0.0 datadir = /var/lib/mysql pid_file = /var/run/mariadb/mysqld.pid socket = /var/run/mariadb/mysqld.sock !includedir /etc/my.cnf.d EOL
配置Pacemaker群集
我们希望配置逻辑和顺序如下:
- 开始:mysql_fs01-> mysql_service01-> mysql_VIP01,
- 停止:mysql_VIP01-> mysql_service01-> mysql_fs01.
其中mysql_fs01是文件系统资源,mysql_service01是mysqld服务资源,mysql_VIP01是浮动虚拟IP 10.8.8.60。
pc的一个方便功能是能够将多个更改排队到一个文件中,并自动提交这些更改。
为此,我们首先使用来自CIB的当前原始XML配置填充文件:
[pcmk01]# pcs cluster cib clust_cfg
禁用STONITH。
请注意,节点级别的防护配置在很大程度上取决于环境。
我们可以在此页面上查看VMware上的Pacemaker STONITH设备配置。
[pcmk01]# pcs -f clust_cfg property set stonith-enabled=false
将仲裁策略设置为忽略:
[pcmk01]# pcs -f clust_cfg property set no-quorum-policy=ignore
防止资源在恢复后移动,因为这通常会增加停机时间:
[pcmk01]# pcs -f clust_cfg resource defaults resource-stickiness=200
为DRBD设备创建一个名为mysql_data01的集群资源,并创建一个另外的克隆资源MySQLClone01,以允许该资源同时在两个集群节点上运行:
[pcmk01]# pcs -f clust_cfg resource create mysql_data01 ocf:linbit:drbd \ drbd_resource=mysql01 \ op monitor interval=30s
[pcmk01]# pcs -f clust_cfg resource master MySQLClone01 mysql_data01 \ master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 \ notify=true
注意使用的元变量:
master-max:可以将多少个资源副本提升为主状态,
master-node-max:可以在单个节点上将多少个资源副本提升为主节点状态,
clone-max:要启动的资源的副本数。
默认为集群中的节点数,
clone-node-max:可以在单个节点上启动多少资源副本,
通知:停止或者启动克隆副本时,请事先告知所有其他副本以及操作成功的时间。
为文件系统创建一个名为mysql_fs01的群集资源。
告诉集群,克隆资源MySQLClone01必须与文件系统资源在同一节点上运行,并且克隆资源必须在文件系统资源之前启动。
[pcmk01]# pcs -f clust_cfg resource create mysql_fs01 Filesystem \ device="/dev/drbd0" \ directory="/var/lib/mysql" \ fstype="ext4"
[pcmk01]# pcs -f clust_cfg constraint colocation add mysql_fs01 with MySQLClone01 \ INFINITY with-rsc-role=Master
[pcmk01]# pcs -f clust_cfg constraint order promote MySQLClone01 then start mysql_fs01
为MariaDB服务创建一个名为mysql_service01的集群资源。
告诉集群,MariaDB服务必须与mysql_fs01文件系统资源在同一节点上运行,并且文件系统资源必须首先启动。
[pcmk01]# pcs -f clust_cfg resource create mysql_service01 ocf:heartbeat:mysql \ binary="/usr/bin/mysqld_safe" \ config="/etc/my.cnf" \ datadir="/var/lib/mysql" \ pid="/var/lib/mysql/mysql.pid" \ socket="/var/lib/mysql/mysql.sock" \ additional_parameters="--bind-address=0.0.0.0" \ op start timeout=60s \ op stop timeout=60s \ op monitor interval=20s timeout=30s
[pcmk01]# pcs -f clust_cfg constraint colocation add mysql_service01 with mysql_fs01 INFINITY
[pcmk01]# pcs -f clust_cfg constraint order mysql_fs01 then mysql_service01
最后,为虚拟IP 10.8.8.60创建一个名为mysql_VIP01的群集资源。
[pcmk01]# pcs -f clust_cfg resource create mysql_VIP01 ocf:heartbeat:IPaddr2 \ ip=10.8.8.60 cidr_netmask=32 \ op monitor interval=30s
为什么要使用IPaddr2而不是IPaddr:
- IPaddr-管理虚拟IPv4地址(便携式版本),
- IPaddr2-管理虚拟IPv4地址(Linux特定版本)。
自然,虚拟IP mysql_VIP01资源必须与MariaDB资源在同一节点上运行,并且必须在最后一个节点上启动。
这是为了确保在连接到虚拟IP之前已经启动了所有其他资源。
[pcmk01]# pcs -f clust_cfg constraint colocation add mysql_VIP01 with mysql_service01 INFINITY
[pcmk01]# pcs -f clust_cfg constraint order mysql_service01 then mysql_VIP01
让我们检查配置:
[pcmk01]# pcs -f clust_cfg constraint Location Constraints: Ordering Constraints: promote MySQLClone01 then start mysql_fs01 (kind:Mandatory) start mysql_fs01 then start mysql_service01 (kind:Mandatory) start mysql_service01 then start mysql_VIP01 (kind:Mandatory) Colocation Constraints: mysql_fs01 with MySQLClone01 (score:INFINITY) (with-rsc-role:Master) mysql_service01 with mysql_fs01 (score:INFINITY) mysql_VIP01 with mysql_service01 (score:INFINITY)
[pcmk01]# pcs -f clust_cfg resource show Master/Slave Set: MySQLClone01 [mysql_data01] Stopped: [ pcmk01-cr pcmk02-cr ] mysql_fs01 (ocf::heartbeat:Filesystem): Stopped mysql_service01 (ocf::heartbeat:mysql): Stopped mysql_VIP01 (ocf::heartbeat:IPaddr2): Stopped
我们现在可以提交更改并检查集群状态:
[pcmk01]# pcs cluster cib-push clust_cfg
[pcmk01]# pcs status [...] Online: [ pcmk01-cr pcmk02-cr ] Full list of resources: Master/Slave Set: MySQLClone01 [mysql_data01] Masters: [ pcmk01-cr ] Stopped: [ pcmk02-cr ] mysql_fs01 (ocf::heartbeat:Filesystem): Started pcmk01-cr mysql_service01 (ocf::heartbeat:mysql): Started pcmk01-cr mysql_VIP01 (ocf::heartbeat:IPaddr2): Started pcmk01-cr [...]
提交配置后,Pacemaker将:
- 在两个群集节点上启动DRBD,
- 选择一个节点升级为DRBD主要角色,
- 挂载文件系统,配置集群IP地址,然后在同一节点上启动MariaDB服务器,
- 开始资源监控
我们可以通过在TCP por 3306上远程登录到虚拟IP 10.8.8.60来测试MariaDB服务:
# telnet 10.8.8.60 3306 Trying 10.8.8.60... Connected to 10.8.8.60. Escape character is '^]'. Host 'puppet.hl.local' is not allowed to connect to this MariaDB serverConnection closed by foreign host.