高可用软件 Keepalived 的原理与实践

服务器架构中,经常会遇到服务的一个总入口(比如 Nginx/MyCAT)存在单点故障的隐患。Keepalived 正是解决此类问题的高可用软件,它使用单个虚拟IP(VIP),动态检测多个入口节点的可用性并切换 VIP 指向,从而达到高可用。本文总结了 Keepalived 的原理,并以 Nginx 为例,演示了 Keepalived 在高可用中的应用。

作者:王克锋
出处:https://kefeng.wang/2018/05/18/keepalived/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。

1 Keepalived 原理

1.1 功能

Keepalived是C语言开源的免费路由软件,为 Linux 提供高可用的负载均衡功能:

  • 高可用(HA, High Availability):提供健康检查功能,基于 VRRP(Virtual RouterRedundancy Protocol) 协议实现多台机器间的故障转移服务;
  • 负载均衡(LB, Load Balancing):基于 Linux 虚拟服务器(IPVS)内核模块,提供 Layer4 负载均衡。

1.2 架构原理

  • 分为两大层:内核空间(Kernel Space)、用户空间(User Space)
  • IPVS(IP Virtual Server): 实现传输层负载平衡,也称为第4层交换;
  • NETLINK: 用于在内核和用户空间进程之间传输信息;

Keepalived 分为3个守护进程:

  • 父进程: 很简单,负责 fork 子进程,并监视子进程健康(图中 WatchDog 周期性发送检测包,需要的话重启子进程);
  • 子进程A: 负责VRRP框架(图中 VRRP Stack)
  • 子进程B: 负责健康检查(图中 Checkers)

2 Keepalived 部署

假设有两台 CentOS: IP[1]=192.168.126.101 和 IP[2]=192.168.126.102
两台都安装 Nginx,分别作为 Master / Backup,同时指定 VIP(虚拟IP) 为 192.168.126.100
则客户端可通过 192.168.126.100 高可用地访问两个 Nginx。

2.1 安装 Nginx

参照博文 Nginx 负载均衡及其 HTTPS 部署 中相关章节。安装并防火墙放行。
而 Tomcat 的安装对于本文不是必需的,可以参照博文 Tomcat 安装及其单机多实例部署

2.2 安装 Keepalived

Keepalived 官网只提供源代码,不提供任何 Linux 发行版的软件包。
但大多数 Linux 发行版(比如 CentOS)都提供 Keepalived 软件包作为主线软件包。可以直接安装:

sudo yum -y install keepalived

2.3 Nginx 检测脚本

本示例的简易处理规则:如果 nginx 进程不存在,则停止服务 keepalived,以便 VIP 转至其他节点。
如果是正式部署,可以改进为 curl 检测 Tomcat,失败时尝试重启 Nginx/Tomcat,依旧检测失败,才停止服务 keepalived。

#!/bin/bash
## sudo vim /etc/keepalived/nginx_check.sh
## sudo chmod +x /etc/keepalived/nginx_check.sh

NGINX_COUNT=`ps -C nginx --no-header | wc -l`
if [ $NGINX_COUNT -eq 0 ]; then
    sudo systemctl stop keepalived
fi

2.4 配置 Keepalived

keepalived.conf 用于配置高可用和负载均衡。
分为三大块:全局定义(global_defs)、VRRP实例(vrrp_instance)、虚拟服务器(virtual_server,本文不需要)。

## sudo cp /etc/keepalived/keepalived.conf{,.bak}
## sudo vim /etc/keepalived/keepalived.conf

global_defs {
    router_id HOSTNAME ## 本节点标识,可使用主机名(centos1/centos2)
}

vrrp_script nginx_check { ## 定义检测脚本,设定名称
    script "/etc/keepalived/nginx_check.sh" ## 检测脚本的路径
    interval 1 ## 重复执行脚本的时间间隔(s)
    weight -20  ## 每失败一次,当前 VRRP 节点的优先级就下降 20
}

