摘要
高可用性(High availability,HA)指系统无中断地执行其功能的能力,是进行系统设计时的准则之一。随着容器集群技术大行其道,寄宿主机可用性成为影响最大的因素之一。高可用性通常通过提高系统的容错能力来实现,Pacemaker 高可用集群提供了超融合等方案之外的低成本选择。
前提
本文的实验环境基于 Ubuntu 22.04.4 LTS,安装在 KVM 虚拟机中,安装模式为 Minimal Server ,内核版本为 5.15.0-107-generic。
Pacemaker
Pacemaker:领跑人、标兵、心脏起搏器,形象地说明了 Pacemaker 在高可用集群中的位置。利用集群基础架构(Corosync / Heartbeat)提供的消息和集群成员管理功能,Pacemaker 实现节点和资源级别的故障检测及资源恢复,从而最大程度保证集群服务的高可用。
Pacemaker 支撑的体系中,集群分为三层:
- 对集群无感知组件,包括管理资源使用的脚本、API、代理、守护进程等;
- 负责管理资源的组件,监控事件并作出响应,扮演着集群的决策中枢角色;
- 底层支撑构架,集群运行的消息和运行状态交换。
以上三个部分分别被称为:资源( Resources )、集群管理器 (Pacemaker)和 群组通讯系统(Corosync / heartbeet)。Pacemaker 内部由包含集群数据库(CIB)、集群资源管理(Crmd)、本地资源管(Lrmd)、策略引擎(Pengine)和栅篱设备(Fence)等组件组成。
Pacemaker 拥有两套命令行控制系统,pcs 和 cmrsh;本文中采用 pcs 作为集群控制命令。
安装
Red Hat Enterprise Linux
首先激活 redhat highaviability 仓库安装所须的软件。 fence 在 redhat 集群中负责对问题节点的隔离工作,针对不同类型的设备,rpm 仓库中提供了多种选择,此处我们选择安装 fence-agents-drac5 和 fence-agents-virsh。
# 激活订阅
subscription-manager repos --enable=rhel-9-for-x86_64-highavailability-rpms
# 安装
dnf install pcs pacemaker fence-agents-all # fence-agents-all将安装所有的 fence-agent-*,可选
从选择的列表中,可以查询到支持的列表。根据实际情况选择安装,二选一必选。
# 使用 iDRAC 控制物理服务器
dnf install pcs pacemaker fence-agents-drac5
# 或
# 使用 virsh 控制虚拟主机
dnf install pcs pacemaker fence-agents-virsh
Ubuntu 安装
Ubuntu 下配置 Pacemaker & Corosync 集群的方法和 RHEL 下基本一致,但是 Ubuntu 推荐使用 crmsh 工具进行配置。经测试采用 RHEL 下的 pcs 配置方式在 Ubuntu 系统下效果一致,并且与 crmsh 工具配置信息可以同步。故在 Ubuntu 系统中需要安装 pcs 工具。
# 安装必要的软件,此处同时安装了 `crmsh` 和 `pcs`
apt install corosync pacemaker pacemaker-cli-utils resource-agents fence-agents-base crmsh pcs -y
准备工作
设置时钟同步
时钟同步是集群正常运行的前提条件,首先在各加入集群的主机上启用 ntp 时钟同步。
# 检查同步状态
timedatectl status
# 使能 ntp 时钟同步
timedatectl set-ntp true
# [使能|禁用]本地时间
timedatectl set-local-rtc [yes|no]
启动服务
然后可以启动集群管理守护进程。
systemctl enable --now corosync
systemctl enable --now pacemaker
systemctl enable --now pcsd
创建账号
在加入集群的各主机上创建集群管理账号,并设置认证密码
useradd haclusteradm
passwd haclusteradm
# 输入密码
配置集群
集群的配置,仅需要在其中一台主机中进行配置即可
1) 配置集群资源管理器授权认证
# 认证所有服务器
pcs host auth havms21.vms.exapmle.com havms22.vms.exapmle.com havms23.vms.exapmle.com
# 这一步要求输入前面创建的用户名密码
2) 创建集群
# 设置集群
pcs cluster setup ha-cluster --start havms21.vms.example.com addr=192.168.1.251 havms22.vms.example.com addr=192.168.1.252 havms23.vms.example.com addr=192.168.1.253
# 将产生以下输出 >>
# No addresses specified for host 'havms21.vms.example.com', using 'havms21.vms.example.com'
# No addresses specified for host 'havms22.vms.example.com', using 'havms22.vms.example.com'
# No addresses specified for host 'havms23.vms.example.com', using 'havms23.vms.example.com'
# Destroying cluster on hosts: 'havms21.vms.example.com', 'havms22.vms.example.com', 'havms23.vms.example.com'...
# havms21.vms.example.com: Successfully destroyed cluster
# havms22.vms.example.com: Successfully destroyed cluster
# havms23.vms.example.com: Successfully destroyed cluster
# Requesting remove 'pcsd settings' from 'havms21.vms.example.com', 'havms22.vms.example.com', 'havms23.vms.example.com'
# havms21.vms.example.com: successful removal of the file 'pcsd settings'
# havms23.vms.example.com: successful removal of the file 'pcsd settings'
# havms22.vms.example.com: successful removal of the file 'pcsd settings'
# Sending 'corosync authkey', 'pacemaker authkey' to 'havms21.vms.example.com', 'havms22.vms.example.com', 'havms23.vms.example.com'
# havms21.vms.example.com: successful distribution of the file 'corosync authkey'
# havms21.vms.example.com: successful distribution of the file 'pacemaker authkey'
# havms23.vms.example.com: successful distribution of the file 'corosync authkey'
# havms23.vms.example.com: successful distribution of the file 'pacemaker authkey'
# havms22.vms.example.com: successful distribution of the file 'corosync authkey'
# havms22.vms.example.com: successful distribution of the file 'pacemaker authkey'
# Sending 'corosync.conf' to 'havms21.vms.example.com', 'havms22.vms.example.com', 'havms23.vms.example.com'
# havms21.vms.example.com: successful distribution of the file 'corosync.conf'
# havms23.vms.example.com: successful distribution of the file 'corosync.conf'
# havms22.vms.example.com: successful distribution of the file 'corosync.conf'
# Cluster has been successfully set up.
3) 等待集群同步完成
# 检查状态
pcs cluster status
# 将产生以下输出 >>
# ...
# 最开始会报告状态 节点下线 Node xxx: UNCLEAN (offline)
# Node List:
# * Node havms21.vms.example.com: UNCLEAN (offline)
# * Node havms22.vms.example.com: UNCLEAN (offline)
# * Node havms23.vms.example.com: UNCLEAN (offline)
# 稍后再次查询所有节点状态都转为上线
pcs cluster status
# 将产生以下输出 >>
# Cluster Status:
# Cluster Summary:
# * Stack: corosync
# * Current DC: havms21.vms.example.com (version 2.1.2-ada5c3b36e2) - partition with quorum
# * Last updated: Fri May 24 07:37:45 2024
# * Last change: Fri May 24 07:37:03 2024 by hacluster via crmd on havms21.vms.example.com
# * 3 nodes configured
# * 0 resource instances configured
# Node List:
# * Online: [ havms21.vms.example.com havms22.vms.example.com havms23.vms.example.com ]
#
# PCSD Status:
# havms23.vms.example.com: Online
# havms21.vms.example.com: Online
# havms22.vms.example.com: Online
4) 允许群集在节点系统引导时运行
# 在所有节点上运行
pcs cluster enable --all
# 将产生以下输出 >>
# havms21.vms.example.com: Cluster Enabled
# havms22.vms.example.com: Cluster Enabled
# havms23.vms.example.com: Cluster Enabled
创建集群资源
Fence-Agent
当一个节点不能正常响应时,就需要一个机制,将工作不正常的节点排除在外,避免影响正常集群运行(比如:脑裂)。这种隔离机制被称为 fence ,在集群中执行隔离具体操作的组件叫做 fence-agent 。
在此前的准备工作阶段,已经安装了两个 fence-agent: fence-agents-drac5 和 fence-agents-virsh,所以这里跳过安装步骤。
pcs 提供了一些指令用于查询、监测 fence-agent 。
# 检查可以用的 snoith
pcs stonith list [<filter>]
# ...
# external/libvirt - libvirt STONITH device
# ...
# fence_virsh - Fence agent for virsh
# ...
# ssh - SSH STONITH device
# ...
# 查看指定 snoith 的属性描述
pcs stonith describe fence_virsh
# ...
# pcs 状态
pcs status
# >>
# Cluster name: k3sbackend
#
# WARNINGS:
# No stonith devices and stonith-enabled is not false
#
# Cluster Summary:
# * Stack: corosync
# * Current DC: daemh2ha-vms11.vms.example.com (version 2.1.2-ada5c3b36e2) - partition with quorum
# * Last updated: Tue May 2 05:05:50 2023
# * Last change: Mon May 1 15:07:30 2023 by hacluster via crmd on daemh2ha-vms11.vms.example.com
# * 3 nodes configured
# * 0 resource instances configured
#
# Node List:
# * Online: [ daemh2ha-vms11.vms.example.com daemh3ha-vms12.vms.example.com daemh4ha-vms13.vms.example.com ]
#
# Full List of Resources:
# * No resources
#
# Daemon Status:
# corosync: active/enabled
# pacemaker: active/enabled
# pcsd: active/enabled
Shoot The Other Node In The Head (STONITH)
STONITH 是一类 fence 组件,正如命名,对脑死的主机一枪爆头(开发者实锤丧尸题材粉了,但是取名的确简洁、贴切)
创建用户
用于执行 Stonith 操作的账户,应该在目标主机上创建。如果使用 iDARC 等设备操作主机,则应在 iDARC 系统中创建用户;这里以 kvm 虚拟机组成的集群为例子:在虚拟机所在的物理主机上创建用户。
useradd stonithadm
mkdir -p /home/stonithadm/.ssh
ssh-keygen -t ed25519 -f /home/stonithadm/.ssh/stonithamd-key -N '' -C 'stonith fence virsh'
为非 root 用户配置环境参数
如果 用户不是 root 用户,需要额外的工作用以创建运行环境。
{
UNM=stonithadm
usermod $UNM -G kvm,libvirt,qemu
mkdir -p /home/$UNM/.config/libvirt/
cp -f /etc/libvirt/libvirt.conf /home/$UNM/.config/libvirt/
chown $UNM:$UNM /home/$UNM/.config -R
echo "export LIBVIRT_DEFAULT_URI=qemu:///system" >> /home/$UNM/.bashrc
}
配置免密 sudo
# 编辑 sudo, 配置新用户免密
visudo
# >>
# Host_Alias ha-cluster = havms21, havms22, havms23
# Cmnd_Alias VIRTCLI = /usr/bin/virsh
# 从集群主机上登录并获取 root 身份
# stonithadm ha-cluster=(root) NOPASSWD: VIRTCLI
在集群中创建 Stonith 资源
在集群中配置了 Stonith 资源,即允许集群使用以上资源建立围栏。
pcs stonith create stonith-s02 fence_virsh \
pcmk_host_check="static-list" \
pcmk_host_list="havms21" \
ipaddr="192.168.1.226" \
ssh=true \
use_sudo="1" \
login="stonithadm" \
identity_file="/home/stonithadm/.ssh/stonithamd-key"
pcs stonith create stonith-s03 fence_virsh \
pcmk_host_check="static-list" \
pcmk_host_list="havms22" \
ipaddr="192.168.1.227" \
ssh=true \
use_sudo="1" \
login="stonithadm" \
identity_file="/home/stonithadm/.ssh/stonithamd-key"
pcs stonith create stonith-s04 fence_virsh \
pcmk_host_check="static-list" \
pcmk_host_list="havms23" \
ipaddr="192.168.1.228" \
ssh=true \
use_sudo="1" \
login="stonithadm" \
identity_file="/home/stonithadm/.ssh/stonithamd-key"
# 配置排除约束
pcs constraint location stonith-s02 avoids havms21.vms.example.com=INFINITY
pcs constraint location stonith-s03 avoids havms22.vms.example.com=INFINITY
pcs constraint location stonith-s04 avoids havms23.vms.example.com=INFINITY
Stonith 要点总结
- 为每个 Host 节点配置一个 stonith
- Host 节点上的 fence_agent 可以配置多个 plug / port
- 目标主机上应将 fence 用户配置为免密使用 virsh
- use_sudo 应配置为 use_sudo="1"
- 非root用户需要额外的配置
异常与调试
至此高可用集群即配置完毕,以下是配置过程中可能用到的部分排错方法。
销毁集群
当需要完全重置集群时,可使用 pcs cluster destory 指令,完全销毁所有集群配置。由于销毁后的主机脱离集群,所以这个命令应该在集群中的每一台主机上执行。
检查 corosync 消息状态
corosync-quorumtool -si
Quorum information
------------------
Date: Mon May 1 15:10:29 2023
Quorum provider: corosync_votequorum
Nodes: 3
Node ID: 1
Ring ID: 1.12
Quorate: Yes
Votequorum information
----------------------
Expected votes: 3
Highest expected: 3
Total votes: 3
Quorum: 2
Flags: Quorate
Membership information
----------------------
Nodeid Votes Name
1 1 192.168.1.252 (local)
2 1 192.168.1.253
3 1 192.168.1.254
验证 fence_virsh 功能
** 通过 fence_virsh 执行指令 **
fence_virsh -a 192.168.1.228 -l stonithadm -x -o list -k /home/stonithadm/.ssh/stonithamd-key
手动隔离节点 (慎重,隔离以后需要恢复集群状态)
# 手动隔离节点
pcs stonith fence havms21 [--off]
参考: RHEL Chapter 2. Getting started with Pacemaker Oracle Linux: 使用 Gluster 和 Oracle Linux 创建高可用性的 NFS 服务 Chapter 2. Getting started with Pacemaker Ubuntu HA - Pacemaker Fence Agents corosync架构详解 How to configure fence_virsh in a Red Hat High Availability cluster with pacemaker? - Red Hat Customer Portal Testing a fence device. fence_virsh --how does it work? What's meaning of ipaddr, port at this segment and how to use/set fence_virsh? Ubuntu HA - Pacemaker Fence Agents Configuring fencing in a Red Hat High Availability cluster Ubuntu High Availability - Corosync, Pacemaker & Shared Disk Environment