1. keepalived

简介

  • Keepalived是一个轻量级别的高可用解决方案,Keepalived起初是为LVS设计的,专门用 来监控集群系统中各个服务节点的状态,如果某个服务器节点出现故障,Keepalived将检测到后自动将节点从集群系统中剔除。
  • Keepalived 是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前端服务的高可用。

核心功能

  • 健康检查(针对RS)

    • 采用tcp三次握手, icmp请求,http请求等方式对负载均衡器后面的实际的服务器(通常是提供真实服务的服务器)进行检查并保活
  • 失败切换(针对负载均衡器)

    • 当主负载均衡器出现问题时, 由备负载均衡器承载对应的业务,从而在最大限度上减少流量损失,并提供服务的稳定性

工作原理

  • 网络层:通过ICMP协议向后端服务器集群中发送数据报文
  • 传输层:利用TCP协议的端口连接和扫描技术检测后端服务器集群是否正常
  • 应用层:自定义keepalived工作方式(脚本)

VRRP协议

虚拟路由冗余协议

  • VRRP 协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器 IP(一个或多个),而在路由器组内部,如果实际拥有这个对外 IP 的路由器如果工作正常的话就是 MASTER,或者是通过算法选举产生, MASTER 实现针对虚拟路由器 IP 的各种网络功能,如 ARP 请求, ICMP,以及数据的转发等;其他设备不拥有该虚拟 IP,状态是 BACKUP,除了接收 MASTER 的VRRP 状态通告信息外,不执行对外的网络功能。
  • 当主机失效时, BACKUP 将接管原先 MASTER 的网络功能。VRRP 协议使用多播数据来传输 VRRP 数据, VRRP 数据使用特殊的虚拟源 MAC 地址(拥有虚拟的IP+MAC(00-00-5e-00-01-VRID)地址)发送数据而不是自身网卡的 MAC 地址,
  • VRRP 运行时只有 MASTER 路由器定时发送 VRRP 通告信息,表示 MASTER 工作正常以及虚拟路由器 IP(组), BACKUP 只接收 VRRP 数据,不发送数据,如果一定时间内没有接收到 MASTER 的通告信息,各 BACKUP 将宣告自己成为 MASTER,发送通告信息,重新进行 MASTER 选举状态。 | 虚拟路由器 | VRRP组中所有的路由器,拥有虚拟的IP+MAC(00-00-5e-00-01-VRID)地址 | | —- | —- | | 主路由器(MASTER) | 虚拟路由器内部通常只有一台物理路由器对外提供服务,主路由器是由选举算法产生, 对外提供各种网络功能 | | 备份路由器(BACKUP) | VRRP组中除主路由器之外的所有路由器,不对外提供任何服务,只接受主路由的通 告,当主路由器挂 掉之后,重新进行选举算法接替master路由器。 |
  • 选举机制

    • 优先级高的优先选举
    • 抢占模式,即MASTER从故障中恢复后,会将VIP从BACKUP节点中抢占过来
    • 非抢占模式,即MASTER恢复后不抢占BACKUP升级为MASTER后的VIP
  • 三种状态

    • Initialize状态:系统启动后进入initialize状态
    • Master状态
    • Backup状态

架构

  • SchedulerI/OMultiplexer

    • 是一个I/O复用分发调度器,它负载安排Keepalived所有内部的任务请求
  • Memory Mngt

    • 是一个内存管理机制,这个框架提供了访问内存的一些通用方法;
  • Control Plane

    • 是keepalived的控制面板,可以实现对配置文件编译和解析;
  • Core componets

    • Watchdog:是计算机可靠领域中极为简单又非常有效的检测工具,Keepalived正是通过它监控Checkers和 VRRP进程的。
    • Checkers:这是Keepalived最基础的功能,也是最主要的功能,可以实现对服务器运行状态检测和故障隔离。
    • VRRP Stack:这是keepalived后来引用VRRP功能,可以实现HA集群中失败切换功能。负责负载均衡器之间的失败切换
    • FailOver IPVS wrapper:这个是IPVS功能的一个实现,IPVSwarrper模块将可以设置好的IPVS规则发送到内核空间并且提供给IPVS模块,最终实现IPVS模块的负载功能。
    • Netlink Reflector:用来实现高可用集群Failover时虚拟IP(VIP)的设置和切换
  • keepalived运行时会启动三个进程

    • core:负责主进程的启动,维护和全局配置文件的加载;
    • check:负责健康检查
    • vrrp:用来实现vrrp协议,负责失败切换

