SOP — 清理 haproxy backend 中已永久关闭的 master-02/03¶
变更主题:删去 haproxy 后端列表里指向已关闭虚机(192.168.31.11/.12)的两条记录 执行时间:2026-09-29 20:51(CST)|主机:
k8s-master-01(192.168.31.10) 承接:k8s-restart-16443-selinux-20260929/SOP.md第 8 章遗留项
目录¶
- 背景 2. 目标 3. 前置条件 4. 影响范围 5. 分步操作 6. 验证 7. 回滚 8. 风险说明
附录 A:备份与留档|附录 B:交付物清单
1. 背景¶
2026-09-16 集群按计划缩容为单控制面后(见 k8s_136_cluster_deploy/docs/SOP.md 5.10),
k8s-master-02(.11) 与 k8s-master-03(.12) 两台虚机已关闭,并禁用 libvirt autostart
(避免宿主机重启后自动拉起残缺控制面)。
但 /etc/haproxy/haproxy.cfg 的 backend 仍保留三条 server 记录,其中两条指向这两台已不存在的虚机:
backend k8s-api-backend
option tcp-check
server master-1 192.168.31.10:6443 check inter 2000 fall 2 rise 2
server master-2 192.168.31.11:6443 check inter 2000 fall 2 rise 2 ← 目标不存在
server master-3 192.168.31.12:6443 check inter 2000 fall 2 rise 2 ← 目标不存在
后果:haproxy 每 2 秒对两个不可达目标做一次健康检查,持续产生 Layer4 connection problem /
is DOWN 告警,污染 journalctl -u haproxy 日志,也让运维难以从日志中辨认真正的后端异常。
2. 目标¶
- backend 只保留
master-1(192.168.31.10:6443); haproxy -c配置校验通过;- reload 生效后 haproxy 仍
active且监听0.0.0.0:16443; curl -sk https://192.168.31.8:16443/healthz返回ok;- 日志中不再出现 master-2/3 相关告警。
3. 前置条件¶
| 项 | 要求 |
|---|---|
| 权限 | 本机 root 免密 ssh 到 k8s-master-01 |
| 现状 | systemctl is-active haproxy 为 active(入口正常,见上一份 SOP) |
| 前提确认 | .11/.12 确实不可达(虚机已关闭,非临时故障) |
| 工具 | haproxy(-c 校验)、sed、systemctl |
| 依赖 | 无。apiserver 与业务不受影响 |
4. 影响范围¶
- 主机:仅
k8s-master-01。 - 组件:haproxy 配置与进程。
- 是否停服:否。采用
systemctl reload(unit 的ExecReload为kill -USR2,平滑重载), 已建立的 API 连接不断开。 - 业务影响:无。剩余后端
master-1即当前唯一 apiserver,负载能力不变。 - 窗口:以秒计,无停机窗口要求。
5. 分步操作¶
步骤 1:确认两条后端确实不可达¶
删除前必须确认不是"临时不可达"。若虚机只是暂时关机、日后计划恢复,应改走"标记 disabled"而非删除。
ping -c1 -W2 192.168.31.11; ping -c1 -W2 192.168.31.12
# 预期:均不可达(本环境两虚机已关闭且禁用 autostart)
步骤 2:备份原配置(原位 .bak)¶
坑:该文件含 haproxy stats 口令明文,不在项目目录留副本,备份保持在 /etc/haproxy/ 原位,
并在 backup/README.md 登记位置与用途(见附录 A)。
TS=$(date +%Y%m%d-%H%M%S)
ssh root@192.168.31.10 "cp -a /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak.$TS"
# 实测生成:/etc/haproxy/haproxy.cfg.bak.20260929-205100(585 字节,变更前版本)
步骤 3:删除 master-2 / master-3 两条记录¶
ssh root@192.168.31.10 "sed -i '/^ server master-[23] /d' /etc/haproxy/haproxy.cfg"
ssh root@192.168.31.10 "grep -nE 'backend|server' /etc/haproxy/haproxy.cfg"
# 预期:仅剩 server master-1 192.168.31.10:6443 ...
失败判断:若 grep 仍能看到 master-2/3 → 匹配模式与实际缩进不符,先恢复备份再核对原文重做。
步骤 4:配置校验¶
reload 前先校验,避免用坏配置打断入口。
ssh root@192.168.31.10 "haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d"
# 预期:Configuration file is valid(Warnings 为日志格式告警,与本次无关)
步骤 5:平滑重载¶
ssh root@192.168.31.10 "systemctl reload haproxy && sleep 2 && systemctl is-active haproxy"
ssh root@192.168.31.10 "ss -lntp | grep 16443"
# 预期:active;0.0.0.0:16443 LISTEN
6. 验证¶
# 1) 仅剩 master-1,且无 master-2/3 告警
ssh root@192.168.31.10 "journalctl -u haproxy --since '-3min' --no-pager -l | grep -E 'UP|DOWN|Reloaded'"
# 实测:Reloaded HAProxy Load Balancer + Loading success;无 DOWN
# 2) 入口健康
ssh root@192.168.31.10 "curl -sk --max-time 6 https://192.168.31.8:16443/healthz" # 预期:ok
# 3) 集群可见
kubectl get nodes # 预期:4 节点 Ready
实测结果:以上三项全部通过;配置由 585 字节缩为 449 字节,reload 后 haproxy 仍 active 并监听 16443。
7. 回滚¶
ssh root@192.168.31.10 "cp -a /etc/haproxy/haproxy.cfg.bak.20260929-205100 /etc/haproxy/haproxy.cfg"
ssh root@192.168.31.10 "haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d && systemctl reload haproxy"
回滚后验证:配置恢复为 585 字节、含三条 server 记录;haproxy active、16443 监听正常。
备份存放位置:k8s-master-01:/etc/haproxy/haproxy.cfg.bak.20260929-205100(原位,含口令,不落项目目录);
对应的远端 haproxy.cfg 变更前快照已在本 SOP 第 1 章写明内容结构。台账见本主题 backup/README.md。
8. 风险说明¶
| 风险 | 说明 | 缓解 |
|---|---|---|
| 日后扩回 3 控制面时需重新添加后端 | 本次删除后,扩回需补 master-2/3 两条记录 | 扩回流程本就由部署工程重跑生成配置(k8s_136_cluster_deploy/docs/RUNBOOK.md 第 5 章),手工配置被覆盖,不构成额外负担 |
| 误删有效后端 | 若 .11/.12 其实只是临时关机,删除会削弱冗余 | 步骤 1 先确认不可达;备份可一键回滚 |
| 备份含明文口令 | .bak 文件含 stats auth 口令 |
保持在 /etc/haproxy/(root 600 权限目录),不复制到项目目录,不在文档中记录口令内容 |
| 配置与工程定义漂移 | 手工改动未同步回 deploy.yaml 模板 |
本次属"与现状对齐"的清理;若部署工程会重写该文件,重跑后仍会带出 master-2/3——待确认项(见附录 B) |
附录 A:备份与留档¶
- 原位备份:
k8s-master-01:/etc/haproxy/haproxy.cfg.bak.20260929-205100 - 未在项目目录留副本的原因:文件含 stats 口令明文(
stats auth),按凭据管理约定不落交付物目录 - 登记位置:
k8s-followup-20260929/backup/README.md
附录 B:交付物清单与待确认项¶
| 文件 | 内容 |
|---|---|
SOP.md |
本文件:backend 清理的实施、验证与回滚 |
20260929-K8s全节点-SELinux-AVC巡检报告.md |
同批执行的只读巡检结论 |
backup/README.md |
备份台账(登记远程原位备份) |
已确认(2026-09-29 20:54 复查工程源码):k8s_136_cluster_deploy/deployer.py 的
_render_haproxy_cfg() 按 config/deploy.yaml 中全部 role=master 节点(3 台)渲染后端列表;
写入函数 _write() 的语义为「哈希一致跳过,不一致先备份再覆盖」。故:
- 重跑部署工程会把本 SOP 删除的 master-2/3 两条后端写回,本次清理属临时性;
- 缩容/扩回工具
control_plane_scale.py不写该文件(其注释声明"保留后端列表"是设计意图),不受影响。
决策(用户确认):保持本次清理现状,不做工程侧收敛(不在 _render_haproxy_cfg 中增加"只渲染启用 master"的逻辑)。
重跑工程后如再需消除噪音,按本 SOP 步骤 3 重做一次即可。
来源:
/home/rain/Documents/k8s_ins/k8s-followup-20260929/SOP.md| 最后更新:2026-09-29 20:54(由build/sync.py同步,请勿在站点侧修改)