CentOS 7上具有DRBD的主动/被动MySQL高可用性Pacemaker群集

时间:2020-03-21 11:42:29  来源:igfitidea点击:

我们将使用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.