配置文件

  • 主节点master配置文件
  1. # vim /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs{
  4. # keepalived 自带的邮件提醒需要开启sendmail服务。 建议用独立的监控或第三方SMTP
  5. router_id node1 #标识本节点的字符串,通常为hostname
  6. }
  1. ## keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。如果脚本执行结果为0,并且 weight 配置的值大于 0,则优先级相应的增加。如果脚本执行结果非0,并且 weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值。
  2. vrrp_script_chk_nginx{
  3. script "/etc/keepalived/nginx_check.sh" #检测nginx状态的脚本路径
  4. interval 2 #检测时间间隔
  5. weight -20 #如果条件成立,权重减20
  6. }
  7. ##定义虚拟路由,VI_1为虚拟路由标识符,可以自定义
  8. vrrp_instance_VI_1{
  9. state MASTER #主节点,备份节点为BACKUP
  10. interface ens33 #绑定虚拟IP的网络接口(网卡)与本机IP地址所在的网络接口同
  11. #虚拟路由的ID号,两个节点设置必须一样,可选 IP 最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
  12. virtual_router_id 33
  13. mcast_src_ip xxx.xxx.xxx.xxx #本机ip地址
  14. priority 100 #节点优先级,范围0-254,MASTER比BACKUP高
  15. nopreempt #优先级高的设置,用在非抢占模式下,设置了之后不会去抢占
  16. advert_int 1 # 组播信息发送间隔,两个节点设置必须一样, 默认1s
  17. ## 设置验证信息,两个节点必须一致
  18. authentication {
  19. auth_type PASS
  20. auth_pass 1111 ## 真实生产,按需求对应该过来
  21. }
  22. #将 track_script 块加入 instance 配置块
  23. track_script {
  24. chk_nginx #执行 Nginx 监控的服务
  25. }
  26. # 虚拟 IP 池, 两个节点设置必须一样
  27. virtual_ipaddress {
  28. xxx.xxx.xxx.xxx ## 虚拟 ip,可以定义多个,一行一个
  29. }
  30. }

keepalived+nginx

实现高可用 Web 负载均衡搭建

