把Kubernetes高可用集群里的“流量入口”这件事彻底讲透。之前不少朋友在搭生产级K8s时习惯先把三个master节点装好再在每台master前面挂一个Nginx或者用云厂商的SLB结果要么单点还在要么云上LB的会话保持和健康检查调得头疼。今天要说的这套方案是我在多套生产环境里实际用过的组合haproxy做四层负载均衡pacemaker做高可用仲裁两者合起来就是一套不依赖云厂商、纯自建的k8s高可用负载均衡集群。它解决的核心问题很明确让多个kube-apiserver实例有一个统一、稳定、自动故障转移的接入入口同时也适合那些机房自建、没有现成云LB的场景。这套方案适合谁看如果你正在规划生产级K8s集群或者你已经有了多master节点但入口还挂在单台LB上又或者你在对比keepalived和pacemaker的差异那这篇文章值得认真读完。我不会只贴命令还会把为什么这么配置、踩过的坑、验证方法都讲清楚照着搭即可直接用。1. 整体设计与需求拆解1.1 高可用负载均衡集群在K8s架构中的位置Kubernetes控制平面由多个组件组成其中kube-apiserver是所有请求的必经入口。无论是kubectl、kubelet、controller-manager、scheduler还是集群内组件最终都要通过apiserver完成资源读写。生产环境为了保证控制平面不挂通常会部署三个甚至更多master节点每个节点上跑一个apiserver。但这里有个问题你总不能把三个apiserver地址都填到kubectl配置里也没法让每个kubelet分别连不同地址。需要一个前置的统一入口把这多个apiserver合并成一个虚拟地址对外提供服务。这个入口就是负载均衡层。K8s官方架构图里也明确画出了这一层通常叫Load Balancer但官方没有规定你必须用什么实现所以给了我们自建的发挥空间。这套方案中的haproxy承担的就是这样的角色它监听一个虚拟IPVIP把来自客户端kubectl、kubelet、controller-manager等的6443端口请求按照轮询算法转发到后端三个apiserver节点。而pacemaker负责两件事一是保证这个VIP永远只在一台节点上生效节点挂了自动漂移到另一台二是保证haproxy进程宕了也能自动拉起或者把VIP一并带走让后端的故障对客户端完全透明。1.2 为什么不直接用Nginx或Keepalived很多人第一反应是“负载均衡用Nginx不就行了吗”或者“高可用用Keepalived不挺简单吗”。这两种方案在小型环境确实能用但放在K8s控平接入层这个具体场景里各有各的别扭。Nginx在做TCP四层转发时upstream配置本身需要手动维护对后端节点的健康检查能力和动态调整能力不如haproxy灵活。更重要的是Nginx本身不解决“谁持有VIP、故障了怎么切换”的问题你得再叠一层Keepalived这就等于要维护两套配置体系。而haproxy自带的就是专门做四层负载均衡的工具配置语义清晰统计页面强大排障起来非常直观。再说Keepalived它实现HA的核心是VRRP协议本质上是“主备抢占”模型。而pacemaker是基于集群资源管理的成熟方案支持的不只是IP漂移还有服务、文件系统、虚拟IP等多种资源的统一编排。在K8s场景里我们需要的是“VIP haproxy服务”作为一个资源组统一管理、按顺序启动、按约束调度这正是pacemaker的强项。换句话说Keepalived把VIP切过去了haproxy是否启动、启动顺序、谁先谁后这些都得靠脚本自己折腾pacemaker则用一个resource group就把这些事标准化了。1.3 方案适用场景与边界这套haproxypacemaker组合最适合的场景是物理机或自建机房的K8s集群网络环境可控且没有现成的云负载均衡产品可用。比如内网IDC环境、政务云裸金属区、混合云自建区域这些东西经常没有云LB或者云LB要收费且限制多用本文方案最踏实。不适用的场景也有如果你的环境就是公有云且云LB已经做得很好比如健康检查、多可用区容灾都成熟那直接用云LB更省事如果只有两个master节点且业务量不大可以用更轻量的keepalived如果集群规模极大、后端节点几十个可能要考虑专门的四层负载均衡硬件或者云LB毕竟haproxy单机性能总有上限。提示本文所有配置基于haproxy 2.x版本和pacemaker 2.0/PCS版本CentOS 7/8或Rocky Linux 8/9均适用。不同发行版命令略有差异我会在对应位置标注。2. 关键原理拆解haproxy与pacemaker各自干了什么2.1 haproxy的四层负载均衡是如何工作的haproxy支持两种核心代理模式七层HTTP模式和四层TCP模式。K8s的apiserver走HTTPS协议我们这里不需要做HTTP头解析、URL路由这些只需要把TCP流量原封不动地从客户端搬到apiserver所以选用四层模式。在haproxy里这个能力叫TCP proxy配置段写在一组listen或backend里mode那行填tcp。四层转发意味着haproxy根本不关心HTTP请求内容它只维护一条TCP连接和数据流的双向搬运。这对性能极其友好因为不需要读写和解析应用层协议CPU开销小、延迟低。从内核角度看haproxy做的是用户态代理但配合epoll事件驱动模型在普通物理机上处理几万并发毫无压力对于K8s客户端数量来说绰绰有余。haproxy的核心优势之一是内置健康检查。对于TCP后端可以配置tcp-check定期向6443端口发起TCP连接尝试甚至可以通过配置发送一段数据、期望一段响应来确认apiserver真的活着。这样比单纯探测端口活性更可靠——端口通不代表进程健康但apiserver的HTTPS握手能完成基本能确认它处于可服务状态。2.2 pacemaker的集群资源管理与故障转移逻辑pacemaker是一个分布式资源管理器它运行在多个节点上组成一个集群通过选举出一个Designated CoordinatorDC来决策资源应该运行在哪个节点。它管理的最小单位叫“资源”resource每类资源有对应的Resource Agent也就是一个脚本或程序用来执行start、stop、monitor等操作。在我们的场景里需要管理两类资源一个是IPaddr2类型的虚拟IP资源负责在节点上配置/解除VIP另一个是systemd类型的haproxy服务资源负责启动、停止、监控haproxy服务。pacemaker把这两个资源放在同一个资源组里确保它们要么在同一台节点上一同运行要么一同停止不存在VIP在A节点、服务在B节点的错位情况。故障转移的逻辑是这样的pacemaker通过corosync进行节点间心跳通信默认情况下所有节点互相通信并同步集群状态。当某个节点的haproxy进程挂了pacemarker的本机资源监控会立刻检测到monitor失败先把整个资源组在当前节点停止然后根据资源约束和节点得分把资源组调度到另一台健康节点上启动。同样的如果整台节点宕机断电corosync会在指定超时通常几秒后判定节点失联其他节点把资源组接管过来。这里有个关键概念叫fencing隔离。虚拟IP这种资源有个特性如果原来持有VIP的节点只是网络分区但进程还在而另一台节点又把这个VIP绑定到自己的网卡上就可能出现IP冲突、两边同时持有VIP后果就是流量进入两个后端状态错乱。所以生产环境必须配置stonith设备通常是带外管理控制器比如服务器的BMC/IPMI或者专门的PDU电源管理在故障节点被剔除前先把它强制断电或重启保证同一时刻只有一个节点能持有VIP。这也是pacemaker设计上比keepalived更严谨的地方——它不允许“脑裂”这种情况存在。2.3 为什么VIP漂移能对K8s客户端透明对K8s组件来说它们访问的地址就是haproxy上的VIP加6443端口。VIP本质是一个额外的IP地址绑定在某块网卡上。正常情况下A节点持有VIP所有流量都进A节点的haproxy。当A节点故障pacemaker做的动作是在A节点上删除VIPifconfig/ip addr del在B节点上添加VIPip addr add然后B节点的haproxy立刻开始对外服务。从客户端视角看它访问的IP没变、端口没变只是背后的服务器变了所以没有任何感知。K8s各组件的连接池可能会有短时间的连接重置但apiserver客户端库通常都有重试机制下一次请求就恢复正常了。这也是为什么给K8s用的LB必须做长连接友好和重试容忍haproxy的纯TCP代理天然满足这一点。3. 实操落地全过程从零搭建haproxypacemaker集群3.1 架构规划与节点准备以三台LB节点为例设置如下。为了措辞方便节点代号我直接用lb01、lb02、lb03代替域名部分使用内部测试域实际操作时替换为你的环境变量。节点IP地址角色lb01192.168.100.21haproxypacemakerlb02192.168.100.22haproxypacemakerlb03192.168.100.23haproxypacemakerVIP192.168.100.20集群对外服务IP后端K8s master节点假设三台节点对应apiserver地址master01192.168.100.11:6443master02192.168.100.12:6443master03192.168.100.13:6443此外每台节点必须满足几个前置条件操作系统推荐Rocky Linux 8.6以上或CentOS 7.9均可内核版本无特殊要求。节点之间能通过内网IP互通且开放corosync所需的组播/单播端口默认5404、5405单播模式用5405即可。时间必须同步。重要程度不高你可以在pacemaker集群里配置timeout甩锅但更稳妥的做法是每台节点装chrony保证时间偏差在100毫秒内。如果使用防火墙需要放行以下端口6443对客户端开放通过VIP、5410haproxy统计页面端口、5405corosync集群通信、2224/3121pcsd集群管理端口。每台节点的主机名要唯一且能互相解析。建议在/etc/hosts里直接配好。3.2 haproxy安装与配置详解在三台节点上分别安装haproxy# Rocky Linux 8/9 dnf install -y haproxy # CentOS 7 yum install -y haproxyhaproxy的主配置文件在/etc/haproxy/haproxy.cfg。默认配置有global和defaults段我们需要在后面自定义前端和后端但在K8s场景里直接用listen块最简单把监听、转发、健康检查都写在同一个块里。下面是一份可以照抄的配置注意根据实际情况修改IP。vim /etc/haproxy/haproxy.cfgglobal log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats defaults mode tcp log global option tcplog option dontlognull option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout check 10s maxconn 3000 # 前端入口监听VIP的6443端口 frontend k8s-api bind *:6443 default_backend k8s-apiserver # 后端三个apiserver节点 backend k8s-apiserver balance roundrobin option tcp-check tcp-check connect tcp-check send-proxy server master01 192.168.100.11:6443 check inter 3s fall 3 rise 2 weight 1 server master02 192.168.100.12:6443 check inter 3s fall 3 rise 2 weight 1 server master03 192.168.100.13:6443 check inter 3s fall 3 rise 2 weight 1 # 统计页面便于排障 listen stats bind *:5410 mode http stats enable stats uri /stats stats refresh 10s stats auth admin:admin123这里有几个细节要说明。第一balance roundrobin是轮询算法对apiserver这种无状态应用很合适能均匀分配请求。老版本haproxy里roundrobin在服务器动态增删时会暂时不平滑但2.x版本已经修复可以放心。第二tcp-check send-proxy这句话要特别注意。它表示haproxy会向后端发送一个代理协议头。Kubernetes的apiserver默认支持代理协议吗其实是支持的如果apiserver启动参数里配置了对应处理。但如果你的apiserver没有启用--proxy-protocol设置这里会导致后端拒绝连接。注意如果apiserver没有启用PROXY protocol请不要写tcp-check send-proxy这一行。多数场景下我们其实不需要它直接把这一行删掉仅保留tcp-check connect就够了。我在生产里习惯只做TCP拨号检查简单可靠。第三check inter 3s fall 3 rise 2表示每3秒探测一次连续3次失败判定为down连续2次成功判定为up。对K8s控平这种组件这个频率够用不会给master节点带来额外压力。配置写好后启动haproxy并设置开机自启systemctl enable --now haproxy systemctl status haproxy curl http://127.0.0.1:5410/stats用浏览器或curl访问统计页面能看到后端三个server的健康状态。此时还没配VIPhaproxy监听的是节点的所有网卡地址测试可以直接用节点IP加6443访问确认转发链路是好的。3.3 corosync与pacemaker集群初始化先安装集群相关软件包。三台节点都要执行# Rocky Linux 8/9 dnf install -y pacemaker pcs fence-agents-all # CentOS 7 yum install -y pacemaker pcs fence-agents-all设置pcs管理用户的口令默认用户是haclusterpasswd hacluster启动pcsd服务并设置开机自启systemctl enable --now pcsd接下来在任意一台节点上这里选lb01创建集群并加入另外两台。注意三台节点的主机名要能互相解析前面提过的hosts配置必须完成。pcs host auth lb01 lb02 lb03 -u hacluster -p 你的口令 pcs cluster setup k8s-lb-cluster lb01 lb02 lb03 --transport udp --force这条命令会生成corosync的配置文件/etc/corosync/corosync.conf默认使用UDP组播方式通信。如果你的网络环境禁用了组播很多云VPC禁组播就需要改成单播模式在setup参数里加上pcs cluster setup k8s-lb-cluster lb01 lb02 lb03 --transport udp --force --token 5000单播模式下corosync会从配置中读取interface段里的member IP列表进行点对点通信同样能工作只是多了一条静态对端配置。启动集群并设置开机自启pcs cluster start --all pcs cluster enable --all检查集群状态pcs status正常情况下应该看到三台节点都在线集群没有配置任何资源也没有stonith设备报错。此时如果pcs status里出现资源相关的红色警告没关系因为还没有资源。3.4 配置资源组VIP haproxy服务现在核心操作来了。我们需要定义两个资源然后把它们放进同一个组里让pacemaker统一管理。先创建虚拟IP资源pcs resource create vip_k8s ocf:heartbeat:IPaddr2 ip192.168.100.20 cidr_netmask24 nicens192 op monitor interval10s timeout20s参数说明ocf:heartbeat:IPaddr2是pacemaker自带的IP地址资源脚本ip就是我们的VIPcidr_netmask按实际子网填写nic换成实际网卡名用ip addr查看op monitor interval10s表示每10秒检查一次IP是否还在。如果你的网络环境需要指定广播地址可以加broadcast192.168.100.255。再创建haproxy服务资源pcs resource create haproxy_svc systemd:haproxy op monitor interval10s timeout20s on-failrestartsystemd:haproxy表示pacemaker通过systemd管理haproxy服务on-failrestart是重要参数如果haproxy进程异常退出pacemaker会在当前节点直接重启该服务而不是立刻把资源组漂移到另一台节点。这个策略适合进程级故障——先尝试快速恢复如果反复失败再考虑切节点。生产实际中haproxy进程本身很稳定偶发崩溃时原地拉起比重启VIP更快更平滑。把两个资源放进同一个资源组pcs resource group add k8s-ha-group vip_k8s haproxy_svc资源组的意义在于VIP和haproxy永远在同一节点上启动顺序是按组内顺序先vip后haproxy停止顺序相反。这样不会出现haproxy起来了但VIP还没绑定的空窗期也不会有VIP绑定了但haproxy没起的摆设状态。查看资源运行情况pcs status正常会输出类似Resource Group: k8s-ha-group vip_k8s (ocf::heartbeat:IPaddr2): Started lb01 haproxy_svc (systemd:haproxy): Started lb01此时在客户端测试用任意节点上的kubectl把server指向https://192.168.100.20:6443应该能正常访问apiserver并发现请求被轮询到不同的master后端。3.5 配置stonith隔离设备生产环境强制要求配置stonith。没有fence设备pacemaker会拒绝在故障节点上启动某些资源或者给出严重警告更重要的是无法安全处理节点失联。最常用的fence设备是基于IPMI的fence_ipmilan。我的建议是先用fence_ipmilan前提是你的服务器BMC支持IPMI 2.0。每台节点分别定义一个对应的fence设备pcs stonith create fence_lb01 fence_ipmilan pcmk_host_listlb01 ipaddr192.168.100.201 loginroot passwd你的BMC密码 lanplus1 pcmk_reboot_actionoff这里ipaddr是lb01的BMC管理口IP通常跟业务网段隔离lanplus1表示用IPMI 2.0加密通道。pcmk_reboot_actionoff是个人偏好pacemaker隔离时直接断电off比reboot更彻底能避免一些键鼠或固件层面的意外。如果你的设备只支持reboot也可以改成reboot但相比offreboot后节点有概率再次加入集群打架风险略高。配好后检查pcs stonith show pcs status如果暂时没有真实BMC设备在测试环境可以用fence_pcmk配合pcmk_host_list做一个空操作模拟但这是临时方案线上绝对不能这么干。3.6 资源约束让VIP按预期漂移刚才三个节点的资源组如果全部健康它会自动选择一个节点运行。默认策略是偏向于得分高的节点在没有额外约束时首个成功启动资源的节点得分较高通常就是lb01。但我们往往希望控制它的倾向比如让优先级最高的节点先持有VIP。用pcs constraint location命令可以设置资源优先在某节点运行。比如希望资源组尽量在lb01和lb02之间切换避免跑到lb03pcs constraint location k8s-ha-group prefers lb01100 pcs constraint location k8s-ha-group prefers lb0250数字越大优先级越高。当lb01在线时资源组一定在lb01lb01故障退避到lb02lb02也挂了才轮到lb03。这种约束对流量路径稳定很有帮助减少VIP乱跳带来的网络设备MAC缓存刷新。另一个必要约束是“资源不要同时跑在哪些节点”这种反亲和性但在我们的场景里只有一个VIP一份haproxy资源不存在同时运行的问题所以不需要配置。如果以后要扩展成多个LB组同时服务不同端口再考虑pcs constraint colocation之类的配置。3.7 验证集群故障转移配完所有东西必须做故障注入验证不然等于白配。第一步验证VIP访问while true; do curl -k https://192.168.100.20:6443/healthz; sleep 1; done正常会一直返回ok。如果有负载均衡轮询的痕迹能看到请求被打到不同apiserver但响应一致。第二步手动停掉当前持有VIP节点的haproxysystemctl stop haproxy # 在lb01上执行 pcs status因为配置了on-failrestart你会发现pacemaker立刻把haproxy拉起来了VIP还在lb01上几乎无感知。第三步模拟整机故障直接拔掉lb01的网线或者systemctl stop corosync.service模拟节点失联。此时pacemaker会发现lb01心跳丢失触发stonith对lb01断电同时资源组在lb02上启动。vip_k8s和haproxy_svc都会变成Started lb02。这一步最能检验配置是否合格。执行后观察pcs status输出重点看Fencing是否被记录Failed Actions: * lb01_reboot_0000: Master/Slave fencing...以及资源是否成功迁移到lb02。整个切换过程通常10秒内完成客户端如果有少量重试完全无所谓。4. 常见问题与排查技巧实录4.1 资源组一直报错haproxy_svc启动失败这个问题出现的概率极高。典型报错是Failed to start haproxy_svc原因往往是haproxy配置语法错误导致systemd起不来。排查思路先手动执行一次启动看具体错误systemctl start haproxy systemctl status haproxy journalctl -u haproxy -n 50确认配置无误后在pacemaker里确认资源定义是否有问题pcs resource config haproxy_svc pcs resource debug-start haproxy_svcpcs resource debug-start可以在命令行直接启动资源代理脚本并打印输出这是排查资源脚本问题的利器比看pcs status的闪烁提示高效得多。一个隐蔽的坑是haproxy在systemd环境下启动时默认会读取/etc/sysconfig/haproxy里的额外参数。如果这个文件里残留了旧的启动参数比如OPTIONS-f /etc/haproxy/haproxy.cfg可能跟默认配置冲突。出现异常时把该文件里多余配置删掉再重启服务。4.2 后端apiserver健康检查一直DOWNhaproxy统计页面上后端server状态不稳定一会儿UP一会儿DOWN或者始终DOWN。这种问题要从三个层面排查。第一端口通不通telnet 192.168.100.11 6443第二检查方法是不是太苛刻。前面提过tcp-check send-proxy的坑如果误加了代理协议头apiserver又没有开启代理协议支持后端就会拒绝连接健康检查必然失败。把发代理协议那行去掉只保留tcp-check connect问题立即消失。第三注意apiserver的证书时间。如果TLS证书过期或时间不准即使TCP能连上TLS握手也会失败haproxy的tcp-check如果配置成了send-proxy后接expect字符串就更容易暴露这个问题。可以通过openssl命令验证openssl s_client -connect 192.168.100.11:6443 -brief如果输出CONNECTION ESTABLISHED说明TLS握手正常证书时间没问题。4.3 VIP漂移后客户端连不上了切换完成后集群状态正常VIP已经漂移到新节点但客户端访问超时。这种情况大概率不是pacemaker问题而是网络层面的问题交换机上原端口的ARP表还残留旧MAC客户端缓存的ARP条目没有刷新。解决思路有两种。第一种是让客户端主动刷新ARP但这不现实不能要求所有客户端都手动清。第二种是pacemaker的IPaddr2资源默认会发送免费ARPgratuitous ARP通告新节点绑定VIP后立刻广播“这个IP对应的MAC是我”交换机收到后刷新端口映射。如果这种现象频繁出现需要检查网卡配置是否启用了arp_ignore、arp_announce等内核参数以及交换机端口是否开启了portfast之类的特性延迟了MAC学习。另外如果VIP绑定在bond网卡上IPaddr2的nic参数务必写上bond设备名不要写物理网卡。否则MAC地址不对免费ARP发出去也无效。4.4 stonith设备配置后仍提示未被fence这是我没少遇到过的问题。pcs status显示节点处于unclean状态但stonith设备没真正生效。敲pcs stonith show看设备状态正常但触发隔离失败。排查顺序检查BMC IP是否可达从存活节点上ping 192.168.100.201不通就说明管理网段问题。检查IPMI凭据用命令在存活节点上手动执行一次fence测试比如验证lb01的BMC是否正确响应。更安全的方式是ipmitool -I lanplus -H 192.168.100.201 -U root -P 密码 chassis status看能否返回电源状态。确认pcmk_host_list里的主机名跟pacemaker节点名完全一致区分大小写。不一致时fence命令会匹配不到目标直接跳过。如果BMC IP和业务IP在同一网段注意BMC网卡是否和业务网卡冲突有时IPMI响应慢导致fence超时可以适当调大pcmk_reboot_timeout。4.5 常见问题速查表症状原因解决办法pcs resource debug-start没有输出且服务状态不对resource agent脚本路径不对检查ocf:heartbeat:IPaddr2里的heartbeat路径是否存在是否缺少ocf包corosync通信超时节点反复加入/离开防火墙未放行5405/UDP放行corosync端口或者改用单播模式VIP ping不通IPaddr2资源没有绑定或绑了但网卡名写错检查pcs status中vip_k8s是否Started以及ip addr看VIP是否生效haproxy日志刷屏连接超时后端地址写错、防火墙拦截逐条telnet检查后端6443pacemaker提示资源冲突、资源找不到资源ID重复或资源未定义到组pcs resource config核对ID删除多余资源后重新定义5. 扩展思考与进阶优化5.1 是否可以把haproxy换成其他LB组件从架构上看haproxy这层可以被任何四层LB替换但换成别的方案要考虑跟pacemaker的兼容性。比如换成nginx四层代理资源代理从systemd:haproxy改成systemd:nginx即可其他逻辑完全一致。比较少见但可行。换成envoy的话配置复杂度会明显上升没必要为这个场景引入重武器。而如果用云厂商的SLB那就直接放弃pacemaker了因为SLB本身完成了高可用VIP由云平台接管不再需要自管IP资源。我的观点是在自建环境里haproxypacemaker是控制平面入口的性价比最优解。它足够简单、足够可靠、社区资料也足够多。5.2 与Keepalived的对比再深入一层很多人纠结keepalived还是pacemaker。说一个个人观察keepalived适合“我只需要一个VIP来回飘”的轻量场景pacemaker适合“我把VIP和服务绑在一起做调度、有依赖关系、需要复杂约束”的场景。K8s接入层表面上看只需要VIP飘但实际上VIP必须伴随着haproxy服务haproxy挂了不能让VIP留在原节点变成黑洞。这个“把服务和IP放在一起”的需求用pacemaker资源组表达最清晰。在可观测性上pacemaker的pcs status、pcs constraint、历史告警日志都更丰富出了问题容易复盘。而keepalived的状态要么看进程、要么看日志很多情况下得靠抓包确认VRRP状态排障成本高一些。5.3 后续还能往哪些方向扩展这套LB集群投入使用后有几个方向可以继续优化。第一把haproxy的统计页面接入监控系统比如Prometheus通过haproxy_exporter采集这样LB层本身的状态就能做到可视化。第二如果apiserver的流量有明显的读写不对称比如写操作多、读缓存命中率低可以考虑给haproxy加option tcp-smart-accept和option tcp-smart-connect这类内核优化参数提升连接处理效率。第三pacemaker本身就是通用集群管理框架这套节点以后如果想复用比如再加一套MySQL高可用虚拟IP也可以往同一个集群里加新的资源组不用另起炉灶。写在最后的一点心得这套方案我在生产环境用了快两年印象最深的一件事是第一次做故障演练直接断电一台LB客户端只出现了一次TCP连接重置下一个请求就自动恢复了kubectl命令全程没感觉到后端切换。那一刻你会觉得之前花时间把haproxy配置、pacemaker约束、fence设备挨个打磨到位是值得的。我个人实操中最想提醒你的是三个点。第一haproxy的配置一定要用haproxy -c提前做语法检查别等到pacemaker资源报错了才回头改。第二fence设备必须真实验证过一次我自己就见过配置了BMC但密码错误导致fence失败的事故这种一旦遇到节点故障资源就卡在unclean状态整个集群都受影响。第三定期做切换演练不要上线了就不管把“拔网线测试”变成季度例行操作你会发现很多隐藏的网络问题是靠演练才暴露出来的。另外在生产环境里千万不要为了省事跳过stonith。pacemaker在未配置stonith时根本不允许资源正常启动这个设计是有道理的。VIP资源最大的风险就是脑裂fence是唯一能安全止血的手段。宁可多花点时间把BMC调通也别拿集群的可用性冒险。如果你打算在云环境里复刻这套方案记得把组播改成单播同时确认云厂商的安全组是否允许IPMI类带外连接——大多数公有云裸金属并不开放这个能力这时候可以评估是不是用云厂商的LB更实际。如果只是在公司内部IDC环境这套方案可以放心落地。有任何配置上的问题欢迎照着文章里的命令逐条核对。多踩几个坑自然就熟了。