4. ECS服务与负载均衡集成

在ECS上运行服务时,负载均衡器承担着流量入口的角色。ECS服务与负载均衡的集成并不是“把实例挂上去”这么简单,它涉及目标组注册方式、端口映射模式、健康检查判定、部署策略与流量切换五个相互关联的环节。理解这些环节的配合关系,才能让服务在扩缩容、版本发布和故障恢复时保持稳定。

一、ALB与NLB的选择与目标组注册

ALB工作在应用层(HTTP/HTTPS),支持基于路径、主机头、查询参数的路由规则,适合Web应用、微服务和需要内容分发的场景。NLB工作在网络层(TCP/UDP/TLS),具备超低延迟和静态IP能力,适合数据库代理、游戏网关、需要固定入口IP或非HTTP协议的服务。选择哪种负载均衡器,取决于协议类型和路由需求,而不是性能高低。

ECS服务通过loadBalancers字段与目标组绑定。注册方式有两种:实例模式(target type为instance)将EC2实例注册到目标组,由负载均衡器把流量转发到实例端口;IP模式(target type为ip)直接注册任务的弹性网络接口IP,是awsvpc网络模式下的推荐方式,也是Fargate唯一支持的方式。IP模式下,每个任务拥有独立IP,负载均衡器直接面向任务转发,实例层面的端口冲突问题被彻底消除。

注册过程由ECS服务控制器自动完成:任务启动后,控制器读取任务的网络接口信息,将其注册到指定目标组;任务停止时自动注销。这意味着目标组的健康状态会随任务生命周期动态变化,无需人工干预。

二、动态端口映射的工作机制

当任务使用桥接网络模式(bridge)时,同一实例上多个任务副本不能同时占用宿主机的同一个端口。动态端口映射解决了这个问题:容器端口固定(如80),宿主机端口留空或设为0,Docker在启动时为每个任务随机分配一个宿主机端口(通常落在32768-61000范围内)。

此时目标组必须配置为实例模式,因为负载均衡器需要知道“实例IP + 动态端口”这一组合。ECS服务控制器会把每个任务实际映射的宿主机端口注册到目标组,同一实例上的多个任务因此可以各自拥有独立的目标端口。若使用IP模式,则不需要动态端口映射,因为流量直接到达任务的容器端口。

判断依据:awsvpc网络模式 + IP目标组 = 无需动态端口;bridge网络模式 + 实例目标组 = 必须使用动态端口映射。两者混用会导致注册失败或健康检查持续不通过。

三、健康检查与优雅停止

目标组的健康检查参数决定了负载均衡器如何判断任务是否可接收流量。关键参数包括:健康检查路径(如/health)、协议与端口、间隔时间(默认30秒)、超时时间(默认5秒)、健康阈值(连续成功次数,默认5次)、不健康阈值(连续失败次数,默认2次)。

ECS服务侧还有两个与之配合的参数:healthCheckGracePeriodSeconds(健康检查宽限期)和deregistrationDelay(注销延迟)。宽限期让新启动的任务有时间完成初始化,在此期间即使健康检查失败也不会被判定为不健康;注销延迟则让正在处理请求的任务在注销后仍能完成响应,避免连接被强制中断。ALB默认注销延迟为300秒,可根据请求时长调整。

优雅停止的完整链路是:任务收到停止指令 → ECS将其从目标组注销 → 负载均衡器停止发送新请求 → 等待注销延迟结束 → 任务收到SIGTERM → 应用完成收尾 → 任务退出。如果应用忽略SIGTERM,ECS会在超时后发送SIGKILL强制终止。

四、滚动更新与蓝绿部署

滚动更新是ECS服务的默认部署方式。通过minimumHealthyPercent和maximumPercent控制更新节奏。例如期望任务数为4,设置最小健康比例50%、最大比例200%,则更新过程中至少保持2个健康任务,最多可同时运行8个任务。控制器会先启动新版本任务,待其通过健康检查后再逐步停止旧任务,实现不中断发布。

蓝绿部署需要配合CodeDeploy使用。其核心是创建两个目标组(蓝组和绿组),新版本任务注册到绿组,验证通过后通过监听器规则切换流量。切换方式有两种:全部一次性切换(AllAtOnce)和线性/金丝雀切换(如每5分钟切换10%流量)。蓝绿部署的优势在于可以快速回滚——只需把监听器指回蓝组即可,无需重新部署旧版本。

配置蓝绿部署时,ECS服务的deploymentController需设为CODE_DEPLOY,并在CodeDeploy应用与部署组中指定两个目标组和监听器。部署组还定义了流量切换策略、等待时间以及回滚条件(如部署失败或CloudWatch告警触发)。

五、配置示例与结果判读

以下是一个使用awsvpc网络模式、ALB + IP目标组、滚动更新的ECS服务配置片段(示例参数,非实测结果):

{
  "serviceName": "web-service",
  "launchType": "FARGATE",
  "desiredCount": 4,
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "subnets": ["subnet-0a1b2c3d", "subnet-4e5f6g7h"],
      "securityGroups": ["sg-0123456789abcdef0"],
      "assignPublicIp": "DISABLED"
    }
  },
  "loadBalancers": [{
    "targetGroupArn": "arn:aws:elasticloadbalancing:...:targetgroup/web-tg/abc123",
    "containerName": "web",
    "containerPort": 80
  }],
  "healthCheckGracePeriodSeconds": 60,
  "deploymentConfiguration": {
    "maximumPercent": 200,
    "minimumHealthyPercent": 50
  }
}

部署后可通过以下方式判断集成是否正常:目标组中注册的目标数量应等于运行中的任务数;目标健康状态应为healthy;ALB访问日志中应出现来自任务IP的请求记录;若目标持续为unhealthy,优先检查安全组是否放行健康检查端口、健康检查路径是否返回200、宽限期是否过短。

客户端 HTTP/HTTPS ALB 应用层路由 NLB 网络层转发 监听器规则 路径/主机头路由 监听器 TCP/UDP 端口 蓝组目标组 v1.0 稳定版本 绿组目标组 v2.0 新版本 任务 v1.0 IP: 10.0.1.5 任务 v1.0 IP: 10.0.1.6 任务 v2.0 IP: 10.0.1.7 任务 v2.0 IP: 10.0.1.8 健康检查参数 路径 /health · 间隔 30s · 超时 5s 健康阈值 5次 · 不健康阈值 2次 · 宽限期 60s 流量切换策略 AllAtOnce / 线性 / 金丝雀 回滚:监听器指回蓝组 关键配合关系: awsvpc + IP目标组 → 无需动态端口映射,任务IP直接注册 bridge + 实例目标组 → 必须使用动态端口映射,注册“实例IP + 随机宿主机端口”

从整体上看,ECS与负载均衡的集成是一条从“流量入口”到“任务实例”的完整链路:负载均衡器接收请求,监听器按规则分发到目标组,目标组根据健康检查结果决定是否转发,ECS服务控制器负责把任务动态注册到目标组。滚动更新和蓝绿部署则是在这条链路上叠加的发布策略,前者通过替换任务实现渐进式更新,后者通过双目标组和流量切换实现可快速回滚的发布。掌握这五个环节的配合关系,就能在实际运维中快速定位问题——无论是目标组注册失败、健康检查不通过,还是发布过程中流量异常,都能沿着这条链路逐段排查。