You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ECS蓝绿部署用ECSAllAtOnce忽略健康检查问题求解

问题

我有一个采用FARGATE启动类型的ECS服务,使用CodeDeploy执行蓝绿部署。当前遇到的问题:

  • 使用CodeDeployDefault.ECSAllAtOnce部署配置时,新的绿色目标健康状态不会被校验,即便新实例无响应,部署仍会继续并将流量路由至该实例,导致服务异常。
  • 使用CodeDeployDefault.ECSLinear10PercentEvery1Minutes时,健康状态会正常校验,一旦新实例不健康,部署会停止,这符合预期。

需求:实现一次性切换所有实例(类似ECSAllAtOnce的全量切换),同时确保仅在新目标健康时才执行流量切换。

解决方案

要实现全量切换+健康校验,核心是利用蓝绿部署的健康校验机制,配合目标组和CodeDeploy的配置调整,具体步骤如下:

  • 保留蓝绿部署模式:你的模板已使用BLUE_GREEN部署类型和WITH_TRAFFIC_CONTROL选项,这是实现健康校验的基础,无需修改。
  • 替换为全量部署配置:直接将DeploymentConfigName改为CodeDeployDefault.ECSAllAtOnce。
  • 确保目标组健康检查配置有效:确认TargetGroup1和TargetGroup2配置了合理的健康检查规则(如检查路径、响应码、超时时间等),这是CodeDeploy判断目标健康的核心依据。
  • 调整部署就绪等待时间:根据服务启动初始化时长,合理设置DeploymentReadyOption中的WaitTimeInMinutes,确保有足够时间让实例完成健康检查。
修改后的CloudFormation代码片段
EcsService:
  Type: AWS::ECS::Service
  DependsOn:
    - TargetGroup1
    - TargetGroup2
  Properties:
    Cluster: !Ref EnvironmentName
    DeploymentController: 
      Type: CODE_DEPLOY
    DesiredCount: 1
    HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriod
    LaunchType: FARGATE
    LoadBalancers: 
      - TargetGroupArn: !Ref TargetGroup1
        ContainerName: !Ref EnvironmentName
        ContainerPort: 8080
    NetworkConfiguration: 
      AwsvpcConfiguration:
          Subnets: [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]
          SecurityGroups: [ !Ref ECSHostSecurityGroup ]
          AssignPublicIp: ENABLED
    PlatformVersion: LATEST
    SchedulingStrategy: REPLICA
    ServiceName: !Ref EnvironmentName
    TaskDefinition: !Ref TaskDefinition

CodeDeployDeploymentGroup:
  Type: AWS::CodeDeploy::DeploymentGroup
  DependsOn: EcsService
  Properties:
    ApplicationName: !Ref EnvironmentName
    DeploymentGroupName: !Ref EnvironmentName
    # 替换为全量部署配置
    DeploymentConfigName: CodeDeployDefault.ECSAllAtOnce
    ServiceRoleArn: !GetAtt EcsRoleForCodeDeploy.Arn
    DeploymentStyle:
      DeploymentType: BLUE_GREEN
      DeploymentOption: WITH_TRAFFIC_CONTROL
    BlueGreenDeploymentConfiguration:
      TerminateBlueInstancesOnDeploymentSuccess:
        Action: TERMINATE
        TerminationWaitTimeInMinutes: 0
      DeploymentReadyOption: 
        ActionOnTimeout: STOP_DEPLOYMENT
        # 根据服务启动时长调整等待时间,确保健康检查能完成
        WaitTimeInMinutes: 10
    LoadBalancerInfo:
        TargetGroupPairInfoList:
          - TargetGroups:
            - Name: !Sub ${EnvironmentName}-1
            - Name: !Sub ${EnvironmentName}-2
            ProdTrafficRoute:
              ListenerArns: [ !Ref ALBListenerHTTPS ]
    ECSServices:
      - ServiceName: !Ref EnvironmentName
        ClusterName: !Ref EnvironmentName
关键说明
  • 之前ECSAllAtOnce不校验健康的原因:蓝绿部署模式下,ECSAllAtOnce配置本身不会主动触发健康校验,需要依赖目标组健康检查和CodeDeploy的DeploymentReadyOption配合。线性部署配置会在每批实例启动后等待健康校验,而全量配置需要明确让CodeDeploy等待目标健康后再切换流量。
  • 目标组健康检查的作用:CodeDeploy会监听目标组状态,只有当绿色目标组内所有实例都健康时,才会执行流量切换;如果等待超时仍未健康,部署会按ActionOnTimeout设置停止,避免流量路由到异常实例。
  • 健康检查宽限期:ECS服务的HealthCheckGracePeriodSeconds需设置合理值,避免服务启动初期就被标记为不健康,确保有足够时间完成初始化。

内容的提问来源于stack exchange,提问作者Alex Harris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:48:23