首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Kubernetes高可用负载均衡:haproxy+pacemaker故障自愈实战
📅 2026/10/21 13:47:01
✍️ 爱科研究院
👁 阅读 3,247
1. 架构设计与方案选型1.1 为什么K8s前面必须有一层高可用负载均衡很多刚接触Kubernetes的工程师会有一个直观疑问kube-apiserver本身是多个节点组成的集群为什么客户端kubectl、kubelet、调度器不能直接连多个apiserver答案很简单kubeconfig里只能填一个地址。或者说虽然你可以填多个server地址但Kubernetes官方的client-go至今没有内置原生的多apiserver failover逻辑。实际生产中控制平面节点要么用Nginx四层转发要么用云厂商的SLB要么自建负载均衡层把多个apiserver统一收口成一个入口。但自建这一层的时候很多人会犯一个致命错误只部署一台Nginx或者HAProxy然后它就变成了整个集群的单点。apiserver做成了高可用入口反而是单点这等于把鸡蛋全部放进了一个篮子里。我就见过不止一个团队k8s集群三个master节点、三个etcd节点前面却只有一个nginx在转发6443节点宕机后整个集群对外完全不可用。所以这里聊的方案是haproxy pacemaker组合搭建一层具备故障自愈能力的负载均衡入口。haproxy负责真正的四层流量分发pacemaker负责守护haproxy进程和虚拟IPVIP当某个节点宕机、haproxy进程崩溃或者网络异常时VIP会自动漂移到存活节点kubectl连接的地址始终不变。这个组合的优势在于组件全部开源、不依赖云厂商、不引入额外的商业License、运维逻辑清晰。相比keepalived方案pacemaker能做更细粒度的资源监控和约束控制相比云SLB它不限制在特定云平台上私有化和混合云环境都能用。1.2 haproxy pacemaker 和主流备选方案的取舍先说说为什么选haproxy而不是Nginx。K8s的apiserver流量对负载均衡层的要求非常明确L4 TCP转发、低延迟、高吞吐、连接数大。haproxy本身就是做四层起家的配置模型对TCP代理场景非常友好健康检查支持TCP端口探测、HTTP探测、脚本探测等多达十余种方式。而Nginx虽然也支持stream模块转发TCP但在高并发长连接场景下haproxy的事件驱动模型和内存管理机制表现更稳定而且在haproxy里配置多个backend、做流量权重调整、查看实时连接状态都是开箱即用的功能。再说说pacemaker和keepalived的区别。keepalived的核心能力是VRRP虚IP漂移它的配置模型围绕IP漂移展开最多再做点简单的脚本检测。pacemaker是个完整的集群资源管理器CRM它不仅能管VIP还能管服务进程、文件系统挂载、IP地址之外的第三方资源代理。pacemaker对资源状态的判断更严谨它会通过corosync组播持续探查节点存活状态配合fencing机制避免脑裂。实际选型时我用一个标准来判断我的负载均衡层需要管几个东西只需要一个VIP漂移keepalived就够。需要管VIP haproxy进程 健康检查 资源启动顺序 同节点约束pacemaker明显更顺手。在生产环境里haproxy进程意外退出、节点网卡闪断、corosync通信异常这些故障场景keepalived处理起来都很吃力而pacemaker可以把每一个资源都纳入监控任何一项异常都会触发切换动作这是它最大的价值。2. 环境规划与基础组件安装2.1 节点角色与网络规划先规划一套最小高可用环境后面所有配置都按这套环境展开。这套环境我通常会放在高可用前置层和K8s集群之间可以是独立的三台机器也可以和master节点复用生产环境建议独立部署避免资源争抢。角色主机名IP地址说明LB-1lb01192.168.1.21主用负载均衡节点LB-2lb02192.168.1.22备用负载均衡节点LB-3lb03192.168.1.23备用负载均衡节点VIP-192.168.1.20虚拟IP对外统一入口Master-1master01192.168.1.11kube-apiserverMaster-2master02192.168.1.12kube-apiserverMaster-3master03192.168.1.13kube-apiserver这里有个网络细节要注意VIP必须和集群节点位于同一网段否则基于ARP的IP漂移机制无法生效。如果一定要跨网段使用VIP那就得依赖路由器做ARP代理或使用BGP方案复杂度就上去了。生产环境大多数场景下LB节点和VIP放在同一个二层网络里就够用。操作系统选择上我用的是CentOS 7.9或者Rocky Linux 8.x这类RHEL系发行版。如果你用Ubuntu软件包名和systemd服务名会有一点差异但整体配置逻辑完全一致。三台LB节点的内核版本、系统版本最好完全一致不然corosync在协议协商上偶尔会出一些奇怪的问题。2.2 基础环境配置与组件安装环境准备阶段有几件事必须提前处理好否则后面集群起不来或者莫名其妙抖动第一件事是主机名解析。三台LB节点必须在 /etc/hosts 里互相写全hostname解析不能依赖DNS。corosync在启动阶段会做节点名称和IP的对应解析如果解析失败节点会一直处于offline状态。192.168.1.21 lb01 192.168.1.22 lb02 192.168.1.23 lb03第二件事是防火墙和SELinux。corosync要使用UDP 5404和5405端口做组播通信haproxy要监听6443端口监控工具可能需要访问2224端口pcsd。如果不想在生产环境排查一个下午的节点为什么总是ring错误建议提前把这些端口放行或者直接关闭防火墙。SELinux如果开启了haproxy绑定非标准端口和pacemaker执行资源脚本都会受到限制我建议在实验环境直接setenforce 0生产环境按安全基线放行具体策略。第三件事是时间同步。corosync对节点间时间偏差比较敏感偏差过大会导致心跳超时和选举异常。用chrony或者ntpd把三台节点同步到同一时间源。组件安装直接使用yum仓库# RHEL/CentOS系 yum install -y haproxy pacemaker pcs fence-agents-all resource-agents corosync # Ubuntu/Debian系 # apt install -y haproxy pacemaker pcs fence-agents resource-agents corosync这里我把 pcs 单独列出来因为它是pacemaker的命令行管理工具早期版本用crm命令管理新版本RHEL 7默认用pcs。下面所有配置操作我都用pcs完成。3. haproxy核心配置与参数细节3.1 四层转发配置与健康检查解析haproxy的功能定位非常纯粹把访问VIP:6443的TCP流量转发到后端的三个kube-apiserver。所以配置文件不需要七层http模式不需要ssl卸载不需要acl路由全是backend server的IP:Port列表。我的核心配置如下global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin user haproxy group haproxy daemon nbproc 1 defaults log global mode tcp option tcplog option dontlognull retries 3 timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen k8s-api bind 0.0.0.0:6443 mode tcp balance roundrobin option tcp-check server master01 192.168.1.11:6443 check inter 3s fall 2 rise 2 server master02 192.168.1.12:6443 check inter 3s fall 2 rise 2 server master03 192.168.1.13:6443 check inter 3s fall 2 rise 2逐个参数说下我的考虑mode tcpK8s的apiserver默认是TLS加密通信在这种场景下haproxy只能用四层模式直接透传TCP流量不做TLS终止也做不了因为证书握手需要完整TLS上下文。option tcp-check这是四层健康检查的关键。haproxy会和后端apiserver建立TCP连接连接成功就认为节点健康。apiserver的6443端口有TLS监听但不影响TCP三次握手完成。这里我刻意没有用更复杂的tcp-check send/expect字符串因为apiserver的TLS握手响应内容因证书配置不同有差异用简单的connect检查最稳。check inter 3s fall 2 rise 2每3秒检查一次连续失败2次标记为down连续成功2次标记为up。生产环境这个参数需要根据实际网络质量微调。如果内网环境比较稳定可以把fall调成3避免偶发抖动导致后端被摘除如果机器负载经常很高检查间隔可以延长到5秒。timeout client/server 50000ms在实际生产里apiserver的请求偶尔会持续较长时间例如大量Pod删除时watch请求长时间保持。50秒超时不能设置得太短否则长连接被haproxy强行断开客户端会体验到avaliable变成unavailable的诡异闪断。如果你发现kubectl经常报connection reset先看看haproxy的超时时间是不是不够。3.2 配置校验与平滑重载实践haproxy配置文件的语法校验用一个命令搞定haproxy -c -f /etc/haproxy/haproxy.cfg这个命令只做语法解析不做实际启动非常适合改完配置后先校验再重载。校验通过后用systemctl重载服务systemctl reload haproxy注意这里用的是reload而不是restart。haproxy支持平滑重载旧进程继续处理已有连接新进程接管新连接连接不会中断。但这要求haproxy以daemon模式运行并且正确配置了socket否则reload可能会失败。实测下来reload过程中kubectl那边的长连接几乎感知不到变化。如果是restartTCP连接会全部重置客户端需要重连体验就会差很多。所以配置变更走reload是底线操作。4. pacemaker集群资源编排实战4.1 corosync集群创建pacemaker依赖corosync做底层通信和成员管理二者配合的集群搭建逻辑是这样的corosync解决哪些节点是活的这个问题pacemaker在这个基础上决策资源应该跑在哪。先启动pcsd并设置hacluster用户密码systemctl enable --now pcsd passwd hacluster # 设置统一密码三台节点保持相同然后在一台节点上执行集群认证pcs host auth lb01 lb02 lb03 -u hacluster -p 你的密码接着创建集群。走到这一步有个重要选项transport。远古版本用组播现代环境更推荐单播。组播在部分云网络环境会被禁用单播更稳。pcs cluster setup k8s-lb lb01 lb02 lb03 transport udp这里我选择了UDP单播传输。如果你所在环境网络质量一般也可以用transport knet这是corosync 3.x之后新的网络内核支持加密和自动链路切换。实测中knet在丢包环境中更稳但配置稍微复杂一丢丢。启动集群pcs cluster start --all pcs cluster enable --all启动后查看状态pcs status正常情况下三台节点都应该是Online状态。如果某个节点一直显示Offline第一件事就是检查corosync日志/var/log/cluster/corosync.log重点看有没有Link send error、Ring 0相关报错。4.2 高可用资源定义与约束资源编排是pacemaker的核心魅力所在。我们一共要创建三类资源VIP资源IPaddr2haproxy服务资源systemd: haproxy对这两个资源的约束关系创建VIP资源pcs resource create lb-vip ocf:heartbeat:IPaddr2 \ ip192.168.1.20 cidr_netmask24 niceth0 \ op monitor interval5sIPaddr2是pacemaker自带的资源代理负责IP地址的增删和ARP广播。op monitor interval5s表示每5秒检测一次VIP是否正常。这里有个细节nic参数建议显式指定如果默认网卡名在部分发行版里是ens192之类的不指定会导致VIP绑定到错误的接口上。创建haproxy服务资源pcs resource create lb-haproxy systemd:haproxy \ op monitor interval5ssystemd:haproxy是pacemaker的systemd资源代理它做的事情就是跟随集群状态启动/停止haproxy服务并且周期性确认haproxy进程是否存活。如果haproxy进程崩溃monitor会在5秒内发现异常并在本节点重启haproxy。这里要停下来解释一个很多人踩过的坑为什么不直接systemd enable haproxy让它开机自启因为如果haproxy在系统启动时被systemd拉起了而pacemaker以为这个资源不在集群控制范围内启动顺序和资源状态就会错乱出现VIP在A节点、haproxy在B节点的尴尬局面。正确做法是把haproxy的systemd自启禁止掉完全交给pacemaker来管理systemctl disable haproxy --now4.3 VIP和haproxy的联动资源创建完了还不行必须加约束否则pacemaker不知道这两个资源该怎么配合。我用两条约束搞定第一条是排列约束colocation要求VIP和haproxy必须运行在同一台节点上pcs constraint colocation add lb-vip with lb-haproxy INFINITY第二条是顺序约束order要求haproxy先启动VIP后启动pcs constraint order start lb-haproxy then start lb-vip顺序约束为什么是haproxy先启动而不是反过来因为haproxy监听的地址是0.0.0.0:6443它不需要VIP处于up状态也能正常监听。反过来如果VIP先绑定了haproxy还没起来中间会有一段流量黑洞时间kubectl连过来会直接拒绝连接。先启动haproxy再绑定VIP流量入口真正对外提供服务时后端已经是就绪状态了。约束配置完成后整体资源状态可以用pcs status查看。理想状态是三台节点上有一台同时运行着lb-vip和lb-haproxy另外两台节点不运行任何资源但成员状态是Online。当主节点宕机时这两台备用节点中的一个会接管VIP并拉起haproxy服务。5. 故障切换验证与流量路径复盘5.1 手动故障演练步骤资源编排完成以后最重要的不是看pcs status是不是全绿色而是做故障演练确认切换动作真的符合预期。我每周例行的故障演练流程是这样的场景一优雅切主pcs resource relocate lb-haproxy lb02这条命令会把这个资源从当前节点请走到指定节点。执行后观察资源状态pcs status预期结果lb-vip和lb-haproxy同时出现在lb02上lb01上的VIP被释放。整个过程中用kubectl连续执行命令应该不会感知到任何中断。场景二模拟宕机在lb01上执行systemctl stop corosync模拟节点异常退出。预期结果集群在心跳超时后默认约10-30秒lb02或lb03接管资源。这个场景最有价值因为它能暴露出很多潜在问题比如STONITH配置不当导致节点无法被fence、corosync通信异常导致分裂、资源代理脚本在cgroup环境下启动失败等。场景三进程级故障pkill -9 haproxy预期结果pacemaker在5秒内检测到haproxy进程消失自动重新拉起。VIP不受影响因为haproxy还在原来的节点上重新启动。5.2 切换过程时序与调优pacemaker切换的过程其实是一个选举 资源迁移的组合动作大致时序如下corosync检测到节点A心跳丢失更新成员状态pacemaker的DC节点Designated Controller评估资源状态DC发现资源依赖的节点失效触发资源迁移决策在存活节点上执行资源启动先haproxy后VIP如果配置了fencing先隔离故障节点再启动资源这里最容易影响RTO恢复时间目标的是第1步和第2步。corosync的token超时时间默认是3000ms也就是说节点故障后最多约3秒时间确认死亡。如果网络抖动频繁容易误判。生产环境我会把token调到5000ms左右pcs cluster setup时加参数pcs cluster setup k8s-lb lb01 lb02 lb03 transport udp token5000不要把token调得太激进。我之前在一个跨机房的场景里把token调成1000ms结果每半天误切换一次负载均衡节点频繁漂移反而比单点故障影响更大。6. 常见问题与避坑指南6.1 配置与排障高频问题把我在实际维护中遇到的问题整理成一张速查表不一定全但覆盖了90%的高发场景问题现象排查思路解决建议节点状态Offline检查corosync日志、UDP 5404/5405端口、防火墙确认/etc/hosts解析一致协议栈版本一致VIP绑不到指定网卡检查nic参数显式指定网卡名如eth0/ens192haproxy起不来journalctl看systemd日志检查SELinux策略、配置文件语法、6443端口占用kubectl间歇性断连检查haproxy超时配置调整timeout client/server为50s以上资源漂移后VIP仍在原节点检查是否残留地址未清空手动ip addr del清楚后再让pacemaker接管节点网络分区导致集群分裂确认corosync是否配了多链路生产环境建议双网卡冗余有一个场景值得单独提醒多路径存储和VIP的冲突。如果你的环境里用了multipath它可能会在系统启动时检查VIP地址是否存在导致VIP绑定时出现地址已存在的报错。我遇到过两次解决方法是给multipath加黑名单或者调整VIP的启动资源顺序让IPaddr2先执行清理。6.2 运维心法总结最后分享几个日常维护中验证过的心得这些不在官方文档的突出位置但非常影响实际体验第一永远不要让haproxy和VIP资源散落在不同章节管理。pacemaker的约束一旦建好就不要手动在节点上执行systemctl start haproxy之类操作。一旦手动拉起过haproxypacemarker的资源状态缓存可能就乱了表现为资源一直显示stop但实际进程在跑后续漂移会出妖蛾子。第二pcs status不等于一切正常。pcs status只能反映pacemaker视角的资源状态haproxy配置写错了但进程能启动、后端server全部标记down这些它都看不出来。我的习惯是配合haproxy的socket命令定期检查后端节点健康状态echo show stat | socat stdio /var/lib/haproxy/haproxy.sock如果master01的status是DOWN说明haproxy已经探到apiserver有异常虽然VIP还是漂在主节点但实际流量被摘除了一部分。第三版本升级一定先在一台节点上试。pacemaker的大版本升级常常会动资源代理的写法比如RHEL 7的pcs命令到RHEL 8/9就有不少差异。升级之前先在测试环境跑一遍pcs resource config导出配置和升级后的语法做对比。生产环境我见过因为升级导致ocf:heartbeat:IPaddr2参数解析失败的案例影响面是整个集群断连。第四监控就要监控到链路。负载均衡层的监控不能只看进程在不在要看VIP到后端的整条链路通不通。我建议在外部监控点定期探测VIP的6443端口同时用haproxy的统计接口拿到每个backeend的队列深度。当某个apiserver的请求排队超过阈值时即使haproxy还在正常工作也要触发告警因为后端性能已经出问题了。第五清空集群要走pcs cluster stop --all再逐个节点清理。很多运维图省事直接reboot节点如果corosync的ring信息没清理干净重启后可能会出现旧节点身份残留导致新节点加入失败。用pcs cluster stop --all带上--force参数可以让节点彻底退出集群再重新加入时干净很多。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/21 13:47:01
lingbot-map实战:从架构设计到落地的地图可视化指南
2026/10/21 13:47:01
Harbor镜像仓库高可用:HAProxy主备切换与故障演练
2026/10/21 13:47:01
生产级K8s高可用流量入口:haproxy+pacemaker负载均衡集群详解
2026/10/21 16:54:50
Docker系统性入门:从镜像构建到容器运行的底层原理
2026/10/21 16:54:49
Carsim与Simulink联合仿真横向控制:从坐标匹配到预瞄算法实战
2026/10/21 16:54:49
Altium原理图位号自动标注:规则设置与工程实践全解析
2026/10/21 16:54:49
CELSMA:混沌增强领导者机制的黏菌算法求解分布式置换流水车间调度
2026/10/21 16:54:49
模块化数据采集仪实战:DAQ970A与DAQM901A多通道自动巡检指南
2026/10/21 16:49:48
Windows逆向工程实战:微信QQ防撤回补丁原理与Hook实现
2026/10/21 0:01:44
ClickHouse实战:从列式存储到亿级数据秒级查询
2026/10/21 0:01:44
高效筛选arXiv机器学习论文:四步法实战指南
2026/10/21 0:01:44
Python爬取百度迁徙数据:接口签名、反爬与SQLite存储实战
2026/10/20 16:07:12
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/21 14:47:26
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/20 16:49:38
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/20 2:24:03
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/20 2:23:57
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/20 2:23:53
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)