利用keepalived达成服务高可用

官方网站Keepalived for Linux

1.keepalived简介

vrrp 协议的软件实现,原生设计目的为了 高可用 ipvs 服务
功能:
基于 vrrp 协议完成地址流动
为 vip 地址所在的节点生成 ipvs 规则 ( 在配置文件中预先定义 )
为 ipvs 集群的各 RS 做健康状态检测
基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持 nginx 、 haproxy 等服务
健康检查和失败切换是keepalived的两大核心功能

  • 健康检查,就是采用tcp三次握手,icmp请求,http请求,udp echo请求等方式对负载均衡器后面的实际的服务器(通常是承载真实业务的服务器)进行保活
  • 而失败切换主要是应用于配置了主备模式的服务器,利用VRRP协议维持主备服务器的心跳,当主服务器出现问题时,由备服务器承载对应的业务,从而在最大限度上减少损失,并提供服务的稳定性

2.选举机制

既然有主备就会有选举机制,那么我们keepalived的选举机制如下

非抢占模式(默认),只要Master不挂掉,优先级高的路由器只能等待

复制代码
vrrp_instance VI_1 {
    state MASTER #主服务器 BACKUP 对应是从服务器
    interface eth0 #对应网卡
    virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一
    priority 100     #当前物理节点在此虚拟路由器的优先级,范围:1-254
                     #值越大优先级越高,每个keepalived主机节点此值不同
    advert_int 1        #vrrp通告的时间间隔,默认1s
    authentication {
        auth_type PASS   #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
        auth_pass 1111  #预共享密钥,仅前8位有效
                        #同一个虚拟路由器的多个keepalived节点必须一样
    }
    virtual_ipaddress {#虚拟IP,生产环境可能指定上百个IP地址
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

抢占模式,一旦有优先级高的路由器加入,立即成为Master,

复制代码
priority 100 #优先级高
nopreempt #非抢占模式 加入

3.配置解析

3.1全局配置

复制代码
#全局配置
global_defs {
   notification_email { #keepalived 发生故障切换时邮件发送的目标邮箱
     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   #邮件服务器连接timeout
   router_id LVS_DEVEL   #每个keepalived主机唯一标识
   vrrp_skip_check_adv_addr    #对所有通告报文都检查,会比较消耗性能,收到的通告报文和上一
                               个路由器一样则跳过检查
   vrrp_strict
    #严格遵循vrrp协议
    #启用此项后以下状况将无法启动服务:
    #1.无VIP地址
    #2.配置了单播邻居
    #3.在VRRP版本2中有IPv6地址
    #建议不加此项配置
   vrrp_garp_interval 0 #报文发送延迟,0表示不延迟
   vrrp_gna_interval 0  #消息发送延迟
#vrrp_mcast_group4 224.0.0.18 #指定组播IP地址范围:
}

3.2 虚拟路由配置

复制代码
vrrp_instance VI_1 {
state MASTER
interface eth0 #绑定为当前虚拟路由器使用的物理接口,如:eth0,可以和VIP不在一
个网卡
virtual_router_id 51 #每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一
                        #否则服务无法启动
                        #同属一个虚拟路由器的多个keepalived节点必须相同
                        #务必要确认在同一网络中此值必须唯一
priority 100            #当前物理节点在此虚拟路由器的优先级,范围:1-254
                        #值越大优先级越高,每个keepalived主机节点此值不同
advert_int 1            #vrrp通告的时间间隔,默认1s
authentication { #认证机制
auth_type AH|PASS          #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
auth_pass 1111             #预共享密钥,仅前8位有效
                           #同一个虚拟路由器的多个keepalived节点必须一样
        }
virtual_ipaddress {        #虚拟IP,生产环境可能指定上百个IP地址
            <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
            172.25.254.100 #指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认32
            172.25.254.101/24 dev eth1
            172.25.254.102/24 dev eth2 label eth2:1
        }
}

4.keepalived 单主架构

4.1 配置环境

后面环境通用

|-------------|---------------|-----|
| 主机 | ip | 服务 |
| client | 172.25.254.10 | 客户端 |
| keepalived1 | 172.25.254.20 | |
| keepalived2 | 172.25.254.30 | |
| web1 rs1 | 172.25.254.40 | |
| web2 rs2 | 172.25.254.50 | |

4.2 keepalived1 配置

为了美观性和方便理解我们采用子配置书写

cd /etc/keepalived/conf.d

vim router.conf

添加虚拟路由并作为我们的VIP虚拟访问IP

systemctl restart keepalived

重启服务后查看虚拟IP是否添加成功

同理对keepalived2做相同操作

由于是单骨架我们的BACKUP服务器不会启动也就不会有虚拟路由,当我们关闭keepalived1上的服务时我们的服务才会转移到keepalived2上去

5.keepalived 双主架构

cp -p router.conf router1.conf 为了方便我们直接复制即可

也就是配置两个虚拟路由IP一人当一个虚拟IP的master

6.组播传输和单波传输

vrrp_mcast_group4 IP#指定组播IP地址范围

测试:tcpdump -i ens33 -nn host 224.0.0.18

启用 vrrp_strict 时,不能启用单播 , 否则服务无法启动 , 并在 messages 文件中记录下面信息

unicast_src_ip 172.25.254.20 # 本机 IP
unicast_peer {
172.25.254.30 # 指向对方主机 IP

如果有多个 keepalived, 再加其它节点的 IP

}

组播如下配置

测试 tcpdump -i ens33 vrrp -n
tcpdump -i eth0 -nn host 224.0.0.18

测试:

单波

默认 keepalived 主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
unicast_src_ip <IPADDR> # 指定发送单播的源 IP
unicast_peer {
<IPADDR> # 指定接收单播的对方目标主机 IP
......
}

测试

7.实现双主架构下的LVS-DR

7.1 虚拟服务器配置

virtual_server IP port { #VIP 和 PORT
delay_loop <INT> # 检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh # 定义调度方法
lb_kind NAT|DR|TUN # 集群的类型 , 注意要大写
persistence_timeout <INT> # 持久连接时长
protocol TCP|UDP|SCTP # 指定服务协议 , 一般为 TCP
sorry_server <IPADDR> <PORT> # 所有 RS 故障时,备用服务器地址
real_server <IPADDR> <PORT> { #RS 的 IP 和 PORT
weight <INT> #RS 权重
notify_up <STRING>|<QUOTED-STRING> #RS 上线通知脚本
notify_down <STRING>|<QUOTED-STRING> #RS 下线通知脚本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } # 定义当前主机健康状
态检测方法
}
}

注意 : 括号必须分行写 , 两个括号写在同一行 , 如 : }} 会出错

7.2 检测服务存活方法

TCP监测传输层检测: TCP_CHECK

TCP_CHECK {
connect_ip <IP ADDRESS> #向当前 RS 的哪个 IP 地址发起健康状态检测请求
connect_port <PORT> #向当前 RS 的哪个 PORT 发起健康状态检测请求
bindto <IP ADDRESS> #发出健康状态检测请求时使用的源地址
bind_port <PORT> #发出健康状态检测请求时使用的源端口
connect_timeout <INTEGER> #客户端请求的超时时长
#等于 haproxy 的 timeout server
}
应用层检测 HTTP_GET|SSL_GET
HTTP_GET|SSL_GET {
url {
path <URL_PATH> #定义要监控的URL
status_code <INT> #判断上述检测机制为健康状态的响应码,一般为 200
}
connect_timeout <INTEGER> #客户端请求的超时时长 , 相当于haproxy的timeout server
nb_get_retry <INT> #重试次数
delay_before_retry <INT> #重试之前的延迟时长
connect_ip <IP ADDRESS> #向当前 RS 哪个 IP 地址发起健康状态检测请求
connect_port <PORT> #向当前 RS 的哪个 PORT 发起健康状态检测请求
bindto <IP ADDRESS> #向当前 RS 发出健康状态检测请求时使用的源地址
bind_port <PORT> #向当前 RS 发出健康状态检测请求时使用的源端口
}

复制代码
virtual_server 172.25.254.100 80 {
        delay_loop 6
        lb_algo wrr
        lb_kind DR
        protocol TCP
        #sorry_server 172.25.254.30

real_server 172.25.254.40 80 {
        weight 1
        TCP_CHECK {
                connect_timeout 5
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
}
real_server 172.25.254.50 80 {
        weight 1
        HTTP_GET {
            url {
                        path /
                        status_code 200
                }
        connect_timeout 1
        nb_get_retry 3
        delay_before_retry 1
                }
        }
}
virtual_server 172.25.254.200 80 {
        delay_loop 6
        lb_algo wrr
        lb_kind DR
        protocol TCP
        #sorry_server 172.25.254.30

real_server 172.25.254.40 80 {
        weight 1
        TCP_CHECK {
                connect_timeout 5
                nb_get_retry 3
                delay_before_retry 3
                connect_port 80
        }
}
real_server 172.25.254.50 80 {
        weight 1
        HTTP_GET {
            url {
                        path /
                        status_code 200
                }
        connect_timeout 1
        nb_get_retry 3
        delay_before_retry 1
                }
        }
}

写入子配置文件 vim /etc/keepalived/lvs.conf

7.3 配置web服务器

ip addr add 172.25.254.100/32 dev lo

systemctl restart ipvsadm.service

systemctl restart keepalived

测试

8.实现HAProxy高可用

8.1 配置环境

RS1和RS2

vim /etc/sysctl.d/arp.conf

keepalive1和keepalive2

将lvs里面的虚拟主机配置文件删掉或者替换

将 由于我们haproxy需要监控vip但本机没有需要开启一个内核参数,让其能监控不在本机的Ip
在两个 ka1 和 ka2 两个节点启用内核参数
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1

8.2 配置基础haproxy

在keepalived上下载haproxy
写入基本配置

复制代码
listen webserver
    bind 172.25.254.100:80
    server web1 172.25.254.101:80 check
    server web2 172.25.254.102:80 check

8.3 keepalived启用脚本

为了保证我们haproxy的高可用我们需要写一个脚本去检测haproxy服务的存活

我们采用killall -0 haproxy 来检查haproxy服务是否运行,当然也可采用其他方法

mkdir /etc/keepalived/conf.d/scripts

vim /etc/keepalived/conf.d/scripts/haproxy.sh

复制代码
#haproxy 内容
#!/bin/bash
/usr/bin/killall -0 haproxy

赋予脚本可执行权限

keepalived 调用脚本
复制代码
track_script {
    SCRIPT_NAME_1
    SCRIPT_NAME_2
}
定义脚本
复制代码
vrrp_script <SCRIPT_NAME> {
    script <STRING>|<QUOTED-STRING> #此脚本返回值为非0时,会触发下面OPTIONS执行
    OPTIONS
}

vrrp_script <SCRIPT_NAME> { #定义一个检测脚本,在global_defs 之外配置
script <STRING>|<QUOTED-STRING> #shell 命令或脚本路径
interval <INTEGER> # 间隔时间,单位为秒,默认 1 秒
timeout <INTEGER> # 超时时间
weight <INTEGER:-254..254> # 默认为 0, 如果设置此值为负数,

当上面脚本返回值为非 0 时

会将此值与本节点权重相加可以降低本节点权重,

即表示 fall.

如果是正数,当脚本返回值为 0 ,

会将此值与本节点权重相加可以提高本节点权重

即表示 rise. 通常使用负值

fall <INTEGER> # 执行脚本连续几次都失败 , 则转换为失败,建议设为 2 以上
rise <INTEGER> # 执行脚本连续几次都成功,把服务器从失败标记为成功
user USERNAME [GROUPNAME] # 执行监测脚本的用户或组
init_fail # 设置默认标记为失败状态,监测成功之后再转换为成功状态
}

操作实例

vim /etc/keepalived/conf.d/haproxy.conf

复制代码
vrrp_script check_haproxy {
        script "/etc/keepalived/conf.d/scripts/haproxy.sh"
        interval 1
        weight -30
        fall 2
        rise 2
        timeout 2
}

vim /etc/keepalived/conf.d/router.conf

复制代码
vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 20
        priority 100
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                172.25.254.100/24 dev ens33 label ens33:0
        }
        unicast_src_ip 172.25.254.20
        unicast_peer {
                172.25.254.30
        }
        track_script{  #新加入的作用是调用
                check_haproxy
        }
}

测试

相关推荐
多吃蔬菜!!!3 分钟前
vscode 搭建C/C++开发环境搭建(linux)
linux·c语言·c++
李李李li12 分钟前
Ubuntu 22.04 安装tensorrt
linux·tensorrt
phoenix09812 小时前
Linux入门DAY29
linux·运维
一休哥助手2 小时前
Naive RAG:简单而高效的检索增强生成架构解析与实践指南
运维·人工智能·架构
叔叔别拉了我害怕2 小时前
封装FTPSClient连接ftps服务器
服务器·git·github
入秋2 小时前
Linux服务器安装部署 Nginx、Redis、PostgreSQL、Docker
linux·前端
不甘懦弱2 小时前
阿里云搭建flask服务器
服务器·python·flask
Bi3 小时前
包含多个子项目集成一个项目部署Vercel方法
运维·前端
Mr. Cao code3 小时前
使用Tomcat Clustering和Redis Session Manager实现Session共享
java·linux·运维·redis·缓存·tomcat
zcz16071278213 小时前
Linux 网络命令大全
linux·运维·网络