{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2020-01-11 23:13:44","updateBy":"admin","updateTime":"2026-05-22 13:36:28","remark":null,"id":14,"articleTitle":"Keepalived高可用","articleUrl":"keepalived","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220906/ead03235c356458c9e3fa664b3f5837f.jpg","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"Keepalived的作用是检测服务器的状态，如果有一台web服务器宕机，或工作出现故障，Keepalived将检测到，并将有故障的服务器从系统中剔除，同时使用其他服务器代替该服务器的工作，当服务器工作正常后Keepalived自动将服务器加入到服务器群中，这些工作全部自动完成，不需要人工干涉，需要人工做的只是修复故障的服务器。","articleContent":"## VRRP协议\n\n在现实的网络环境中，主机之间的通信都是通过配置静态路由完成的，而主机之间的路由器一旦出现故障，通信就会失败，因此在这种通信模式中，路由器就成了一个单点瓶颈，为了解决这个问题就引入了VRRP协议\n\nVRRP协议是一种主备模式的协议，通过VRRP可以在网络发生故障时透明地进行设备切换不影响主机间的数据通信，这其中涉及两个概念：物理路由器和虚拟路由器\n\nVRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由器，这个虚拟路由器通过虚拟IP（一个或多个）对外提供服务，二在虚拟路由器内部，是多个物理路由器协同工作，同一时间只有一台物理路由器对外提供服务，这台物理路由器被称之为主路由器（处于master状态角色）。它拥有对外提供的虚拟ip，提供各种网络功能，比如arp请、icmp、数据转发等，二其他物理路由器不拥有对外提供的虚拟ip，也不提供对外网络功能，仅仅接收master的vrrp状态通告信息，这些路由器被统称为备份路由器（处于backup角色）。当主路由器失效时，处于backup角色的备份路由器将重新进行选举，产生一个新的主路由器进入master角色继续对外服务，整个切换过程对于用户来说完全同名\n\n在一个虚拟路由器中，只有处于master角色的路由器会一直发送vrrp数据包，处于backup角色的路由器只接受master发过来的报文信息，用来监控master运行状态，因此，不会发生master抢占的现象，除非它的优先级更高，而当master不可用时，backup也就无法收到master发过来的报文信息，于是就认定master出现故障，接着多台backup就会进行选举，优先级最高的backup将成为新的master，这种选举并进行角色的过程非常快，因此也就保证了服务的持续可用性。\n\n## keepalived介绍\n\n### keepalived是什么\n\n　　Keepalived软件起初是专为LVS负载均衡软件设计的，用来管理并监控LVS集群系统中各个服务节点的状态，后来又加入了可以实现高可用的VRRP功能。因此，Keepalived除了能够管理LVS软件外，还可以作为其他服务（例如：Nginx、Haproxy、MySQL等）的高可用解决方案软件。\n\n　　Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router RedundancyProtocol(虚拟路由器冗余协议）的缩写，VRRP出现的目的就是为了解决静态路由单点故障问题的，它能够保证当个别节点宕机时，整个网络可以不间断地运行。\n\n\n### keepalived功能\n\n- 管理LVS负载均衡软件\n- 实现LVS集群节点的健康检查中\n- 作为系统网络服务的高可用性（failover）\n\n### keepalived工作原理\n\n　　Keepalived高可用服务对之间的故障切换转移，是通过 VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议）来实现的。\n\n　　在 Keepalived服务正常工作时，主 Master节点会不断地向备节点发送（多播的方式）心跳消息，用以告诉备Backup节点自己还活看，当主 Master节点发生故障时，就无法发送心跳消息，备节点也就因此无法继续检测到来自主 Master节点的心跳了，于是调用自身的接管程序，接管主Master节点的 IP资源及服务。而当主 Master节点恢复时，备Backup节点又会释放主节点故障时自身接管的IP资源及服务，恢复到原来的备用角色。\n\n### keepalived高可用架构\n\n![](https://www.asumimoe.com/imgfiles/20220907/dea768a47d4b4aaa8fcf5e80cf911207.png)\n\n#### 文字，表述\n\nKeepalived的工作原理：\n\nKeepalived高可用对之间是通过VRRP通信的，因此，我们从 VRRP开始了解起：\n\n1) VRRP,全称 Virtual Router Redundancy Protocol,中文名为虚拟路由冗余协议，VRRP的出现是为了解决静态路由的单点故障。\n\n2) VRRP是通过一种竟选协议机制来将路由任务交给某台 VRRP路由器的。\n\n3) VRRP用 IP多播的方式（默认多播地址（224.0_0.18))实现高可用对之间通信。\n\n4) 工作时主节点发包，备节点接包，当备节点接收不到主节点发的数据包的时候，就启动接管程序接管主节点的开源。备节点可以有多个，通过优先级竞选，但一般 Keepalived系统运维工作中都是一对。\n\n5) VRRP使用了加密协议加密数据，但Keepalived官方目前还是推荐用明文的方式配置认证类型和密码。\n\n介绍完 VRRP,接下来我再介绍一下 Keepalived服务的工作原理：\n\nKeepalived高可用对之间是通过 VRRP进行通信的， VRRP是遑过竞选机制来确定主备的，主的优先级高于备，因此，工作时主会优先获得所有的资源，备节点处于等待状态，当主挂了的时候，备节点就会接管主节点的资源，然后顶替主节点对外提供服务。\n\n在 Keepalived服务对之间，只有作为主的服务器会一直发送 VRRP广播包,告诉备它还活着，此时备不会枪占主，当主不可用时，即备监听不到主发送的广播包时，就会启动相关服务接管资源，保证业务的连续性.接管速度最快可以小于1秒。\n\n## keepalived配置\n\n### keepalived安装\n\nyum的方式安装\n\n```bash\nyum install keepalived -y\n\n/etc/keepalived\n/etc/keepalived/keepalived.conf     #keepalived服务主配置文件\n/etc/rc.d/init.d/keepalived         #服务启动脚本\n/etc/sysconfig/keepalived\n/usr/bin/genhash\n/usr/libexec/keepalived\n/usr/sbin/keepalived\n```\n\n编译安装\n\nyum安装的方式目前只能安装1.x版本，需要安装2.x版本的情况下就需要自己进行编译安装。\n\n```bash\n1.安装依赖\nyum install -y gcc openssl-devel libnl-devel libnl3-devel\n2.上传keepalived安装包并解压\ntar -zxvf keepalived-2.2.8.tar.gz -C /opt/\n3.编译安装\ncd /opt/keepalived-2.2.8\n./configure --prefix=/usr/local/keepalived\nmake && make install\n4.修改配置文件\nkeepalived安装完成后默认配置文件的位置仍然是/etc/keepalived/keepalived.conf。如果需要修改指定配置文件的位置，则在keepalived启动选项中添加如下选项\nvim /usr/local/keepalived/etc/sysconfig/keepalived\n# Options for keepalived. See `keepalived --help' output and keepalived(8) and\n# keepalived.conf(5) man pages for a list of all options. Here are the most\n# common ones :\n#\n# --vrrp               -P    Only run with VRRP subsystem.\n# --check              -C    Only run with Health-checker subsystem.\n# --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop.\n# --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.\n# --dump-conf          -d    Dump the configuration data.\n# --log-detail         -D    Detailed log messages.\n# --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)\n#\nKEEPALIVED_OPTIONS=\"-D -f /usr/local/keepalived/etc/keepalived/keepalived.conf\"\n\n5.keepalived service配置\ncat /usr/lib/systemd/system/keepalived.service #编译安装完成后自动生成该文件\n[Unit]\nDescription=LVS and VRRP High Availability Monitor\nAfter=network-online.target syslog.target \nWants=network-online.target \nDocumentation=man:keepalived(8)\nDocumentation=man:keepalived.conf(5)\nDocumentation=man:genhash(1)\nDocumentation=https://keepalived.org\n\n[Service]\nType=forking\nPIDFile=/run/keepalived.pid\nKillMode=process\nEnvironmentFile=-/usr/local/keepalived2.2/etc/sysconfig/keepalived\nExecStart=/usr/local/keepalived2.2/sbin/keepalived  $KEEPALIVED_OPTIONS\nExecReload=/bin/kill -HUP $MAINPID\n\n[Install]\nWantedBy=multi-user.target\n```\n\n### keepalived配置文件介绍\n\n```bash\nvim /etc/keepalived/keepalived.conf\n\n! Configuration File for keepalived\n#全局配置\nglobal_defs {\n   notification_email {\n     acassen@firewall.loc           #定义邮件报警地址\n     failover@firewall.loc\n     sysadmin@firewall.loc\n   }\n   notification_email_from Alexandre.Cassen@firewall.loc\n   smtp_server 192.168.200.1        #邮箱服务器\n   smtp_connect_timeout 30          #定义超时时间\n   router_id LVS_DEVEL              #定义路由标识信息，相同局域网唯一\n   vrrp_skip_check_adv_addr\n   vrrp_strict\n   vrrp_garp_interval 0\n   vrrp_gna_interval 0\n}\n\nVRRP配置DS1\nvrrp_instance VI_1 {                #定义实例\n    state MASTER                    #角色类型MASTER|BACKUP\n    interface eth0                  #网卡名称\n    virtual_router_id 51            #虚拟路由id（需要与BACKUP一致）\n    priority 100                    #优先级决定是主还是备，两个节点的优先级必须不同，否则容易导致脑裂发生\n    advert_int 1                    #每1秒检查一次\n    #nopreempt                      #非抢占模式\n\n    authentication {\n        auth_type PASS              #认证类型  主备之间必须一样\n        auth_pass 1111              #认证密码  主备之间必须一样\n    }\n    virtual_ipaddress {\n        192.168.10.20               #虚拟ip（vip）\n    }\n}\n\n#LVS配置\nvirtual_server 192.168.10.20 80 {    \n    delay_loop 3                    #健康检查时间间隔\n    lb_algo rr                      #负载均衡调度算法  \n    lb_kind DR                      #负载均衡转发规则 \n    protocol TCP                    #协议\n\n    real_server 192.168.10.11 80 {  #要监控的real_server的ip和端口号\n            weight 1                #权重\n            TCP_CHECK {                 #基于tcp协议的检查\n                connect_timeout 3       #连接时间超时 \n                retry 3                 #重连次数\n                delay_before_retry 3    #重连间隔时间\n            }\n    }\n    real_server 192.168.10.12 80 {\n            weight 1\n            TCP_CHECK {\n                connect_timeout 3\n                retry 3\n                delay_before_retry 3\n            }   \n    }   \n}\n```\n\n\n\n### 查看虚拟IP\n\n```bash\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN \n    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    inet 127.0.0.1/8 scope host lo\n    inet6 ::1/128 scope host \n       valid_lft forever preferred_lft forever\n2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\n    link/ether 00:0c:29:90:7f:0d brd ff:ff:ff:ff:ff:ff\n    inet 192.168.10.10/24 brd 192.168.10.255 scope global eth0\n    inet 192.168.10.20/24 scope global secondary eth0:1\n    inet6 fe80::20c:29ff:fe90:7f0d/64 scope link \n       valid_lft forever preferred_lft forever\n```\n\n### 服务高可用\n\n使用脚本监控的方式\n\n```bash\n修改nginx监听参数  listen 10.0.0.3:80; \n\n修改内核参数，实现监听本地不存在的ip\necho 'net.ipv4.ip_nonlocal_bind = 1' >>/etc/sysctl.conf\nsysctl -p\n\n编写nginx监控脚本\n#!/bin/bash\n\nwhile true\ndo\nif [ `ps -ef |grep nginx |grep -v grep |wc -l` -lt 2 ]\nthen\n   exit 1 # 监控脚本中不要出现kill -9 keepalived这种强制停止Keepalived进程的命令，防止VIP还没释放，备机已经获取了VIP导致脑裂\nfi\ndone\n\n为脚本授权\nchmod +x check_www.sh\n\nvim /etc/keepalived/keepalived.conf\n! Configuration File for keepalived\n\n...\nvrrp_script check {         #定义脚本\n   script \"/server/scripts/check_www.sh\"  # 表示将一个脚本信息赋值给变量check_web\n   interval 2    # 执行监控脚本的间隔时间\n   weight 2  # 利用权重值和优先级进行运算，从而降低主服务优先级使之变为备服务器（建议先忽略）\n}\n\n...\n    virtual_ipaddress {\n        192.168.10.20/24 dev eth0 label eth0:1\n    }\n    track_script {     #调用脚本\n       check\n    }\n}\n```\n\n使用命令监控的方式\n\n```bash\nvim /etc/keepalived/keepalived.conf\nvrrp_script check {         #定义脚本\n   script \"killall -0 nginx\"  # 除此配置外，其余与上一种方式相同\n   script \"systemctl is-active --quiet nginx\" # 监控服务的方式\n   script \"pidof nginx\" # 检测进程的方式\n   script \"ss -nlt | grep -q ':80 '\" # 检测端口的方式\n   interval 2 \n   weight 2 \n}\n```\n\nkillall中的0信号为特殊信号，该信号不会对程序做任何干预，只会检测进程是否存在。如果进程存在，则它的返回值为0；如果进程不存在，则它的返回值为1。\n\n**注意**：在命令与脚本中将命令的结果返回值输出为1在1.x版本并不会切换成功，需要升级为2.x版本才能正常切换。\n\n### keepalived单播模式\n\n单播：在同一局域网内，两个设备点对点的通信就是单播通信。\n\n组播：在同一网络可达范围内，一个网络设备与关心其数据的部分设备进行通信就是组播。\n\n广播：在同一网络可达范围内，一个网络设备向本网络内所有设备进行通信就是广播。\n\n简单地说，单播->组播->广播，是通信数量不断增加的通信方式。当然，通信数量的增多，带来的是通信设备的资源消耗更大，整体网络环境的复杂度更高。\n\n在组播模式下，keepalived将全部的心跳包信息都会向默认的224.0.0.18的组播地址发送，这样会产生众多的无用信息，这对于有多个keepalived实例时甚至会产生干扰和冲突，因此须要将组播模式改成单播默认是一种安全的做法，可以避免局域网内有大量的keepalived形成虚拟路由id的冲突。\n\n```bash\n开启单播模式\n# MASTER主节点\n! Configuration File for keepalived\n\nglobal_defs {\n   router_id LB1\n   #vrrp_strict\t\t\t#关闭这个参数或者不加这个参数\n}\n\nvrrp_instance VI_1 {\n\t...\n\tunicast_src_ip 192.168.118.129         #配置单播的源地址，即本机地址\n\tunicast_peer { \n      192.168.118.132                      #配置单播的目标地址，即对方备节点地址，备有多台就配置多个地址\n    }\n}\n```\n\n\n\n### keepalived节点优先级增减\n\n```bash\nvrrp_script check_run {\n    script \"killall -0 nginx\"\n    interval 3\n    weight -20\n    rise 1\n    fall 1\n}\n```\n\n1）weight：权重值变化，正数和负数代表不同的含义。当值为正数时，代表检测脚本执行成功时，节点的实际优先级为priority+weight（如100+20=120）；当值为负数时，代表代表检测脚本执行失败时，节点的实际优先级为priority+weight（如100+（-20）=80）。\n\n2）rise 1：表示脚本检测成功一次就置当前主机为正常状态。\n\n3）fall 1：表示脚本检测失败一次就置当前主机为故障状态，如果主节点故障，则发生切换。\n\n## Keepalived非抢占模式\n\nKeepalived默认为抢占模式：即当master节点挂了之后会自动切换至backup节点，当主节点恢复后会将VIP从备节点抢回。一般在业务中，我们认为第二次切换是多余的，即可将keepalived配置为非抢占模式。\n\n非抢占模式配置的要素为：\n\n1）两个节点的state都必须配置为BACKUP（官方推荐）；\n\n2）两个节点都需要在vrrp_instance中添加nopreempt参数；\n\n3）其中一个节点的优先级必须高于另一个节点的优先级。\n\n```bash\nvrrp_instance VI_1 {                #定义实例\n    state BACKUP                    #角色类型\n\t...\n    nopreempt                       #非抢占模式\n```\n\n配置了非抢占模式后，需要注意keepalived的启动顺序，先启动的节点会变为主节点，VIP会绑定在该节点上，如果需要让A机成为备节点，就不能先启动A机的keepalived服务。\n\n**注意：**在非抢占模式下，如果配置了相同的优先级，那么在脑裂恢复后，由于两个节点都处于Master状态（脑裂期间），当它们重新通信时，会重新选举，此时非抢占模式并不会阻止这个选举过程。优先级相同，则比较发送者的IP地址（注意：是发送VRRP通告的源IP，即节点的接口IP）。IP地址较大的节点将成为Master，而另一个节点将转变为Backup。\n\n### Keepalived初始主节点\n\n影响Keepalived 节点成为初始 Master 的核心配置及因素如下（按重要性排序）：\n\n1）优先级priority：优先级最高的节点自动成为初始 Master，若所有节点优先级相同 → 触发 IP地址比较规则。\n\n2）节点初始状态state：当优先级相同时，state为MASTER的节点是主节点，但最终会被优先级高的替代。\n\n3）IP地址比较：当优先级相同时会触发此规则，IP地址大的节点成为主节点。\n\n## 脑裂\n\n在高可用（HA）系统中，当联系2个节点的“心跳线”断开时，本来为一整体、动作协调的HA系统，就分裂成为2个独立的个体。由于相互失去了联系，都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样，争抢“共享资源”、争起“应用服务”，就会发生严重后果——或者共享资源被瓜分、2边“服务”都起不来了；或者2边“服务”都起来了，但同时读写“共享存储”，导致数据损坏（常见如数据库轮询着的联机日志出错）。\n\n### 脑裂产生的原因\n\n- **网络与防火墙问题**：这是最常见的原因。主备节点间的网络链路中断，或防火墙未放行VRRP协议（IP协议号112），导致心跳消息被阻断。\n- **Keepalived配置不当**：`virtual_router_id`不一致、`advert_int`心跳间隔过长导致误判，或主从节点优先级相同但在特定启动顺序下引发争议。\n- **节点自身故障**：主节点的Keepalived进程因资源耗尽或配置错误而假死，业务服务正常但心跳停止。\n- **软件Bug**：某些旧版本存在因`vrrp_startup_delay`配置重载导致节点无法处理VRRP报文的Bug。\n\n\n### 常见的解决方案\n\n在实际生产环境中，我们可以从以下几个方面来防止裂脑问题的发生：\n\n-  **硬件与网络冗余**：配置双或多条心跳链路（物理双网卡、交换机）、使用独立心跳网络，并跨机房部署时配置专线/VPN保障通信。\n-  **规范配置与防火墙**：统一各节点的`virtual_router_id`和VRRP版本，所有节点设为`BACKUP`状态并通过`priority`值竞争，避免直接指定`MASTER/SLAVE`。务必放行**IP协议号112（vrrp）**和组播地址**224.0.0.18**。\n-  **调整超时与自动隔离**：调小心跳间隔并增加失败次数，减少对短时抖动的误判。数据一致性要求极高的系统可配置STONITH硬件实现“爆头”强制隔离故障节点。\n\n### 脑裂监控脚本\n\n```bash\n#当备服务器上出现vip时认为发生脑裂或主备切换\n#!/bin/bash\nwhile true\ndo\nif [ `ip a show eth0 |grep 10.0.0.3|wc -l` -ne 0 ]\nthen\n    echo \"keepalived is error!\"\nelse\n    echo \"keepalived is OK !\"\nfi\ndone\n```\n\n参考自：[https://www.cnblogs.com/clsn/p/8052649.html](https://www.cnblogs.com/clsn/p/8052649.html)","categoryId":6,"viewCount":1495,"categoryName":"集群与高可用","author":"球接子","authorAvatar":null,"tagIds":[11,8],"tagNames":["高可用","Keepalived"]}}