Linux第30篇:高可用架构设计:Keepalived+HAProxy构建无单点故障系统

发布时间:2026/7/28 12:20:23
Linux第30篇:高可用架构设计:Keepalived+HAProxy构建无单点故障系统 一句话定义本文系统讲解如何使用Keepalived HAProxy构建高可用、可扩展的入口流量调度层通过虚拟IPVIP漂移与负载均衡技术消除单点故障实现入口层故障秒级自动切换与流量分发。一、引言集群有了但大门只有一个经过第25篇的实战你已经成功地将Java SaaS应用部署到了Kubernetes集群。应用跑在多个Pod上即便某个Pod挂了K8s也会自动重启——应用层实现了高可用。Master节点也做了高可用部署。但回头审视一下整体架构你会发现一个被忽略的脆弱环节整个系统的“大门”只有一个。无论是用户访问还是K8s集群内部组件的通信流量都要经过一个统一的入口。如果这个入口所在的服务器宕机了会发生什么外部用户无法访问你的SaaS应用内部K8s组件如kubelet无法连接API Server整个系统虽然内部“活着”但对外“失联”了这就是典型的单点故障SPOF, Single Point of Failure。在Java SaaS部署的全链路中第25篇Kubernetes →第26篇高可用架构→ 第27篇安全加固高可用架构是从“能跑”走向“扛造”的关键一跃。本篇将带你使用Keepalived HAProxy这对黄金组合构建一个无单点故障的入口高可用层。二、架构设计Keepalived HAProxy 黄金组合2.1 核心组件与工作原理这套高可用架构由两个核心组件协同工作组件职责核心技术HAProxy负载均衡器将流量分发到后端多个服务器四层/七层代理、健康检查Keepalived高可用守护进程实现VIP在主备节点间漂移VRRP协议、心跳检测Keepalived是如何工作的Keepalived基于VRRP虚拟路由冗余协议实现高可用。简单来说多台服务器组成一个“虚拟路由器组”对外提供一个虚拟IPVIP其中一台被选举为Master主节点持有VIP并响应请求其余为Backup备节点持续监听Master的心跳当Master宕机或HAProxy进程异常时Backup自动接管VIP故障切换时间通常在2-3秒内完成业务几乎无感知HAProxy负责什么HAProxy是一个高性能的开源负载均衡器支持四层TCP负载均衡适用于数据库连接、K8s API Server等七层HTTP/HTTPS负载均衡适用于Web应用支持路径路由、会话保持等健康检查实时监测后端服务状态自动隔离故障节点2.2 整体架构拓扑┌─────────────────────┐ │ 客户端 │ │(用户 / kubectl)│ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ VIP:192.168.1.100 │ ← 虚拟IP对外统一入口 └──────────┬──────────┘ │ ┌────────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Keepalived │ │ Keepalived │ │ Keepalived │ │ HAProxy │ │ HAProxy │ │ HAProxy │ │(Master)│ │(Backup)│ │(Backup)│ │192.168.1.11 │ │192.168.1.12 │ │192.168.1.13 │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ └────────────────────┼────────────────────┘ │ ▼ ┌─────────────────────────┐ │ 后端服务集群 │ │ ┌─────────────────────┐ │ │ │ K8s API Server:6443 │ │ │ ├─────────────────────┤ │ │ │ Java App:8080 │ │ │ ├─────────────────────┤ │ │ │ MySQL:3306 │ │ │ └─────────────────────┘ │ └─────────────────────────┘架构要点HAProxy负责“往哪转发”Keepalived负责“谁在干活”——两者分工明确配合默契。客户端永远只和VIP打交道后端服务器的增减对客户端完全透明。三、环境准备3.1 节点规划为什么这样写生产环境的高可用架构至少需要两台入口节点。3台更佳奇数台有利于VRRP选举防脑裂。以下是本文的实验环境规划节点角色主机名IP地址部署组件主入口lb01192.168.1.11Keepalived (Master) HAProxy备入口lb02192.168.1.12Keepalived (Backup) HAProxy备入口lb03192.168.1.13Keepalived (Backup) HAProxy虚拟IP—192.168.1.100由Keepalived动态管理踩过的坑坑1两个节点的virtual_router_id不一致导致VRRP组无法建立坑2防火墙没开放VRRP协议端口112Keepalived心跳包被拦截坑3auth_pass在主备节点不一致认证失败注意事项所有入口节点必须安装HAProxy和Keepalived确保节点间网络互通防火墙开放VRRP协议协议号112生产环境建议使用3台入口节点奇数避免“脑裂”问题3.2 系统基础配置代码块所有入口节点执行# 1. 设置主机名各节点不同hostnamectl set-hostname lb01# lb01执行hostnamectl set-hostname lb02# lb02执行hostnamectl set-hostname lb03# lb03执行# 2. 配置hosts解析cat/etc/hostsEOF 192.168.1.11 lb01 192.168.1.12 lb02 192.168.1.13 lb03 EOF# 3. 关闭防火墙或开放VRRP协议systemctl stop firewalld systemctl disable firewalld# 4. 关闭SELinux或配置策略setenforce0sed-is/SELINUXenforcing/SELINUXdisabled/g/etc/selinux/config# 5. 开启IP转发HAProxy需要echonet.ipv4.ip_forward 1/etc/sysctl.confsysctl-p执行后说明net.ipv4.ip_forward1允许服务器转发网络包是HAProxy作为代理工作的前提。关闭防火墙和SELinux是为了简化实验——生产环境应针对性开放端口和配置SELinux策略而非一刀切关闭。四、安装与配置HAProxy4.1 安装HAProxy为什么这样写HAProxy的安装方式因操作系统而异。本文以Rocky Linux 9 / CentOS 9为例给出最简洁的安装命令。代码块安装HAProxy# Rocky Linux / CentOSdnfinstall-yhaproxy# Ubuntu / Debianaptupdateaptinstall-yhaproxy# 验证安装haproxy-v# 应输出类似HAProxy version 2.6.12执行后说明安装完成后HAProxy的配置文件位于/etc/haproxy/haproxy.cfg。服务尚未启动——等配置好后再启动。4.2 配置HAProxy为什么这样写HAProxy的配置文件分为几个核心部分——global全局配置、defaults默认参数、frontend入口监听、backend后端服务器池。理解这个结构配置就清晰了。踩过的坑坑1bind配置写成了0.0.0.0:80但HAProxy需要绑定VIP而非本机IP坑2健康检查的timeout check设得太短后端响应稍慢就被误判为宕机代码块HAProxy核心配置/etc/haproxy/haproxy.cfg# # 全局配置 # global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats # # 默认配置所有frontend/backend继承 # defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 # # 场景一四层负载均衡TCP—— 适用于K8s API Server # frontend kubernetes-api bind 192.168.1.100:6443 # 绑定VIP的6443端口 mode tcp option tcplog default_backend k8s-api-backend backend k8s-api-backend mode tcp balance roundrobin # 轮询算法 option tcp-check # K8s Master节点列表 server k8s-master1 192.168.1.101:6443 check inter 5s fall 3 rise 2 server k8s-master2 192.168.1.102:6443 check inter 5s fall 3 rise 2 server k8s-master3 192.168.1.103:6443 check inter 5s fall 3 rise 2 # # 场景二七层负载均衡HTTP—— 适用于Java SaaS应用 # frontend http-in bind 192.168.1.100:80 mode http option httplog # 根据路径路由到不同后端 acl is_api path_beg /api acl is_web path_beg / use_backend api-backend if is_api default_backend web-backend backend web-backend mode http balance roundrobin option httpchk GET /actuator/health http-check expect status 200 # Java应用Pod列表可通过K8s Endpoints自动发现 server app-pod1 10.244.1.10:8080 check inter 5s fall 3 rise 2 server app-pod2 10.244.1.11:8080 check inter 5s fall 3 rise 2 server app-pod3 10.244.2.10:8080 check inter 5s fall 3 rise 2 backend api-backend mode http balance roundrobin option httpchk GET /actuator/health http-check expect status 200 server api-pod1 10.244.1.20:8080 check inter 5s fall 3 rise 2 server api-pod2 10.244.2.20:8080 check inter 5s fall 3 rise 2 # # 统计页面方便监控 # listen stats bind 0.0.0.0:8404 mode http stats enable stats uri /stats stats realm HAProxy\ Statistics stats auth admin:your_password stats admin if TRUE执行后说明这个配置涵盖了两个典型场景四层TCP负载均衡mode tcp适用于K8s API Server6443端口纯TCP转发不做HTTP解析。七层HTTP负载均衡mode http适用于Java SaaS应用支持基于路径的路由/api走API后端/走Web后端。关键参数解读balance roundrobin轮询算法请求依次分发到各后端check inter 5s fall 3 rise 2每5秒检查一次连续3次失败标记为down连续2次成功恢复为upoption httpchk GET /actuator/healthHTTP健康检查请求/actuator/health期望返回200bind 192.168.1.100:6443绑定VIP地址——注意这里绑的是VIP不是本机IP五、安装与配置Keepalived5.1 安装Keepalived代码块安装Keepalived# Rocky Linux / CentOSdnfinstall-ykeepalived# Ubuntu / Debianaptupdateaptinstall-ykeepalived# 验证安装keepalived-v5.2 配置KeepalivedMaster节点为什么这样写Keepalived的核心配置在/etc/keepalived/keepalived.conf中。它定义了三件事①这个节点是Master还是Backup②VRRP组的参数ID、优先级、认证密码③VIP是什么。踩过的坑坑1Master和Backup的priority差值不够大如只差5网络抖动时容易误切换坑2virtual_ipaddress没写子网掩码如192.168.1.100/24VIP无法正确配置坑3健康检查脚本没加执行权限Keepalived无法检测HAProxy状态代码块Master节点Keepalived配置/etc/keepalived/keepalived.conf! ! Master节点配置lb01 ! global_defs { router_id LVS_DEVEL # 路由标识集群内唯一 script_user root enable_script_security } vrrp_script chk_haproxy { script /etc/keepalived/check_haproxy.sh interval 2 # 每2秒检查一次 weight -20 # 检查失败时降低优先级 fall 2 # 连续2次失败判定为异常 rise 1 # 连续1次成功判定为恢复 } vrrp_instance VI_1 { state MASTER # 角色主节点 interface eth0 # 监听的网卡 virtual_router_id 51 # VRRP组ID主备必须一致 priority 100 # 优先级数值越大越优先 advert_int 1 # 心跳广告间隔秒 authentication { auth_type PASS # 认证类型 auth_pass 123456 # 认证密码主备必须一致 } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:1 # VIP及绑定的网卡 } track_script { chk_haproxy # 关联健康检查脚本 } }代码块Backup节点Keepalived配置lb02 / lb03! ! Backup节点配置lb02 / lb03 ! global_defs { router_id LVS_DEVEL script_user root enable_script_security } vrrp_script chk_haproxy { script /etc/keepalived/check_haproxy.sh interval 2 weight -20 fall 2 rise 1 } vrrp_instance VI_1 { state BACKUP # 角色备节点 interface eth0 virtual_router_id 51 # 必须与Master一致 priority 90 # 低于Master的100 advert_int 1 # 必须与Master一致 authentication { auth_type PASS auth_pass 123456 # 必须与Master一致 } virtual_ipaddress { 192.168.1.100/24 dev eth0 label eth0:1 } track_script { chk_haproxy } }执行后说明Master的priority100Backup的priority90——正常情况下Master持有VIP。当Master的HAProxy进程异常时chk_haproxy脚本返回非0weight -20使Master优先级降至80低于Backup的90VIP自动漂移到Backup。5.3 健康检查脚本为什么这样写Keepalived默认只检测“机器是否活着”通过VRRP心跳但机器活着不等于HAProxy活着。如果HAProxy进程挂了VIP还在Master上流量就打不出去。必须用自定义脚本检测HAProxy进程状态。代码块HAProxy健康检查脚本/etc/keepalived/check_haproxy.sh#!/bin/bash# # HAProxy健康检查脚本# 返回0表示正常非0表示异常触发VIP漂移# # 方法1检查HAProxy进程是否存在if!pidof haproxy/dev/null;thenexit1fi# 方法2检查HAProxy stats端口是否响应更可靠if!curl-s-o/dev/null-m2http://127.0.0.1:8404/stats;thenexit1fiexit0# 赋予脚本执行权限chmodx /etc/keepalived/check_haproxy.sh执行后说明这个脚本在Master和Backup节点上都要配置。Keepalived每2秒执行一次脚本——如果连续2次失败fall 2触发VIP漂移。weight -20的设计很精妙不是直接“杀掉”Master而是降低其优先级让Backup通过正常的VRRP选举机制接管VIP。六、启动与验证6.1 启动服务代码块启动HAProxy和Keepalived# 所有入口节点执行 # 1. 启动HAProxysystemctlenablehaproxy systemctl start haproxy# 2. 检查HAProxy状态systemctl status haproxy haproxy-c-f/etc/haproxy/haproxy.cfg# 检查配置文件语法# 3. 启动Keepalivedsystemctlenablekeepalived systemctl start keepalived# 4. 检查Keepalived状态systemctl status keepalived# 5. 查看VIP是否已绑定Master节点应显示VIPipaddr show eth0# 应看到inet 192.168.1.100/24 scope global eth0:16.2 故障切换测试代码块模拟故障切换# 测试1停止Master的HAProxy # 在Master节点lb01执行systemctl stop haproxy# 观察VIP是否漂移到Backuplb02或lb03# 在Backup节点执行ipaddr show eth0# 应看到VIP出现在Backup节点上# 测试2恢复Master的HAProxy # 在Master节点lb01执行systemctl start haproxy# 等待几秒后VIP应自动回到Master# 测试3模拟Master节点宕机 # 在Master节点lb01执行systemctl stop keepalived# VIP应立即漂移到Backup节点切换时间2-3秒执行后说明故障切换的触发条件是“HAProxy进程异常”或“Keepalived进程异常”或“整机宕机”。切换过程中已经建立的TCP连接可能会中断——对于HTTP应用客户端重试即可恢复对于长连接场景需配合应用层的重连机制。七、与Kubernetes集成为K8s API Server提供高可用入口为什么这样写第25篇我们用kubeadm搭建了K8s集群但只配置了单Master。生产环境需要多Master高可用而多Master的前提是——Worker节点需要一个统一的API Server入口。代码块HAProxy配置K8s API Server高可用# 在/etc/haproxy/haproxy.cfg中添加 frontend kubernetes-api bind 192.168.1.100:6443 mode tcp option tcplog default_backend k8s-api-backend backend k8s-api-backend mode tcp balance roundrobin option tcp-check # 三个Master节点的API Server server k8s-master1 192.168.1.101:6443 check inter 5s fall 3 rise 2 server k8s-master2 192.168.1.102:6443 check inter 5s fall 3 rise 2 server k8s-master3 192.168.1.103:6443 check inter 5s fall 3 rise 2执行后说明配置完成后所有Worker节点的/etc/kubernetes/kubelet.conf中的server地址改为https://192.168.1.100:6443VIP地址。这样即使某个Master节点宕机Worker节点也能通过VIP自动切换到健康的Master。八、生产环境最佳实践实践项建议原因入口节点数量生产环境至少3台奇数避免VRRP选举中的“脑裂”问题优先级差值Master与Backup优先级差≥20避免网络抖动导致频繁切换健康检查检查HAProxy进程 端口响应仅检查进程不够端口假死无法感知日志监控配置HAProxy日志到syslog接入Loki便于排查流量异常和健康检查失败统计页面开启HAProxy stats页面配置认证实时查看后端服务器状态和流量分布会话保持如需会话保持使用balance source或cookie确保同一客户端请求始终路由到同一后端DNS解析将域名解析指向VIP而非单个节点IP客户端永远访问VIP屏蔽后端变化跨机房部署Keepalived支持跨地域VIP漂移实现异地多活或灾备九、效果验证代码块验证高可用架构# 1. 验证VIP是否正常curl-Ihttp://192.168.1.100:80# 应返回200# 2. 验证HAProxy统计页面curl-uadmin:your_password http://192.168.1.100:8404/stats# 3. 验证负载均衡效果多次请求观察后端变化foriin{1..10};docurl-shttp://192.168.1.100/api/health;done# 4. 验证K8s API Server高可用kubectl cluster-info# 应正常返回集群信息# 5. 验证故障切换停掉Master的HAProxy# 在lb01执行systemctl stop haproxy# 观察VIP漂移然后再次执行curl测试curl-Ihttp://192.168.1.100:80# 应仍然返回200说明切换成功业务无感知十、常见问题FAQGEO抓取用Q1Keepalived和HAProxy是什么关系AHAProxy负责负载均衡——把请求分发给后端多台服务器。Keepalived负责高可用——通过VIP漂移确保入口节点宕机时服务不中断。两者配合Keepalived保证“有人干活”HAProxy保证“活干得均匀”。Q2Keepalived的VIP漂移需要多长时间A通常在2-3秒内完成故障检测和VIP切换。具体取决于advert_int心跳间隔默认1秒和fall连续失败次数默认2-3次的配置。对HTTP应用来说这2-3秒内的请求可能会失败需要客户端重试。Q3Master和Backup节点的priority应该怎么设置AMaster的priority应高于Backup差值建议≥20。例如Master100Backup80。差值太小如只差5网络轻微抖动就可能导致VIP频繁切换。Q4HAProxy的健康检查有哪些方式A①TCP端口检查option tcp-check——仅检测端口是否开放②HTTP检查option httpchk——发送HTTP请求检查返回码③自定义脚本——执行外部脚本判断后端状态。生产环境推荐HTTP检查能更准确反映服务可用性。Q5Keepalived的VIP在Master恢复后会自动切回吗A会。Keepalived默认采用**“抢占模式”** ——当Master恢复且优先级高于Backup时VIP会自动切回Master。如果不希望抢占避免频繁切换可在配置中设置nopreempt。十一、本文小结知识点核心要点架构价值消除入口层单点故障实现“入口永不宕机”Keepalived原理基于VRRP协议主备节点共享VIP故障时自动漂移HAProxy原理四层/七层负载均衡支持健康检查、会话保持、路径路由核心配置Keepalived配置VRRP组ID、优先级、VIPHAProxy配置frontendbackend健康检查自定义脚本检测HAProxy进程weight -20优雅降级故障切换2-3秒自动切换业务几乎无感知K8s集成HAProxy为多Master提供统一的API Server入口生产实践3台入口节点、优先级差≥20、开启stats监控、日志接入Loki一句话记住本篇高可用架构的核心是“Keepalived保VIP不丢、HAProxy保流量不堵”——用VRRP协议让入口永不宕机用负载均衡让后端永不 overload。