一、Keepalived概述
概念
- keepalived 是Linux下一个轻量级的高可用解决方案
- 主要是通过虚拟路由冗余协议(VRRP)来实现高可用功能
- Virtual Router Redundancy Protocol
- 起初就是为了补充LVS功能而设计的,用于监控LVS集群内后端真实服务器状态
- 后来加入了VRRP的功能,它出现的目的是为了解决静态路由出现的单点故障问题
功能
- LVS规则管理
- LVS集群真实服务器状态监测
- 管理VIP
使用Keepalived实现LVS高可用
实验环境准备
| 主机名 | IP地址 | 角色 |
|---|---|---|
| pubserver(已存在) | eth0:192.168.88.240 | ansible主机 |
| client(已存在) | eth0:192.168.88.10 | 客户端 |
| lvs1(已存在) | eth0:192.168.88.5 | lvs1调度器 |
| lvs2 | eth0:192.168.88.6 | lvs2调度器 |
| web1(已存在) | eth0:192.168.88.100 | web服务器 |
| web2(已存在) | eth0:192.168.88.200 | web服务器 |
# 清理lvs1主机原有规则和VIP配置
root@pubserver cluster\]# vim 10_rm_dr_manual.yml > --- > > - name: clean lvs1 manual config #清理手工配置LVS-DR规则,后续交给Keepalived管理 > > hosts: lvs1 > > tasks: > > - name: clean ipvs rule > > shell: "ipvsadm -C" > > - name: rm vip file #清理手工eth0:0配置,后续交给Keepalived管理 > > file: > > path: /etc/sysconfig/network-scripts/ifcfg-eth0:0 > > state: absent > > notify: deactive vip > > handlers: > > - name: deactive vip #关闭eth0:0接口 > > shell: ifdown eth0:0 > > \[root@pubserver cluster\]# ansible-playbook 10_rm_dr_manual.yml > > \[root@pubserver cluster\]# ansible lbs -a "ip a s \| grep 192.168" > > lvs1 \| CHANGED \| rc=0 \>\> > > inet 192.168.88.5/24 brd 192.168.88.255 scope global noprefixroute eth0 **# 调整Ansible配置** \[root@pubserver cluster\]# vim inventory > \[clients
client ansible_ssh_host=192.168.88.10
webservers
web1 ansible_ssh_host=192.168.88.100
web2 ansible_ssh_host=192.168.88.200
lbs
lvs1 ansible_ssh_host=192.168.88.5
lvs2 ansible_ssh_host=192.168.88.6 #新添加
all:vars
ansible_ssh_user=root
ansible_ssh_pass=a
root@pubserver cluster\]# ansible all -m ping # 更新所有主机yum源 \[root@pubserver cluster\]# ansible-playbook 05_config_yum.yml #### 配置测试高可用负载均衡集群 **## 配置高可用负载均衡集群** # lvs1和lvs2节点安装LVS和Keepalived软件 \[root@pubserver cluster\]# vim 11_inst_lvs_kp.yml > --- > > - name: install soft > > hosts: lbs > > tasks: > > - name: install pkgs #安装软件 > > yum: > > name: ipvsadm,keepalived > > state: present \[root@pubserver cluster\]# ansible-playbook 11_inst_lvs_kp.yml **# 配置lvs1节点Keepalived软件** **\[root@lvs1 \~\]# vim /etc/keepalived/keepalived.conf** > global_defs { > > ... > > **router_id lvs1 #集群节点唯一标识** > > **vrrp_iptables #放行防火墙规则** > > **...** > > **vrrp_strict #严格遵守VRRP规则** > > ... > > } > > vrrp_instance VI_1 { > > **state MASTER #状态** > > **interface eth0 #网卡** > > **virtual_router_id 51 #虚拟路由唯一标识符** > > **priority 100 #优先级** > > **advert_int 1 #心跳包间隔时间** > > **authentication { #认证方式** > > **auth_type PASS #密码认证** > > **auth_pass 1111 #集群密码** > > } > > **virtual_ipaddress { #定义VIP** > > **192.168.88.15/24 dev eth0 label eth0:0 #VIP地址及绑定网卡和虚接口标签** > > **}** > > } > > **virtual_server 192.168.88.15 80 { #定义LVS虚拟服务器** > > **delay_loop 6 #健康检查延时6s开始** > > **lb_algo wrr #调度算法** > > **lb_kind DR #LVS工作模式** > > **persistence_timeout 50 #50s内相同客户端发起请求由同一服务器处理** > > **protocol TCP #虚拟服务器协议** > > **real_server 192.168.88.100 80 { #定义真实服务器** > > **weight 1 #权重** > > **TCP_CHECK { #健康检查方式** > > **connect_timeout 3 #连接超时时间为3s** > > **nb_get_retry 3 #连续3次访问失败则认为真实服务器故障** > > **delay_before_retry 3 #健康检查包时间间隔** > > **}** > > } > > real_server 192.168.88.200 80 { > > weight 2 > > TCP_CHECK { > > connect_timeout 3 > > nb_get_retry 3 > > delay_before_retry 3 > > } > > } > > } # 启动服务测试 **\[root@lvs1 \~\]# ipvsadm -Ln #启动服务前无LVS规则** IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn **\[root@lvs1 \~\]# systemctl enable --now keepalived #加入开机自启并立即启动** \[root@lvs1 \~\]# ipvsadm -Ln #启动服务后有LVS规则 IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.88.15:80 wrr persistent 50 -\> 192.168.88.100:80 Route 1 0 0 -\> 192.168.88.200:80 Route 2 0 0 \[root@lvs1 \~\]# ip a s \| grep 192.168 #VIP已绑定 inet 192.168.88.5/24 brd 192.168.88.255 scope global noprefixroute eth0 inet 192.168.88.15/24 scope global secondary eth0:0 #同一服务器处理请求 \[root@client \~\]# for i in {1..6} \> do \> curl http://192.168.88.15 \> done Welcome to web2 Welcome to web2 Welcome to web2 Welcome to web2 Welcome to web2 Welcome to web2 **\[root@lvs1 \~\]# vim /etc/keepalived/keepalived.conf #注释持久连接时长** **...** **#persistence_timeout 50** **...** \[root@lvs1 \~\]# systemctl restart keepalived \[root@client \~\]# for i in {1..6};do curl http://192.168.88.15; done Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web2 Welcome to web1 Welcome to web2 **# 配置lvs2节点Keepalived软件** **\[root@lvs1 \~\]# scp /etc/keepalived/keepalived.conf root@192.168.88.6:/etc/keepalived/** **\[root@lvs2 \~\]# vim /etc/keepalived/keepalived.conf** > router_id lvs2 #集群节点唯一标识符 > > state BACKUP #状态 > > priority 50 #优先级 \[root@lvs2 \~\]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn \[root@lvs2 \~\]# systemctl start keepalived \[root@lvs2 \~\]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.88.15:80 wrr -\> 192.168.88.100:80 Route 1 0 0 -\> 192.168.88.200:80 Route 2 0 0 # 验证真实服务器健康检查 **\[root@web1 \~\]# systemctl stop nginx #模拟web1故障** \[root@lvs1 \~\]# ipvsadm -Ln #LVS规则中web1被擦除 TCP 192.168.88.15:80 wrr -\> 192.168.88.200:80 Route 2 0 0 \[root@lvs2 \~\]# ipvsadm -Ln TCP 192.168.88.15:80 wrr -\> 192.168.88.200:80 Route 2 0 0 \[root@web1 \~\]# systemctl start nginx #模拟web1修复 \[root@lvs2 \~\]# ipvsadm -Ln #LVS规则中web1被添加回来 TCP 192.168.88.15:80 wrr -\> 192.168.88.100:80 Route 1 0 0 -\> 192.168.88.200:80 Route 2 0 0 \[root@lvs2 \~\]# ipvsadm -Ln TCP 192.168.88.15:80 wrr -\> 192.168.88.100:80 Route 1 0 0 -\> 192.168.88.200:80 Route 2 0 0 # 验证高可用负载均衡 \[root@lvs1 \~\]# ip a s \| grep 88.15 #VIP绑定于lvs1 inet 192.168.88.15/24 scope global secondary eth0:0 \[root@lvs1 \~\]# systemctl stop keepalived #模拟lvs1节点故障 \[root@lvs1 \~\]# ip a s \| grep 88.15 #VIP释放 \[root@lvs1 \~\]# ipvsadm -Ln #LVS规则被清空 \[root@lvs2 \~\]# ip a s \| grep 88.15 #VIP绑定于lvs2 inet 192.168.88.15/24 scope global secondary eth0:0 \[root@lvs2 \~\]# ipvsadm -Ln TCP 192.168.88.15:80 wrr -\> 192.168.88.100:80 Route 1 0 0 -\> 192.168.88.200:80 Route 2 0 0 \[root@client \~\]# for i in {1..6} do curl http://192.168.88.15 done #不影响客户端 Welcome to web1 Welcome to web2 Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web2 ## 二、Haproxy负载均衡集群 ### Haproxy相关概念 * 概念 * HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理 * 是免费、快速并且可靠的一种解决方案 * HAProxy非常适用于并发大(并发达1w以上)web站点,这些站点通常又需要会话保持或七层处理 * 可以很简单安全的整合至当前的架构中,同时可以保护web服务器不被暴露到公网 * 工作模式 * mode http:只适用于web服务 * mode tcp:适用于各种服务 * mode health:仅做健康检查,很少使用 * 调度算法 * roundrobin:轮询 * static-rr:加权轮询 * leastconn:最少连接者先处理 * source:根据请求源IP,类似于nginx的ip_hash * ri:根据请求的URI * rl_param:根据请求人URL参数'balance url_param' * rdp-cookie(name) :根据cookie(name)来锁定并哈希每一次的TCP请求 * hdr(name) :根据HTTP请求头来锁定每一次HTTP请求 haproxy属于L4和L7负载均衡器,可以在TCP和HTTP层面上进行负载均衡。 其工作原理是将客户端请求转发到后端服务器,从而实现负载均衡。具体来说,haproxy会根据预先定义的负载均衡算法(如轮询、加权轮询、最少连接数等)将请求分配给后端服务器,并且会根据后端服务器的健康状况进行动态调整。同时,haproxy还支持会话保持、SSL终止、请求重定向等高级功能,可以满足各种负载均衡场景的需求。 ### 实验环境准备 | 主机名 | IP地址 | 角色 | |----------------|---------------------|------------| | pubserver(已存在) | eth0:192.168.88.240 | ansible主机 | | client(已存在) | eth0:192.168.88.10 | 客户端 | | proxy | eth0:192.168.88.5 | haproxy服务器 | | web1(已存在) | eth0:192.168.88.100 | web服务器 | | web2(已存在) | eth0:192.168.88.200 | web服务器 | #### 安装haproxy服务 ## 实验环境准备 # 关机lvs2节点 \[root@lvs2 \~\]# poweroff # lvs1节点安装Haproxy软件 \[root@pubserver cluster\]# vim 12_install_haproxy.yml > --- > > - name: config haproxy > > hosts: lvs1 > > tasks: > > - name: stop keepalived #停止Keepalived服务 > > service: > > name: keepalived > > state: stopped > > enabled: false > > - name: remove softs #卸载软件 > > yum: > > name: ipvsadm,keepalived > > state: absent > > - name: modify hostname #设置主机名 > > shell: "hostnamectl set-hostname haproxy" > > - name: install haproxy #安装软件 > > yum: > > name: haproxy > > state: present \[root@pubserver cluster\]# ansible-playbook 12_install_haproxy.yml #### 配置Haproxy **## 配置Haproxy负载均衡集群** # 配置文件说明 **global为全局配置,通常保持默认即可** **defaults为缺省配置,如果后续有相同配置则覆盖缺省值** **# 配置Haproxy** **\[root@haproxy \~\]# vim /etc/haproxy/haproxy.cfg** ... #先把包括64行在内的之后的行全部删除,然后添加以下配置 > ... > > listen webservers #定义虚拟服务器 > > bind 0.0.0.0:80 #定义监听端口 > > mode http #定义工作模式 > > balance roundrobin #定义调度算法 > > server web1 192.168.88.100:80 check inter 2000 rise 2 fall 5 > > server web2 192.168.88.200:80 check inter 2000 rise 2 fall 5 > > #check:对后端服务器进行健康检查 > > #inter:健康检查心跳包发送时间间隔 > > #rise:连续检查N次有响应则认为健康 > > #fall:连续检查N次无响应则认为故障 \[root@haproxy \~\]# systemctl start haproxy \[root@haproxy \~\]# ss -antlp \| grep haproxy tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:\* users:(("haproxy",pid=33351,fd=5)) # 访问测试 \[root@client \~\]# for i in {1..6} do curl http://192.168.88.5 done Welcome to web1 Welcome to web2 Welcome to web1 Welcome to web2 Welcome to web1 Welcome to web2 #### 开启Haproxy健康检查页面 ## Haproxy健康检查页面 **# 配置Haproxy** **\[root@haproxy \~\]# vim /etc/haproxy/haproxy.cfg** > ... > > listen stats #定义虚拟服务器 > > bind 0.0.0.0:1080 #定义监听端口 > > stats refresh 30s #定义页面刷新时间 > > stats uri /stats #定义请求路径 > > stats auth admin:admin #定义用户/密码 \[root@haproxy \~\]# systemctl restart haproxy \[root@haproxy \~\]# ss -antlp \| grep haproxy LISTEN 0 128 0.0.0.0:1080 0.0.0.0:\* users:(("haproxy",pid=28627,fd=7)) LISTEN 0 128 0.0.0.0:80 0.0.0.0:\* users:(("haproxy",pid=28627,fd=5)) # 浏览器访问测试: http://192.168.88.5:1080/stats 用户名/密码:admin/admin   ## 三、负载均衡软件对比 ### 适用场景 * **LVS适用于需要高并发性和稳定性的场景** * **Nginx适用于静态文件服务和反向代理等应用层负载均衡场景** * **HAProxy则具备较为丰富的功能和灵活性,适用于多种负载均衡场景** ### 对比 * LVS:Linux Virtual Server * 优点: * 高性能:LVS使用Linux内核中的IP负载均衡技术,能够实现非常高的并发处理能力 * 稳定性:LVS经过长时间的实践应用,成熟稳定,被广泛使用 * 可用性:支持高可用性的配置,可以实现故障自动切换,提供无中断的服务 * 灵活性:可根据需要采用多种负载均衡算法,如轮询、加权轮询、哈希等 * 缺点: * 配置复杂:相对于其他两个技术,LVS的配置相对较为复杂,需要更深入的了解和配置 * 功能相对局限:LVS主要是一种传输层负载均衡技术,无法像Nginx和HAProxy那样对应用层协议进行处理 * Nginx * 优点 * 高性能:Nginx采用了基于事件驱动的异步非阻塞架构,能够处理大量并发连接 * 负载均衡:Nginx具备内置的负载均衡功能,可以根据配置进行请求的转发 * 丰富的功能:Nginx支持反向代理、静态文件服务、缓存、SSL等,在Web服务器领域有很广泛的应用 * 缺点 * 功能相对较少:相对于LVS和HAProxy,Nginx在负载均衡算法和健康检查等方面的功能相对较少 * 限制于应用层协议:Nginx只能对HTTP和HTTPS等应用层协议进行处理,无法处理其他协议 * Haproxy * 优点 * 灵活性:HAProxy支持丰富的负载均衡算法和会话保持方式,可以根据需求进行灵活配置 * 完整的功能:HAProxy支持高可用性配置、健康检查、故障恢复、SSL等功能,在负载均衡领域应用广泛 * 高性能:HAProxy性能优良,能够处理大量并发连接,并且支持异步IO模型 * 缺点 * 内存占用:相对于Nginx和LVS,HAProxy在处理大量连接时消耗的内存稍高一些 * 高可用性:HAProxy需要借助额外的工具来实现高可用性,例如Keepalived ## 四、扩展 ### keepalived实现web集群高可用 #### 实验环境 | 主机名 | IP地址 | 角色 | |-------------|---------------------|----------------------| | client(已存在) | eth0:192.168.88.10 | 客户端 | | web1(已存在) | eth0:192.168.88.100 | web服务器,keepalived高可用 | | web2(已存在) | eth0:192.168.88.200 | web服务器,keepalived高可用 | #### 配置Keepalived高可用集群 ## 配置Keepalived高可用集群 # 安装Keepalived软件 \[root@pubserver cluster\]# vim 08_inst_web_kp.yml > --- > > - name: install keepalive on webservers > > hosts: webservers > > tasks: > > - name: install keepalived #安装软件 > > yum: > > name: keepalived > > state: present \[root@pubserver cluster\]# ansible-playbook 08_inst_web_kp.yml # 配置Keepalived集群 **\[root@web1 \~\]# vim /etc/keepalived/keepalived.conf** > 1 ! Configuration File for keepalived > > 2 > > ... > > 11 smtp_connect_timeout 30 > > 12 router_id web1 #设置集群节点唯一标识符 > > 13 vrrp_iptables #手工添加,与vrrp_strict协同工作,自动放行iptables规则 > > 14 vrrp_skip_check_adv_addr > > 15 vrrp_strict #严格遵守VRRP协议,将iptables默认规则设置为拒绝 > > 16 vrrp_garp_interval 0 > > 17 vrrp_gna_interval 0 > > 18 } > > 19 > > 20 vrrp_instance VI_1 { > > 21 state MASTER #状态,节点角色master主,BACKUP备用角色 > > 22 interface eth0 #keepalived监听的网卡 > > 23 virtual_router_id 51 #虚拟路由器唯一表示,范围0-255, > > 24 priority 100 #优先级 > > 25 advert_int 1 #心跳包频率1s > > 26 authentication { #认证方式 > > 27 auth_type PASS #认证类型 > > 28 auth_pass 1111 #集群内节点认证密码 > > 29 } > > 30 virtual_ipaddress { > > 31 192.168.88.80/24 dev eth0 label eth0:1 #VIP地址及绑定网卡和虚接口标签 > > 32 } > > 33 } > > 34 #34行之后的全部删除,后面是lvs相关的配置 **\[root@web2 \~\]# vim /etc/keepalived/keepalived.conf** > 1 ! Configuration File for keepalived > > 2 > > 3 global_defs { > > ... > > 11 smtp_connect_timeout 30 > > 12 router_id web2 #集群节点唯一标识 > > 13 vrrp_iptables #放行iptables规则 > > 14 vrrp_skip_check_adv_addr > > 15 vrrp_strict > > 16 vrrp_garp_interval 0 > > 17 vrrp_gna_interval 0 > > 18 } > > 19 > > 20 vrrp_instance VI_1 { > > 21 state BACKUP #状态 > > 22 interface eth0 > > 23 virtual_router_id 51 > > 24 priority 50 #优先级值低于master > > 25 advert_int 1 > > 26 authentication { > > 27 auth_type PASS > > 28 auth_pass 1111 > > 29 } > > 30 virtual_ipaddress { > > 31 192.168.88.80/24 dev eth0 label eth0:1 > > 32 } > > 33 } # 启动服务 \[root@web1 \~\]# systemctl start keepalived.service \[root@web2 \~\]# systemctl start keepalived.service # 验证VIP绑定情况 \[root@web1 \~\]# ip a s \| grep 192.168 #web1主机绑定vip inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 inet 192.168.88.100/24 brd 192.168.88.255 scope global noprefixroute eth0 inet 192.168.88.80/24 scope global secondary eth0:1 \[root@web1 \~\]# \[root@web2 \~\]# ip a s \| grep 192.168 #web2主机未绑定vip inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0 \[root@web2 \~\]# **# 测试高可用** \[root@client \~\]# curl http://192.168.88.80 #访问VIP得到web1节点首页内容 Welcome to web1 \[root@web1 \~\]# systemctl stop keepalived.service #模拟web1节点故障 \[root@client \~\]# curl http://192.168.88.80 #访问VIP得到web2节点首页内容 Welcome to web2 \[root@web2 \~\]# ip a s \| grep 192.168 #确认web2主机绑定VIP inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0 inet 192.168.88.80/24 scope global secondary eth0:1 \[root@web1 \~\]# systemctl start keepalived.service #模拟web1节点修复 \[root@web1 \~\]# ip a s \| grep 192.168 #确认VIP被web1抢占 inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 104 inet 192.168.88.100/24 brd 192.168.88.255 scope global noprefixroute eth0 inet 192.168.88.80/24 scope global secondary eth0:1 \[root@web2 \~\]# ip a s \| grep 192.168 #确认VIP被web2释放 inet 192.168.88.15/32 brd 192.168.88.15 scope global lo:0 inet 192.168.88.200/24 brd 192.168.88.255 scope global noprefixroute eth0 关联节点服务 * **配置高可用的web集群时,Keepalived只为服务器提供了VIP** * **Keepalived不知道服务器上运行了哪些服务** * **MASTER服务器可以通过跟踪脚本监视本机的80端口,一旦本机80端口失效,则将VIP切换至BACKUP服务器** * **Keepalived对脚本的要求是,退出码为0表示访问成功;退出码为1表示失败** **## 解决Keepalived关联节点服务** # 编写服务检查脚本 \[root@web1 \~\]# vim /etc/keepalived/check_http.sh > #!/bin/bash > > ss -antpul \| grep -q nginx \&\& exit 0 \|\| exit 1 \[root@web1 \~\]# chmod +x /etc/keepalived/check_http.sh # 配置Keepalived关联服务 \[root@web1 \~\]# vim /etc/keepalived/keepalived.conf \[root@web1 \~\]# cat -n /etc/keepalived/keepalived.conf > 1 ! Configuration File for keepalived > > 2 > > ... > > 18 } > > 19 > > 20 vrrp_script chk_http_port { > > 21 script "/etc/keepalived/check_http.sh" #声明关联的脚本,定义检测脚本位置 > > 22 interval 2 #定义脚本执行频率 > > 23 } > > 24 > > 25 vrrp_instance VI_1 { > > 26 state MASTER > > 27 interface eth0 > > 28 virtual_router_id 51 > > 29 priority 100 > > 30 advert_int 1 > > 31 authentication { > > 32 auth_type PASS > > 33 auth_pass 1111 > > 34 } > > 35 virtual_ipaddress { > > 36 192.168.88.80/24 dev eth0 label eth0:1 > > 37 } > > 38 track_script { #引用脚本chk_http_port > > 39 chk_http_port > > 40 } > > 41 } \[root@web1 \~\]# systemctl restart keepalived.service **# 测试高可用配置** \[root@web1 \~\]# ip a s \| grep 88.80 #确认VIP绑定在web1 inet 192.168.88.80/24 scope global secondary eth0:1 \[root@web1 \~\]# systemctl stop nginx.service #模拟web1故障 \[root@web1 \~\]# ip a s \| grep 88.80 #确认web1释放VIP \[root@web2 \~\]# ip a s \| grep 88.80 #确认VIP绑定于web2 inet 192.168.88.80/24 scope global secondary eth0:1 \[root@web1 \~\]# systemctl start nginx.service #模拟web1故障修复 \[root@web1 \~\]# ip a s \| grep 88.80 #确认VIP绑定于web1 inet 192.168.88.80/24 scope global secondary eth0:1