[toc]
集群架构-用keepalived配置高可用集群
扩展 heartbeat和keepalived比较 DRBD工作原理和配置 mysql+keepalived
一、集群介绍
根据功能划分为两大类:高可用和负载均衡;
高可用集群通常为两台服务器,一台工作,另外一台作为冗余,当提供服务的机器宕机,冗余将接替继续提供服务;
实现高可用的开源软件有:heartbeat、keepalived; 负载均衡集群,需要有一台服务器作为分发器,它负责把用户的请求分发给后端的服务器处理,在这个集群里,除了分发器外,就是给用户提供服务的服务器,这些服务器数量至少为2;
实现负载均衡的开源软件有LVS、keepalived、haproxy、nginx,商业的有F5、Netscaler。
二、用keepalived搭建高可用集群
在这里我们使用keepalived来实现高可用集群,因为heartbeat在centos6上有一个问题,影响实验效果
keepalived通过VRRP(Virtual Router Redundancy Protocl)来实现高可用。
在这个协议里会将多台功能相同的路由器组成一个小组,这个小组里会有1个master角色和N(N>=1)个backup角色。
master会通过组播的形式向各个backup发送VRRP协议的数据包,当backup收不到master发来的VRRP数据包时,就会认为master宕机了。此时就需要根据各个backup的优先级来决定谁成为新的mater。
keepalived要有三个模块,分别是core、check和vrrp。其中core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析,check模块负责健康检查,vrrp模块是来实现VRRP协议的。
keepalived 负载均衡的框架是依赖于著名的并且被广泛使用的 Linux Virtual Server(LVS 的 ipvs)内核模块提供的 Layer 4(OSI 参考模型的第四层,传输层)上的负载均衡。keepalived 实现了一套通过对服务器池(也就是Real Server 池,Server pool)健康状态来动态地、自动维护的管理被负载均衡的服务器池的 checker。
而 keepalived 高可用(High-available)是通过 VRRP 协议来实现的,VRRP 在路由器的故障转移中是非常基础、常用的,而 keepalived 实现了一套 hooks 为 VRRP finite state machine 提供底层,高速的协议互动。
keepalived 框架可以被用于独立的亦或者是全部一起使用来提供弹性服务的基础设施,并且是一个免费,开源的软件。总的来说它能为我们提供这样一些功能:
- 在 LVS 框架上扩展,二者具备良好的兼容性。
- 通过对服务器池的健康检查,对失效机器的故障隔离与通知。
- 通过 VRRP 实现的负载均衡器之间的切换,达到高可用
通过结构图我们了解到 keepalived 涉及到内核空间的两个网络功能,分别是:
- IPVS:LVS 的 IP 负载均衡技术的使用
- NETLINK:提供高级路由及其他相关的网络功能
在用户空间主要分为4个部分,分别是Scheduler I/O Multiplexer、Memory Mangement、Control Plane 和Core components。
- Scheduler I/O Multiplexer:一个I/O复用分发调度器,它负责安排keepalived 所有内部的任务请求。
- Memory Management:一个内存管理机制,这个框架提供的访问内存的一些通用方法。
- Control Plane 是 keepalived 的控制面板,可以实现对配置文件进行编译和解析,keepalived的配置文件解析比较特殊,它只有在用到某模块时才解析相应的配置。
- Core components 是 keepalived 要核心组件,包含了一系列的功能模块,
而其中就会有这样的一些模块:
- WatchDog:监控checkers和VRRP进程的状况;
- Checkers:真实服务器的健康检查 health checking,是 keepalived 最主要的功能;
- VRRP Stack:负载均衡器之间的切换;
- IPVS wrapper:设定规则到内核 ipvs 的接口;
- Netlink Reflector:设定 vrrp 的vip地址等路由相关的功能。
Keepalived 原理
通过上诉我们了解到 keepalived 主要功能实现还是依赖于 LVS 与 VRRP。LVS 我们已经知道是什么了。但是 VRRP 又是什么?
最早的 VRRP 是由 IETF 提出的解决局域网中配置静态网关出现单点失效现象的路由协议,使得在发生故障而进行设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。VRRP 协议需要具有IP地址备份,优先路由选择,减少不必要的路由器间通信等功能。
VRRP 协议的功能实现是将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP,而在路由器组内部,通过算法多角度的选举此时的 MASTER 机器作为这个对外 IP 的拥有者,也就是 ARP 的解析,MASTER 的 MAC 地址与 IP 相互对应,其他设备不拥有该 IP,状态是 BACKUP,而 BACKUP 除了接收 MASTER 的 VRRP 状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP 将立即接管原先 MASTER 的网络功能。从而达到了无缝的切换,而用户并不会知道网络设备出现了故障。
简单来说,vrrp 就是让外界认为只有一个网关在工作(在逻辑结构上将两台虚拟成一台设备),当一般情况下,所有的网络功能都通过 Master 来处理,而其突然出问题的时候,有一个备胎能够立马接替他的工作,而不用用户手动修改自己的电脑配置
而上文所说的 Master,也就是我们的主路由(也就是当前工作的路由)是通过主备路由之间相互通信,通过其 route_id、优先级等来综合判定从而选举出来的,
主路由会每隔 1 秒(这个值可以修改配置)发送 vrrp 包通知 Backup 路由自己还是健康的存活着,而 Backup 路由若是3秒(这个值可以修改)没有收到主路由的 vrrp 包,便会将自己切换成主路由来接替工作。
而若是原主路由突然复活了,在接收到当前主路由发来的 vrrp 包是会从中解析其优先级的值,若是自己的优先级较高便会将自己切换成主路由,并告知当前的主路由,然后开始工作。而当前的路由便会将自己切换成 Backup。
如果优先级相等的话,将比较路由器的实际IP,IP值较大的优先权高;
不过如果对外的虚拟路由器IP就是路由器本身的IP的话,该路由器始终将是MASTER,这时的优先级值为255。
当我们了解了 VRRP 的工作原理之后,我们会发现其实它与 LVS 的工作原理似乎差不多呀,都是虚拟出一个 IP 出来给别人,然后自己在内部通过某种机制来进行切换,这应该便是为什么它们有这么高的契合度的原因.
但是它们还是有区别的:
LVS 在后面的Server Pool 中每台都可以同时工作,而 VRRP 同时工作的机器只有一台,只有当一台出问题之后才会启用另外一台。
所以我们换着方式让两个工具相互结合,让 keepalived 工作在 Load Balancer 上,做好出口路由的高可用,LVS 在后端做好负载均衡,这样大大地提高了我们的服务质量,特别是在突然的大流量冲击下。
三、 用keepalived配置高可用集群
用keepalived配置高可用集群
- 准备两台机器Master和Backup
- 两台机器都执行yum install -y keepalived
- 两台机器都安装nginx,其中Mater上已经编译安装过nginx,backup上需要yum安装nginx: yum install -y nginx(或者源码编译)
- 设定vip为100
- 编辑master上keepalived配置文件,vim /etc/keepalived/keepalived.conf
- master上编辑nginx监控脚本,vim /usr/local/sbin/check_ng.sh
- 给脚本755权限
- systemctl start keepalived 启动服务,ip add查看vip地址
- Backup上编辑配置文件,vim /etc/keepalived/keepalived.conf;state和priority跟master有区别
- backup上编辑监控脚本,vim /usr/local/sbin/check_ng.sh
- 给脚本755权限
- backup上也启动服务 systemctl start keepalived
3.1 准备工作
准备两台机器130和133,130作为master,133作为backup
两台机器都执行yum install -y keepalived
两台机器都安装nginx,其中130上已经编译安装过nginx,133上需要yum安装nginx
设定VIP为100(虚拟IP或者叫浮动IP),服务器靠这个VIP对外提供服务
准备阶段:先在backup上安装nginx
wget nginx安装包 nginx-1.12.1.tar.gztar zxvf nginx-1.12.1.tar.gzcd nginx-1.12.1/./configure --prefix=/usr/local/nginxmake&make installvim /etc/init.d/nginxchmod 755 /etc/init.d/nginxchkconfig -add nginxchkconfig nginx onvim /usr/local/nginx/conf/nginx.conf/usr/local/nginx/sbin/nginx -t/etc/init.d/nginx start
3.2 配置master
a. 编辑keepalived配置(先清空后编辑)
[root@xavi ~]# > /etc/keepalived/keepalived.conf[root@xavi ~]# cat /etc/keepalived/keepalived.conf # Configuration File for keepalivedglobal_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}
- 清空后编辑
[root@xavi ~]# vim /etc/keepalived/keepalived.conf#出现问题时发送邮件global_defs { notification_email { xavi@xavilinux.com //定义接收邮件人 } notification_email_from root@xavilinux.com //定义发邮件的地址 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL}vrrp_script chk_nginx { script "/usr/local/sbin/check_ng.sh" # 自定义脚本,该脚本为监控Nginx服务的脚本 interval 3 #检测脚本,检测时间3s一次}vrrp_instance VI_1 { state MASTER //定义角色为master interface ens33#vrrp协议使用的网卡是ens33 virtual_router_id 51 priority 100 // 权重100,此数值要大于backup advert_int 1 authentication { auth_type PASS auth_pass xavilinux //定义密码 } virtual_ipaddress { 192.168.72.100 # 定义VIP,主从都要用到 } track_script { chk_nginx #加载检查脚本,这里和上面的vrr_script后面的字符串保持一致 }
b. 定义监控Nginx服务脚本
[root@xavi ~]# vim /usr/local/sbin/check_ng.sh#!/bin/bash#时间变量,用于记录日志d=`date --date today +%Y%m%d_%H:%M:%S`#计算nginx进程数量n=`ps -C nginx --no-heading|wc -l`#如果进程为0,则启动nginx,并且再次检测nginx进程数量,#如果还为0,说明nginx无法启动,此时需要关闭keepalivedif [ $n -eq "0" ]; then /etc/init.d/nginx start n2=`ps -C nginx --no-heading|wc -l` if [ $n2 -eq "0" ]; then echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log systemctl stop keepalived fifi
脚本上systemctl stop keepalived关闭keepalived服务是为了启动backup上的keepaliveed时候 不会出现“脑裂”现象。即master和backup的keepaliveed各自抢占资源,如VIP,外部访问时候出现两台机器同个ip。
脑裂”,在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样,争抢“共享资源”、争起“应用服务”,就会发生严重后果——或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏如何判断脑裂?分别在两台机查看当前服务器是否拥有虚拟IP,如果两台服务器都拥有,则说明发生了脑裂,证明目前双机通信出现问题,产生此问题的原有在于 两台服务器都探测不到组内其他服务器的状态(心跳请求无法正常响应),私自判定另一台服务器挂起,则抢占虚拟IP,脑裂的出现是不被允许的,解决此问题的方法为检查防火墙设置(关闭防火墙)或者使用串口通信。
c. 给该脚本赋予755权限,否则无法被keepalived调用
[root@xavi ~]# chmod 755 /usr/local/sbin/check_ng.sh[root@xavi ~]# systemctl start keepalived
查看
[root@xavi ~]# ps aux |grep keeproot 3037 0.0 0.0 120740 1404 ? Ss 22:07 0:00 /usr/sbin/keepalived -Droot 3038 0.0 0.1 127480 3284 ? S 22:07 0:00 /usr/sbin/keepalived -Droot 3039 0.0 0.1 131676 3028 ? S 22:07 0:01 /usr/sbin/keepalived -Droot 5195 0.0 0.0 112684 976 pts/1 S+ 22:44 0:00 grep --color=auto keep[root@xavi ~]# ps aux |grep nginxroot 5239 0.0 0.0 112680 972 pts/1 S+ 22:45 0:00 grep --color=auto nginx[root@xavi ~]# /etc/init.d/nginx startStarting nginx (via systemctl): [ 确定 ][root@xavi ~]# ps aux |grep nginxroot 5287 0.0 0.0 46004 1276 ? Ss 22:46 0:00 nginx: master process /usr/local/ngin/sbin/nginx -c /usr/local/nginx/conf/nginx.confnobody 5288 0.0 0.2 50576 4252 ? S 22:46 0:00 nginx: worker processnobody 5289 0.0 0.2 50576 4252 ? S 22:46 0:00 nginx: worker processroot 5301 0.0 0.0 112684 972 pts/1 S+ 22:46 0:00 grep --color=auto nginx
开启keepalived服务后,停止防火墙,关闭SElinux
[root@ying01 ~]# systemctl stop firewalld[root@ying01 ~]# getenforce Disabled[root@ying01 ~]# iptables -nvLChain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination [root@xavi ~]# iptables -F[root@xavi ~]# iptables -nvLChain INPUT (policy ACCEPT 9 packets, 616 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 5 packets, 556 bytes) pkts bytes target prot opt in out source destination
3.3 配置backup
a. 修改keepalived配置
[root@xavi-002 ~]# vim /etc/keepalived/keepalived.conf [root@xavi-002 ~]# cat /etc/keepalived/keepalived.conf global_defs { notification_email { xavi@xavilinux.com } #出现问题时发送邮件 notification_email_from root@xavilinux.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL}#上述自定义参数vrrp_script chk_nginx { script "/usr/local/sbin/check_ng.sh"# 自定义脚本,该脚本为监控Nginx服务的脚本 interval 3}#检测脚本,检测时间3s一次vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 # 权重90,此数值要大于backup advert_int 1 authentication { auth_type PASS auth_pass xavilinux>com } virtual_ipaddress { 192.168.72.100 }# 定义VIP track_script { chk_nginx }# 定义监控chk_nginx}
b. 添加Nginx服务监控脚本
[root@xavi-002 ~]# vim /usr/local/sbin/check_ng.sh #时间变量,用于记录日志d=`date --date today +%Y%m%d_%H:%M:%S`#计算nginx进程数量n=`ps -C nginx --no-heading|wc -l`#如果进程为0,则启动nginx,并且再次检测nginx进程数量,#如果还为0,说明nginx无法启动,此时需要关闭keepalivedif [ $n -eq "0" ]; then systemctl start nginx /etc/init.d/nginx start if [ $n2 -eq "0" ]; then echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log systemctl stop keepalived fifi
[root@xavi-002 ~]# chmod 755 /usr/local/sbin/check_ng.sh [root@xavi-002 ~]# systemctl start keepalived
4.测试高可用
确定两台机器nginx差异
关闭master、backup防火墙和selinux
[root@xavi nginx-1.12.1]# systemctl stop firewalld[root@xavi nginx-1.12.1]# getenforceDisabled[root@xavi nginx-1.12.1]# iptables -nvLChain INPUT (policy ACCEPT 56032 packets, 27M bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED 0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0 0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable 0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachableChain OUTPUT (policy ACCEPT 42392 packets, 46M bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68[root@xavi nginx-1.12.1]# iptables -F[root@xavi nginx-1.12.1]# iptables -nvLChain INPUT (policy ACCEPT 7 packets, 468 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 5 packets, 572 bytes) pkts bytes target prot opt in out source destination
启动master keepalived服务,查看master vip:ip add是否为192.168.72.100。
[root@xavi ~]# systemctl start keepalived[root@xavi ~]# ip add1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ea:14:79 brd ff:ff:ff:ff:ff:ff inet 192.168.72.130/24 brd 192.168.72.255 scope global ens33 valid_lft forever preferred_lft forever inet 192.168.72.100/32 scope global ens33 //以显示VIP地址 valid_lft forever preferred_lft forever inet6 fe80::1d7a:ffe8:8235:a2a5/64 scope link valid_lft forever preferred_lft forever
查看nginx服务进程,这里虽然没有启动,但是keepalived会自动拉起来nginx服务了
[root@xavi ~]# ps aux|grep nginxroot 2694 0.0 0.0 20500 608 ? Ss 22:21 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.confnobody 2695 0.0 0.1 25028 3232 ? S 22:21 0:00 nginx: worker processnobody 2696 0.0 0.1 25028 3232 ? S 22:21 0:00 nginx: worker processroot 5837 0.0 0.0 112684 976 pts/0 S+ 22:45 0:00 grep --color=auto nginx
如何区分主和从上的nginx?
Mater机器,是源码包安装的nginx
[root@xavi ~]# mv /usr/local/nginx/html/index.html /usr/local/nginx/html/index.html.bak[root@xavi ~]# vim /usr/local/nginx/html/index.htmlThis is the Master site!
Backup机器,是源码包安装的nginx
[root@xavi-002 ~]# mv /usr/local/nginx/html/index.html /usr/local/nginx/html/index.html.bak[root@xavi-002 ~]# vim /usr/local/nginx/html/index.htmlThis is for Backup website!
验证高可用是否生效:
访问master主页
访问VIP主页
把master的keepalived关闭,模拟master宕机,查看VIP,已经不存在
[root@xavi ~]# systemctl stop keepalived[root@xavi ~]# ip add1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:ea:14:79 brd ff:ff:ff:ff:ff:ff inet 192.168.72.130/24 brd 192.168.72.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::1d7a:ffe8:8235:a2a5/64 scope link valid_lft forever preferred_lft forever
查看backup机器上的VIP信息:
[root@xavi-002 ~]# ip add1: lo:mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:66:d4:59 brd ff:ff:ff:ff:ff:ff inet 192.168.72.133/24 brd 192.168.72.255 scope global ens33 valid_lft forever preferred_lft forever inet 192.168.72.100/32 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::7276:ecaf:14ca:5827/64 scope link valid_lft forever preferred_lft forever
[root@xavi-002 ~]# curl -I 192.168.72.100HTTP/1.1 200 OKServer: nginx/1.12.2Date: Wed, 12 Sep 2018 15:51:09 GMTContent-Type: text/htmlContent-Length: 3700Last-Modified: Tue, 06 Mar 2018 09:26:21 GMTConnection: keep-aliveETag: "5a9e5ebd-e74"Accept-Ranges: bytes[root@xavi-002 ~]# curl -I 192.168.72.133HTTP/1.1 200 OKServer: nginx/1.12.2Date: Wed, 12 Sep 2018 15:51:43 GMTContent-Type: text/htmlContent-Length: 3700Last-Modified: Tue, 06 Mar 2018 09:26:21 GMTConnection: keep-aliveETag: "5a9e5ebd-e74"Accept-Ranges: bytes[root@xavi-002 ~]# curl -I 192.168.72.130curl: (7) Failed connect to 192.168.72.130:80; 拒绝连接
总结
在生产环境中,可能会用到2-3台backup角色, vim /etc/keepalived/keepalived.conf 这里面的权重调成不通级别,权重越高优先级越高!除了nginx服务的话,还可以做MySQL的高可用集群服务。(做mysql的高可用,一定要保证两边的数据一致)