Amazon DOP-C02: CI/CD 流水线和部署策略 — 学习指南
属于 AWS DevOps Engineer Professional DOP-C02 — 学习指南. 使用经过验证的答案练习: Amazon 考试中心, 或参加限时模拟考试: ExamRoll.io.
概述
AWS 上一个稳健的 CI/CD 系统将源控制、构建、测试、构建产物治理、部署编排以及跨多账户和区域的安全发布策略结合在一起。核心托管服务——CodeCommit、CodeArtifact、CodeBuild、CodePipeline 和 CodeDeploy——无需维护服务器,与 IAM 和 KMS 紧密集成,并为面向 EC2/Auto Scaling、ECS 和 Lambda 的蓝/绿、金丝雀、滚动和就地部署提供一流的支持。高效的管道还依赖于精确的触发器(webhook、EventBridge、计划任务)、规范的构建产物管理、用于加速的构建缓存,以及结合健康警报进行自动回滚的、有明确策略的流量切换。对于企业而言,跨账户和跨区域模式是强制性的,这需要角色代入、区域性构建产物存储以及一致的加密策略。
使用 AWS Developer Tools 进行编排
使用 CodeCommit 作为私有的、高可用的 Git 服务。它与 EventBridge 集成以处理存储库和拉取请求事件,支持审批规则模板,并使用 IAM 进行精细授权。对于第三方 Git (GitHub/Bitbucket),配置带有 webhook 的 CodePipeline 源操作,以实现近乎实时的触发。
CodeArtifact 为多种生态系统(npm、Maven、PyPI、NuGet)集中管理软件包。它支持与公共注册表的上游连接并进行缓存,支持按存储库进行 KMS 加密,以及会自动过期的、有范围限制的身份验证令牌。通过在 pre_build 阶段调用 aws codeartifact login 来集成到 CodeBuild 中,以配置包管理器,而无需嵌入长期有效的密钥。
CodeBuild 提供临时的、容器化的构建,无需管理工作节点。关键功能:
- 环境隔离和 VPC 支持,用于访问私有依赖项。为 Docker 构建启用特权模式,并启用本地 Docker 层缓存以加速镜像构建。
- 环境变量来自三个来源:明文、SSM Parameter Store 和 Secrets Manager(默认为安全,无硬编码密钥)。您也可以从 CodePipeline 传递变量。
- 用于缩短构建时间的缓存:
- 本地缓存:源缓存、Docker 层缓存以及构建主机上的自定义目录。
- S3 缓存:可在多个构建之间共享的可重用依赖集。
- 构建产物管理:指定 primaryArtifacts 和 secondaryArtifacts 以发布多个输出(例如,应用程序包和 CloudFormation 模板)。使用 KMS 密钥加密构建产物,并避免使用公共 ACL。
- 报告:将日志发送到 CloudWatch Logs/S3。使用报告获取测试结果,并使用 CodeBuild 徽章在 PR 中提供反馈。
CodePipeline 是编排器。定义阶段(源、构建、测试、部署、审批),其中的操作可以并行或顺序运行。最佳实践:
- 触发器:
- 针对 GitHub/Bitbucket 源使用 Webhook。
- 针对 CodeCommit 分支变更使用 EventBridge 规则;当管道未能启动时,请验证规则是否存在。
- 通过调用 StartPipelineExecution 的 EventBridge 计划规则实现计划性管道。
- 构建产物存储:管道在每个区域使用一个 S3 存储桶;使用客户管理的 KMS 密钥。对于跨区域操作,请添加区域性构建产物存储。
- 使用 SNS 或 EventBridge 进行手动审批,以集成聊天/webhook 实现近乎实时的通知。
- 精细化的 IAM:具有最小权限的管道服务角色;为跨账户操作代入按操作指定的角色。
CodeDeploy 是部署引擎,支持 EC2/本地、ECS 和 Lambda 目标。它通过 CloudWatch 警报管理生命周期钩子、流量切换、健康检查和自动回滚。确保 EC2 实例运行 CodeDeploy 代理,具有实例配置文件,并具备到 CodeDeploy 端点的出站连接(或通过 NAT 的出口流量)。跳过的事件和空操作部署通常表示代理、权限或连接性存在问题。
部署策略与 CodeDeploy 生命周期
根据风险、容量和平台选择策略:
- 就地部署 (EC2/本地): 在现有实例上更新应用程序。可与 OneAtATime、HalfAtATime 或 AllAtOnce 部署配置结合使用。附加一个 ELB 以排空并重新注册实例。
- 滚动部署 (ECS): 在同一服务上分批替换任务。可以是 ECS 原生滚动更新,或通过 CodeDeploy 作为蓝/绿部署进行受控切换。
- 蓝/绿部署:
- EC2/Auto Scaling: 预置一个绿色的 ASG,验证后将流量从蓝色环境切换到绿色环境。可选择终止或保留蓝色环境。
- ECS: 在第二个目标组后面创建一个替换任务集;验证后切换侦听器。
- Lambda: 将别名流量切换到新的函数版本并进行监控。
- 金丝雀部署: 首先切换一小部分流量(例如 10%),观察一段时间,然后完成部署。
- 线性部署: 以相等的步长增加流量(例如,每 5 分钟增加 10%)。
CodeDeploy appspec.yml 定义了要安装的内容以及何时运行脚本:
- 对于 EC2/本地 (YAML):
- files: 指定文件的放置位置。
- permissions: 无需自定义脚本即可更新文件所有权/模式。
- hooks (通用): ApplicationStop, BeforeInstall, Install, AfterInstall, ApplicationStart, ValidateService。
- 流量控制钩子 (使用负载均衡器时): BeforeBlockTraffic, AfterBlockTraffic, BeforeAllowTraffic, AfterAllowTraffic。
- 使用预定义的环境变量(例如 DEPLOYMENT_GROUP_NAME, DEPLOYMENT_ID, LIFECYCLE_EVENT)动态修改行为,无需创建单独的修订版本,例如根据部署组切换 Apache 日志级别。
- 对于 ECS:
- resources: TargetService,包含 TaskDefinition 和 LoadBalancerInfo。
- hooks: BeforeInstall, AfterInstall, AfterAllowTestTraffic, BeforeAllowTraffic, AfterAllowTraffic。
- AfterAllowTestTraffic 非常适合使用测试侦听器对绿色任务集进行冒烟/集成测试。
- 对于 Lambda:
- resources 定义要切换的函数、版本和别名。
- hooks: BeforeAllowTraffic 和 AfterAllowTraffic。
流量切换和回滚:
- 配置部署配置:
- Lambda/ECS: Canary10Percent15Minutes、Canary10Percent5Minutes、Linear10PercentEvery1Minute、AllAtOnce 或自定义配置。
- EC2 蓝/绿部署: 通过负载均衡器侦听器/目标组进行一次性、金丝雀或线性流量重路由。
- 向部署组添加 CloudWatch 警报,以便在出现错误、5xx 响应或自定义指标异常时自动回滚。对于 ECS,警报可以监控目标组的 5xx 错误或服务指标;对于 Lambda,可以监控带有别名/版本维度的函数 Errors/Throttles 指标。
- 使用生命周期钩子(例如 AfterAllowTestTraffic)通过 Lambda 或 SSM 运行验证;非零退出将导致回滚。
EC2、ECS 和 Lambda 的蓝/绿部署与流量切换
EC2/Auto Scaling:
- 使用 CodeDeploy 进行蓝/绿部署会为绿色环境预置一个新的 Auto Scaling 组,将其与一个独立的目标组关联,然后切换 ALB 侦听器。您可以选择自动终止蓝色环境,或保留它以便快速回滚。
- 对于 EC2 上的就地部署,可与 ELB 结合使用,以优雅地取消注册/注册实例并保护可用性。部署配置决定了批处理大小和步调。
ECS:
- CodeDeploy 通过 ALB 后面的两个目标组与 ECS 服务集成。系统会使用新的任务定义创建一个替换任务集(绿色环境)。
- 测试流量通过专用的测试侦听器流向绿色目标组;在提升为生产环境之前,生产流量会一直保留在蓝色环境。
- 在监控 CloudWatch 警报的同时,通过金丝雀或线性方式将流量逐步切换到绿色环境。在生产切换之前,使用 AfterAllowTestTraffic 执行验证(例如,调用 Lambda 函数进行综合检查)。
Lambda:
- CodeDeploy 通过加权路由将函数别名更新到新版本。金丝雀和线性模式会逐步转移流量百分比。别名上的 CloudWatch 警报会驱动自动回滚。
- 使用 AWS SAM 或 CDK 时,在模板中设置 AutoPublishAlias 和 DeploymentPreference,以便为每个函数编码金丝雀/线性策略和警报。
CodeDeploy 之外的加权路由:
- 对于多区域或多堆栈的负载均衡,带有运行状况检查的 Route 53 加权记录可提供区域流量拆分(例如,将 1% 的流量发送到次要区域)和故障转移。这是对 CodeDeploy 的单服务流量切换的补充,但不能替代它。
多账户和多区域交付
企业级流水线通常位于一个集中的“工具”账户中,并跨多个区域部署到开发/测试/生产账户:
- 跨账户:
- 在 CodePipeline 操作中,指定目标账户中一个信任流水线角色 principal 的 RoleArn。为每个操作(CloudFormation、CodeDeploy、ECS、Lambda)使用最小权限。
- 对于必须访问目标账户资源的 CodeBuild,让构建过程代入一个角色(STS)或使用每个账户的操作角色,而不是宽泛的 AdministratorAccess 权限。
- 对于向 EC2 进行的 CodeDeploy,目标账户管理应用程序/部署组和服务角色;流水线则代入一个角色来调用 CreateDeployment。
- 跨区域:
- 在流水线配置中为每个区域添加一个构建产物存储(一个带有区域性 KMS 密钥的 S3 存储桶)。更新存储桶策略,以允许流水线角色和每个操作的角色进行读/写。
- 在必要时构建特定于区域的构建产物(例如,使用
aws cloudformation package命令将 Lambda 代码打包到目标区域本地的 S3 存储桶)。 - 在远程区域中的 CloudFormation 部署操作必须引用该区域的构建产物存储,并可以在目标账户中指定一个堆栈执行角色以实现最小权限。
安全性、构建产物和治理:
- 保持构建产物存储桶的私有性;避免使用公共 ACL,如 authenticated-read。依赖于范围限定于流水线和操作角色的存储桶策略,并使用 KMS 加密。
- 标准化 buildspec 以可预测地推送构建产物(例如,用于 EC2/CodeDeploy 的应用程序包,用于 ECS 的 taskdef.json 和 appspec,用于 Lambda 的打包模板)。
- 通过对 EC2 进行 AMI 预烘焙来提倡不可变性,以确保 CodeDeploy 代理和基础运行时保持一致;这可以减少漂移和部署时间。
- 使用 EventBridge 规则将流水线事件镜像到通知、ChatOps 或工单系统,并用于编排手动门控。
实践问题场景
Spotify 需要在其数百个微服务中实现更安全的发布,这些微服务运行在混合计算底层(ECS on Fargate、基于 EC2 的服务和 Lambda)上。他们要求在将流量引入生产环境之前进行金丝雀部署和蓝/绿部署,并伴有自动化测试,同时还需要构建产物治理和多区域提升,并将生产环境保持在独立的账户中。
- 建立代码仓库和包
- 使用 CodeCommit 作为私有仓库,并利用 EventBridge 驱动的 PR/测试自动化。CodeArtifact 托管 npm、Maven 和 PyPI 依赖项,通过上游和 KMS 加密来标准化供应链控制。 为什么:集中的 IAM/KMS 集成,关键仓库无需外部 webhook;CodeArtifact 提供缓存的、精选的包。
- 构建和测试
- 为每个服务创建 CodeBuild 项目,集成 VPC、本地缓存(Docker 层和源代码),并从 Secrets Manager/Parameter Store 获取环境变量。构建镜像并推送到 ECR;生成次要构建产物(taskdef.json/appspec.yaml 或打包的 CloudFormation 模板)。 为什么:临时的、隔离的构建,强大的密钥处理,通过缓存加快周期,以及多输出支持容器和无服务器打包。
- 编排流水线
- 在一个工具账户中创建一个集中的 CodePipeline,包含以下阶段:Source、Build、Unit Tests、Deploy-to-Staging、Automated Tests、Manual Approval、Deploy-to-Prod。触发器来自 CodeCommit 更新时触发的 EventBridge;一个每晚计划的 EventBridge 规则启动集成测试。 为什么:规范化、可审计的流程,带有门控,并支持事件驱动和计划驱动的执行。
- 蓝/绿部署和金丝雀部署
- ECS 服务使用 CodeDeploy 的蓝/绿部署,配备两个目标组和金丝雀流量切换;验证在 AfterAllowTestTraffic 钩子中通过一个执行合约测试和综合检查的 Lambda 函数运行。EC2 服务在容量允许时使用 CodeDeploy 的原地部署(OneAtATime)或蓝/绿 ASG 交换。Lambda 函数使用 CodeDeploy 进行部署,采用 Canary10Percent15Minutes 策略,并针对 API Gateway 的 Errors 和 5xx 指标设置 CloudWatch 告警。 为什么:每个运行时都有一流的流量控制,并在告警触发时自动回滚,从而最大限度地减少对客户的影响。
- 跨账户和跨区域提升
- 流水线在开发/测试/生产账户中代入每个环境的角色。对于 us-east-1 和 eu-west-1,配置区域性构建产物存储和区域性 KMS 密钥;CodeBuild 生成特定于区域的打包模板,并将构建产物上传到区域本地的存储桶。每个账户/区域中的 CloudFormation 操作使用堆栈执行角色;CodeDeploy 操作则针对特定于环境的应用程序/部署组。 为什么:生产环境的强隔离,通过角色代入实现最小权限,以及合规的加密,同时运营开销低。
- 构建产物治理和安全
- 强制使用带有严格策略的私有 S3 构建产物存储桶,并移除任何公共 ACL。签署容器镜像和模板;将 SBOM 作为构建产物存储。使用 IAM 条件键将生产操作限制在工具账户中的流水线。 为什么:防止数据泄露,提高来源可追溯性,并符合供应链最佳实践。
- 可观测性和通知
- 将 CloudWatch 告警附加到所有部署组;EventBridge 规则将 CodePipeline 的执行和批准事件转发到一个 SNS 主题和一个将消息发布到 Slack 的 Lambda 函数。 为什么:更快的反馈,自动回滚,以及在需要时进行人工介入的批准。
该设计将异构运行时统一在单一的托管工具链下,通过自动化验证提供了安全的发布策略,通过消除自托管的 CI/CD 基础设施减少了维护工作,并以清晰的职责分离实现了全球扩展。
所有领域 · 基础架构即代码和配置管理 →
练习这些题目 → · 在 ExamRoll.io 上限时练习 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通过考试 →