核心摘要
- 蓝绿部署通过并行运行新旧版本实现零停机发布,配合ALB监听器规则可在秒级完成流量切换与回滚
- 完整流水线包含四个阶段:CodeCommit触发、CodeBuild构建镜像、ECR存储、CodeDeploy执行ECS部署
- 生产环境建议使用私有子网运行Fargate任务,通过NAT Gateway访问ECR,提升安全性
- 必须预先创建两个目标组(tg-blue和tg-green)并配置不同端口的监听器,这是蓝绿部署的基础设施前提
CodePipeline自动部署ECS蓝绿发布实战指南
为什么手动部署已无法满足现代交付需求
在容器化应用日益普及的今天,许多团队仍在使用Shell脚本或手动操作完成部署。根据我的实践经验,这种方式存在三个致命问题:环境不一致导致”本地能跑、生产报错”、操作遗漏如忘记更新环境变量、以及回滚困难需要重新构建旧版本镜像。
Amazon CodePipeline与ECS的组合方案从根本上解决了这些痛点。通过将构建、测试、部署流程编排为可重复执行的流水线,每次发布都遵循完全相同的步骤,消除了人为因素带来的不确定性。
方案核心优势深度解析
蓝绿部署的工作机制
蓝绿部署的本质是维护两套完全独立的运行环境。当新版本部署时,CodeDeploy会在”绿”环境中启动新的ECS任务,此时”蓝”环境仍在处理生产流量。只有当”绿”环境通过健康检查后,ALB才会将流量切换过去。
这种架构带来的关键收益是:回滚时间从分钟级降至秒级。因为旧版本的任务仍在运行,只需修改ALB的转发规则即可立即恢复。相比之下,滚动更新在出现问题时需要重新拉取旧镜像、启动新任务,耗时显著更长。
AWS原生服务集成的价值
选择CodePipeline而非Jenkins等第三方工具的核心理由在于IAM权限的精细控制。您可以明确指定CodeBuild只能推送到特定ECR仓库、CodeDeploy只能操作指定ECS集群。所有API调用都被CloudTrail记录,满足金融、医疗等行业的合规审计要求。
架构设计与数据流
完整的CI/CD流水线包含以下阶段:
- Source阶段:开发者向CodeCommit推送代码,包含Dockerfile、appspec.yml和taskdef.json模板
- Build阶段:CodeBuild执行docker build,将镜像推送至ECR,并动态更新taskdef.json中的镜像URI
- Deploy阶段:CodeDeploy读取配置文件,在ECS集群执行蓝绿部署,通过ALB完成流量切换
实战演练:搭建ECS蓝绿部署流水线
前置条件确认
开始之前,请确保具备以下资源和权限:
- AWS中国区账户(cn-north-1或cn-northwest-1)
- IAM用户需具备ECS、ECR、CodePipeline、CodeBuild、CodeDeploy、VPC、ELB的完全访问权限
- 本地已安装Git并完成AWS CLI配置
步骤一:配置网络基础设施
VPC设计是整个方案的基础。生产环境强烈建议将Fargate任务部署在私有子网,通过NAT Gateway访问ECR拉取镜像。本演示为简化流程,使用公有子网并为任务分配公网IP。
关键配置要点:VPC需包含至少两个不同可用区的子网,这是ALB和ECS服务高可用的硬性要求。
步骤二:创建Application Load Balancer
ALB配置是蓝绿部署的核心,需要创建两个目标组和两个监听器:
目标组配置:
- tg-blue:目标类型选择IP(Fargate要求),协议HTTP,端口80,健康检查路径设为/
- tg-green:配置与tg-blue相同,用于承载新版本流量
监听器配置:
- 生产监听器:端口80,默认转发至tg-blue
- 测试监听器:端口8080,转发至tg-green(用于部署后验证)
安全组规则需放行80和8080端口的入站流量。记录ALB的DNS名称,后续验证部署时需要使用。
步骤三:创建ECR镜像仓库
在ECR控制台创建私有仓库,记录完整的repositoryUri,格式如下:
[account-id].dkr.ecr.cn-north-1.amazonaws.com.cn/my-app
此URI将在CodeBuild的buildspec.yml中使用,用于推送构建完成的Docker镜像。
步骤四:部署初始版本(蓝环境)
在配置CI/CD流水线之前,必须先手动部署一个运行中的v1版本作为”蓝”环境基准。
创建ECS任务定义:
- 启动类型:Fargate
- 任务定义名称:my-app-task-def
- CPU架构:arm64(成本更优,但需确保镜像兼容)
- 任务执行角色:ecsTaskExecutionRole(授权ECR镜像拉取)
- 资源配置:0.5 vCPU,1GB内存
- 容器名称:my-app-con
实践建议:任务定义名称需与后续taskdef.json模板中的family字段保持一致,CodeDeploy会基于此名称创建新版本。
关键配置文件详解
appspec.yml结构
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition:
LoadBalancerInfo:
ContainerName: "my-app-con"
ContainerPort: 80
TASK_DEFINITION占位符会被CodeDeploy自动替换为新创建的任务定义ARN。
taskdef.json模板
{
"family": "my-app-task-def",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "my-app-con",
"image": "",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"essential": true
}
],
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024"
}
CodeBuild在构建阶段会将IMAGE_URI替换为包含commit hash的完整镜像地址,确保每次部署使用正确的镜像版本。
故障排查与最佳实践
常见问题诊断
部署卡在”绿”环境启动阶段:检查ECS任务是否能成功拉取镜像,常见原因包括ECR权限不足、私有子网缺少NAT Gateway、安全组未放行443端口出站。
健康检查持续失败:确认容器应用监听的端口与任务定义中的containerPort一致,健康检查路径返回200状态码。
流量切换后服务异常:利用测试监听器(8080端口)在切换前验证新版本,发现问题可通过CodeDeploy控制台一键回滚。
生产环境优化建议
- 启用CodeDeploy部署配置的线性流量切换(如每5分钟切换10%),配合CloudWatch告警实现自动回滚
- 为ECR仓库配置镜像扫描,在流水线中加入安全检查阶段
- 使用Parameter Store或Secrets Manager管理敏感配置,避免硬编码在任务定义中
需要优化您的 AWS 架构? 如果您正在规划容器化应用的CI/CD流水线,或希望将现有部署流程升级为蓝绿发布模式,欢迎联系我们获取针对您业务场景的架构评估与实施方案。