20.高可用配置
在本地部署中实现 NGINX 实例的高可用性,在基于 keepalive 和 VRRP 的解决方案中配置主动-被动对。
本文介绍如何使用基于 keepalived 的解决方案在本地部署中配置 NGINX 实例的高可用性。
注意: 此解决方案设计用于可通过标准操作系统调用控制 IP 地址的环境中,而通常不适用于通过与云基础架构接口来控制 IP 地址的云环境。
基于保持的高可用性支持(High Availability Support Based on keepalived)
keepalive 开源项目包括三个组件:
- Linux 服务器的
keepalived守护程序(daemon)。 - 用于管理虚拟路由器(虚拟 IP 地址或 VIP )的虚拟路由器冗余协议 (Virtual Router Redundancy Protocol )(VRRP) 的实现。 VRRP 确保始终存在主节点。备份节点侦听来自主节点的 VRRP 通告数据包。如果备份节点在超过配置的通告间隔三倍的时间段内未收到通告数据包,则备份节点将接管为主节点,并将配置的 VIP 分配给自身。
- 一种运行状况检查工具,用于确定服务(例如,Web 服务器、PHP 后端或数据库服务器)是否已启动并正常运行。
如果主节点上的服务未达到配置的运行状况检查次数,
keepalived则会将虚拟 IP 地址从主节点重新分配给备份(被动)节点。
配置高可用性(Configuring High Availability)
以 root用户身份在两个节点上运行nginx-ha-setup脚本(该脚本分布在nginx-ha-keepalive包中,除了基本的NGINX Plus包之外,还必须安装该包)。该脚本配置了一个高度可用的 NGINX Plus 环境,其中一对主动-被动节点充当主节点和备份节点。它会提示输入以下数据:
- 本地和远程节点的 IP 地址(其中一个将配置为主节点,另一个将配置为备份节点)
- 一个额外的可用 IP 地址,用作集群终 端节点的(浮动)VIP
keepalived守护进程的配置记录在 /etc/keepalived**/keepalived.conf** 中。文件控制通知设置中的配置块、要管理的 VIP 以及用于测试依赖 VIP 的服务的健康检查。以下是 nginx-ha-setup 脚本在 CentOS 7 机器上创建的配置文件。请注意,这不是NGINX Plus配置文件,因此语法不同(例如,分号不用于分隔指令)。
global_defs {
vrrp_version 3
}
vrrp_script chk_manual_failover {
script "/usr/libexec/keepalived/nginx-ha-manual-failover"
interval 10
weight 50
}
vrrp_script chk_nginx_service {
script "/usr/libexec/keepalived/nginx-ha-check"
interval 3
weight 50
}
vrrp_instance VI_1 {
interface eth0
priority 101
virtual_router_id 51
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.100.100
unicast_peer {
192.168.100.101
}
virtual_ipaddress {
192.168.100.150
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/libexec/keepalived/nginx-ha-notify"
}
描述整个配置超出了本文的范围,但有几点值得注意:
- HA 设置中的每个节点都需要自己的配置文件副本,其中包含适用于节点角色(主节点或备份)的
priority,unicast_src_ip和unicast_peer指令的值。 priority该指令控制哪个主机成为主主机。notify该指令命名分发中包含的 通知脚本,该脚本可用于在发生状态转换或故障时生成系统日志消息(或其他通知)。vrrp_instance VI_1块中virtual_router_id指令的值51是示例值;根据需要对其进行更改,使其在您的环境中是唯一的。- 如果您的本地网络中运行了多对
keepalived实例(或其他 VRRP 实例),请为每个实例创建一个vrrp_instance块,并具有唯一的名称(如示例中VI_1所示)和virtual_router_id编号。
有关指令的更多信息,请参见 keepalive 手册页。keepalived
使用运行状况检查脚本控制哪个服务器是主服务器(Using a Health-Check Script to Control Which Server Is Primary)
keepalived中没有屏蔽机制。如果一对中的两个节点彼此不认识,则每个节点都假定它是主节点,并将 VIP 分配给自己。为了防止这种情况,配置文件定义了一个名为 chk_nginx_service脚本执行机制,该机制定期运行脚本以检查NGINX是否正常运行,并根据脚本的返回代码调整本地节点的优先级。代码 0(零)表示操作正确,1代码(或任何非零代码)表示错误。
在脚本的示例配置中,weight指令设置为 50,这意味着当检查脚本成功时(并暗示返回代码 0):
- 第一个节点(其基本优先级为
101)的优先级设置为151。 - 第二个节点(其基本优先级为
100)的优先级设置为150。
第一个节点具有更高的优先级(在本例中 151)并成为主节点。
interval该指令指定检查脚本的执行频率,以秒为单位(在示例配置文件中为 3 秒)。请注意,如果达到超时,则检查将失败(默认情况下,超时与检查间隔相同)。
riseand fall指令(未在示例配置文件中使用)指定在执行操作之前脚本必须成功或失败的次数。
nginx-ha-keepalive软件包提供的 nginx-ha-check脚本检查NGINX Plus是否启动。我们建议根据本地设置创建其他脚本。
显示节点状态(Displaying Node State)
要查看哪个节点当前是给定 VIP 的主节点,请运行定义 VRRP 实例的接口的命令 ip addr show(在以下命令中,节点 centos7-1 和 centos7-2 上的接口 eth0 ):
centos7-1 $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
UP qlen 1000
link/ether 52:54:00:33:a5:a5 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.100/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 3071sec preferred_lft 3071sec
inet 192.168.100.150/32 scope global eth0
valid_lft forever preferred_lft forever
centos7-2 $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
UP qlen 1000
link/ether 52:54:00:33:a5:87 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.101/24 brd 192.168.122.255 scope global eth0
valid_lft forever preferred_lft forever
在此输出中,centos7-1 的第二 inet行表示它是主节点 – 定义的 VIP (192.168.100.150) 分配给它。其他 inet行显示主节点的真实 IP 地址 (192.168.100.100) 和备份节点的 IP 地址 (192.168.100.101)。
节点的当前状态记录在本地 /var/run/nginx-ha-keepalived.state 文件中。您可以使用 cat该命令显示它:
centos7-1 $ cat /var/run/nginx-ha-keepalived.state
STATE=MASTER
centos7-2 $ cat /var/run/nginx-ha-keepalived.state
STATE=BACKUP
在 nginx-ha-keepalive 软件包的 1.1 及更高版本中,可以使用以下命令将 VRRP 扩展统计信息和数据转储到文件系统:
centos7-1 $ service keepalived dump
此命令将信号发送到正在运行的 keepalived进程,以将当前状态写入 /tmp/keepalived.stats 和 / tmp/keepalived.data 。
5.强制更改状态(Forcing a State Change)
要强制主节点成为备份节点,请对其运行以下命令:
$ service keepalived stop
当它关闭时,keepalived会向备份节点发送优先级 0的 VRRP 数据包,这会导致备份节点接管 VIP。
如果您的集群使用的是 nginx-ha-keepalive 软件包的 1.1 版,这是一种更简单的强制状态更改的方法:
$ touch /var/run/keepalived-manual-failover
此命令创建一个由 vrrp_script chk_manual_failover块中定义的脚本检查的文件。如果文件存在,keepalived则降低主节点的优先级,这会导致备份节点接管 VIP。
添加更多虚拟 IP 地址
nginx-ha-setup脚本创建的配置非常基本,并使单个IP地址高度可用。
要使多个 IP 地址高度可用,请执行以下操作:
-
将每个新 IP 地址添加到两个节点上的 /etc/keepalived/keepalived.conf 文件中的
virtual_ipaddress块中:virtual_ipaddress {
192.168.100.150
192.168.100.200
}virtual_ipaddress块中的语法复制ip实用程序的语法。(The syntax in the
virtual_ipaddressblock replicates the syntax of theiputility.) -
在两个节点上运行
service keepalived reload该命令以重新加载保持活动服务:centos7-1 $ service keepalived reload
centos7-2 $ service keepalived reload
IPv4 和 IPv6 的双栈配置(Dual-Stack Configuration of IPv4 and IPv6)
keepalived在版本 1.2.20 及更高版本(以及 nginx-ha-keepalive 包的 1.1 及更高版本)中,keepalived不再支持在一个 VRRP 实例(virtual_ipaddress块)中混合使用 IPv4 和 IPv6 地址,因为这违反了 VRRP 标准。
有两种方法可以使用 VRRP 配置双堆栈 HA:
-
添加具有一个家庭地址的
virtual_ipaddress_excluded块。 (Add thevirtual_ipaddress_excludedblock with the addresses of one family.)vrrp_instance VI_1 {
...
unicast_src_ip 192.168.100.100
unicast_peer {
192.168.100.101
}
virtual_ipaddress {
192.168.100.150
}
...
virtual_ipaddress_excluded {
1234:5678:9abc:def::1
}
...
}这些地址从 VRRP 通告中排除,但仍由
keepalived管理,并在状态更改时添加或删除。 -
为 IPv6 地址添加另一个 VRRP 实例。 主节点上 IPv6 地址的 VRRP 配置为:
vrrp_instance VI_2 {
interface eth0
priority 101
virtual_router_id 51
advert_int 1
accept
unicast_src_ip 1234:5678:9abc:def::3
unicast_peer {
1234:5678:9abc:def::2
}
virtual_ipaddress {
1234:5678:9abc:def::1
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/libexec/keepalived/nginx-ha-notify"
}请注意,VRRP 实例可以使用相同的
virtual_router_id,因为 VRRP IPv4 和 IPv6 实例完全相互独立。
保持和 VRRP 故障排除
keepalived守护程序使用 syslog该实用程序进行日志记录。在基于 CentOS、RHEL 和 SLES 的系统上,输出通常写入 /var/log/ messages ,而在基于 Ubuntu 和 Debian 的系统上,输出通常 写入 /var/ log/syslog 。日志条目记录事件,例如 keepalived守护程序的启动和状态转换。
以下是一些示例条目,显示 keepalived守护进程启动和节点将 VRRP 实例转换为主状态(为了便于阅读,centos7-1 主机名已从第一行之后的每一行中删除):
Feb 27 14:42:04 centos7-1 systemd: Starting LVS and VRRP High Availability Monitor...
Feb 27 14:42:04 Keepalived [19242]: Starting Keepalived v1.2.15 (02/26,2015)
Feb 27 14:42:04 Keepalived [19243]: Starting VRRP child process, pid=19244
Feb 27 14:42:04 Keepalived_vrrp [19244]: Registering Kernel netlink reflector
Feb 27 14:42:04 Keepalived_vrrp [19244]: Registering Kernel netlink command channel
Feb 27 14:42:04 Keepalived_vrrp [19244]: Registering gratuitous ARP shared channel
Feb 27 14:42:05 systemd: Started LVS and VRRP High Availability Monitor.
Feb 27 14:42:05 Keepalived_vrrp [19244]: Opening file '/etc/keepalived/keepalived.conf '.
Feb 27 14:42:05 Keepalived_vrrp [19244]: Truncating auth_pass to 8 characters
Feb 27 14:42:05 Keepalived_vrrp [19244]: Configuration is using: 64631 Bytes
Feb 27 14:42:05 Keepalived_vrrp [19244]: Using LinkWatch kernel netlink reflector...
Feb 27 14:42:05 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) Entering BACKUP STATE
Feb 27 14:42:05 Keepalived_vrrp [19244]: VRRP sockpool: [ifindex(2), proto(112), unicast(1), fd(14,15)]
Feb 27 14:42:05 nginx-ha-keepalived: Transition to state 'BACKUP ' on VRRP instance 'VI_1 '.
Feb 27 14:42:05 Keepalived_vrrp [19244]: VRRP_Script(chk_nginx_service) succeeded
Feb 27 14:42:06 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) forcing a new MASTER election
Feb 27 14:42:06 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) forcing a new MASTER election
Feb 27 14:42:07 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 27 14:42:08 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 27 14:42:08 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) setting protocol VIPs.
Feb 27 14:42:08 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.100.150
Feb 27 14:42:08 nginx-ha-keepalived: Transition to state 'MASTER ' on VRRP instance 'VI_1 '.
Feb 27 14:42:13 Keepalived_vrrp [19244]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.100.150
如果系统日志未说明问题的根源,请使用以下参数运行命令 tcpdump以显示在本地网络上发送的 VRRP 通告:
$ tcpdump -vvv -ni eth0 proto vrrp
如果本地网络上有多个 VRRP 实例,并且希望过滤输出以仅包含给定服务的节点与其对等方之间的流量,请包含 host该参数并指定由 keepalived.conf 文件中的 unicast_peer块定义的对等方的 IP 地址,如以下示例所示:
centos7-1 $ tcpdump -vvv -ni eth0 proto vrrp and host 192.168.100.101
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:48:27.188100 IP (tos 0xc0, ttl 255, id 382, offset 0, flags [none],
proto VRRP (112), length 40)
192.168.100.100 > 192.168.100.101: vrrp 192.168.100.100 >
192.168.100.101: VRRPv2 , Advertisement , vrid 51, prio 151,
authtype simple , intvl 1s, length 20, addrs: 192.168.100.150 auth
"f8f0e511"
输出中的几个字段对于调试很有用:
vrid– 虚拟路由器 ID(由virtual_router_id指令设置)prio– 节点的优先级(由priority指令设置)authtype– 正在使用的身份验证类型(由authentication指令设置)intvl– 发送广告的频率(由advert_int指令设置)auth– 发送的身份验证令牌(由auth_pass指令设置)
其他配置示例
nginx-ha-keepalive 包在 /usr/share/doc/nginx-ha-keepalive 目录中包含更多配置示例。