Keepalived 高可用

背景

VRRP协议(VirtualRouter Redundancy Protocol,虚拟路由几余协议)。它是实现路由高可用的一种通信协议,在这个协议里会将多台功能相同的路由器组成一个小组,这个小组里会有1个master(主)角色和N(N=1)个 backup(备用)角色。工作时 master 会通过组播的形式向各个 backup 发送VRRP 协议的数据包,当backup 收不到master 发来的VRRP 数据包时,就会认为 aster 宕机了。此时就需要根据各个 backup 的优先级来决定谁成为新的master。
而 keepalived 就是采用这种VRRP 协议实现的高可用。keepalived 要有三个模块,分别是 core、check 和 vrrp。其中 core 模块为 keepalived 的核心,负责主进程的启动、维护以及全局配置文件的加载和解析:check 模块负责健康检查;vrrp模块用来实现VRRP 协议。

安装keepalived

VRRP 协议有 1个master 角色和至少1个backup 角色,所以做本实验需要准备至少两台 Linux 机器。这里我们拿两台 Liux 虚拟机(30和40,其中30作为master,40作为 backup)来完成以下操作
在两节点上执行如下操作:

yum install -y keepalived

CentOS 默认的 yum 源里就有 keepalived 包,安装 keepalived 很简单,但重点在于配置,下面我们拿一个实际案例来阐述 keepalived 的高可用功能。

Keepalived+Nginx 实现Web高可用

节点规划

master 节点:192.168.15.30 

backup 节点:192.168.15.40 

VIP : 192.168.15.100

VIP的英文名字是“VirtualP”,即“虚拟IP”,也有人把它叫作“浮动IP”。因为这个IP是由 keepalived 给服务器配置上的,服务器靠这个VIP对外提供服务当master 机器宕机,VIP 被分配到 backup 上,这样用户看来是无感知的。

master 节点

#关闭防火墙及selinux
systemctl disable firewalld --now
sed -i "s/SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
setenforce 0
# 编辑 keepalived 配置文件
[root@master ~]# vim /etc/keepalived/keepalived.conf

global_defs {
router_id nginx_01      #标识本节点的名称
}


vrrp_script chk_nginx {
script "/usr/local/sbin/check_ng.sh"
interval 3             #每3秒检测一次nginx的运行状态
weight -20             #失败一次,将自己的优先级-20
}

vrrp_instance VI_1 {
state MASTER           # 状态,主节点为MASTER,备份节点为BACKUP
interface ens33        # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
virtual_router_id 51   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
mcast_src_ip 192.168.162.30     # 本机IP地址
priority 100                    # 节点优先级,值范围0~254,MASTER要比BACKUP高
advert_int 1                    # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
# 设置验证信息,两个节点必须一致
authentication {                # 认证相关信息
auth_type PASS                  # 认证类型 
auth_pass Abc@1234              # 密码的形式是一个字符串
}
# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个
virtual_ipaddress {
192.168.15.100
}

track_script {                    # 加载脚本
chk_nginx                         # nginx存活状态检测脚本
}
}

# 定义监控脚本
[root@master ~]# 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 进程数量
if [ $n -eq "0" ]; then
		systemctl start  nginx
		  n2=$(ps -C nginx --no-heading|wc -l)
		  #如果还为0,说明nginx无法启动,此时需要关闭keepalived
		  if [ $n2 -eq "0" ]; then
		  			echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log
		  			systemctl stop keepalived
		  fi
fi

# 赋予权限 (否则无法被keepalived调用)
[root@master ~]# chmod a+x /usr/local/sbin/check_ng.sh
# 启动 master 上的Keepalived
# 得先安装nginx服务,否则上面的脚本检测不到,以至于启不了keepalived服务
[root@master ~]# systemctl start keepalived
[root@master ~]# systemctl status keepalived
[root@master ~]# ip add

ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether 00:0c:29:a4:e8:22 brd ff:ff:ff:ff:ff:ff
   inet 192.168.15.30/24 brd 192.168.15.255 scope global noprefixroute ens33
      valid_lft forever preferred_lft forever
   `inet 192.168.15.100/32 scope global ens33`
      valid_lft forever preferred_lft forever
   inet6 fe80::9710:98b2:9ee2:c5f0/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
      
# 可以看到master上已经自动配置了192.168.15.100这个IP
# 添加nginx源
[root@master ~]# vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
# 下载 nginx 服务
[root@master ~]# yum install -y nginx
# 查看Nginx服务是否已经启动
[root@master ~]# ps aux | grep nginx
# 查看nginx服务
[root@master ~]# systemctl status nginx

backup 节点

#关闭防火墙及selinux
systemctl disable firewalld --now
sed -i "s/SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
setenforce 0
# 编辑配置文件
[root@backup ~]# vim /etc/keepalived/keepalived.conf

global_defs {
router_id nginx_01      #标识本节点的名称
}

vrrp_script chk_nginx {
script "/usr/local/sbin/check_ng.sh"
interval 3             #每3秒检测一次nginx的运行状态
weight -20             #失败一次,将自己的优先级-20
}

