cloud-lb-502

云负载均衡返回 502,但直连后端正常;健康检查时好时坏,错误呈间歇性。

现象

客户端经云 LB(AWS ALB/CLB、GCP LB、Azure App Gateway、阿里云 SLB 等)访问返回 502,绕过 LB 直连后端正常;健康检查可能间歇失败,错误集中在发布、扩缩容或空闲之后。

快速定位

先看 LB 侧日志/target 状态,判断 502 是 LB 生成还是后端返回:

aws elbv2 describe-target-health --target-group-arn <tg-arn> --output table
aws s3 cp s3://<alb-log-bucket>/AWSLogs/<account>/elasticloadbalancing/<region>/<date>/<file>.log.gz - | zcat | awk '{print $9, $10}' | sort | uniq -c | sort -nr | head
gcloud compute backend-services get-health <backend-service> --global
gcloud logging read 'resource.type="http_load_balancer" AND jsonPayload.statusDetails!=""' --limit 20 --format json
az network application-gateway show-backend-health -g <rg> -n <gateway>
aliyun slb DescribeHealthStatus --LoadBalancerId <lb-id>

ALB 访问日志中 elb_status_code 是 LB 返回码,target_status_code 是后端返回码;- 表示没拿到响应。CloudWatch 同时对比 HTTPCode_ELB_502_Count 与 HTTPCode_Target_5XX_Count。

再从 VPC 内直连 target,验证安全组和协议:

curl -v --resolve app.example.com:443:<target-ip> https://app.example.com/health
ss -lntp | grep ':<target-port>'

易误判:HTTPCode_ELB_502_Count 是 LB 自己生成的 502(连接失败/响应非法),HTTPCode_Target_5XX_Count 才是后端返回的 5xx;两者根因完全不同。健康检查从 LB 所在子网发起,安全组只放行客户端网段会误杀;NLB 是四层,不产生 HTTP 502,经 NLB 看到的 502 来自后端。

常见根因

  1. 安全组/NACL 未放行来自 LB 节点或 LB 子网的流量,健康检查和转发被拒。
  2. 后端 keepalive 短于 LB idle timeout,LB 复用已关闭连接,出现间歇 502。
  3. 健康检查配置错误或过于敏感:路径、端口、协议、期望状态码、超时和阈值不当。
  4. 后端进程崩溃、OOM 或滚动发布,target_status_code 为 5xx 或无响应。
  5. LB 到 target 的协议不匹配(HTTP/HTTPS、SNI、Host 头),或证书校验失败。
  6. 后端处理时间超过 LB idle/response timeout,或 target connect 超时。
  7. 摘除过快:deregistration delay 太短,连接被硬断;target 提前退出。
  8. IP target 模式下 Pod IP 变化未同步,或跨 AZ/跨 VPC 路由不通。

修复

相关命令

读完自测

  1. HTTPCode_ELB_502_Count 与 HTTPCode_Target_5XX_Count 有什么区别?
  2. 为什么只放行客户端网段的安全组会导致健康检查失败?
  3. ALB 访问日志里 target_status_code 为 - 说明什么?
答案
  1. 前者是 LB 自己生成(没拿到合法响应),后者是后端返回的 5xx。
  2. 健康检查由 LB 节点从其子网发起,源地址不是客户端;需放行 LB 子网或 LB 安全组。
  3. 后端没有返回 HTTP 响应,通常是连接失败、超时或连接被重置。