vrrp_instance VRRP_100 { ## VRRP_100 是 VRRP 的实例名称
    state BACKUP ## 状态: 两台节点都用 BACKUP。支持两种:MASTER(主节点,优先使用)/BACKUP(备节点,主节点失效时才自动转换为MASTER,主节点恢复后会主动让位)
    interface ens33 ## VIP绑定的网卡接口名称,使用命令 ifconfig 查看
    virtual_router_id 100 ## 虚拟路由的ID,各节点必须一样,可以取 VIP 的末段
    priority 100 ## 节点优先级(0~255),MASTER高于BACKUP
    advert_int 1 ## 发送组播时间间隔(s),两个节点必须一样
    nopreempt ## 非抢占模式

    ## 验证信息,两个节点必须一样
    authentication {
        auth_type PASS
        auth_pass 1111
    }

    ## VIP(可以多个,每行一个,不要分隔符),两个节点必须一样
    virtual_ipaddress {
        192.168.126.100
    }

    ## 定时检测 nginx 状态
    track_script {
        nginx_check ## 前面的 vrrp_script 中设定
    }
}

2.4.1 非抢占模式(推荐)

节点类型全部是 BACKUP,
BACKUP-1 故障时,BACKUP-2 会抢占 VIP,
BACKUP-1 从故障中恢复后,不会从 BACKUP-2 抢回 VIP。
优点:故障恢复时,可避免 VIP 切换造成的服务延迟。

配置要点:

vrrp_instance VRRP_100 {
    state BACKUP ## 各节点类型都是 BACKUP
    nopreempt ## 非抢占(preempt 意思是抢占)
}

2.4.2 抢占模式

节点类型分别 MASTER/BACKUP,
MASTER 故障时,BACKUP 会抢占 VIP,
MASTER 从故障中恢复后,会从 BACKUP 抢回 VIP。

配置要点:

vrrp_instance VRRP_100 {
    state MASTER|BACKUP ## 节点类型分为 MASTER/BACKUP
    ## 不要指定 nopreempt(默认为抢占)
}

2.5 启动两个 Nginx

sudo nginx

2.6 启动两个 keepalived

sudo systemctl enable keepalived
sudo systemctl start keepalived
sudo tail -f /var/log/messages ## 日志文件

## sudo systemctl stop keepalived
## sudo systemctl disable keepalived

3 高可用效果演示

3.1 区分两台 Nginx

修改 Nginx 首页文件,以便能区分来自于哪个节点。

## sudo vim /usr/share/nginx/html/index.html
## 原内容:<h1>Welcome to nginx!</h1>
## 第1台修改为:<h1>Welcome to nginx! [1]</h1>
## 第2台修改为:<h1>Welcome to nginx! [2]</h1>

注意:下列命令要在另外一台 CentOS 上执行,否则 keepalived 有优化算法(优先路由至本机)。

3.2 两个节点都正常

curl -s http://192.168.126.101 | grep "h1" ## 结果 [1]
curl -s http://192.168.126.102 | grep "h1" ## 结果 [2]
curl -s http://192.168.126.100 | grep "h1" ## 结果 [1],VIP 指向节点1

可见,101/102分别指向第1/2个节点,101指向主节点(101)。

3.3 停掉节点1

sudo nginx -s quit ## 节点1上执行:停掉 nginx
curl -s http://192.168.126.101 | grep "h1" ## EMPTY
curl -s http://192.168.126.102 | grep "h1" ## [2]
curl -s http://192.168.126.100 | grep "h1" ## [2],VIP 指向节点2

3.4 恢复节点1

sudo nginx ## 节点1上执行:启动 nginx
sudo systemctl start keepalived ## 节点1上执行:启动 keepalived
curl -s http://192.168.126.101 | grep "h1" ## [1]
curl -s http://192.168.126.102 | grep "h1" ## [2]
curl -s http://192.168.126.100 | grep "h1" ## [2],VIP 仍指向节点2,非抢占模式

4 更多应用

4.1 MyCAT 高可用

MyCAT 的部署请参考:MyCAT+MySQL 读写分离部署
可以部署两台相同配置的 MyCAT,使用同一个VIP,当作本例中 Nginx 那样配置。

4.2 Redis 高可用

Redis 的部署请参考:Redis 服务器单机的安装
两台 Redis,指定了数据同步。使用同一个VIP,像本例中 Nginx 那样配置。

4.3 更多高可用

简易的多个节点的高可用和负载均衡,都可以酌情采用 Keepalived 实现。

猜你喜欢

转载自blog.csdn.net/kefengwang/article/details/81430712