vrrp_instance VI_1 {
state BACKUP           # 状态,主节点为MASTER,备份节点为BACKUP
interface ens33        # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
virtual_router_id 51   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
mcast_src_ip 192.168.162.30     # 本机IP地址
priority 90                    # 节点优先级,值范围0~254,MASTER要比BACKUP高
advert_int 1                    # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
# 设置验证信息,两个节点必须一致
authentication {                # 认证相关信息
auth_type PASS                  # 认证类型 
auth_pass Abc@1234              # 密码的形式是一个字符串
}
# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个
virtual_ipaddress {
192.168.15.100
}

track_script {                    # 加载脚本
chk_nginx                         # nginx存活状态检测脚本
}
}

# 编辑监控脚本
[root@backup ~]# vim /usr/local/sbin/check_ng.sh

d=$(date --date today +%Y%m%d_%H:%M:%S)
n=$(ps -C nginx --no-heading|wc -l)
if [ $n -eq "0" ]; then
		systemctl start nginx
		n2=$(ps -C nginx --no-hedading|wc -l)
		if [ $n2 -eq "0" ]; then
					echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log
					systemctl stop keepalived
		fi
fi		
		
# 赋予权限
[root@backup ~]# chmod a+x /usr/local/sbin/check_ng.sh
# 添加nginx源
[root@backup ~]# vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
# 下载依赖包
[root@backup ~]# yum install -y epel-release 
# 安装nginx服务
[root@backup ~]# yum install -y nginx
# 启动keepalived服务
[root@backup ~]# systemctl start keepalived
[root@backup ~]# systemctl status keepalived
# 
[root@backup ~]# curl -I 192.168.15.30
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 19 Dec 2023 13:18:09 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Apr 2023 17:22:34 GMT
Connection: keep-alive
ETag: "6435975a-267"
Accept-Ranges: bytes
# 启动nginx
[root@backup ~]# systemctl status nginx
[root@backup ~]# systemctl start nginx

[root@backup ~]# curl -I 192.168.15.40
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 19 Dec 2023 13:19:22 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Apr 2023 17:22:34 GMT
Connection: keep-alive
ETag: "6435975a-267"
Accept-Ranges: bytes

# 查看VIP是否在master上
[root@backup ~]# curl -I 192.168.15.50
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 19 Dec 2023 13:23:33 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Apr 2023 17:22:34 GMT
Connection: keep-alive
ETag: "6435975a-267"
Accept-Ranges: bytes
验证
# 故意关掉master上的Nginx 查看状态
[root@master ~]# netstat -ntpl | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1837/nginx: master
# 关闭nginx服务
[root@master ~]# systemctl stop nginx --now
# 查看相关进程是否存在
[root@master ~]# netstat -ntpl | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6361/nginx: master
# 查看nginx状态
[root@master ~]# systemctl status nginx
# 查看 Nginx被启动的信息
[root@master ~]# cat /var/log/messages

# 模拟master宕机
[root@master ~]# iptables -I OUTPUT -p vrrp -j DROP 
# 加载完规则后,到 backup上查看是否设置VIP
[root@backup ~]# ip add

ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether 00:0c:29:a4:d6:be brd ff:ff:ff:ff:ff:ff
   inet 192.168.15.40/24 brd 192.168.15.255 scope global noprefixroute ens33
      valid_lft forever preferred_lft forever
   inet6 fe80::322d:1492:b1f8:d0b9/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
      
#等待几秒
[root@backup ~]# ip add

ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:a4:d6:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.15.40/24 brd 192.168.15.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    `inet 192.168.15.100/32 scope global ens33`
       valid_lft forever preferred_lft forever
    inet6 fe80::322d:1492:b1f8:d0b9/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

脑裂

脑裂(split-brain):指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。 对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(比如MySQL)的HA,必须要严格防止脑裂。

master和backup都绑定了VIP,对外服务会出现紊乱


# 关掉 master 上的keepalived服务
[root@master ~]# systemctl stop keepalived
# 直接访问VIP,判断 VIP 位置
curl -I 192.168.15.100

HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Wed, 20 Dec 2023 03:12:47 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Apr 2023 17:22:34 GMT
Connection: keep-alive
ETag: "6435975a-267"
Accept-Ranges: bytes

# 开启 master 上的keepalived服务
[root@master ~]# systemctl start keepalived

[root@backup ~]# curl -I 192.168.15.100

HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Wed, 20 Dec 2023 03:15:17 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Apr 2023 17:22:34 GMT
Connection: keep-alive
ETag: "6435975a-267"
Accept-Ranges: bytes
验证虚拟IP自动漂移
[root@master ~]# ip a | grep 192.168.15.100
    inet 192.168.15.100/32 scope global ens33
# master 节点有浮动IP    
[root@backup ~]# ip a | grep 192.168.15.100
# backup 节点没有浮动IP

# 停止master节点keepalived服务
[root@master ~]# ip a | grep 192.168.15.100
# master 节点没有浮动IP  
[root@backup ~]# ip a | grep 192.168.15.100
    inet 192.168.15.100/32 scope global ens33
# backup 节点有浮动IP
`可以看出备节点接管绑定VIP`
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值