Google托管实例组缩容负载均衡异常,求正确关机脚本
GCP托管实例组缩容时避免负载均衡误发请求的正确关机方案
你的问题核心是默认关机脚本执行时机过晚,赶在实例网络断开后才运行,导致健康检查失效操作没来得及被负载均衡器感知。以下是可靠的解决方法:
核心思路
通过systemd配置预关机钩子,在实例关机流程的最早期触发健康检查失效操作,等待足够时间让负载均衡器完成实例剔除,再继续关机流程。
具体步骤
1. 编写预关机脚本
创建/opt/prepare-for-shutdown.sh脚本,根据你的健康检查类型做对应操作:
#!/bin/bash # 示例1:HTTP健康检查返回500(假设健康检查端口是8080,路径/health) echo -e "HTTP/1.1 500 Service Unavailable\r\nContent-Length: 0\r\n\r\n" | nc -l -p 8080 > /dev/null 2>&1 & # 示例2:TCP健康检查直接关闭监听端口(比如应用端口是8080) # fuser -k 8080/tcp # 示例3:修改nginx健康检查配置返回500 # sed -i 's/return 200 OK;/return 500 Service Unavailable;/' /etc/nginx/conf.d/health_check.conf # nginx -s reload # 等待负载均衡器完成健康检查剔除(时间=健康检查间隔*(不健康阈值+1),比如间隔10s、阈值2次,就等30s) sleep 30 # 可选:停止应用服务,避免残留请求处理 # systemctl stop your-application.service
2. 配置systemd预关机服务
创建/etc/systemd/system/pre-shutdown.service文件,确保脚本在关机前优先执行:
[Unit] Description=Pre-shutdown health check fail hook DefaultDependencies=no Before=shutdown.target reboot.target halt.target [Service] Type=oneshot ExecStart=/opt/prepare-for-shutdown.sh TimeoutSec=0 RemainAfterExit=yes [Install] WantedBy=shutdown.target reboot.target halt.target
3. 在实例模板中配置启动脚本
把以下命令加入实例模板的启动脚本,确保实例启动时就启用该服务:
# 设置脚本权限 chmod +x /opt/prepare-for-shutdown.sh # 重载systemd并启用服务 systemctl daemon-reload systemctl enable pre-shutdown.service
关键注意事项
- 等待时间必须匹配你的健康检查配置:比如健康检查间隔10s、不健康阈值2次,至少等待30s,确保负载均衡器完成3次检查(1次正常+2次失败)后剔除实例。
- 健康检查失效的操作要和你的实际检查逻辑完全对应,确保负载均衡器能准确识别实例为不健康状态。
- 不要依赖GCP默认的
shutdown-script,它的执行时机在关机流程后期,网络已经开始断开,无法被负载均衡器感知。
内容的提问来源于stack exchange,提问作者Markus Hervén
相关产品推荐
相关产品推荐