网络拓扑

  • RS部署web服务
  1. #下载apache
  2. [root@rs1 ~]# yum install -y httpd
  3. [root@rs2 ~]# yum install -y httpd
  4. #关闭防火墙
  5. [root@rs1 ~]# systemctl stop firewalld
  6. [root@rs1 ~]# setenforce 0
  7. [root@rs2 ~]# systemctl stop firewalld
  8. [root@rs2 ~]# setenforce 0
  9. #配置站点并开启服务
  10. [root@rs1 ~]# echo "<h1>This is RS1</h1>" > /var/www/html/index.html
  11. [root@rs1 ~]# systemctl start httpd
  12. [root@rs2 ~]# echo "<h1>This is RS2</h1>" > /var/www/html/index.html
  13. [root@rs2 ~]# systemctl start httpd
  • nginx服务器部署
  1. #下载nginx
  2. [root@nginx1 ~]# yum install -y nginx
  3. [root@nginx2 ~]# yum install -y nginx
  4. #关闭防火墙
  5. [root@nginx1 ~]# systemctl stop firewalld
  6. [root@nginx1 ~]# setenforce 0
  7. [root@nginx2 ~]# systemctl stop firewalld
  8. [root@nginx2 ~]# setenforce 0
  9. #负载均衡配置
  10. [root@nginx1 ~]# vim /etc/nginx/conf.d/proxy.conf
  11. upstream webserver{
  12. server 192.168.244.135;
  13. server 192.168.244.139;
  14. }
  15. server{
  16. listen 80;
  17. server_name 192.168.244.128;
  18. location / {
  19. proxy_pass http://webserver;
  20. }
  21. }
  22. [root@nginx2 ~]# vim /etc/nginx/conf.d/proxy.conf
  23. upstream webserver{
  24. server 192.168.244.135;
  25. server 192.168.244.139;
  26. }
  27. server{
  28. listen 80;
  29. server_name 192.168.244.129;
  30. location / {
  31. proxy_pass http://webserver;
  32. }
  33. }
  • keepalived部署
  1. #下载keepalived
  2. [root@nginx1 ~]# yum install -y keepalived
  3. [root@nginx2 ~]# yum install -y keepalived
  4. #配置文件
  5. [root@nginx1 ~]# mv /etc/keepalived/keepalived.conf{,.bak}
  6. [root@nginx1 ~]# vim /etc/keepalived/keepalived.conf
  7. global_defs {
  8. router_id nginx1
  9. }
  10. vrrp_script chk_http_port {
  11. script "/etc/keepalived/check_nginx.sh"
  12. interval 1
  13. weight -2
  14. }
  15. vrrp_instance VI_1 {
  16. state MASTER
  17. interface ens33
  18. virtual_router_id 10
  19. priority 100
  20. mcast_src_ip 192.168.244.128
  21. advert_int 1
  22. authentication {
  23. auth_type PASS
  24. auth_pass 1111
  25. }
  26. track_script {
  27. chk_http_port
  28. }
  29. virtual_ipaddress {
  30. 192.168.244.100
  31. }
  32. }
  33. [root@nginx1 ~]# systemctl restart keepalived
  34. [root@nginx2 ~]# vim /etc/keepalived/keepalived.conf
  35. global_defs {
  36. router_id nginx2
  37. }
  38. vrrp_script chk_http_port {
  39. script "/etc/keepalived/check_nginx.sh"
  40. interval 1
  41. weight -2
  42. }
  43. vrrp_instance VI_1 {
  44. state BACKUP
  45. interface ens33
  46. virtual_router_id 10
  47. priority 90
  48. mcast_src_ip 192.168.244.128
  49. advert_int 1
  50. authentication {
  51. auth_type PASS
  52. auth_pass 1111
  53. }
  54. track_script {
  55. chk_http_port
  56. }
  57. virtual_ipaddress {
  58. 192.168.244.100
  59. }
  60. }
  61. [root@nginx2 ~]# systemctl restart keepalived
  62. #编写脚本
  63. [root@nginx1 ~]# vim /etc/keepalived/check_nginx.sh
  64. #! /bin/bash
  65. nginx_process_number=`ps -C nginx --no-header | wc -l`
  66. if [ $nginx_process_number -eq 0 ];then
  67. # systemctl restart nginx
  68. nginx_process_number=`ps -C nginx --no-header | wc -l`
  69. if [ $nginx_process_number -eq 0 ];then
  70. exit 1
  71. else
  72. exit 0
  73. fi
  74. else
  75. exit 0
  76. fi
  77. [root@nginx1 ~]# chmod +x /etc/keepalived/check_nginx.sh
  78. [root@nginx2 ~]# vim /etc/keepalived/check_nginx.sh
  79. #! /bin/bash
  80. nginx_process_number=`ps -C nginx --no-header | wc -l`
  81. if [ $nginx_process_number -eq 0 ];then
  82. # systemctl restart nginx
  83. nginx_process_number=`ps -C nginx --no-header | wc -l`
  84. if [ $nginx_process_number -eq 0 ];then
  85. exit 1
  86. else
  87. exit 0
  88. fi
  89. else
  90. exit 0
  91. fi
  92. [root@nginx1 ~]# chmod +x /etc/keepalived/check_nginx.sh
  • 测试:将nginx1上的服务关闭
  1. [root@nginx1 ~]# systemctl stop keepalived
  2. [root@nginx1 ~]# nginx -s stop
  • 此时,VIP已经漂移到nginx2上去了