AWS-认证-DevOps-工程师-全-
AWS 认证 DevOps 工程师(全)
原文:
annas-archive.org/md5/b44a68a3321a441a0fdffa7dcbaf1892译者:飞龙
前言
越来越多的公司正在转向云计算,特别是Amazon Web Services(AWS)云服务。进入云端后,这些公司和企业希望通过采用 DevOps 实践中的技术来精简其流程和软件开发生命周期(SDLC)。这包括自动化构建和发布流程,使开发团队能够专注于编写客户所需的代码和功能。还包括确保日志记录和监控到位,这不仅仅是为了在部署清单上勾选一个选项,而是为了使团队能够快速找到问题的根本原因,无论是性能问题、错误问题,还是安全问题。
对于熟练且认证的 AWS 专业人士的需求达到了历史最高点并且还在增长。通过 AWS DevOps 工程师专业认证考试,您可以立刻与他人区别开来,证明您不仅花时间和精力学习这些宝贵的技能,还通过了 AWS 专业认证这一严格的标准。
AWS 提供的认证,尤其是专业认证考试,绝非易事。行业内的从业者和招聘方都知道这一点。考试本身不仅需要耗费大约 3 小时的时间,而且还在不断更新。
这次考试有大量信息需要消化和理解。您不仅需要了解 AWS 提供的蓝图中涵盖的主题,还需要具备扎实的 AWS 知识基础,以便有效地使用这些服务。如果您有实际的工作经验,或者至少有动手实践的经验,那将大大帮助您。这也是本书中包含的练习的意义所在。它们不仅仅是一个终点,而是一个起点,帮助您构建其他项目,从而在参加考试时,能够自信地点击“开始”按钮,拥有通过认证考试所需的技能和知识,并将您的职业生涯提升到一个新的水平。
本书旨在帮助您扎实掌握 AWS DevOps 专业认证考试中涉及的服务。这通过多种方式实现。书中为许多服务提供了示例架构,帮助您可视化不同服务如何协同工作。书中还提供了大量的实践示例,帮助您了解如何在实际场景中应用这些服务。此外,还提供了不同服务的最佳使用案例和反模式示例。这些内容对于评估专业认证考试中的问题尤为重要,因为这些问题通常呈现为大型场景格式。理解某项服务在哪些场景下最为合适,在哪些场景下不适用,有助于您作出正确的选择。
最后,本书不仅是一本通过考试的学习指南,还是通过考试后日常工作中的参考指南。这就是超越的意义所在。书中提供了额外的信息,这些信息虽然不要求出现在考试中,但有意为之。我想分享一些我在与各种企业(从中小型公司到大型财富 100 强企业)在 AWS 上合作过程中积累的多年经验。
本书的目标读者
无论你在 AWS 的旅程中处于何种阶段,如果你有成为认证 DevOps 专业工程师的愿望,那么本书将帮助你理解基本概念和服务,同时考察考试大纲中涵盖的关键服务。
在开篇的章节中,我们为 AWS 世界中什么是“优秀”奠定了基础,尽管这看起来像是很多理论,但它有助于你解决考试题目中提出的许多复杂场景。书中还提供了大量的实践练习,帮助你使用一些可能不熟悉的服务,以便你在考试期间和之后都能获得信心和经验。
在每章的结尾,都有知识评估,帮助自我检查是否掌握了不仅能通过这项具有挑战性的考试,还能成功完成未来云计算领域其他任务所需的信息。
本书涵盖的内容
第一章,亚马逊 Web 服务支柱,聚焦于构成 AWS Well-Architected Framework 的基础支柱。通过理解这些支柱,你将更好地理解认证考试中所提问题的背景。
第二章,基本 AWS 服务,探讨了大量基本的 AWS 服务,了解这些服务对于继续学习后续章节至关重要。对一些已经通过初级认证考试的人来说,这可能看起来像是复习。然而,它也能作为一个快速回顾,并提供一些之前未曾了解的小技巧。
第三章,AWS 中的身份与访问管理及处理机密,聚焦于 AWS 的基本安全构建块,即通过 IAM 服务进行身份和访问管理。在简要介绍 AWS 的共享安全模型以及授权与认证的概念后,我们将回顾创建用户和用户组的过程。本章还涵盖了通过跨账户访问提供对其他账户的访问权限,并进行实际操作练习。在这一基础安全章节中,我们还会讨论其他在考试题目中可能出现的重要安全服务,如 AWS 目录服务、Secrets Manager 和 Systems Manager Parameter Store。本章还将比较 AWS 目录服务的不同版本使用场景,并讨论哪些服务更适合存储你的机密。最后,我们将介绍 Amazon Cognito,以及它如何帮助应用程序认证。
第四章,亚马逊 S3 Blob 存储,聚焦于 AWS 简单存储服务(S3)中的一个关键服务。尽管此服务易于立即开始使用,但它也具有许多功能和特性,若你打算获得 AWS 认证,必须了解这些功能和特性。
第五章,亚马逊 DynamoDB,解释了原生的 NoSQL 数据库 DynamoDB。它不仅讲解了 DynamoDB 的一些基本概念,还涉及诸如流、全球表、使用 DynamoDB 加速器,甚至使用 Web Federation 连接到 DynamoDB 表等主题。
第六章,理解 CI/CD 和软件开发生命周期(SDLC),聚焦于持续集成、持续开发和持续部署的许多理论方面。接下来,我们将介绍 SDLC,并查看哪些服务映射到 SDLC 的不同阶段。
第七章,使用 CloudFormation 模板部署工作负载,教你如何使用原生的 CloudFormation 服务来进行基础设施即代码(IaC)。首先,我们将介绍 CloudFormation 模板的基础知识,然后快速进入基本模板的变更集创建示例,接着讨论内在函数和嵌套堆栈。利用 CloudFormation 模板的知识,我们将讨论如何使用 ServiceCatalog 为开发人员和非开发人员快速便捷地提供模板设计。本章最后,我们将讨论 Cloud Development Kit,它可以用你选择的编程语言编写,然后用来创建 CloudFormation 模板。
第八章,使用 CodeCommit 和 CodeBuild 创建工作负载,引导您使用 AWS 原生工具进行软件开发生命周期(SDLC)的初步步骤。我们首先创建一个全新的用户组和用户,并为其分配一整套仅限该角色的权限。创建了初始的 CodeCommit 仓库后,我们让开发者使用 Git 将代码提交到特性分支,并请求将其合并到主分支。接下来,我们通过让 CodeBuild 服务使用 AWS CodeBuild 构建一个容器,来探讨 CodeBuild 服务。
第九章,使用 CodeDeploy 和 CodePipeline 部署工作负载,展示了如何使用原生的 AWS CodePipeline 服务创建 DevOps 管道。这一章涉及了我们之前讨论和练习过的许多服务。示例中的管道是通过 CloudFormation 模板构建的。我们之前创建的开发者用户需要扩展权限,以便查看和运行我们的管道,因此本章还包含了扩展他们 IAM 权限的练习。此外,本章还讨论了如何使用 AWS CodeDeploy 服务来部署工作负载。
第十章,使用 AWS OpsWorks 管理和部署您的应用堆栈,重点介绍了如何使用 AWS OpsWorks 服务创建堆栈和层,以便部署基础设施和应用程序。文中对不同版本的 OpsWorks 进行了比较,并附有一个练习,指导如何创建包含层和应用程序的堆栈。
第十一章,使用 Elastic Beanstalk 部署您的应用程序,详细讲解了 DevOps 专业考试中的一个关键服务——Elastic Beanstalk。使用 EB CLI 在 Elastic Beanstalk 中创建并部署应用程序,不仅能让你从开发者的角度观察事物,还能帮助你思考如何在现实世界中自动化这些任务。
第十二章,Lambda 部署与版本管理,探讨了无服务器计算的概念,并介绍了如何使用 AWS Lambda 平台进行无服务器计算。通过按需计算和按使用量计费的方式运行计算任务,可以带来显著的成本节约,这种模式正成为当今组织中越来越受欢迎的趋势。我们不仅讨论了如何部署和监控 Lambda 函数,还讨论了如何实现版本管理和别名。在本章的最后,我们还将演示如何在步骤函数中协调多个 Lambda 函数的运行。
第十三章,蓝绿部署,重点介绍了蓝绿部署策略及其不同的变种,包括哪些服务可以使用这些策略以及如何根据你使用的服务来实施不同的策略。在使用 EC2 实例和自动扩展组时,你可以采用特定的策略,而在使用 Lambda 函数时,也有其他可用的策略。本章的核心目标是确保即使在部署过程中遇到问题,你的最终用户和客户也能享受到无缝的体验。
第十四章,CloudWatch 和 X-Ray 在 DevOps 中的角色,展示了监控和日志记录在使用 AWS 原生 CloudWatch 和 X-Ray 服务中的作用。日志流和日志搜索可能是繁琐的任务,有时感觉就像在大海捞针。性能问题也同样如此。将 X-Ray 服务添加到 Lambda 应用中,可以帮助你快速定位问题所在,并知道如何解决这些问题。
第十五章,CloudWatch 指标和 Amazon EventBridge,展示了如何使用来自各个服务的指标,并将其与 Amazon EventBridge 服务结合,创建自动化的系统警报。我们讨论了哪些指标对于不同的关键服务最为有用,帮助我们保持监控。我们还演示了如何在 Amazon CloudWatch 控制台中创建仪表板。
第十六章,生成的各种日志(VPC 流日志、负载均衡器日志和 CloudTrail 日志),探讨了 AWS 服务生成的其他类型日志,这些日志并非 CloudWatch 日志。这些日志在故障排除时非常有价值,可能需要在某些或所有情况下启用。作为 DevOps 专业人员,了解如何获取这些日志以及如何搜索这些日志可能是你需要执行的任务。
第十七章,高级和企业日志场景,展示了构建和处理日志文件的现实场景和架构。这不仅包括 CloudWatch 和 CloudTrail 服务,还包括 Elasticsearch、Kinesis 和 Lambda 等服务,用于实时处理多个日志流。理解如何收集和处理大量日志文件的概念,对于现实工作中的应用和 DevOps 专业认证考试中的潜在场景都至关重要。
第十八章**, 自动扩展和生命周期挂钩,详细讲解了自动扩展和自动扩展组的工作原理。这包括检查自动扩展生命周期和生命周期挂钩。还有一个练习,指导你创建启动模板,这是启动配置的继任者。我们还将进行实践,介绍如何在自动扩展组内删除和终止实例。
第十九章,保护静态和传输中的数据,展示了如何使用诸如密钥管理服务和 Amazon 证书管理器等服务,保护既处于静态状态又在传输中的数据。如果你使用基础设施即代码构建系统,你需要将这些关键部分集成到你的系统中,以确保从一开始就保护你的数据安全。
第二十章,使用系统管理器的角色和 AWS Config 强制执行标准和合规性,重点讲解了如何使用自动化来保持 AWS 环境的合规状态。通过使用 AWS Config 服务,你可以持续检查在 AWS 环境中创建的内容。将此与标记违规行为的规则结合使用,对于不允许的内容,可以发送警报或执行自动化的执行和修复。再加上系统管理器的功能,它可以使用运行手册自动在实例上安装软件,满足病毒扫描器等合规性需求,或进行定期的操作系统升级;这样,创建执行任务的审计日志就变得更加容易。
第二十一章,使用 Amazon Inspector 检查你的环境,演示了如何使用 Amazon Inspector 服务向你的 DevOps 生命周期添加自动化安全扫描。我们将讨论如何以自动化和手动的方式配置 Inspector 服务,然后查看和理解 Inspector 生成的不同报告。
第二十二章,其他需要了解的策略和标准服务,介绍了一些在 DevOps 专业考试中可能出现的服务,但未包含在其他章节中。这些服务包括 AWS GuardDuty、Amazon Macie 和服务器迁移服务。我们还将再次讨论 AWS Organizations 及其与服务目录服务的整合,以确保你全面了解这些服务如何协同工作。
第二十三章,DevOps 专业认证考试概述,解释了测试过程本身。它还列出了你应该与本书结合使用的额外资源,以便阅读和备考,以及一些学习技巧。
第二十四章,实践考试 1,主要是为了帮助你检查准备情况。本章展示了考试中会出现的问题,并提供了答案和解释,帮助你理解为什么选择正确答案。
为了最大程度地从本书中受益
以下领域的知识将帮助你更好地理解本书内容:
-
软件架构、编程语言和应用设计的知识
-
关系型和非关系型数据库的知识
-
AWS 区域和地理位置的知识
-
对 JSON 和 YAML 文件格式的理解
-
操作系统基础知识和系统命令的知识
-
应用程序和系统可用性的日志记录与监控知识

设置 AWS CLI 是完成本书中许多练习的必要步骤。安装 CLI 的逐步操作指南可以在 第二章,基础 AWS 服务中找到,如果你的计算机上尚未安装 CLI。
如果你正在使用本书的数字版,我们建议你自己输入代码或从书中的 GitHub 仓库访问代码(下节会提供链接)。这样可以帮助你避免因复制粘贴代码而导致的潜在错误。
下载示例代码文件
你可以从 GitHub 下载本书的示例代码文件,链接:github.com/PacktPublishing/AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond。如果代码有更新,GitHub 仓库中的代码将会同步更新。
我们还提供了其他代码包,可以从我们丰富的书籍和视频目录中找到,链接:github.com/PacktPublishing/。快来看看吧!
下载彩色图像
我们还提供了一个 PDF 文件,包含本书中使用的截图和图表的彩色图像。你可以在此下载:static.packt-cdn.com/downloads/9781801074452_ColorImages.pdf。
使用的约定
本书中使用了多种文本约定。
文本中的代码:表示文本中的代码词、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 账号。举个例子:“你将看到用户名和密码都未加密地返回在 SecretString 字段中,供你使用。”
一段代码块的格式如下:
{
"Project_ID": {"N": "0100"},
"Dept": {"S": "Test Team"},
"Dept_ID": {"N": "0001"},
"Project_Name": {"S": "Serverless Forms"},
"Owner": {"S": "Jerry Imoto"},
"Builds": {"NS": ["2212121"] },
"Language": {"S": "python" },
"Contact": {"S": "test_team@testcompany.com" }
}
当我们希望你关注代码块的某个特定部分时,相关的行或项会用粗体显示:
[default]
exten => s,1,Dial(Zap/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
任何命令行的输入或输出如下所示:
$ aws iam list-groups --output text
$ aws iam create-group --group-name Admins
粗体:指示新术语、重要词汇或您屏幕上看到的词语。例如,菜单或对话框中的词语显示为粗体。以下是一个示例:"您可以选择使用 SSE-S3 或您选择的密钥管理服务(KMS)密钥来加密报告。"
提示或重要说明
显示为这样。
保持联系
我们随时欢迎读者的反馈。
customercare@packtpub.com并在您的消息主题中提及书名。
勘误:尽管我们竭尽全力确保内容的准确性,错误偶尔还是会出现。如果您在本书中发现错误,我们将不胜感激您的报告。请访问www.packtpub.com/support/errata并填写表格。
copyright@packt.com与资料链接。
如果您有兴趣成为作者:如果您对某个专题有专业知识,并且有意撰写或为一本书作出贡献,请访问authors.packtpub.com。
分享您的想法
一旦您阅读了《AWS 认证 DevOps 工程师-专业认证及更多内容》,我们很乐意听取您的想法!请单击此处直接转到此书的亚马逊评论页面并分享您的反馈。
您的评论对我们和技术社区非常重要,将帮助我们确保提供优质内容。
第一部分:建立基础
在这一部分,我们将了解 AWS 云的基础,包括 Well-Architected Framework 的基础、安全性和存储。
本书的这一部分包括以下章节:
-
第一章, Amazon Web Service 支柱
-
第二章, 基本的 AWS 服务
-
第三章, AWS 中的身份与访问管理及与密钥的使用
-
第四章**, Amazon S3 Blob 存储
-
第五章**, Amazon DynamoDB
第一章:Amazon Web Services 支柱
DevOps 本质上是开发与运维技能的结合,并打破这两个不同团队之间的壁垒。DevOps 使开发人员能够轻松执行运维任务。DevOps 还包括赋能运维团队成员创建自己的基础设施即代码,并使用其他编码技术,如持续集成流水线,以便在多个区域快速部署相同的基础设施。
本书将介绍 DevOps 专业考试中涉及的服务和概念,以便你从实践角度,既通过讲解又通过动手练习,拥有扎实的理解。
成为 Amazon Web Services(AWS)认证工程师不仅能立即验证你所掌握和保持的技术技能,还能强化你作为技术专业人士的能力。AWS DevOps 工程师专业认证是一个累积性的考试,涵盖了 AWS 基础服务的基本知识,包括在 AWS 上运行、管理和监控工作负载的系统操作能力。这些内容还包括将代码开发并部署到函数、容器和实例。
我们将在 第二十三章 中更深入地探讨考试本身,DevOps 专业认证考试概述,并提供一些应试技巧。
AWS 支柱是指导架构师和开发人员在通用云架构和设计中普遍接受的五个指导原则。在 DevOps 专业考试中,这些支柱被间接引用,但它们及其指导方针是与任何云服务提供商合作的最佳实践的基石——尤其是 Amazon Web Services。这些原则是 DevOps 实践和流水线中的指导原则,深入理解这五个方面不仅能帮助你顺利通过考试,还能在你的 DevOps 职业生涯中提供帮助。
在本章中,我们将涵盖以下主要主题:
-
操作卓越
-
安全性
-
可靠性
-
性能效率
-
成本优化
服务支柱概述
一开始,你可能会想,为什么我们不直接进入 AWS、持续集成/持续交付(CI/CD)以及其他 DevOps 相关主题。主要原因是这五个支柱是考试的基础框架。此外,它们将帮助你为公司或客户提供最有效、可靠和高效的环境。这些设计原则不仅在为成功架构 Amazon Web Services 或任何云服务提供商时至关重要,而且在指导你日常工作的实践时同样适用。
一旦您熟悉了这些支柱,您会在进行认证的过程中看到它们及其主题,尤其是在获得 DevOps 专业认证时,测试问题中会涉及到操作、安全性和可靠性等特定部分。
以下是良好架构框架的五个支柱:
-
运营卓越
-
安全性
-
可靠性
-
性能效率
-
成本优化
将这些支柱作为指导原则,不仅用于设计在 AWS 中的工作负载,还用于改进和重构当前的工作负载。每个组织都应努力实现良好架构的应用程序和系统。因此,改进您正在处理的任何 AWS 应用程序将使您成为宝贵的资产。现在,让我们详细看看这些支柱。
运营卓越
当我们查看运营卓越支柱时,特别是在 DevOps 的背景下,这是一个——如果不是最重要的话——对于您日常职责来说最为重要的服务支柱之一。我们将从思考团队如何组织开始;毕竟,DevOps 运动的出现就是为了打破开发与运维团队之间的壁垒。
问题 – 您的团队如何确定其优先事项?
-
是否与客户沟通(无论是内部客户还是外部客户)?
-
是否从已绘制出路线图的产品负责人那里获得方向?
亚马逊概述了五个设计原则,将运营卓越融入云计算中:
-
将操作视为代码执行
-
经常精炼操作
-
进行小规模、频繁且可逆的更改
-
预见失败
-
从所有操作失败中学习
让我们详细看看这些操作设计原则,看看它们如何与您作为 DevOps 工程师的工作相关。随着您逐步了解这些设计原则,不仅仅是这个支柱,而是所有服务支柱,您会发现最佳实践已明确列出,辅以不同的服务,帮助您完成目标。
将操作视为代码执行
借助基础设施即代码(Infrastructure as Code)的构想,云计算使团队能够仅通过代码创建应用程序,而无需与图形界面进行交互。此外,它还允许任何底层的网络、服务、数据存储等,这些都是运行您的应用程序和工作负载所必需的。将大部分(如果不是所有)操作转移到代码中,可以为团队带来以下好处:
-
快速分发知识,防止团队中只有一个人能够执行某个操作
-
允许进行同行评审环境,并进行快速迭代
-
允许快速测试更改和改进,而不会干扰生产环境
在 AWS 中,你可以通过几种不同的服务执行操作代码,例如CloudFormation、Cloud Development Kit(CDK)、特定语言的软件开发工具包(SDK),或者通过使用命令行界面(CLI)。
经常精炼操作
在云端运行工作负载时,你应该处于一个持续改进的过程,不仅是应用程序和基础设施,也包括你的操作方法。采用敏捷流程的团队通常会在每个冲刺后进行回顾会议,提出三个问题:什么做得好,什么做得不好,哪些方面有改进空间?
在云端运行工作负载同样为回顾提供了机会,可以提出那些相同的三个问题。回顾不必发生在冲刺之后,但应该在以下事件之后进行:
-
自动化、手动或混合部署
-
自动化、手动或混合测试
-
在生产问题发生后
-
进行游戏日模拟
在每种情况之后,你应该能够回顾当前的操作设置,并查看哪些方面可以改进。如果你为事故或部署创建了逐步执行手册,问问自己和团队,是否有遗漏的步骤或不再需要的步骤。如果发生了生产问题,是否配置了正确的监控来排查该问题?
做小而频繁且可逆的更改
随着我们将工作负载迁移到云端,最好遵循的设计实践是将大型的单体设计拆分成更小、更解耦的组件,而不是将多个系统放在同一台服务器上。通过将组件做得更小、解耦且更易管理,可以处理更小的、更可逆的变化,以应对可能出现的问题。
逆转更改的能力也可以体现在良好的编码实践中。AWS CodeCommit 允许在代码仓库中使用 Git 标签。在每次发布部署后,通过为每个版本打标签,你可以快速重新部署以前的工作版本,以防代码库中出现问题。Lambda 也有类似的功能,称为版本。
预见故障
不要认为仅仅因为你将应用程序迁移到云端,且所依赖的服务被标记为托管服务,就不再需要担心故障。故障会发生,虽然可能不常见;然而,在经营业务时,任何形式的停机都可能导致收入损失。拥有一个应对风险的计划(并且测试该计划)实际上可能意味着保持你的服务级别协议(SLA)与不得不道歉,甚至更糟的是不得不给客户补偿或退款之间的差异。
从失败中学习
事情偶尔会失败,但当它们失败时,重要的是不要纠缠在失败中。相反,进行事后分析,并找到可以使团队和工作负载更强大和更具弹性的教训。跨团队分享学习有助于集中每个人的视角。失败后应该问并回答的一个主要问题是,问题是否可以通过自动修复来解决?
当今较大组织中的一个重要问题是,在追求伟大的过程中,它们停止了做好的努力。有时,您需要在日常事务中做好您所做的事情。这可能是通往伟大的垫脚石。然而,如果没有回顾阻碍您变得优秀的原因,永恒追求卓越有时可能只是在原地打转,而不是获得进展。
示例 – 运营卓越
让我们来看一个相关示例,展示了在环境中为实例实施自动化补丁的情况:

图 1.1 – 运营卓越 – 自动化补丁组
如果您的环境中有需要自行管理并需要更新补丁的实例,那么您可以使用系统管理器 – 补丁管理器来帮助自动化保持操作系统的更新任务。这可以通过使用系统管理器维护任务定期完成。
初始步骤是确保安装了SSM代理(以前称为简易系统管理器)在您希望通过补丁保持更新的机器上。
接下来,您将创建一个补丁基线,其中包括在发布后几天内自动批准补丁的规则,以及已批准和已拒绝补丁的列表。
之后,您可能需要修改实例上的 IAM 角色,以确保 SSM 服务具有正确的权限。
可选地,您可以设置补丁管理组。在前面的图表中,我们可以看到我们有两种不同类型的服务器,它们都运行在相同的操作系统上。然而,它们运行不同的功能,因此我们希望为 Linux 服务器设置一个补丁组,为数据库服务器设置另一个组。数据库服务器可能只会获得关键补丁,而 Linux 服务器可能会获得关键补丁以及更新补丁。
安全
下一个是 AWS Well-Architected Framework 的安全支柱。今天,安全问题是每个人头脑中的重要问题。恶意行为者始终试图找到任何代码和基础设施(无论是在本地还是在云中)的漏洞。回顾 AWS 前 10 年的经验教训时,CTO Werner Vogels 表示保护您的客户应始终是您的首要任务...对 AWS 来说绝对如此。(Vogels,2016)
如今,确保所有云系统具有安全实践是每个人的责任。这种(保护)包括为应用程序服务的基础设施和网络组件,使用安全编码实践和数据保护,最终确保客户拥有安全的体验。
当你思考安全时,安全支柱关注四个主要领域。它们在下图中展示:

图 1.2 – 安全支柱中的四个主要安全领域
安全支柱由七个原则构成:
-
实施强大的身份基础
-
启用可追溯性
-
在所有层面应用安全性
-
自动化安全最佳实践
-
保护传输中和静态数据的安全
-
将人员远离数据
-
准备应对安全事件
在本书的过程中,你将找到一些针对安全支柱中介绍的安全原则的实际答案和解决方案。这将帮助你养成将安全性融入到所构建的每个部分中的肌肉记忆,而不是将自己的部分交给安全团队去担心。记住,安全是每个人的责任。最初,我们将更详细地了解这些安全原则。
实施强大的身份基础
在建立强大的身份基础时,一切从实现最小权限原则开始。任何用户或角色的权限都不应多于或少于执行其工作或职责所需的权限。如果进一步深化这个概念,如果你使用 IAM 来管理用户,那么请确保密码策略到位,以确认密码定期轮换,避免密码变得过时。检查 IAM 密码策略与公司密码策略是否一致也是一个好主意。
此外,随着组织的成长和用户与权限管理变得更加复杂,你应考虑建立集中身份管理,使用 Amazon 单点登录或连接公司 Active Directory 服务器。
启用可追溯性
安全事件可能会让你处于被动应对的状态;然而,你的反应能力取决于你能够收集到多少关于该事件的信息。在事件发生之前,建立适当的监控、日志记录、警报以及审计环境和系统的能力,对于在需要时能够执行正确的评估和步骤至关重要。
从多个来源捕获足够的日志可以通过 AWS 服务来实现,例如 CloudWatch Logs、VPC Flow Logs、CloudTrail 等。在本书的第三部分,我们将详细探讨日志记录和监控,因为它们对于 DevOps 专业认证考试非常重要。
考虑以下场景:
有人通过弱密码获得了服务器访问权限并且破坏了一些数据。你认为你当前收集了很多日志;然而,你能弄清楚以下问题吗?
-
用于访问系统的用户名
-
用于访问源的 IP 地址
-
访问开始的时间
-
被更改、修改或删除的记录
-
受影响的系统数量
在所有层级应用安全措施
保护环境中的所有层级有助于通过为你的行为提供更广泛的覆盖来提高安全性。为了应对网络级别的安全,可以使用简单的技术,如安全组和网络 ACL 来保护不同的 VPC。经验丰富的 AWS 专业人士知道,额外的安全层会扩展安全防护的范围——例如,在边缘(AWS 云的网络接入点)、操作系统级别,甚至通过向左偏移来保护应用程序代码本身。
自动化安全最佳实践
随着你和你的团队在云端安全实践方面的教育不断深入,重复性的任务应该被自动化。这可以让你更快速地响应正在发生的事件,甚至在你没有意识到事件发生时也能作出反应。
这是你开始深入学习时需要关注的话题。作为一名 DevOps 专家,你习惯于将重复的手动流程通过自动化来提高效率。自动化可以表现为自动分析日志、删除或修复不符合组织安全政策的资源,或智能地检测威胁。
亚马逊 Web 服务推出了一些工具来帮助这一过程,包括 GuardDuty、CloudWatch、EventHub 和 AWS Config。
保护传输中和静态存储的数据
坏意图的攻击者无处不在,他们不断寻找可以被利用的、在互联网上未加保护的数据。你绝对不能依赖最终用户使用最佳实践,如通过 VPN 进行安全通信,因此,这项工作需要由你和你的团队在服务器端实施最佳实践。诸如在负载均衡器、CloudFront 分发上,甚至在服务器层面实施证书等基本操作,可以确保数据在传输过程中进行加密,从而实现端到端的安全传输。
同理,打个比方,确保通过启用传输层安全协议(TLS)或 IPsec 协议来验证网络通信,有助于确保网络通信的认证。
AWS 提供了一些服务来帮助保护你的数据,无论是在传输中还是静态存储中,例如 AWS 证书管理器、AWS Shield、AWS Web 应用防火墙(即另一个WAF)以及 Amazon CloudFront。密钥管理服务(KMS)也可以帮助保护静态存储的数据,允许你轻松创建、使用和轮换加密密钥。
要深入了解如何保护传输中和静态数据,请参阅第十九章,保护传输和静态数据。
使用机制将人员与数据隔离
有多种方法可以自动化数据访问,而不是允许个人直接访问数据。通过变更控制过程验证的项目通常是一个更好的选择。这些项目可以是系统管理运行手册或 Lambda 函数,负责访问数据。与此相对的是允许通过堡垒主机或弹性 IP 地址/CNAME 直接访问数据源。
提供这种直接访问可能导致人为错误或用户名和密码被泄露,最终导致数据丢失或泄露。
为安全事件做准备
即使您执行了前面描述的所有安全原则,也不能保证未来不会发生安全事件。您最好通过练习并准备一套快速执行的步骤,以防万一。
您可能需要创建一个或多个运行手册或操作手册,列出如何执行任务的步骤,例如拍摄 AMI 快照进行取证分析并将其转移到安全账户(如果有的话)。当这些步骤变得必要时,会有来自不同地方的问题。这些答案将有时间方面的要求。如果负责执行这些任务的团队从未进行过这些任务的练习,也没有为他们制定指南,那么宝贵的时间将被浪费,仅仅是为了组织和安排。
以下是 AWS 与您(客户)之间的共享责任模型:

图 1.3 – AWS 共享责任模型
提问问题
- 如何保护您的根账户?
-
根账户上是否有多因素认证(MFA)设备?
-
根账户是否未被使用?
-
如何分配 IAM 用户和组?
-
如何委派 API/CLI 访问权限?
接下来,让我们了解云端可靠性的五个设计原则。
可靠性
云端可靠性设计有五个原则:
-
自动化故障恢复
-
测试恢复程序
-
横向扩展以提高整体工作负载的可用性
-
停止猜测容量
-
管理自动化中的变更
自动化从故障中恢复
当你想到自动化故障恢复时,大多数人首先想到的是技术解决方案。然而,这不一定是可靠性服务支柱中所指的上下文。这些故障点应该是基于业务设定的关键绩效指标(KPIs)。
作为恢复过程的一部分,了解组织或工作负载的恢复时间目标(RTO)和恢复点目标(RPO)非常重要。
-
RTO(恢复时间目标):服务中断和恢复之间可以接受的最大延迟时间
-
RPO(恢复点目标):自上次数据恢复点(备份)以来可接受的最大时间(亚马逊网络服务,2021 年)
测试恢复程序
在你的云环境中,你不仅应该测试工作负载是否能正常运行,还应测试它们是否能够从单个或多个组件故障中恢复,特别是在服务、可用区或区域层面发生故障时。
通过使用基础设施即代码、持续集成(CD)流水线和区域备份等实践,你可以快速启动一个全新的环境。这可以包括你的应用程序和基础设施层,能够让你测试其是否与当前生产环境中的工作方式相同,并且数据是否正确恢复。你还可以记录恢复所需的时间,并通过自动化恢复时间来改进它。
主动记录运行手册或操作手册中每一个必要步骤,可以促进知识共享,并减少对构建系统和流程的特定团队成员的依赖。
水平扩展以提高工作负载可用性
从数据中心环境过渡时,规划峰值容量意味着找到一台可以运行应用程序所有不同组件的机器。一旦达到该机器的最大资源,就需要迁移到更大的机器。
当你从开发环境迁移到生产环境,或者当你的产品或服务的受欢迎程度增长时,你需要扩展资源。实现这一点的主要方法有两种:垂直扩展或水平扩展:

图 1.4 – 水平扩展与垂直扩展
垂直扩展的主要问题之一是你会在某个时刻碰到瓶颈,必须不断迁移到更大的实例。最终,你会发现没有更大的实例可以迁移,或者更大的实例运行成本太高,无法负担。
另一方面,水平扩展使你能够以成本效益的方式,在需要时获得所需的容量。
采用云思维意味着将应用程序组件解耦,将多个相同的服务器组放在负载均衡器后面,或从队列中拉取并根据当前需求进行最优的上下扩展。
停止猜测容量
如果资源被压垮,它们往往会发生故障,尤其是在本地部署时,当需求激增,而这些资源没有能力向上或向外扩展以满足需求时。
有一些服务限制需要注意,尽管它们中的许多被称为软限制。这些限制可以通过简单的请求或打电话给支持团队来提高。还有一些被称为硬限制。它们是为每个账户设置的固定数字,无法提高。
注意
虽然没有必要记住所有这些限制,但熟悉它们并了解其中的一些限制是个好主意,因为它们有时会出现在一些测试问题中——并不是作为直接问题,而是作为情景的背景。
自动化中的变更管理
虽然手动更改基础设施(或应用程序)似乎更容易且有时更快捷,但这可能导致基础设施漂移,并且无法重复操作。最佳实践是通过基础设施即代码、代码版本控制系统和部署管道自动化所有更改。这样,所有更改都可以被追踪和审查。
性能效率
如果你和你的架构设计团队来自数据中心基础设施,并且配置过程需要几周或几个月才能获得所需的系统,那么云资源的快速性和可用性无疑是一次清新的体验。需要了解如何根据工作负载需求选择正确的实例类型或计算选项(即基于服务器、容器化或基于函数的计算)。
一旦你做出了初步选择,就应该进行基准测试,以查看你是否充分利用了分配的所有 CPU 和内存资源,并确认工作负载是否能处理它所需执行的任务。在选择实例类型时,不要忘记考虑成本,并记录那些可能节省你资金或在基准测试过程中让你花费更多的成本差异。
AWS 提供了本地工具来创建、部署和监控基准测试,如下图所示:

图 1.5 – 使用 AWS 工具进行基准测试
使用 AWS 提供的工具,你可以快速启动一个环境来进行资源适配、基准测试和负载测试,检查你为计算实例选择的初始值是否合适。你还可以轻松地更换其他实例类型,查看它们在相同测试下的性能表现。通过使用 CloudFormation 构建基础设施,你可以以快速且重复的方式运行测试,使用 CodeBuild 进行测试,同时通过 CloudWatch 收集度量数据,比较结果,确保你做出了最佳决策,并有数据支持这一决策。在 第七章中,我们将更详细地讨论如何使用 CodeBuild,[使用 CloudFormation 模板部署工作负载]。
性能效率 支柱包括五个设计原则,帮助你在云中保持高效的工作负载:
-
让先进技术更易于为你的团队实现
-
能够在几分钟内实现全球化
-
使用无服务器架构
-
允许你的团队进行实验
-
使用与你目标一致的技术
让先进技术更易于为你的团队实现
随着托管服务的出现,云计算简化了使用先进技术的过程。你不再需要聘请全职数据库管理员来专门处理不同类型的数据库,以测试 Postgres 或 MariaDB 哪个更优化地运行。类似地,如果你需要该数据库的复制,只需勾选一个框,你就能立即获得高可用的设置。
过去需要花费时间在文档上,努力搞清楚如何安装和配置特定系统,现在这些时间可以用来专注于最重要的事情——为你的客户和业务提供价值。
能够在几分钟内实现全球化
根据你运行的应用程序或服务,客户可能会集中在一个地区,或者分布在全球各地。一旦你将基础设施转化为代码,通过 CloudFormation 模板或 CDK 中的构造,你可以利用区域参数快速重用之前构建的模式或架构,并将其部署到世界的其他地区。
即使没有部署完整的应用程序和架构,依然有能力利用内容分发网络(CDN)CloudFront 来服务全球用户。在这里,你可以使用应用程序创建安全的全球存在,或者在主要区域(即原始区域)部署内容。
使用无服务器架构
首先,迁移到无服务器架构意味着不再需要管理服务器。这意味着不再需要在启动时配置带有软件包的服务器,不再需要调整服务器大小,也不再需要修补服务器。
无服务器架构意味着你已经解耦了应用程序。无论是使用函数、事件还是微服务,每个组件都应该执行特定的任务。每个组件只处理其独特任务时,你可以在任务级别微调内存和使用 CPU,并在特定任务级别进行扩展。
这并不是每个工作负载的最佳选择,但不要仅仅因为某个工作负载需要进行少量重构就将其排除。当应用程序可以迁移到无服务器架构时,它可以让生活更轻松,使应用程序本身更加高效,通常还会带来成本节省——特别是在长期看来。
允许你的团队进行实验
一旦你迁移到云端,你可以迅速且持续地重构你的工作负载,以提高性能和降低成本。如果你已经将基础设施构建为代码,那么为测试创建一个新的临时环境可以是一个快速且成本高效的方式,尝试你应用程序中的新模块,而无需担心会影响到任何客户或组织的其他部分。
许多实验可能不会成功,但这就是实验的本质。如今的商业竞争异常激烈,找到一个有效的解决方案,使你的服务更快、更便宜、更好,可能会成为真正的游戏规则改变者。
使用与工作负载目标对齐的技术
列出你的业务目标,并让产品负责人根据这些目标帮助推动产品和服务的选择。如果开发团队对某些技术已有一定了解,他们可能会倾向于使用那些他们已经自信的技术。
另一方面,还有一些团队力求使用最新的技术,但这并不一定是因为这些技术解决了已识别的问题。相反,他们的兴趣在于不断丰富简历,确保能够尽早接触并体验到最前沿的服务。
成本优化
许多人误以为迁移到云端会立即为他们的公司或组织带来成本节约。一旦没有严格的控制措施或无法将工作负载分摊给相关团队时,现实就显现了出来,越来越多的团队发现,配置新资源就像按一个按钮一样简单。一旦账单开始出现,大部分情况下,来自高层的成本削减运动就会随之而来。
在你着手优化成本时,要理解那些已被证明是托管服务的云服务,每分钟的费用较高;然而,人力资源成本却要低得多。你无需关心和维护底层服务器,也不需要担心更新底层操作系统。许多服务允许你根据用户需求进行扩展,这些都会自动为你处理。
监控成本和使用情况的能力也是成本优化策略的关键要素之一。拥有一个合理的资源标签策略,可以使负责财务管理 AWS 账户的人进行正确部门的费用分摊。
云中的成本优化有五项设计原则:
-
实施云财务管理
-
采用消费模型
-
衡量整体效率
-
停止为无差异的大量基础设施工作付费
-
分析和归因支出
实施云财务管理
云财务管理正在各大组织中迅速发展,无论大小。它需要一个专门的团队(或者一组部分负责此任务的团队成员)来建立一个系统,能够看到云支出的去向。该团队会查看费用使用报告,设置预算警报,跟踪开支,并希望能够执行一个计费标签,以展示每个部门、成本中心或项目的费用分摊。
什么是费用分摊?
IT 费用分摊是一种流程,允许各个部门将费用与特定的部门、办公室或项目关联,从而准确跟踪 IT 支出。我们在此示例中具体指的是云支出,但 IT 费用分摊也应用于 IT 的其他领域,例如会计目的。
采用消费模型
使用云并不需要复杂的预测模型来控制成本,尤其是在有多个环境的情况下。开发和测试环境应该能够在不使用时关闭或暂停,从而节省空闲时的费用。这就是云端按需定价的魅力。如果开发人员因数据丢失而抱怨,那么可以教他们在关闭之前使用快照功能备份数据库实例;这样,他们就可以从中断的地方继续开发。
一个更好的策略是自动化在工作日结束时关闭开发和测试环境的过程,并要求使用专门的标签,这样可以防止实例在下班后或周末被关闭。你还可以自动化在工作日开始前 30 到 60 分钟重启实例的过程,以便操作系统有足够的时间启动,确保团队认为它们根本没有被关闭过。只需要注意,任何运行在实例存储上的 EC2 实例可能会丢失数据。
衡量整体效率
组织在云预算方面失去效率的最明显方式之一就是忽视停用未使用的资产。虽然在云中启动新服务和创建备份较为容易,但如果没有计划将折旧的数据、卷备份、机器镜像、日志文件和其他物品进行退役,这将增加每月账单的底线。这应该用手术刀而非砍刀进行。数据一旦删除,就无法恢复;然而,并不需要将所有东西永远保存。即使是合规要求,也有一个渐退期,数据可以以更合理的价格存储在冷存储中。
一个完美的例子是 EBS 快照。试图主动保护数据的客户可能每天多次对卷进行快照,并将这些快照复制到灾难恢复区域。如果在 30 天、60 天或 90 天后没有办法使旧的快照失效,那么这个成本中心项可能很快就会成为一个问题。
停止在无差异的重型工作上花费资金。
当我们谈论重型工作时,我们指的是在数据中心中架设、堆叠和冷却服务器。运营数据中心是一项 24 小时全天候、365 天的工作,而当你不使用这些机器和存储时,不能轻易关闭它们。将工作负载迁移到云端,减轻了团队成员对数据中心运营的负担,使他们可以将更多时间和精力投入到关注客户需求和功能上,而不是照料和管理服务器及硬件。
分析和归因支出
云计算——尤其是 AWS 云——提供了帮助你分析和参考账户费用来源的工具。工具箱中的第一个工具是标签和标签策略。一旦你决定了一个稳定的基础标签集,包括成本中心、部门和应用等内容,你就为其余可用工具奠定了基础。
通过使用 AWS Organizations 从单一账户结构扩展到多个账户和组织单元,可以在不使用账户级别标签的情况下自动分类支出。
AWS 成本探索器允许你的财务管理团队深入分析费用发生的服务和区域,并能够创建自动化仪表板,快速可视化支出。亚马逊网络服务还设定了预设的服务配额,其中一些是不可更改的硬性配额,但许多则是允许你通过简单请求增加特定服务数量(在某个区域内)的软性配额。
总体服务支柱原则
《良好架构框架》识别了一套通用设计原则,旨在促进云端的良好设计:
-
在完整生产规模下测试系统。
-
自动化尽可能多的组件,使实验尽可能简单。
-
使用数据驱动架构设计。
-
停止猜测容量需求。
-
允许架构随着新技术和服务的出现而不断演进。
-
利用游戏日推动团队改进。
在你思考这些服务原则并如何将它们付诸实践时,要意识到有时候这些原则可能会感觉相互矛盾。最明显的例子是成本优化支柱。如果这是你所在的组织最关注的支柱,其他支柱可能会影响纯粹的成本节约。加强你在可靠性支柱中发现的弱点,通常意味着更多的资产,而资产意味着更多的资金。然而,你仍然可以努力使这些资产尽可能具有成本效益,从而符合所有支柱的要求。
总结
在本章中,我们学习了指导架构师和开发人员设计良好的五个服务原则。我们讨论了这些原则是如何成为 DevOps 专业考试中的测试问题的基础主题,以及掌握这些基础知识在你确定正确答案时如何帮助你。我们在讨论每个服务支柱时,也讨论了它们的基础设计原则。
我们简要提到了一些不同的 AWS 服务,以及哪些服务支柱或设计原则在特定服务中发挥作用。在下一章中,我们将学习贯穿于你将要工作中的环境和账户的基本 AWS 服务。
复习题
-
Well-Architected 框架的五个支柱是什么?
-
安全在云中的五个主要领域是什么?
-
性能效率支柱包含的四个领域是什么?
-
可靠性支柱包含的三个领域是什么?
-
RTO 的定义是什么?
-
RPO 的定义是什么?
复习答案
-
Cost Optimization, Reliability, Operational Excellence, Performance Efficiency, 和 Security。(使用助记符CROPS帮助记住这五个支柱,每个支柱的首字母分别是 C、R、O、P、S。)
-
数据保护、基础设施保护、权限管理、事件响应和侦测控制。
-
计算、存储、数据库和网络。
-
基础、变更管理和故障管理。
-
恢复时间目标 – 中断服务和恢复服务之间可接受的最大延迟。
-
恢复点目标 – 自上次数据恢复点(备份)以来可接受的最大时间间隔。
深入阅读
以下是推荐的论文和资源列表,供进一步阅读:
-
AWS Well-Architected 白皮书:
d1.awsstatic.com/whitepapers/architecture/AWS_Well-Architected_Framework.pdf -
安全白皮书:
docs.aws.amazon.com/wellarchitected/latest/security-pillar/wellarchitected-security-pillar.pdf -
计算系统总可用性:
-
Well-Architected 实验室:
-
AWS Well-Architected 框架支柱:
-
10 年 AWS 经验的 10 个教训:
www.allthingsdistributed.com/2016/03/10-lessons-from-10-years-of-aws.html
第二章:基础 AWS 服务
现在我们已经了解了构成最佳实践的服务原则和支柱,这些内容构成了使用Amazon Web Services(AWS)时的基本框架,是时候来看一些你将在环境和账户中使用的基础服务了。我们提到的基础服务包括计算服务,如弹性云计算(EC2)、全球域名系统(DNS)服务Route 53、数据库服务,如RDS和Aurora,以及咨询服务Trusted Advisor。如果你已经参加过云从业者、SysOps 或开发者考试,这些服务可能会让你感觉像是在复习已知内容。然而,由于现在没有要求在参加(并通过)DevOps 专业考试之前必须通过任何较低级别的关联考试,因此对一些基本服务进行复习也是一个不错的选择。
本章并不打算全面介绍这些服务。所提到的服务将被引入到 DevOps 考试的背景中,因此不建议跳过本章。不过,如果你认为自己对这些话题有很强的掌握,可以通过检查复习题和参考资料来验证这一点。同样,你也可以复习任何你已经掌握的主题。
在本章中,我们将覆盖以下主要内容:
-
设置和访问你的 AWS 账户
-
虚拟私有云网络和 Route 53 网络
-
云数据库
-
消息和队列系统
-
Trusted Advisor
技术要求
你需要一个 AWS 账户才能访问管理控制台和 CLI,这些内容将在本章的初始部分提到。如果你需要创建账户的帮助,访问aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/页面,它将指导你完成创建新账户的步骤。还需要具备基本的终端使用知识,以便完成 shell 命令。
重要提示
在本书中,我们不会详细讨论 AWS 的地理位置、区域、可用区或边缘位置。这些是你在尝试 DevOps 考试之前应该牢牢掌握的基本概念。
设置和访问你的 AWS 账户
在这一点上,你很可能已经拥有一个 AWS 账户来进行操作;然而,你可能只能通过你的工作场所访问该账户,其中一些权限被限制,因此你无法练习所有你需要掌握的技能,以便自信地通过 DevOps 专业考试。
如果您尚未为测试设置个人账户,那么现在是设置一个账户的完美时机。即使您已经有一个账户,您可能希望花时间设置一个新账户,专门用于考试,以确保您能够在提供的服务中利用首年的免费套餐(在 AWS 上分配)。
如果您已经拥有账户,转换到 AWS 组织 特别是使用控制塔,是一个很好的练习,如果您希望创建服务控制策略、组织单位、单点登录(SSO)和跨账户角色。
重要提示
控制塔需要至少三个不同的电子邮件账户来启动创建的三个独立账户。
创建主账户后,您可以向之前创建的账户发送邀请,并允许其加入组织。
进入 AWS 管理控制台
AWS 管理控制台是访问您的 AWS 账户的前门(GUI)。
首先打开任何网页浏览器并访问 aws.amazon.com/。
在起始页面上,查找 我的账户 菜单项。将鼠标悬停在此菜单项上,应该会给您选择 AWS 管理控制台 的选项:

图 2.2 - 创建我们的用户
-
然后我们可以点击下一步,继续设置权限。
-
在设置权限下,我们要选择直接附加现有策略。
-
对于这个初始用户,我们将使用AdministratorAccess职位功能策略。选择此策略,使左侧的框被选中,然后点击底部的下一步:标签按钮:
![图 2.3 - 附加策略]()
图 2.3 - 附加策略
-
只需点击底部的下一步:审查按钮。
-
如果一切看起来正常,点击底部的蓝色按钮,标记为创建用户。
-
因为我们已经选择了程序访问权限,所以一旦我们创建了用户,就会有机会查看秘密访问密钥,并下载访问密钥和秘密密钥对的 CSV 文件。请记下此用户的秘密密钥,或下载该文件,因为这是唯一一次可以获取秘密访问密钥的机会。
到此为止,我们已经设置了第一个用户及其访问策略、密码、访问密钥和秘密密钥。在本书的其他练习中,我们将引用此用户。你可以自由设置任何你喜欢的用户名,但对于一个不使用 root 账户的管理用户账户,我们将使用devops用户。
设置和使用 AWS CLI v2
你确实可以使用基于图形的 Web 界面管理控制台执行大多数任务。作为 DevOps 工程师,你会希望在环境中自动化一些操作,CLI 通过一系列脚本功能赋予你这种能力。CLI 是许多人最喜爱的工具之一,因其速度和强大的功能。
以前 CLI v1 用户注意
如果你之前安装过 AWS CLI v1,强烈建议你在安装 CLI v2 之前先卸载 v1。两个 CLI 命令都使用相同的命令名称aws。如果你不想卸载 CLI v1,那么可以在你的路径中设置别名。
Mac 设置
只要你的机器上有 sudo 权限,你就可以轻松使用捆绑安装程序在 Mac 上安装 AWS CLI v2:
-
打开终端窗口。
-
运行以下两条命令来安装 AWS CLI:
$ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" $ sudo installer -pkg AWSCLIV2.pkg -target / -
通过运行以下命令来检查是否已安装正确版本:
$ aws --version输出应该类似于以下内容:
aws-cli/2.1.29 Python/3.8.8 Darwin/18.7.0 exe/x_86_64
只要cli后面的数字以2开头,你就成功安装了 AWS CLI v2。
现在你可以跳到配置 CLI 的部分。
PC 设置
PC 用户注意
要运行 CLI v2,你的 Windows XP 或更高版本操作系统必须是 64 位版本。
如果您有在计算机上安装软件的管理权限,您可以按照以下说明安装 AWS CLI v2:
-
下载适用于 Windows 的 AWS CLI MSI 安装程序:
awscli.amazonaws.com/AWSCLIV2.msi。 -
运行下载的 MSI 安装程序并按照屏幕上的指示进行操作。
-
通过运行以下命令确认是否已安装正确的版本:
C:\> aws --version
Linux 设置
在 Linux 机器上安装 CLI v2 之前,需要先处理一些先决条件:
-
您需要具备解压软件包的能力,可以使用系统的
unzip命令或其他已安装的软件包。 -
为了确保 AWS CLI v2 正常运行,您需要确保在发行版中已安装
glibc、groff和less软件包。大多数主要发行版默认已安装这些软件包。 -
AWS 支持在更新的 64 位版本的 CentOS、Fedora、Ubuntu、Amazon Linux 1 和 Amazon Linux 2 上使用 AWS CLI v2\。
现在先决条件已满足,您可以按照以下说明安装 CLI:
-
运行以下
curl命令以下载 AWS CLI v2 的 ZIP 文件:$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" $ sudo installer -pkg AWSCLIV2.pkg -target / -
现在 ZIP 文件已下载,我们可以解压它:
$ unzip awscliv2.zip -
解压后,我们可以运行
install程序:$ sudo ./aws/install -
通过运行以下命令检查是否已安装正确的版本:
$ aws --version -
输出应类似于以下内容:
aws-cli/2.1.29 Python/3.8.8 Linux/4.14.133-133.105.amzn2.x86_64 botocore/2.0.0
设置 CLI 的参考资料可以在 AWS 的文档中找到:docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html。
配置 CLI
安装 CLI 后,建议进行配置。如果您曾安装过 CLI v1 并使用过配置文件,您应该可以继续使用这些配置文件。为了快速配置 CLI,您可以使用 aws configure 命令;不过,作为先决条件,最好事先在 IAM 中为您的用户创建并下载密钥和秘密密钥。如果您要配置默认配置文件或辅助配置文件用于本书中的示例,您将需要这对凭证。
如果您尚未操作,请通过管理控制台重新登录 AWS 账户,然后导航至 IAM 服务,创建一个用户和角色。使用该用户,您可以分配 访问密钥 ID 和 秘密密钥 ID,并将其输入 CLI 中,以便在本书中的教程中使用。
获得密钥对后,按照以下步骤配置 CLI:
-
运行
aws configure命令:$ aws configure -
当提示时,剪切并粘贴访问密钥 ID。
-
当提示时,剪切并粘贴秘密密钥 ID。
-
当提示时,为示例设置默认区域(我们将使用
us-east-2)。 -
您可以直接按 Enter 键退出并使用默认的 JSON 输出;然而,我发现将输出设置为表格形式会更易于用户阅读。
在本书的许多示例中,CLI 命令将会添加一个 profile。
AWS 中的云计算
当我们谈论 AWS 中的计算时,我们指的是多个服务,包括 Amazon EC2、弹性负载均衡(Elastic Load Balancing)、AWS 批处理(AWS Batch)、弹性容器服务(Elastic Container Service)和弹性 Kubernetes 服务(Elastic Kubernetes Service),以及 AWS Fargate 这项托管服务,它允许你以最小的开销运行容器。它甚至包括 Lightsail,这是开发人员在云中快速启动的最快方式,无需配置软件或网络:

图 2.4 – AWS 中的计算服务
虽然 AWS 中有许多服务属于计算服务的范畴,但最基础的服务是 EC2。EC2 是你在 Amazon 云中的虚拟实例。尽管其他服务,如弹性容器服务(Elastic Container Service)、弹性 Kubernetes 服务(Elastic Kubernetes Service),甚至 Elastic Beanstalk,都可以让你在 AWS 中运行容器,但它们的核心仍然是运行在 EC2 实例上。因此,了解 EC2 服务的基础知识,例如如何选择正确的实例类型,如何使用最优的负载均衡器(因为有三种可供选择),以及如何将存储卷添加到实例中,这些都是相对的信息,无论是处理 DevOps 专业考试问题,还是作为专业人士在日常工作中的任务:

图 2.5 – EC2 在实际架构中的应用
在前面的图示中,我们可以看到一个实际场景,其中 EC2 实例被用于自动扩展组中,以支持 WebSphere 平台。多个 EC2 实例位于一个私有子网中,外部用户只能通过 Route 53 中的 DNS 记录,通过应用负载均衡器访问这些实例。如果内部用户需要访问 WebSphere 服务器中的任何一个,可以通过位于公共子网中的堡垒主机使用 SSH 协议进行访问。堡垒主机位于一个跨越两个可用区的自动扩展组中,但每次只有一个主机处于活动状态。
现在我们将更详细地了解这些服务,特别是 EC2 服务。
亚马逊弹性云计算(EC2)
亚马逊 EC2 允许你创建一个虚拟服务器,在云中执行多个任务。EC2 提供了广泛的定制选项。你可以选择多种操作系统,以满足应用需求。适当配置内存和处理能力只需根据工作负载的需求选择合适的实例类型即可。
EC2 还提供三种不同的定价模式,每种模式都可以根据需求提供灵活性或折扣。它们分别是按需实例、预留实例和竞价实例。
按需实例是默认的实例类型,在请求 EC2 计算实例时无需长期承诺。你可以自行决定何时启动、停止、休眠、启动或终止实例,并且不会有任何后果。从定价的角度来看,你只需为处于运行中状态的按需实例按秒计费。
如果你有已知的工作负载将在 EC2 上持续运行一年,或需要在特定可用区内的预定容量,那么预留实例可以提供成本节省,并且在该特定可用区内提供预留容量。预留实例有两种不同的承诺期限,分别为 1 年和 3 年,后者在长期承诺下提供更大的节省。
当 AWS 有多余的容量未被利用时,这些实例会作为竞价实例以大幅折扣提供。不同类型实例的供需情况会导致价格波动,有时波动较快。这些折扣可以达到正常按需定价的 80%;然而,这也有一些限制。首先,你必须立即启动实例,并且不能停止或休眠竞价实例。在启动竞价实例时,你需要设置一个最大价格,例如当前的按需价格,如果价格超过你设置的最大价格,AWS 会发出信号,给你 2 分钟的时间保存工作,然后实例会被终止。
EC2 实例类型
在写本文时,已有超过 170 种实例类型,允许你根据任何想要在云中运行的工作负载定制计算需求。并不重要的是记住所有不同类型和大小的实例,以及它们的计算和内存规格。然而,了解 EC2 在工作负载特定性方面如何划分不同的类别,以及哪些 EC2 系列属于这些类别,是一个好主意。
注意
只有部分 EC2 实例支持增强型网络,这可能成为选择正确实例类型时的决定性因素。增强型网络功能在处理故障排除或工作负载时尤其重要,因为它支持更高的带宽和每秒更多的数据包。
由于有许多类型的工作负载正在迁移到云中,每种工作负载都有其特定的需求,AWS 创建了几个不同的 EC2 实例系列。每个系列包含一种或多种实例类型,并具有优先应用程序配置文件。
这些实例系列可以按以下方式进行分组:
-
通用型实例
-
计算优化型实例
-
内存优化型实例
-
加速计算实例
-
存储优化型实例
让我们更详细地看看这些内容。
通用型实例
通用型实例平衡内存、计算和网络资源,是各种工作负载的理想选择。这包括 T 类实例,这些实例具有可积累的突发信用点。若你没有完整的工作负载分类,通用型实例是一个很好的起点。
使用案例:Web 服务器、开发和测试服务器、代码库、小型到中型数据库以及 SAP 后台服务器。
计算优化实例
计算优化实例专为从高性能处理器中获益的工作负载量身定制。该系列中的实例还具备增强网络功能,并默认优化为弹性块存储(EBS)。
使用案例:批处理、视频编码、广告投放、分布式分析、基于 CPU 的机器学习、游戏、科学建模以及高性能科学与工程应用,如基因组分析或计算流体动力学。
内存优化实例
这一系列实例,顾名思义,是为内存密集型应用而设计的。它们旨在为需要大量内存的任务提供快速的性能能力。
使用案例:开源数据库、内存缓存和实时分析。
加速计算实例
加速计算实例包含协处理器或硬件加速器,这些加速器比其他处理器执行特定功能的效率更高。这些功能可能包括数据模式匹配、浮点数计算和图形处理。
使用案例:语音识别、高性能计算、药物发现、计算金融和自动驾驶汽车。
存储优化实例
存储优化实例提供直接连接的存储选项,能够满足特定的存储需求。这意味着实例存储可以针对非常定制化的输入和输出(I/O)性能进行优化,例如 H1 实例,或者在高存储(HS)实例的情况下提供非常高的存储密度。
使用案例:NoSQL 数据库、数据仓库、Elasticsearch、内存数据库、传统数据库和分析工作负载。
实例由两种存储类型支持:实例存储和 EBS。在选择实例类型时,系统会显示该实例是由 EBS 还是实例存储支持。这两种存储类型之间存在一些重要区别,尤其是在持久性方面。实例存储的一个主要优势是其高 I/O 和吞吐量。这是因为它直接连接到实例。基于实例存储的卷的缺点则在于持久性。如果你重新启动一个由实例存储支持的 EC2 实例,所有临时数据,如日志和临时文件,将会丢失。基于 EBS 的实例则不同,因为存储并未直接连接到实例。
了解 Amazon 机器镜像(AMI)
每当您启动 EC2 实例时,它必须从Amazon 机器镜像(AMI)启动,以便包含启动所需的信息。这些可以是基础操作系统镜像,实际上是干净的起点。或者,它们也可以是您或其他实体创建的 AMI,作为一个有效的工作系统或在单个实例上运行的多个系统的检查点。
AMI 可以由 Amazon 本身提供,由您的用户账户提供,私下与您的其他账户共享,或者来自合作伙伴账户,由社区成员创建,甚至可以在 AWS Marketplace 上免费或按小时收费提供。
AMI 的使用案例
您可以创建自己的 AMI,用于自动伸缩组或加速启动需要多个步骤下载、安装和配置软件的复杂实例。
也有一种情况是组织中的基础镜像,预先批准了操作系统,并为所有用户预装了安全设置以便遵循。
有可用的社区 AMI;然而,使用这些 AMI 时需要自行承担风险,因为它们上面可能已安装了未知的软件包。
另一种选择是使用由供应商和合作伙伴提供的市场 AMI,这些 AMI 已经经过验证并预先配置了已知的软件。这些 AMI 通常会在运行实例时收取每小时额外费用。
备份 Amazon EC2 实例
如果您想备份您的实例,无论是为了时间点恢复的目的,还是为了在自动伸缩配置中使用它,那么您需要创建一个 AMI:
-
首先,我们必须借助 Systems Manager 服务找到最新版本的 Amazon Linux2 AMI,并将其存储到变量中以便下一步使用:
$IMAGE='aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --output text --region us-east-2' -
启动 EC2 实例。现在我们知道了要使用的基础 AMI 的最新版本,我们需要有一个实例来进行备份并创建自定义 AMI:
i-02666d4b05eee61c1.Create the AMI as a backup:ImageId 值:
{ "ImageId": "ami-0aa7408c42669e27b" } -
验证镜像:
State. If the value says available, then you have successfully backed up your EC2 instance and are ready to test. -
让我们测试一下我们的备份。
在这里,我们将回到我们在步骤 2中用于创建实例的原始命令,但现在,我们将用我们刚刚创建的 AMI 替换原始的镜像 ID:
$aws ec2 run-instances \ --image-id ami-0aa7408c42669e27b \ --instance-type t2.micro \ --region us-east-2
正如您所看到的,借助几个简单的命令,我们不仅备份了正在运行的 EC2 实例,而且还从中创建了一个可启动的 AMI。我们可以进一步备份,将 AMI 复制到另一个区域;只要镜像上没有硬编码的区域特定项目,它应该能够顺利启动并运行。
一旦您完成了 EC2 实例的启动并创建了 AMI,建议终止实例并删除 AMI,以免在 AWS 账户中产生额外费用。
使用用户数据脚本在启动时配置 EC2 实例
尽管我们可以启动 EC2 实例,然后手动配置所需的软件和包,但这并不是最有效的方法。除了手动步骤容易出错外,这种方法比使用自动化过程更加耗时。
示例用户数据脚本
接下来,我们将查看一个用户数据脚本的示例,该脚本可以通过预先执行创建文件、更新已安装的包、更新软件仓库,甚至运行命令等操作,在无需用户交互的情况下配置 EC2 实例:
#cloud-config
package_upgrade: true
repo_update: true
repo_upgrade: all
packages:
- boto3
- aws-cfn-bootstrap
write_files:
- path: /test.txt
content: |
This is my file.
There are many like it but this one is mine.
runcmd:
- [ sed, -i, -e, 's/is/was/g', /test.txt]
- echo "modified my file"
- [cat, /test.txt]
到此为止,我们已经学习了如何使用用户数据脚本在启动时自动配置 EC2 实例,这些脚本可以完成安装和升级包、运行脚本和命令等操作。接下来,我们将了解 EC2 实例的网络接口。
弹性网络接口(ENI)
弹性网络接口(ENI)就像虚拟网络卡,因此它们允许实例拥有一个 IP 地址,并连接到特定子网。EC2 实例允许附加多个 ENI,每个网络接口可以在同一子网中,或者由于特定原因穿越不同的子网:

图 2.6 – 不同安全组中的 ENI
由于安全组是在网络接口级别而不是实例级别附加的,向实例添加额外的 ENI(弹性网络接口)可以使实例加入多个安全组,以满足特定需求。如果你有一台需要访问公共互联网的 Web 服务器,你可以将一个网络接口附加到提供此功能的安全组中。此外,在同一实例中,你可能需要通过 SSH 连接到机器,以便团队成员查看日志或检查服务器上运行的进程。可以通过这种方式锁定附加到特定 ENI 的安全组,从而限制对 SSH 端口(端口22)的访问。
弹性块存储(EBS)
虽然 EBS 和 EC2 紧密相关,但值得记住它们是两个独立的服务。EBS 是一个存储服务,提供基于网络的存储,它被分配到与实例相同的可用区,并挂载供使用。分配给实例的存储量因实例类型而异,并且并非所有类型的 EC2 实例都包含实例存储卷。
EBS 与基于一些关键特性的 实例存储 有所不同。实例存储卷是物理附加到 EC2 实例的存储。由于实例存储在实例停止、终止或实例故障时不会持久化,因此它最适合用于临时存储。相比之下,存储在 EBS 卷上的数据将会持久化:

图 2.7 – AWS 中的 EBS 概述
EBS 卷可以在实例创建时分配,也可以在实例已放入服务后作为额外存储创建。
从 DevOps 的角度来看,在分配和恢复 EBS 卷时需要记住的一个关键特性是,卷必须保留在它创建时所在的同一可用区。
在尝试决定使用哪种类型的 EBS 卷时,一个关键的术语是每秒输入/输出操作数(IOPS)或预配置 IOPS(PIOPs)。IOPS 是测量每秒卷所能执行的输入/输出操作(以千字节为单位)。通过使用 CloudWatch 指标,你可以监控特定卷的性能,使用的卷度量标准包括以下内容:
-
VolumeReadOps -
VolumeReadBytes -
VolumeWriteOps -
VolumeWriteBytes
现在我们已经了解了如何测量 EBS 卷性能的基本概念,接下来我们将查看一些可用的不同类型的 EBS 卷。
EBS 卷类型
EBS 卷有三种主要类型,这些类型在性能、最佳使用场景和成本上各不相同:
-
固态硬盘(SSD):这是一种针对重读写操作进行优化的驱动器,适用于需要更高 IOPS 的场景。可以为配置提供两种类型的 SSD EBS 卷:
a. 通用型 SSD:提供成本与性能的平衡,最适合用于开发和测试环境。
b. 预配置 IOPS SSD:用于性能关键的任务工作负载,例如数据库或缓存。
-
硬盘驱动器(HDD):这是一种针对流媒体工作负载进行优化的驱动器,当需要因持续读取和/或写入而保证性能时使用。可以为配置提供两种类型的 HDD EBS 卷:
a. 吞吐量优化型硬盘(HDD):这种类型的 EBS 卷最适合用于数据仓库、日志服务器或大数据工作负载。
b. 冷 HDD:这是一种低成本的 HDD,适合用于不常访问的数据。
-
前一代:这是一种适合用于较小数据集且不具有关键重要性的数据驱动器。与 SSD 不同,这些 EBS 卷使用的是磁盘,因此性能不如其他两种类型的 EBS 卷。只有一种前一代 EBS 驱动器,适合用于不常访问的数据。
查看 EC2 服务,其中还包括 AMI 和 EBS 卷,你可以选择多个选项,能够根据实例的需求选择合适的大小。这不仅仅与操作系统的选择有关,还包括如何快速配置实例,以及存储性能的要求。
接下来,我们将了解 AWS Batch,这是一个服务,允许我们轻松执行大规模操作,无论是按需还是按计划执行。
AWS Batch
有时,你需要大量的计算资源。
这里可以考虑的一个例子是统计选举结果。一旦投票结束,多个人员和机器开始在不同的区域中心进行计数。每个区域中心统计票数并提交该小计,以便获得最终结果。
统计票数的这个过程是一个批处理过程。如果所有票数都保存在不同的逗号分隔值(CSV)文件中,那么它们可以全部上传并由 AWS Batch 服务处理。
AWS Batch 可以将作业作为 Shell 脚本、Linux 可执行文件或 Docker 容器来运行。
AWS Batch 有五个主要组件:
-
作业
-
作业定义
-
作业队列
-
作业调度器
-
计算环境
让我们更详细地看一下这些内容。
作业
在 AWS Batch 中,作业仅仅是工作单元。这些单元可以是 Shell 脚本、Docker 容器镜像或 Linux 可执行文件,但无论作业如何提交,都会在容器化环境中运行。
作业定义
告诉作业如何运行是 AWS Batch 作业定义的功能。这也是你为作业提供额外详细信息的地方,例如,如果作业需要访问其他 AWS 资源,你可以指定使用的 IAM 角色,还可以定义作业所需的内存和计算能力。
作业队列
直到计算环境可用来运行作业时,作业将停留在作业队列中。你并不限于每个 AWS 账户只有一个作业队列,因为队列可以与不同类型的计算环境关联。
高优先级作业可能会被放入由按需实例组成的队列中。低优先级作业则可能会等待在由抢占实例组成的队列中,直到抢占实例可用时才能运行。
作业调度器
一旦 AWS Batch 作业被提交到队列中,调度器会评估当前的计算环境,看它们是否可以运行该作业。由于作业可能依赖于其他作业的运行和/或完成,因此调度器也会考虑这一点。正因如此,作业会按合理的顺序从队列中提交并运行,但并不总是能保证一个精确的顺序。
计算环境
一旦你设置好作业队列所在的计算环境,你有多个选择。你可以选择托管或非托管的计算环境,并指定特定的实例类型,或者仅在可用的最新实例类型上运行。
如果你使用 Batch 的原因之一是为了节省成本,你还可以确定计算实例的抢占价格。如果计算环境的可靠性是必要的,那么你最好设置按需实例来搭建环境。
虚拟私有云网络和 Route 53 网络
AWS 的 虚拟私有云(VPC)服务允许你在云中创建虚拟网络。它允许你的计算和数据库实例要么允许互联网连接,要么与互联网隔离。安全性可以通过有状态或无状态的虚拟防火墙规则来实现,这些规则提供了你认为合适的网络连接量:

图 2.8 – AWS 中的网络流量与安全
VPC 服务包含多个组件,可以让你路由和保护来自 AWS 服务的流量,且可选地包括互联网和/或本地网络。
VPC
虽然解决方案架构师(或可能是网络架构师)通常会确定用于 VPC 的 CIDR 地址范围,但很多时候,实施 VPC 的工作由 DevOps 工程师来完成,利用 基础设施即代码(IaC)。
有很多组件可以帮助构成一个 VPC。虽然我们不会深入讨论 VPC,但我们将介绍一些你应当了解的项目,以防它们出现在考试题目中。
子网
子网定义了 VPC 中的 IP 地址范围。既有公共子网,也有私有子网。公共子网应当用于需要通过互联网访问的资源。私有子网应当用于那些无法从互联网访问的资源。每个子网只能存在于一个可用区,无法跨越多个可用区。
安全组
安全组充当 Amazon VPC 中的虚拟防火墙。每个 EC2 实例最多可以拥有五个安全组,并且安全组在实例级别强制执行(而不是在子网级别)。
安全组允许有状态的流量,这意味着如果流量根据规则被允许进入,那么它将被返回,而不受任何现有规则的影响。你可以根据端口、IP 范围或其他安全组的组合来指定入站流量规则。
网络访问控制列表(NACL)
网络访问控制列表(NACLs)在子网级别工作(与在实例级别工作的安全组不同)。
虽然安全组是有状态的,但 NACL(网络访问控制列表)是无状态的,任何需要通过 NACL 返回的流量都需要打开端口和 IP 范围。NACL 规则按照顺序进行评估,最低的规则首先被处理。
互联网网关
除非你将 VPC 作为数据中心的私有扩展,否则你需要互联网连接。互联网网关为 VPC 提供与互联网的连接,具有高度可用、可扩展和冗余的特点。互联网网关提供的两个主要功能是:第一个是为路由表中指定的子网提供互联网访问;第二个是为已分配 IPv4 公共地址的实例提供网络地址转换。
仅出站互联网网关
如果你正在为 VPC 和实例使用 IPv6,那么你需要一个 单向出口互联网网关,而不是常规的互联网网关。这种类型的互联网网关可以防止互联网主动连接到你的实例,但仍然提供与其他互联网网关相同的可扩展性、冗余性和高可用性。
网络地址转换器(NAT)
当你的实例位于私有子网时,默认情况下,它们无法访问互联网。即使你已经设置了互联网网关,你也希望将私有实例与直接的互联网访问分离。这时,NAT 实例或 NAT 网关便发挥作用。
NAT 设备将私有子网中的实例流量转发到互联网或其他 AWS 服务。自从 VPC 端点 的出现以来,使用 NAT 来与账户中的其他 AWS 服务通信被认为是一种不安全的做法,绝不应该在生产环境中使用。
VPC 端点
如果你需要从 VPC 安全地访问 AWS 服务,可以创建 VPC 端点。VPC 端点允许 EC2 实例和其他 AWS 计算服务(如 Lambda 和 Fargate)与支持的 AWS 服务(如 S3 和 DynamoDB)进行通信,而无需创建互联网网关,甚至不需要公共 DNS 名称。
这对于那些既不需要也不应该连接互联网的 EC2 实例尤其有用。使用 VPC 端点允许数据连接通过内部 AWS 网络进行传输,并且不需要互联网网关、虚拟私有网关、NAT 设备、VPN 连接或 AWS Direct Connect 连接。VPC 端点是虚拟设备,可以根据需求进行扩展,并且具有冗余和高可用性。
DHCP 选项集
当你创建 VPC 时,Amazon 会默认自动为你创建一组 动态主机配置协议(DHCP)选项。然而,你可以通过创建新的 DHCP 选项集 来自定义一些可用设置,然后将该 DHCP 选项集附加到你的 VPC(从而移除默认的 DHCP 选项集)。
一些允许的选项包括:
-
domain-name-servers:使用你自己的 DNS,而不是 AWS 提供的 DNS。 -
domain-name:未限定的服务器的默认域名。 -
ntp-servers:你可以指定最多四个网络时间协议(NTP)服务器。 -
netbios-name-servers:你可以指定最多四个 NetBIOS 名称服务器。 -
netbios-node-type:NetBIOS 节点类型(1、2、4 或 8);此设置默认为空,且 Amazon 不支持广播或多播。注意
了解 DHCP 选项对于在实际环境中配置 VPC 非常有用,但记住所有可用选项并不是 DevOps 专业考试的必要要求。
使用自定义 DNS 配置你的 VPC
亚马逊提供了一个默认的 DNS 服务器(Route 53 解析器);不过,如果你愿意,也可以使用自己的 DNS 服务器。一些公司要么在混合环境中从他们的数据中心运行 DNS,要么将当前的 DNS 服务器镜像到云端,这样他们就不需要创建包含所有必需信息的 Route 53 托管区域,或者干脆选择在他们最熟悉的平台上管理 DNS。
如果是这种情况,且你想指定 DNS 而不是使用默认的 DNS 服务器,那么你需要创建一个 DHCP 选项集,并填写你的 DNS 服务器的值。完成后,你可以将该 DHCP 选项集附加到你的 VPC,VPC 中的实例将开始使用你指定的 DNS 服务器。
连接多个网络的方法
在 AWS 网络世界中,提供了多种工具来帮助你连接不同的网络。
VPN 连接
你可以使用多种选项将 AWS 与自己的 虚拟专用网络(VPN)连接:
-
AWS 站点到站点 VPN:这个选项创建一个 IPSec 连接,将你的 VPN 与远程 VPC 连接。
-
AWS 客户端 VPN:这个选项使用一个托管客户端,允许你的用户通过基于 OpenVPN 的客户端从几乎任何位置连接。
-
AWS VPN CloudHub:这个选项允许你通过虚拟专用网关创建与多个 VPC 的站点到站点 VPN 连接。(其他选项仅创建与单一 VPC 的 VPN 连接。)
-
第三方 VPN 设备:这个选项允许你使用在 EC2 实例上运行的第三方软件创建 VPN 连接。然而,重要的是要注意,在选择此选项时,你需要负责 EC2 实例的维护和保养。
AWS Transit Gateway
AWS Transit Gateway 允许你通过一个中央网络中心连接本地网络和多个 VPC。Transit Gateway 作为你的云连接的路由器,只需将每个网络连接到 Transit Gateway 一次。连接完成后,其他网络可以通过 AWS 全球私有网络而非公共互联网,使用定义的网络规则相互通信。
AWS Direct Connect
如果你或你的公司有持续的数据传输需求,既需要向 AWS 传输数据,也需要从 AWS 传输数据,那么 Direct Connect 服务可以为你的本地环境与 AWS 之间提供一个私有网络连接。这些专用连接可以通过直连服务提供商以 1 Gbps、10 Gbps 或 100 Gbps 的速度进行连接。
与直接通过公共互联网连接不同,使用 AWS Direct Connect 连接通过专用通道将数据从你的数据中心或办公室传输到 AWS,而不是通过公共互联网,从而提供一致的网络性能。
Route 53
AWS 提供的全球 DNS 服务是 Route 53。这是 AWS 中为数不多的几个不与任何特定区域相关联的服务之一。Route 53 服务还拥有最强的承诺之一,声明其 将采取商业上合理的努力,使 Amazon Route 53 保持 100% 可用(Amazon Web Services, 2021)。
Route 53 有三个主要的组成部分是基础性的重要:
-
注册(并管理)域名的能力
-
DNS 服务
-
执行健康检查(并随后根据其功能性、可用性和可达性路由流量)的能力
本节将介绍一些有关 Route 53 服务的基本信息,特别是那些对 DevOps 考试有帮助的话题。
了解 Route 53 中可用的不同类型的记录
有许多不同类型的 DNS 记录,目前为止,Route 53 支持以下类型的 DNS 记录:
-
地址 (A) 记录
-
AAAA(IPV6 地址记录)
-
规范名称 (CNAME) 记录
-
认证机构授权 (CAA)
-
邮件交换 (MX) 记录
-
名称授权指针记录 (NAPTR)
-
名称服务器 (NS) 记录
-
指针 (PTR) 记录
-
授权起始 (SOA) 记录
-
发件人策略框架 (SPF)
-
服务 (SRV) 位置
-
文本 (TXT) 记录
-
别名记录(这是 Route 53 特有的 DNS 扩展)
现在我们知道了 Route 53 支持哪些类型的记录,接下来让我们看看域名和托管区域之间的区别。
了解域名和托管区域之间的区别
了解域名和托管区域的第一件事是,首先,域名是一个互联网构造,属于域名服务器,它将一个人或组织的唯一名称与一个数字地址的互联网资源关联起来。
域名有区域文件,它们是不同资源及其关联的名称、地址和当前映射类型的文本映射。而托管区域则是 Route 53 独有的东西。它在结构和映射上类似于 DNS 区域文件(你可以将 DNS 区域文件导入到 Route 53 托管区域中),但一个主要的不同之处在于它可以通过 Route 53 界面、CLI 或 API 进行管理和修改。
Route 53 健康检查
Route 53 允许你检查应用程序的健康状况,然后根据你提供的规则将流量重新路由到其他服务器或资源。你甚至可以在 Route 53 的 web 控制台中查看健康检查的最新状态。
检查特定终端节点的健康状况
在这种情况下,您将创建一个来自 Route 53 的检查,该检查将在您指定的常规间隔内执行检查。您的健康检查监控的是一个端点,可以是 IP 地址或域名。然后 Route 53 会按照间隔检查该服务器、应用程序或其他资源是否可用且正常运行。您还可以请求一个特定的网页或 URL,该 URL 会模拟大多数用户的操作,而不仅仅是放在服务器上的一个简单健康检查页面,该页面会在系统正常运行时返回简单的 200 代码。
计算健康检查(监控其他健康检查的健康检查)
如果您有多个执行相同功能的资源,您可能会想知道是否至少有一些资源是健康的。这时计算健康检查就派上用场了:

图 2.9 – 计算健康检查示例
计算健康检查充当根健康检查,其中后代检查可以失败,直到源被视为不健康。
如果触发任何警报,此类健康检查会失败。
检查 CloudWatch 警报的状态
Route 53 可以利用 CloudWatch 指标和警报的功能。一旦创建了 CloudWatch 警报,您可以在 Route 53 中创建一个健康检查,观察与 CloudWatch 警报相同的数据流。
为了提高 CloudWatch 警报健康检查的可用性和灵活性,Route 53 查看来自 CloudWatch 的数据,然后确定该路由是否健康。它不会等待达到 ALARM 状态后再将路由设置为不健康。
Route 53 路由策略
Route 53 中的路由策略告诉服务如何处理查询。这些策略可以从简单到复杂,正如我们接下来将看到的。
简单路由
这是指 DNS 配置没有特殊配置。您只需要设置 DNS 文件应指向的单个记录。没有加权,也没有故障转移——只需保持简单即可。
故障转移路由
使用故障转移路由时,当初始记录集中的主资源不可用或未通过定义的健康检查时,您将有一个备用记录。
这可以是另一个位于不同区域的服务器,或者是通过 S3 存储桶提供的备用网站。
地理位置路由
如果您有一个跨越某个国家、洲或全球的观众或用户群,并且希望根据他们的地理位置向他们提供定制的信息或网站(而无需使用复杂的 cookies 和动态内容),那么您可以使用 Route 53 的地理位置路由功能,将他们引导到最适合其源位置的服务器或内容来源。
您可以按洲、国家或美国的州指定地理位置。
地理邻近路由
您可能有一个地理上分布广泛的用户群,但希望能够将更多(或更少)流量推送到某个特定地区或资源集。地理接近路由与地理位置路由的区别在于此功能。它可以根据每个特定资源的偏移值以及请求用户的原始位置,决定将更多或更少的流量路由到该资源。偏移值会扩大或缩小流量路由到资源的地理区域的范围。
基于延迟的路由
当您的观众或用户群体地理分布广泛,并且您在多个区域运行资源时,您可以使用基于延迟的路由将每个用户引导到能够提供最快响应时间的资源或内容。
问题
地理位置路由与基于延迟的路由有什么区别?
尽管在这两种情况下您都在处理一个地理上扩展的用户群,基于延迟的路由则基于 Route 53 创建并存储在原始点和 IP 或 DNS 记录点的延迟记录。这些延迟记录可能会发生变化,因此最好确保提供一致的体验,或根据客户设置提供定制化的体验。
地理位置路由,另一方面,是将用户请求与已与该源 IP 地址地理绑定的资源进行匹配,这样您就可以为最终用户体验提供本地化的内容。
多重响应路由
尽管多重响应路由不能取代负载均衡器,但它确实允许 Route 53 随机选择最多八个健康的值来响应。
您可能想使用多重响应路由的一些场景如下:
-
创建多个相同名称类型的记录
-
将流量路由到多个源
-
将 Route 53 健康检查与记录关联
加权路由
如果您有多个资源,并希望将请求分配到这些资源,同时实现不均衡的流量分配,您可以通过 Route 53 设置加权路由。这有几个应用场景,例如推出带有重要或次要更新的金丝雀发布,并将仅一部分流量重定向到新环境。您可以根据关键绩效指标(如放弃购物车的数量)来评估。
实现加权路由从有多个资源开始,您希望将流量在这些资源之间进行平衡。然后,您可以在 Route 53 托管的区域内创建记录来反映这些资源。这些记录必须是同一类型的记录,且位于同一域或子域中;也就是说,两者需要是 A 记录。
一旦记录设置完成,您可以继续配置路由,通过为特定资源分配权重来进行路由。加权值可以是从 0 到 255 之间的任何数字(如果您指定为 0,则该记录将不再接收流量)。
流量是通过计算当前记录的权重来平衡的,然后将其除以所有记录的总和。
示例:如果你有两台服务器运行,并且服务器 A 的记录权重为 75,服务器 B 的权重为 150,那么 75 + 150 = 225 总权重,使用公式 75 / 225 = 0.3333333,服务器 A 将获得 33%的流量。

图 2.10 – 在 Route 53 中创建加权记录
Route 53 将在稍后详细讨论,当我们进入第十三章,蓝绿部署,并讨论蓝绿部署策略时。
云数据库
当你查看下图时,可能会想,为什么有这么多种数据库。这源于过去几十年应用架构的演变,其中专业化、速度和规模都已成为这一行业成功的关键。

图 2.11 – AWS 中的数据库类型和服务
本章篇幅有限,无法介绍 AWS 提供的每种数据库类型。不过,作为本基础概述的一部分,我们确实希望涵盖一些关系型数据库及其基本特性。
我们将在接下来的章节中更详细地讨论键值数据库 Dynamo DB。
关系型数据库
说到数据库,通常会想到关系型数据库,它们有行、列和模式。
AWS 中的关系型数据库有三种主要的类型,并且其引擎可以根据社区版、商业版或云原生进行分类。云原生引擎被用于 Aurora 服务,因为它们是基于社区引擎构建的,具有云原生存储、备份和复制能力。
注释
当我们谈到云原生时,我们指的是构建和运行利用云计算模型的应用程序:松耦合的服务,动态可扩展,可以在多租户平台上运行,并具备灵活的网络和存储。
关系型数据库通常遵循 ACID 数据库属性集合:
-
原子性:你的所有事务要么都成功,要么都不成功。
-
一致性:写入数据库的任何数据必须符合所有已定义的规则。
-
隔离性:确保并发执行事务时,数据库会保持在一个与按顺序执行事务时相同的状态。
-
持久性:一旦事务被提交,它将保留在系统中,即使系统发生崩溃。
关系型数据库服务
关系型数据库服务(RDS)旨在接管以前由数据库管理员执行的任务,数据库管理员曾需要在职,但现在很多日常工作都可以通过自动化和脚本来处理。这些任务包括配置新数据库、创建备份、扩展为只读副本、修补和升级实例,以及在发生事件时切换到高可用性实例。RDS 简化了软件和数据库配置的设置与安装。使用托管的 RDS 服务还可以帮助组织在创建和部署数据库时实现一致性标准。无需自定义脚本来部署、设置和修补数据库,因为这一切都在后台自动处理。
部署后,开发人员和应用程序可以访问一个可以方便连接的数据库端点,用户可以通过客户端或身份验证应用程序进行连接,然后对数据库执行查询。
RDS 提供多种不同的引擎格式,包括两个商业引擎和三个流行的开源引擎。支持的两个商业引擎是 Oracle 和 Microsoft SQL Server。这两个商业引擎都广泛用于企业中。RDS 支持通过 Oracle SQL 访问 Oracle 模式,并提供 Microsoft SQL Server 的本地工具,如 SQL Server Management Studio。在社区版中,RDS 允许使用 MySQL、PostgreSQL 和 MariaDB 创建数据库。MySQL 是最受欢迎的社区关系型数据库之一,AWS 运行该数据库的社区版,默认使用 InnoDB 表,并在文档中说明 MyISAM 存储引擎不支持可靠的崩溃恢复。
PostgreSQL
PostgreSQL 是另一个非常流行的数据库,开发人员青睐其丰富的功能集。RDS 支持常用工具,如 pgAdmin,或通过 JDBC/ODBC 驱动程序连接到数据库。
确定选择的引擎后,您可以选择一个实例类型,以便提供不同级别的计算和内存能力。通常用于测试环境的有突发性实例(T 系列)。在将数据库工作负载迁移到更生产化的环境时,建议选择通用实例(M 系列)或内存优化实例(R 系列)。
RDS 和你在 EC2 实例上自行运行的相同类型引擎之间的一个区别是副本的工作方式。只需点击一个按钮,无论是在同一可用区还是不同可用区,都可以极其容易地创建只读副本;然而,这些节点是只读的,不能执行写操作。在同一背景下,你可以让实例立即具备高可用性,将数据异步复制到另一可用区或区域的主节点副本中。如果发生故障,应用和最终用户将感受不到任何中断,因为它们用于连接数据库的 DNS 地址保持不变。然而,这个二级主节点不能从主主服务器上分担负载,因为它除了作为故障转移节点外,不能承担其他任何功能(例如作为只读副本)。只读副本可以提升为独立数据库,并且此时它将具备执行写操作的能力。然而,它将不再与之前所复制的主节点保持同步。
Aurora
Amazon Aurora 是为了响应客户希望获得像 Oracle 或 Microsoft SQL Server 这样的商业级数据库引擎的性能,同时不必处理与这些产品相关的许可束缚问题而构建的。
关于 Amazon Aurora 的另一个重点是,与其他由 EBS 存储支持的 RDS 引擎不同,Aurora 在听取了多年来多位客户的需求后,从零开始构建了自己的存储解决方案。
Amazon Aurora 提供 MySQL 兼容版和 PostgreSQL 版。用户可以选择将 Aurora 作为集群运行,甚至运行 Aurora 数据库的无服务器版本。需要了解关于 Aurora 无服务器版本的主要事项是,它根据应用或用户的需求按需提供容量。这是预配 Aurora 集群与无服务器版本之间的显著区别。
键值数据库
随着应用的构思,初期无法完全预测会服务多少用户。通常人们希望,随着时间的推移,应用的受欢迎程度会从初期的用户和测试者扩展到指数级规模。为了支持这种增长,底层数据库必须能够无缝应对这种规模。这也是键值数据库的特点之一。
我们将在 第五章 中更详细地了解 DynamoDB,Amazon DynamoDB。
内存数据库
当你频繁从主数据存储(如关系型数据库)访问存储的项目时,有时仅从数据库请求数据无法提供客户期望的用户体验。这时,像Amazon Elasticache这样的内存数据库成为一个可行的选择。
Elasticache 提供两个不同的引擎版本:Redis 和 Memcached。
文档数据库
文档数据库是一种非关系型数据库,它允许你以 JSON 格式存储文档和数据,并查询这些数据以找到所需的内容。文档数据库的一个独特特点是没有固定的架构,并且它们可以包含互相嵌套的文档。
AWS 提供了Amazon DocumentDB(具有 MongoDB 兼容性)作为一个托管数据库服务,适用于那些曾经使用过 MongoDB 或者正在寻找文档数据库功能的用户。如果你曾经在 MongoDB 的操作端工作过,那么你知道,尽管 MongoDB 功能强大并具有一些高级功能,包括在当前主节点不可用时自我选举新主节点,但其部署和运行有一些复杂的设置要求。
它需要(在生产环境中)至少三个节点——可以是两个节点和一个仲裁者,或者三个主节点。所有这些复杂的设置在 DocumentDB 中都不再需要。亚马逊会处理设置和安全性,并允许你配置自动备份,然后可以将备份存储在 S3 上。
你可能会放弃一些小的功能,比如无法使用管理员或本地表,这意味着你不能使用 mongodump 或 mongorestore 工具,但有一些功能可以代替这些工具。
文档数据库特别适合那些不想处理数据库管理方面的团队,想通过 JSON 简化初始架构值使用的方式,并且只想开始将数据推送到数据库中,以便之后可以进行简单或高级的查询。
消息和队列系统
当你开始构建云规模应用时,你需要找到一种方法来解耦应用程序的不同层,使得每一层能够独立扩展。这样做有几个原因,包括使你的应用程序更加弹性,并允许每一层独立于其他层进行扩展。能够使用托管服务来执行这些任务,在这种情况下,你或你的团队成员无需担心队列或消息系统的设置和维护,能够加速在云中迁移或开发时使用这些技术。
接下来我们将了解 AWS 提供的消息和队列系统,以及它们如何对你有所帮助。
简单通知服务(SNS)
有时,你需要能够简单地发送消息,无论是来自你的应用程序还是其他服务,消息可以采用多种格式,例如电子邮件或短信,并可以以多种方式使用。这些可以基于编程调用或发生在你的 AWS 账户中的事件。这就是简单通知服务(SNS)派上用场的地方。
SNS 是一个发布者和消费者系统,发布者可以将消息推送到一个主题。然后,任何订阅该主题的消费者都可以消费该消息:

图 2.12 – SNS 广播
SNS 主题充当一个频道,可以将单个消息广播到一个或多个订阅者。发布者,即前面图中的应用程序,只需要将消息发送一次到该主题;每个消费者(或订阅者)可以以适合自己的方式接收并处理该消息。这些消息可以存储在 S3 中作为归档,或在移动短信或电子邮件中按需消费,或者在 Lambda 中进行解析和执行。
简单队列服务(SQS)
如果你在寻找一种完全托管的队列服务,允许你以云原生的方式拆分应用程序,那么 简单队列服务(SQS)就是一个非常合适的服务选择。它有两种类型:标准队列和先进先出(FIFO)队列。标准队列允许至少一次的消息投递,而 FIFO 队列则保证对队列中的消息进行一次性投递。这两种队列的另一个主要区别是,FIFO 队列中的消息会按接收顺序进行处理。标准队列尝试保留接收到的消息顺序;然而,如果消息顺序错乱,它不会进行任何洗牌或重新排序操作来保持原始的消息顺序。
SQS 是一个分布式队列系统,这意味着它分布在区域内的不同节点上。这是 SQS 带来的一项设计特性,它使 SQS 具备了高度可扩展、可用、可靠和耐用的优势。SQS 还支持 服务器端加密(SSE),可以通过 AWS 提供的 KMS 服务密钥或自定义密钥实现。你还可以通过访问策略控制谁可以访问产生或消费的消息。SQS 分布式队列系统的主要组成部分有三部分:
-
生产者/消费者(组件)
-
队列
-
队列中的消息:

图 2.13 – SQS 分布式队列
消息由生产者放入 SQS 队列,然后被分配到队列组件中以实现冗余。当消费者准备处理消息时,它会使用长轮询或短轮询技术检查队列中是否有待处理的消息。如果检测到待处理的消息,它会消费该消息进行处理;然而,消息仅会被标记为已处理,并且可见性超时开始。一旦消费者成功处理消息并删除该消息,消息就会从所有分布式队列节点中移除。
消费者在成功处理消息后必须删除这些消息。由于 SQS 运行的分布式系统的特性,一旦消费者拉取了一个消息进行处理,该消息就会被标记,以确保其他消费者无法拉取相同的消息。不过,在超时期之前,消费者需要确认消息已经处理。如果 SQS 没有收到这个确认,那么该消息会取消标记,并可供其他消费者处理。
在什么情况下使用 SNS 而不是 SQS?
在尝试决定使用哪个消息服务时,有一条规则可以帮助你决定哪个服务最适合你;问以下一组问题:
-
我的消息需要保证送达吗?
-
(如果答案是“是”,那么 SQS 将是最佳选择,因为 SNS 没有提供保证送达的选项。)
-
我的消息是否只会被我的应用程序消费?
(如果答案是“是”,那么 SQS 将是最佳选择。)
-
我的消息是否会被多个来源消费?
(如果答案是“是”,那么 SNS 将是最佳选择。)
通过这三个问题,你可以判断自己是处理一个封闭循环,即收集消息并在应用程序中进行处理(SQS),还是创建一个消息供应用程序外部消费(SNS)。
Amazon MQ
如果你正在迁移一个之前使用 Apache MQ 或 Rabbit MQ 的应用程序,并且你不再想管理实例,那么Amazon MQ是一个不错的选择。Amazon MQ 更像是一个消息代理,而不仅仅是一个简单的队列。
当你去分配你的 Amazon MQ 时,必须选择 Rabbit MQ 或 Apache MQ 引擎类型。选择好引擎类型后,使用管理控制台配置 Amazon MQ 时,它会通过一系列选择提示你使用单一代理,或使用一个高可用的活动和备用代理。它甚至可以通过预定义的蓝图为你创建一个单一或活动与备用代理的网状网络。
Amazon MQ 和 SQS 之间的区别
尽管 SQS 也是 AWS 提供的托管服务,它是一个可扩展的队列,并不需要建立消息代理。Amazon MQ 的优势在于,它允许依赖 MQTT、OpenWire 或 STOMP 等 API 的先前构建的应用程序快速且轻松地迁移到云端,同时保持高可用性,并且几乎没有额外开销。
简单邮件服务(SES)
简单邮件服务(SES)允许你设置并发送电子邮件,而无需处理运行 SMTP 服务器的大多数复杂性。
SES 仅在三个区域运行:us-east-1(北弗吉尼亚)、us-west-2(俄勒冈)和 eu-west-1(爱尔兰)。
亚马逊帮助你验证邮件的来源。通过向我们发送电子邮件的 DNS 记录中添加一系列 DKIM 记录,它为你发送给客户的邮件提供了信任。
可信顾问
随着 AWS 账户中资源数量的增加,跟踪所有资源有时会变得具有挑战性。挑战开始出现,例如有些磁盘处于空闲状态未被使用,弹性 IP(EIPs)也处于空闲状态,未连接到任何实例或接口,这会消耗你的预算。一旦进入受信顾问仪表盘,你将看到该工具为自动检查生成的四个类别:

图 2.14 – 受信顾问仪表盘
当涉及到容错检查时,它可以告诉你是否在单一可用区或区域中拥有过多实例。
可用的受信顾问检查数量随着账户支持级别的提高而增加。对于具有基础或开发者支持级别的账户,显示的是基本检查集。当支持级别提高到商业或企业级时,账户将可以访问所有 115 个受信顾问检查。
即使在基础支持级别,受信顾问也提供四个领域的多个检查:
-
成本优化
-
性能
-
安全
-
容错
注意
你是否注意到受信顾问提供的四个基本检查可以映射到 AWS 服务支柱的四个方面?
此外,受信顾问可以设置为每周向账单联系人、操作联系人、安全联系人或三者的任何组合发送通知。
访问受信顾问
受信顾问具有图形化的仪表盘界面,可以查看,而且当你第一次从 AWS 控制台查看该服务时,甚至可以看到在成本优化图标下可能的月度节省。AWS 一直在精细化控制台界面,使其更易于使用,并尽可能直观,展示每个主要标题图标下的三个图标,分别表示没有警告的检查(绿色)、建议调查的检查(黄色)和建议采取行动的检查(红色)。
你还可以通过 AWS CLI 访问受信顾问。从 DevOps 角度来看,这很有用,尤其是在服务限制检查方面。你可以使用自动化管道或周期性 Lambda 作业来检查特定服务的服务级别,然后自动请求服务级别的提升,或将通知发送到正确的电子邮件或分发列表中,以避免在构建过程中出现中断。
总结
AWS 不断增长其提供的服务数量。我们在本章中简要介绍了许多服务,虽然内容较为简略,但只涵盖了在 AWS 平台上托管和服务应用程序的许多关键服务。
在本章中,我们回顾了 AWS 提供的基础服务。这些服务,以及我们在第一部分剩余部分中将要学习的其他服务,将作为我们 DevOps 旅程中的部署组成部分。掌握这些服务的基础知识可以帮助我们在开发和部署目标上做得更多,同时也有助于我们理解 DevOps 专业考试中的问题,以及在日常工作中遇到的场景。
在下一章中,我们将探讨身份与访问管理,它是保护我们的 AWS 云账户和资产的基础。
回顾问题
-
如果你想对 Amazon EC2 空闲容量进行竞价,以下哪项将允许你做到这一点?
a. 预留实例
b. 自动扩展
c. Spot 实例
d. 节省计划
-
你所合作的公司希望加强网络安全。然而,他们当前不想声明返回流量的出口。你可以使用哪个 VPC 构造来帮助调整他们的安全设置?
a. 网络访问控制列表(NACLs)
b. 网络地址转换器(NAT)
c. VPC 端点
d. 安全组
-
判断题:Trusted Advisor 可以通知你账户即将达到的服务限制。
-
如果你的公司目前在数据中心运行 SQL Server 实例,并希望将其迁移到 AWS 云中,哪些选项可用?
a. 在 EC2 上运行数据库
b. 设置 Direct Connect 使得云资源可以连接到 SQL Server 实例
c. SQL Server on RDS
d. SQL Server on Amazon Aurora
-
以下关于 FIFO SQS 队列的哪项陈述是正确的?
a. 你不能保证消息按照发送顺序到达。
b. 消息将按照 FIFO 顺序精确投递。
c. 消息将被准确投递一次。
d. 消息可以被投递一次或多次。
回顾答案
-
c
-
d
-
正确
-
a 和 c
-
b 和 c
第三章:AWS 中的身份与访问管理以及密钥管理
在掌握了众多基本服务的基础上,我们现在进入 身份与访问管理 (IAM) 部分。
定义用于管理对不同 Amazon Web Services (AWS) 服务的访问的控制和政策,正是 IAM 的基本内容。这可以通过用户、组、政策,甚至访问控制来实现,包括联合访问或短期凭证。还可以使用外部 身份提供者 (IdPs) 来允许用户访问您的应用程序。理解如何使用本地 AWS 工具保护密钥,尤其是在 持续开发 (CD) 过程中,是一种企业级技能,这不仅出现在 DevOps 专业考试中,而且在工作中也至关重要。
在本章中,我们将覆盖以下主要主题:
-
理解 AWS 中的共享责任模型
-
IAM 角色、组、用户和政策
-
将 AWS Organizations 作为指导的一部分
-
与 AWS 账户进行联合身份验证
-
在 AWS 中安全存储密钥
-
使用 Amazon Cognito 与应用程序身份验证
技术要求
在阅读本章时,您应该已经创建了一个 AWS 账户,并安装了 AWS 命令行界面 (CLI) 版本 2 (v2),以便您可以跟随本章中的实际操作活动进行练习。如果您打算跟随 AWS 假设角色练习进行实践,您还需要多个 AWS 账户。
理解 AWS 中的共享责任模型
虽然我们在 第一章 中简要提到过它,亚马逊 Web 服务支柱,但理解共享责任模型对于管理账户的安全性,特别是 IAM 服务,是至关重要的。
下图提供了该模型的概览:

图 3.1 – AWS 共享责任模型:基础设施即服务(IaaS)
共享责任模型的本质是提供灵活性和客户控制。在此模型下,有两个主要概念,如下所示:
-
谁负责 云的安全性:
这是 AWS 承担责任的部分。
-
谁负责 云中的安全性:
这是您作为客户需要承担的责任。
AWS 控制着全球基础设施,其中包括承载所有 AWS 服务的服务器的数据中心。这些数据中心根据安全最佳实践和一系列安全合规规范进行管理。虽然客户不允许访问实际的数据中心,但独立的外部机构会对这些中心和实践进行认证和审计,以确保控制措施、政策和程序得到了遵循。
AWS 在多个层级上保护其数据中心,具体如下:
-
在边界层——AWS 选择用于容纳其数据和计算设施的建筑物并未向公众披露。这些设施也有严格的进入要求,并配备入侵检测和严密的监控来保护它们。
-
在环境层——在选择位置之前,AWS 会考虑环境风险,如恶劣天气、洪水和潜在的地震活动。
-
在基础设施层——在建筑物内部,有一套结合了火灾检测和抑制设备的系统。
作为客户,你的责任之一是你在账户中上传、存储和创建的数据。根据你和客户的需求,你可以选择以未加密的形式存储和传输数据。如果要求比明文数据更严格,AWS 提供了多种加密选项,或者你可以管理自己的加密。我们将在稍后的第十九章《保护静态和传输中的数据》中进一步讨论如何加密数据。
你在 AWS 云上的责任还包括你允许谁和什么访问你账户中的各种服务。这时,IAM 服务发挥着关键作用。默认情况下,AWS 不允许任何应用程序或用户访问其他任何服务。
保持操作系统的更新,包括对你弹性计算云(EC2)实例的任何补丁和更新,也属于你在共享责任模型中的责任。这些服务如系统管理器(SSM)和 Amazon Inspector 可以帮助你完成这项任务,识别关键的安全补丁并遵循维护计划。如果你运行实际的基础设施服务,那么最终责任就落在你身上。
你如何通过网络层允许流量进入你的实例也是你的责任。在第二章《基础 AWS 服务》中,我们讨论了虚拟私有云(VPC)以及你用来通过安全组和网络访问控制列表(网络 ACL)来保护网络的工具。将安全规则限制为仅允许必要的流量——而不是更多——可以防止外部实体通过端口扫描和其他恶意活动获取不必要的信息。
这个最初由 AWS 发布的主要共享安全和责任模型反映了 IaaS 模型中的责任。然而,随着不同的云计算模型的出现,例如平台即服务(PaaS),在容器服务和更像软件即服务(SaaS)的托管服务的情况下,Amazon 承担了更多的责任。
使用容器(特别是在 Fargate 的情况下)时,安全模型更倾向于 PaaS 模式,因此更多的责任被推向 AWS。你不再负责操作系统,因为 AWS 正在管理这一部分。然鹅,你仍然负责客户数据以及进出系统的网络流量,正如下图所示:

图 3.2 – AWS 共享责任模型:容器服务
需要理解的主要内容之一是,在所有共享责任模型中,您需要对数据的保护负责。这包括数据将暴露到多少个端口,以及数据将如何加密或是否保持未加密状态。
授权与认证
当我们开始了解身份和访问管理(IAM)时,我们首先需要完全理解授权与认证的概念。尽管这两个术语听起来相似,并且经常一起使用,但理解它们之间的区别对于我们深入探讨非常重要。
认证
认证是验证你所声称身份的过程。系统在询问你是谁,你通常会用用户名和密码进行回答,但有时也会使用安全会话令牌。认证是在回答问题你是谁? 和 你能验证你自己说的身份吗?
授权
授权发生在认证之后,确定你被允许执行的操作。大多数情况下,它发生在认证之后。规则和政策决定了你被授权访问的内容。在计算机世界中,这可以通过令牌传达,例如承载令牌或JavaScript 对象表示法(JSON)Web 令牌(JWT),它授予你访问服务或应用程序处理接口(API)的权限。
认证与授权的过程如下图所示:

图 3.3 – 认证与授权
认证和授权容易混淆,因为它们看起来相似,但可以将认证看作是你的照片身份证明,而授权则像是一个射频识别(RFID)徽章,它允许你访问。让我们通过另一个例子进一步明确这一点。
授权与认证的实际示例
在许多大型办公楼中,您需要一张带照片的身份证明才能进入大楼。在大多数情况下,您被要求随时佩戴该证件,以证明您已获得授权进入大楼,不会被安保人员拦截。当您走向电梯时,您可能需要扫描您的证件才能访问您工作的楼层。按下您的身份证明,其中包含一个与政策系统和用户资料相关联的 RFID 芯片,系统会知道您可以访问哪些楼层。如果您在三楼工作,那么您已经验证了可以按下 3 号按钮并乘坐电梯到三楼。大楼中可能还有其他门,您可能没有权限访问,具体取决于您的身份验证级别。
IAM 需要理解的术语
当我们开始讨论 IAM 服务及其各个组件时,首先需要列出我们将使用的术语及其定义。对于职业考试来说,没有必要记住这些术语,但它们是您需要了解的整个服务的组成部分,尤其是低级考试中必考的内容。以下列出了这些术语:
-
主体:一个应用程序或人员,使用 AWS 根账户用户、IAM 用户或 IAM 角色进行身份验证并发起请求。这是可以对 AWS 资源执行操作的对象或人员。
-
资源:资源是您可以在 AWS 账户内操作的项目。资源的一个示例可能包括 Lambda 函数、EC2 实例或 简单存储服务(S3)存储桶。
-
实体:实体可以是 IAM 用户、联合用户,或来自身份提供者(IdP)的用户,或者在 AWS 上下文中的假设 IAM 角色。它仅仅是 AWS 用于身份验证的 IAM 资源对象。
-
身份:用于识别谁在使用服务的资源称为 IAM 中的身份。这些包括用户、组和角色。
IAM 可以进行主体身份验证的方式
IAM 具有多种方式可以进行主体身份验证,具体如下:
-
用户名和密码——用户名和密码是进入 AWS 管理控制台的初始方式。
-
访问密钥和秘密访问密钥——这些是可以与用户或根用户关联的长期安全凭证。它们可以被轮换,并且每个用户在任何时刻最多可以关联两个访问密钥。
-
会话令牌——您可以使用假设的角色来利用安全令牌服务(STS)传递一个令牌,允许您或您的应用程序获得分配的访问权限。
注意
AWS 管理控制台用户默认不能使用其用户名和密码凭证运行任何特定程序并访问 AWS 服务或底层基础设施。所有这些都依赖于 IAM 策略提供的授权。
IAM 的授权概念
在为用户和应用程序添加授权时,有两个模型需要注意:基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。接下来我们将讲解每个概念。
RBAC
传统的访问控制基于将用户和应用程序分组为组(或角色),然后为这些组分配权限。很多时候,这些组代表的是工作职能,与该职能相关的权限处理该职能的责任。
将特定的权限集映射到一个角色,将该角色定义为认证服务中的一个组,如Active Directory(AD)或 AWS IAM,然后将用户加入该组,以便他们能够假设这些权限,这被定义为 RBAC。
ABAC
ABAC 可以基于三种不同类型的属性进行访问控制,列举如下:
-
用户属性
-
与要访问的系统相关的属性
-
当前环境条件
在 AWS 中,这些属性大多数通过标签、账户信息(即账户号码、别名或组织单位(OU))以及与用户关联的联合数据来管理。
IAM 服务概念
使用 IAM 时,最重要的概念之一,以及在浏览 AWS 访问时的关键点,是只授予完成任务所需的最小权限,绝不多给。
IAM 角色、组、用户和策略
在 IAM 中控制对资源的访问,归结于你如何设计附加到用户、组和角色的策略。服务本身假设角色,而在 IAM 中创建的用户,如果被放入组中,将更容易进行管理。
注意
每个账户有 500 个 IAM 用户的服务限制。
IAM 策略
IAM 策略是一组权限,以 JSON 语句的形式表示,指定实体拥有哪些访问权限。
当你开始分配账户中的权限时,你将处理这些 IAM 策略。AWS 提供了许多预先制定的策略,帮助你快速入门,可以附加到用户和组或服务上。许多基于 AWS 的策略将资源列为*,但这意味着任何资源都可以被访问。即使是简单策略,也有多种方式可以限制可以访问的资源数量。
让我们看一个非常简单的 IAM 策略示例,展示了如何使用通配符在账户中为所有 S3 存储桶上的所有对象操作授予访问权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllS3ObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": ["*"]
}
]
}
然而,我们可以通过修改策略中的资源行来限制我们的用户可以访问的存储桶,如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllS3ObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": ["arn:aws:s3:::my-bucket/*"]
}
]
}
AWS 中有多种不同类型的策略可以使用,如下所示。每种策略在权限管理中扮演着不同的角色:
-
基于身份的策略
-
基于资源的策略
-
权限边界
-
组织的服务控制策略(SCPs)
-
ACLs
-
会话策略
现在我们知道了 IAM 策略如何工作,以及可用的不同类型的策略,让我们来看看一些 IAM 策略的基本概念,以及不同类型的策略如何协同工作形成有效的权限。
IAM 策略概念
当你开始使用 IAM 时,你需要理解该服务是如何根据其内部逻辑评估策略请求的。以下是你需要记住的规则概览:
-
默认情况下,所有请求都会被拒绝(除非你是根用户)。
-
如果某项服务已被明确拒绝,则该规则优先,即使另一个规则允许该服务。
-
策略中的显式
allow将覆盖默认的隐式deny。 -
如果一个 SCP、会话策略或权限边界授予某项服务访问权限,那么它也会覆盖隐式的
deny。
为了更深入理解规则是如何处理的,我建议你阅读此处提供的文档:docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html。
在 图 3.4 所示的图示中,有三个圆圈。最底部的圆圈是基于身份的策略——即用户或组授予该有效用户权限的位置。然而,还有其他身份策略在起作用,这些策略可以限制——在某些情况下扩展——用户的有效权限。所有策略交汇的中心——在此情况下箭头指向的地方——是该用户的有效权限集,如下所示:

图 3.4 – 有效的策略权限
通过了解这些不同类型的策略如何相互作用以形成有效的权限,我们现在可以开始创建我们的身份,包括角色、组和用户。
身份
当你首次创建 AWS 账户时,注册时使用的电子邮件账户将成为你的 AWS 根用户。尽管你可以使用这个根用户访问管理控制台,并且该用户拥有对 AWS 账户中所有服务和资源的完整无限制权限,但不建议你使用该用户来创建资源和工作负载。
在下图中,我们可以看到根用户位于 AWS 账户结构的顶部,然后我们的组会继承给用户和角色:

图 3.5 – IAM 用户和组
一旦我们确定了要在账户中创建的组,并了解每个组或角色将继承的权限基础,我们就可以开始创建这些组。
IAM 组
以下是关于组的一些重要事项:
-
一个用户可以属于多个组,组也可以有多个用户。
-
组只能包含用户,而不能包含其他组,因此组不能相互嵌套和继承权限。
-
用户必须手动添加到组中。在创建用户或角色时,不会自动为其分配权限的默认组。
创建 IAM 组
在我们实际添加用户之前,让我们创建这些组并将 Amazon 托管的 IAM 策略与这些组关联,如图 3.5所示。我们将创建以下组,并将以下托管策略与它们关联:

图 3.6 – 组及其关联的托管策略
现在我们知道要设置哪些组,让我们使用 CLI 来创建这些组,如下所示:
-
打开你的终端并输入以下命令,我们来创建第一个组(
Admins):Admins at the end of it. -
现在,让我们检查我们账户中的当前组,如下所示:
$aws iam list-groups --output text注意我如何更改输出——对于我即将展示的四个组,这种方法不会占用像 JSON 格式那样多的页面空间。输出应该类似于此处显示的内容:
GROUPS arn:aws:iam::470066103307:group/Admins 2021-03-11T22:36:46+00:00 AGPAW24Q7QQF4DBRNWTM4 Admins / GROUPS arn:aws:iam::470066103307:group/Billing 2021-03-11T22:41:23+00:00 AGPAW24Q7QQF2FJB3ZW27 Billing / GROUPS arn:aws:iam::470066103307:group/Developers 2021-03-11T22:54:10+00:00 AGPAW24Q7QQF7NUSSDSWF Developers / GROUPS arn:aws:iam::470066103307:group/Testers 2021-03-11T22:51:26+00:00 AGPAW24Q7QQFZ6FIU6WDA Testers / -
一旦我们看到列出的所有组,我们就可以开始附加我们之前识别的托管策略。然而,在使用 CLI 时,我们需要知道
grep来帮助我们的搜索,具体如下所示的代码片段:grep command to quickly search through the output and find the exact name we were looking for. We were able to use some of the command-line flags to help narrow our initial search; however, there isn't a great option to search for a particular policy name. If you would like to read more about the options for the command, you can find all flags available on the documentation page listed here: https://docs.aws.amazon.com/cli/latest/reference/iam/list-policies.html.The output should look like this:AdministratorAccess,这是第一个返回的结果。其他的返回是因为它们的名称中包含了 AdministratorAccess。
-
现在我们找到了托管策略的 ARN,我们可以将其附加到组中,具体如下所示的代码片段。一旦 IAM 策略附加到组,任何我们稍后添加的用户将自动获得这些权限:
$aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --group-name Admins执行此命令后,它不会返回任何结果或反馈。
-
我们可以通过命令行检查我们的策略是否已附加到组中,方法如下:
$aws iam list-attached-group-policies --group-name Admins这将返回我们刚刚附加到组上的策略,具体如下所示的代码片段:
{ "AttachedPolicies": [ { "PolicyName": "AdministratorAccess", "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess" } ] }到此为止,我们暂时完成了这一步。我们需要创建用户以便将其添加到组中。
注意
我们也可以使用 CloudFormation 脚本来完成这项任务,这样可以更容易地回滚或清理我们刚刚创建的任何组。我们将深入探讨 CloudFormation 和基础设施即代码(IaC)的内容,在第七章中,使用 CloudFormation 模板部署工作负载。
IAM 用户
IAM 用户是有凭证访问和与指定 AWS 服务集进行交互的人员或应用程序。
当你创建账户时,你会自动成为根账户用户。
创建用户后,他们初始没有任何权限,且未经授权无法对 AWS 资源执行任何操作,直到你或其他管理员(或具有 IAM 权限的人员)通过内联策略授予他们访问权限,或者将他们添加到一个组中。
IAM 用户不能与多个 AWS 账户关联。
IAM 的用户部分也是你存储每个用户的安全外壳(SSH)密钥的地方,以访问 AWS Git 服务 CodeCommit。我们在第八章中才会深入探讨 CodeCommit,使用 CodeCommit 和 CodeBuild 创建工作负载;然而,理解密钥、用户和 IAM 权限之间的相互作用是很重要的,特别是当你希望你的用户能够自我管理、添加、移除和轮换他们自己的 SSH 密钥时。
如果你想为你的账户创建更多具有指定角色的用户,可以使用你刚刚创建的新角色,并按照第二章的步骤,基础 AWS 服务,来创建一个用户。
角色
IAM 角色允许你授权服务、应用程序和其他 AWS 服务在不将访问密钥和秘密访问密钥等凭证硬编码到应用程序中的情况下访问——或者对于用户而言,甚至创建一个访问密钥和秘密访问密钥对。
角色在切换账户时也非常有用。如果你有多个账户——例如,开发、测试和生产账户——你可以在开发账户中使用你的用户,然后在其他两个账户中创建角色,这些角色可以被你的主用户假设。
角色的另一个优点是它们可以由同一服务的多个实例承担(例如,EC2/Lambda)。就像在 IAM 组中一样,如果你需要为角色的策略添加更多权限或移除权限,这些更改几乎会立即生效。
对于 EC2,你会使用实例配置文件将角色传递给 EC2 实例。实例配置文件只能包含一个角色,这是一个无法增加的硬性服务限制。如果实例的权限需求发生变化,你可以移除当前附加到实例配置文件的角色,然后附加一个包含不同权限集的角色。
角色和角色假设也是一种提供访问给第三方的方式,这些第三方可能也有自己的 AWS 账户,但可能需要有限的访问权限。这可能是一个第三方合作伙伴,或者是一个只需要只读访问权限的审计员。
注意
对于本次练习,我们将需要两个账户,如下所示:
账户 A:这将是我们创建一个角色的账户,允许该角色被假设。
账户 B:这将是我们之前在操作的账户,我们将使用之前创建的一个用户来假设该角色并访问另一个账户。
在开始之前,最好知道账户编号,并将其保存在名为账户 A和账户 B的文本文件中。这样在我们开始设置角色的过程时会更加方便。如果您不知道您的 AWS 账户编号,找到它最简单的方法是点击主菜单顶部的用户名。下拉菜单出现后,其中一项是账户,显示您的账户编号。
我们首先进入账户 A,并创建一个角色,具体步骤如下:
-
使用具有管理员用户权限或能够创建 IAM 用户和角色的账户 A中的用户登录控制台。
-
访问 IAM 服务:
console.aws.amazon.com/iam/home。 -
在左侧菜单中,点击角色。
-
一旦角色屏幕出现在主窗口中,点击标签为创建角色的蓝色按钮。
-
在下一屏幕上,您要选择的可信身份类型是另一个 AWS 账户,如下面的截图所示:
![图 3.7 – 创建 IAM 角色]()
图 3.7 – 创建 IAM 角色
-
在账户字段中输入账户 B的账户编号,然后点击页面底部的下一步:权限按钮。
-
在
S3FullAccess上。这将调出AmazonS3FullAccess策略。勾选此策略名称旁边的框。在勾选框后,参照下面的截图,点击页面底部的蓝色按钮,标记为下一步:标签:![图 3.8 – IAM S3 完全访问策略]()
图 3.8 – IAM S3 完全访问策略
-
我们在本练习中不会添加任何标签,所以只需点击屏幕底部的蓝色按钮,标签为下一步:审查。
-
一旦我们进入
AssumeS3,如果您想输入描述,可以输入(请参见下面截图中的示例描述),但这不是必要的。确保一切看起来正确,然后点击底部的创建角色按钮:

图 3.9 – IAM 假设 S3 角色审查
现在我们已经在账户 A中设置了角色,可以退出该账户,然后重新登录到账户 B,以便使用我们创建的新角色,从主角色切换到账户 A中的AssumeS3角色,步骤如下:
-
一旦我们登录后,点击右上角菜单中的您的名字,显示下拉菜单(我们之前通过这种方式查找了账户编号)。
-
在下拉菜单显示时,点击菜单项切换角色,如下面的截图所示:
![图 3.10 – 从 AWS 管理控制台切换角色]()
图 3.10 – 从 AWS 管理控制台切换角色
-
现在,在切换角色屏幕上,点击标签为切换角色的蓝色按钮。
-
在下一屏中,你将看到三个文本框需要填写,具体如下:
a. 在标有
AssumeS3的框中)。c. 在标有
AccountA_S3的框中,如以下截图所示:![图 3.11 – 假设角色在账户 A]()
图 3.11 – 假设角色在账户 A
填入这些信息后,你现在可以切换角色了。
-
填入所有信息后,点击蓝色的切换角色按钮。
-
现在你应该已处于账户 A中,并且菜单栏顶部的颜色标示了
AssumeS3权限,以及角色的显示名称,具体如以下截图所示:

图 3.12 – AWS 管理控制台显示成功切换角色
我们刚刚了解了角色如何帮助我们管理自己账户中的权限,同时也赋予我们在另一个账户中承担定义权限集的能力。接下来,我们将介绍如何通过权限边界在账户级别设置限制,并分享一些 IAM 的最佳实践。
权限边界
权限边界是 IAM 的高级功能,它允许你使用 AWS 托管策略,但为这些策略设置最大资源限制。在实际使用中,权限边界可以非常有用,允许你将具有所需权限的 AWS 托管策略应用到用户、组或角色上,并通过权限边界策略确保该实体不会访问超出所需的资源。
如果我们回顾一下图 3.4,可以看到身份基础的策略与权限边界策略的交集。两者之间的部分即为该实体的有效策略。AWS 提供的大多数托管策略允许在*)范围内使用。对于大多数组织,无论大小,这都是一个过于宽松的权限集。这不仅在组织的不同部门之间存在安全隐患,而且限制访问有助于减轻用户在意外情况下可能造成的影响范围。
IAM 最佳实践
让我们来看看在使用 IAM 时的一些最佳实践,如下所示:
-
不要使用根账户进行日常访问。根账户仅应在初始化管理员用户时使用,或在紧急/破玻璃场景中使用。
-
始终为根用户设置多因素认证(MFA)。此外,最佳实践是为任何账户管理员配置 MFA。尽量为所有用户启用 MFA。
-
设置一个密码策略,要求用户设置强密码,并定期更换密码。
-
不要直接将权限赋给用户;应使用组或允许用户承担角色—将权限集分配给角色,并允许用户承担这些角色。
-
不要让秘密以明文形式留在代码中。使用 Secrets Manager 或 Parameter Store 等秘密存储服务来安全地存储秘密。
在下一部分中,我们将学习如何将 AWS Organizations 作为你指导的一部分。
将 AWS Organizations 作为你指导的一部分
AWS Organizations 是一个帮助你整合多个 AWS 账户以便于管理和计费的服务。AWS Organizations 不仅帮助你在组织框架下快速轻松地创建新账户,还提供了在独立 AWS 账户中无法获得的治理功能。
与 IAM 相关的两个功能是 OU 和 SCP。
使用 OU 进行分离
要理解 OU,首先需要了解两个基本概念,如下所示:
-
组织
-
根账户
组织 是你创建的实体,用于统一你控制下的不同 AWS 账户,以便你能够作为一个单元进行管理。一个主账户会分配给一个组织,该组织可以分支成零个或多个单元。许多时候,组织是以树状结构组织的,根账户位于顶部,OU 和子账户在下面分支。
根账户 是组织中所有其他账户的源容器。如果你将 SCP 应用于根账户,它会向下流动,并因此应用于所有组织账户和子账户。
OU 只是一个用于将账户分组在根账户下的容器。组织账户可以嵌套在其他 OU 单元中,从而创建你的组织层次结构,根账户位于顶部。
组织的功能
组织允许你在 AWS 账户之间集中管理策略。这有助于你通过使用 AWS Organizations 创建一个账户组,并将策略附加到指定的组,从而提升对 AWS 环境的控制,确保在这些账户上应用正确的策略,而无需任何自定义脚本。
你可以集成 AWS 单点登录(SSO),以便在一个地方简化为你的用户提供不同账户的访问权限。
SCP 允许组织为 AWS 服务、资源和区域管理权限保护措施。
AWS Organizations 还允许你轻松设置合并计费,为组织中的所有账户使用单一支付方式。这使你能够享受价格优势,如聚合使用量和不同服务的批量折扣,而这些在账户分开的情况下是无法获得的。
SCP
SCP 是一种工具,您可以使用它通过继承管理特定 OU 或整个组织的策略。它们可以增强或限制用户当前权限的范围,且在与高级 IAM 结构(如 Condition、ArnNotLike、StringNotLike 和特定区域)结合使用时最为有效,从而提供组织一致同意的保护措施,确保用户不会故意或无意地执行不当的操作。
SCP 示例
以下代码示例提供了一个 SCP 示例,您可以将其附加到组织的根级别,以确保如果有人要删除 EC2 或 关系型数据库服务(RDS)实例,则必须先提供多因素设备进行验证:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyDeleteandTerminateWhenMFAIsNotPresent",
"Effect": "Deny",
"Action": [
"rds:Delete*",
"ec2:TerminateInstances"
],
"Resource": "*",
"Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": false}}
}
]
}
您会注意到 SCP 语法几乎与普通的 IAM 策略语法完全相同,包含 Effect、Action、Resource 和 SID。此 SCP 实际上有一个可选的条件值,在这里我们检查是否存在 MFA,如果不存在,则拒绝该操作。
将联合身份验证与 AWS 账户集成
如果将要访问您账户的用户已经拥有身份验证方法,那么有几种不同的方法可以将联合身份验证集成到您的 AWS 账户中。
“身份联合是一种两方之间的信任系统,用于验证用户身份并传递授权访问资源所需的信息。在此系统中,身份提供者(IdP)负责用户身份验证,而服务提供者(SP),如服务或应用程序,控制对资源的访问。”(AWS,2021)
当您集成联合身份验证时,您的用户将使用 STS 来请求一个会话以授权访问您的账户。
一个会话包含以下内容:
-
一个访问密钥
-
一个秘密访问密钥
-
一个安全令牌
-
一个过期日期(用于指示安全令牌何时不再有效)
默认情况下,联合令牌将在 12 小时后过期,但可以设置为在最短 15 分钟或最长 36 小时后超时。
联合令牌是通过几种不同的请求类型从 STS 服务发放的,其中列出了一些请求类型:
-
GetFederatedToken -
AssumeRoleWithSAML
何时使用联合身份验证?
在某些场景下,联合身份验证在您的环境或账户中是非常适用的。首先是如果您有一个安全断言标记语言(SAML)2.0 兼容的企业目录。此类目录的例子有 AD 联合身份验证服务(AD FS)、Okta、Shibboleth 等。当您的目录符合 SAML 2.0 标准时,您可以将其配置为为 AWS 管理控制台提供 SSO 访问。
即使目录不符合 SAML 2.0 标准,您仍然可以为用户提供单点登录(SSO)功能。然而,在这种情况下,您需要创建一个身份代理应用程序来提供 SSO 访问。
你可能会使用联合身份验证的第二种场景是,如果你的用户通过第三方进行身份管理,例如 Web 身份。在这种情况下,Web 身份提供者(IdP)提供身份验证步骤,然后你可以使用联合身份验证授权用户访问他们需要的 AWS 服务。我们将在本章后面讨论如何使用 AWS Cognito 服务时进一步探讨这一点。
使用 AD 联合身份验证与 IAM
当你使用 AD FS 提供账户访问时,流程按以下顺序进行:
-
用户(或应用程序)向联合身份验证代理请求会话。
-
用户然后通过 AD 进行身份验证,以确保他们是活跃用户并且具有访问 AWS 云的权限。
-
接下来,AD 确定用户有权接收的权限数量。
-
然后,联合身份验证代理会从 AWS 账户中的 STS 服务发起
GetFederationToken请求。 -
STS 服务随后返回联合令牌(包括访问密钥、秘密密钥和会话令牌)。
-
联合身份验证代理随后将令牌传递给用户。
-
用户然后可以向 AWS 账户发出 API 调用。
使用联合身份验证来访问你的 AWS 账户,对于拥有大型组织的用户尤其有用,因为这样你就不需要在 AD 和 AWS IAM 中分别管理用户了。它还可以帮助你绕过每个账户最多只能创建 500 个 IAM 用户的服务限制。
AWS 根据你的需求提供了多个不同的版本的 AD,接下来我们将讨论这些选项。
AWS 目录服务
AWS 根据你的需求提供了多种不同的云中使用 AD 的选项。AWS 目录服务提供了三个不同级别的服务,每个服务的用途不同。
AWS 目录服务 for Microsoft AD (MS AD)
如果你希望在云中运行托管服务版的企业版 AD,那么 AWS AD 服务是一个非常好的选择。该服务可以处理最多 50,000 个用户和最多 200,000 个 AD 对象。它还支持在多个区域中以高可用的方式进行部署。多区域复制仅在 AWS 托管 MS AD 的企业版中支持。
如果你有超过 5,000 个用户,并且当前没有 AD 服务器或无需在 AWS 云中管理用户和/或 AD 对象,那么 AWS 目录服务是你最好的选择。
使用此服务的一个缺点是,如果遇到性能问题,你没有很多可调整的选项。这毕竟是一个托管服务,目的是减轻你的管理任务。这也不适用于 Web 联合身份验证。
AD 连接器
如果您已经有一个本地的 AD 服务器,并且想要快速将其扩展到云端,那么 AD 连接器是一个不错的选择。AD 连接器不会在云端缓存信息,而是作为本地 AD 服务器的代理。这也意味着您不能在云端对 AD 连接器进行任何更改,所有更改和更新都必须在本地服务器上进行。
简单 AD
简单 AD 有两个版本:小型版和大型版。小型版支持最多 500 个用户和 2000 个对象,大型版支持最多 5000 个用户和 20000 个对象。如果这些数字无法满足您组织的增长需求,您需要考虑其他解决方案,例如 MS AD。
简单 AD 支持基于 Kerberos 的 SSO 身份验证,并且可以通过 CloudFormation 脚本快速启动。
重要提示
简单 AD 基于 Samba 4,并不是真正的 MS AD。它不支持与其他 AD 系统的信任关系,也不支持 MFA、PowerShell、AWS SSO 或 Amazon Chime 等功能。虽然如果您只有少量用户,或者需要为少量 Windows 机器提供完全合格的域名(FQDN)来使用云端服务,它是一个不错的选择,但请注意其局限性,尤其是在阅读考试题目时。
AWS SSO
即便 AWS 提供了丰富的服务,仍然有其他服务是您或您的客户可能希望作为 SaaS 服务集成,并且这些服务需要身份验证。与其让用户每次都验证自己对每个服务提供商(SP),AWS 使用其自有的 SSO 服务使这一过程变得简单。
即使您使用的是本地的 AD 或 Azure 基础的 AD,您也可以使用第三方身份验证服务,例如 Okta 或 Ping Identity,并且这些服务同样可以与 SSO 集成。
AWS SSO 使管理员轻松管理多个 AWS 账户,您可以快速且轻松地将用户及其角色映射到账户,并通过单一入口点进行管理。这样,您无需再设置 SAML 令牌或让用户去选择切换角色的账户。
选择用户身份策略
使用这些不同的方法来管理用户及其授权管理方式时,您可能需要一些关于何时使用每种方法的指南。
如果您有一个小团队,那么通常使用 IAM 组来管理最为合适。
如果您想使用联合身份验证来管理用户登录,并且已经有一个 AD 环境,那么通过 AD 实现 SAML 联合身份验证将是正确的选择。
如果您需要联合身份验证,并且尚未拥有 AD,且希望获得 AD 提供的额外功能,例如为 Windows 实例提供域名系统(DNS)管理,那么可以使用 AWS 目录服务。
然而,如果你需要联合身份认证,并且不想麻烦地设置和管理 AD 或承担许可费用,那么 AWS SSO 将是你最好的选择。
在 AWS 中安全地存储机密
作为一名 DevOps 工程师,负责通过部署管道对我们的基础设施和应用程序进行编码并部署,并不意味着可以省略诸如用户名、密码或第三方 API 身份验证等凭证管理。然而,这确实要求我们在更加安全和可重复的基础上进行身份验证,从而避免影响开发和测试,并且仅与那些真正需要知道的人共享访问权限。如果所有开发人员都在使用相同的应用程序,并不需要每个人都有数据库的用户名和密码。此外,如果你不直接将凭证分发给每位开发人员,而是让开发人员从秘密管理器中请求凭证,便可以减少每次人员变动时需要更改凭证的管理负担。虽然市场上有第三方解决方案可以执行此任务,但 AWS 提供了两种不同的本地服务,允许进行机密管理,甚至机密轮换。
AWS Secrets Manager
你可以使用 Secrets Manager 来存储、轮换、监控和控制对诸如数据库凭证、API 密钥以及 开放授权(OAuth)令牌等机密的访问。Secrets Manager 的主要特点之一是它允许通过 AWS Lambda 函数自动轮换机密。
不再需要将硬编码的机密存放在你的 IaC 或应用程序代码中,甚至不需要在启动时将其下载到实例并以未加密的易受攻击状态存储。现在,你可以通过调用 Secrets Manager 简单而安全地在需要时检索机密。
对 Secrets Manager 的访问也受到 IAM 策略的管控。用户或角色必须获得访问 Secrets Manager 服务整体或特定实例的权限,才能执行如存储和检索机密等操作。
Secrets Manager 的另一个功能是每次访问机密时,都会留下审计跟踪记录。这在高合规性行业中是一个非常有价值的功能。
你可能会想:什么是机密? 在 Secrets Manager 中,机密通常是用于访问受保护设备的一组凭证(用户名和密码)以及连接详细信息。
Secrets Manager 中机密的基本结构
在 Secrets Manager 中,机密包含加密的机密文本以及多个元数据元素,这些元素表示机密并定义 Secrets Manager 应如何处理机密,如下图所示:

图 3.13 – Secrets Manager 中机密的结构
现在我们已经了解了 Secrets Manager 如何存储和管理我们为安全存储而放入的密钥版本,让我们通过一个练习来创建和存储一个密钥,使用 AWS Secrets Manager。
在 AWS Secrets Manager 中创建和存储密钥
在以下练习中,我们将使用 AWS 管理控制台和 AWS Secrets Manager 安全地存储一个密钥。操作步骤如下:
-
打开浏览器,返回到亚马逊 Web 控制台。如果您的会话已过期,您可能需要重新登录。在顶部的搜索栏中,输入
Secrets Manager,以使Secrets Manager图标显示。点击该图标以进入主AWS Secrets Manager页面,如下图所示:![图 3.14 – 主 Secrets Manager 页面]()
图 3.14 – 主 Secrets Manager 页面
-
在主
Secrets Manager页面或密钥列表页面中,一旦进入控制台中的Secrets Manager部分,点击存储新密钥。 -
在存储新密钥页面上,选择其他类型的密钥,如下图所示:
![图 3.15 – 在存储新密钥页面上选择密钥类型]()
图 3.15 – 在存储新密钥页面上选择密钥类型
-
在指定要存储在此密钥中的键/值对下,选择密钥/值,这样您就可以将密钥作为键值对输入,如下图所示:
![图 3.16 – 向您的密钥添加键值对及值到 Secrets Manager]()
图 3.16 – 向您的密钥添加键值对及值到 Secrets Manager
-
对于
DefaultEncryptionKey,如以下屏幕截图所示:![图 3.17 – Secrets Manager 加密]()
图 3.17 – Secrets Manager 加密
-
在第一个框中,输入
username。在第二个框中,输入devopspro。 -
选择+ 添加行以添加第二个键值对。
-
在第一个框中,输入
password。在第二个框中,输入MyTopSecretP@ssword#。一旦我们输入了密钥的值,我们可以在 JSON 格式下查看它,以确保其正确性。
-
选择密钥的
SecretString字段。 -
对于
DefaultEncryptionKey,然后点击下一步。 -
在
chapter3/SecretManager下。这会将您的密钥存储在一个虚拟的chapter3文件夹中。 -
对于
Secret Manager Tutorial,然后点击下一步。 -
我们不需要轮换此密钥,因此选择禁用自动轮换,然后点击下一步。
-
在复审页面上,您可以检查您所选择的所有设置。如果您在应用程序中使用该密钥,请务必查看示例代码部分,其中包含可以粘贴到您自己应用程序中的代码,以便使用此密钥来检索凭证。每个标签页都包含不同编程语言中的相同代码。
-
要保存更改,请选择存储。
从 Secrets Manager 中检索您的密钥
现在我们知道如何使用 AWS 管理控制台保存秘密,我们将使用 AWS CLI 检索秘密,并查看它已成功存储。操作如下:
-
如果您之前关闭了终端,请打开它,并输入以下命令,以便我们可以检索秘密:
$aws secretsmanager list-secrets执行上述命令后,应该会返回类似于以下内容:
{ "SecretList": [ { "ARN": "arn:aws:secretsmanager:us-east-2:470066103307:secret:chapter3/SecretManager-qBEqSh", "Name": "chapter3/SecretManager", "Description": "Secret Manager Tutorial", "LastChangedDate": "2021-03-15T21:55:53.828000-04:00", "Tags": [], "SecretVersionsToStages": { "83e08e0f-00d6-46d2-b05a-223041403f19": [ "AWSCURRENT" ] }, "CreatedDate": "2021-03-15T21:55:53.783000-04:00" } ] } -
现在我们可以看到我们在 Secrets Manager 中以名称
chapter3/SecretManager存储的秘密,我们可以通过运行以下命令来检索秘密:SecretString field for you to use. You should also notice that it has returned the current value by default. We could have also asked Secrets Manager to return us back to the previous version of the secret stored if we needed that version of the secret.
我们刚刚使用 AWS Secrets Manager 成功创建、存储和检索了一个秘密。我们能够检索秘密的原因之一是因为我们的 IAM 角色赋予了我们这样做的权限。接下来,我们将查看 AWS 为秘密的安全保管提供的另一项服务:SSM 参数存储。
SSM 参数存储
参数存储是 AWS 提供的一项托管服务,用于存储字符串。这些可以是明文字符串,或者在将其用作秘密管理器时,它可以存储加密数据。访问这些参数受 IAM 策略访问的管理。
参数存储比 Secrets Manager 更灵活,如果您在那里存储标准参数,则没有费用,但参数数量有限制为 10,000 个。
存储在参数存储中的秘密和值可以从许多不同的 AWS 服务中访问,包括以下服务:
-
EC2
-
弹性容器服务 (ECS)
-
Secrets Manager
-
AWS Lambda
-
CloudFormation
-
CodePipeline
-
CodeBuild
-
CodeDeploy
如果您或您的团队正在寻找一种集中的方法来将秘密和配置数据与代码库分离,以及存储不同环境的不同值的能力,那么参数存储可能是一个不错的选择。
Secrets Manager 与 Parameter Store
当我们查看不同的 AWS 安全存储秘密的服务时,我们可能会想知道为什么选择其中一个而不是另一个。让我们快速比较这两种服务,看看它们的主要区别,如下所示:
-
如果您正在寻找一种不会增加预算的选项,则 SSM 参数存储是您和您的组织的正确选择。
-
如果您希望能够存储明文秘密,则 SSM 参数存储具有此功能。AWS Secrets Manager 无法存储明文值。
两种服务在安全性方面都是成比例的,因为两者都可以使用密钥管理服务 (KMS) 在静态时安全地加密值。
如果您希望能够自动轮换秘密,则 AWS Secrets Manager 需要成为您的服务选择。(使用参数存储,您将不得不手动轮换秘密。)
使用 Cognito 进行应用程序身份验证
Cognito 是一项服务,允许 Web 和移动应用程序通过用户名和密码或第三方身份验证社交 IdP(如 Amazon、Facebook 或 Google)来进行身份验证。Amazon Cognito 的三个主要功能是用户管理、身份验证和同步。Cognito 可用于协调外部用户通过第三方 IdP 进行身份验证。您还可以通过任何基于 SAML 的 IdP 联邦化您的用户。
使用 Cognito 的一些优势包括以下几点:
-
设置简便,您可以在几分钟内让集成到 AWS 服务中的身份验证和授权系统上线,而与之相对的,自定义编程同样任务所需的时间要长得多。
-
您可以快速而轻松地将 MFA 集成到 Amazon Cognito 中。
-
Cognito 指标可以通过 CloudWatch 服务轻松监控,无需额外的工作或编码。
-
对 Cognito 服务的任何 API 调用都会记录到 CloudTrail(假设您已为该帐户和区域启用 CloudTrail)。
您会在哪里使用 Cognito?
当您为外部客户(即不是您公司的一部分的客户)构建应用程序,并希望这些客户无论使用何种设备都能有相同的体验时,这时使用 AWS Cognito 就是一个合适的选择。Cognito 允许用户无论使用手机、平板、笔记本电脑还是 虚拟机(VM),都能拥有相似的登录体验。
使用 Cognito 的另一个案例是,如果您希望快速将 双重身份验证(2FA),如电子邮件或 简单消息服务(SMS)身份验证集成到您的应用程序中。
用户池
Cognito 的第一个主要组件是用户池。实际上,用户池提供了注册和登录服务。了解关于用户池的以下事实:
-
它们提供注册和登录服务。
-
用户池有一个内置的 用户界面(UI),并且可以自定义。
-
它们允许通过社交 IdP(如 Amazon、Google、Facebook 和 Apple)以及来自用户池的 SAML IdP 进行登录。
-
它们支持诸如 MFA 身份验证等安全功能,可以检查泄露的凭证,并具有帐户接管保护。
-
用户池支持电话和电子邮件验证。
-
用户池允许通过 AWS Lambda 触发器进行自定义工作流以及用户迁移。
一旦您成功通过用户池对用户进行身份验证,Cognito 就会发放一个 JWT,可以用于授权访问您的 AWS 凭证或 API,如下图所示:

图 3.18 – Cognito 用户池身份验证
了解了用户池及其功能后,我们可以来看一下 Amazon Cognito 的另一个主要组件:身份池。
身份池
Amazon Cognito的第二个主要组成部分是身份池。身份池提供访问 AWS 服务的凭证。使用身份池,你可以为用户创建独特的身份,使他们能够临时访问 AWS 服务。
如果你查看图 3.17中显示的工作流,你会看到用户从其设备上的应用程序启动登录(通常是通过 Web IdP)。一旦通过 Web IdP 验证,GetId调用会传递给 Amazon Cognito,后者会验证请求。然后,应用程序会发出GetCredentialsForIdentity请求。Cognito 会再次验证此请求。此时,Cognito 将调用 STS 服务并为应用程序授权的服务获取一个短期令牌,然后将其返回给应用程序,如下图所示:

图 3.19 – Cognito 身份池授权流程
身份池还允许你定义自己的自定义开发者认证身份,除了 AWS 支持的社交 IdP 进行身份验证之外。你可以在 Cognito 控制台中选择自定义,设置自己的名称,然后使用 AWS 提供的示例代码作为创建新自定义联邦身份池的基础。
记住的提示
用户池提供身份验证,身份池提供授权。
总结
在本章中,我们学习了 AWS 中的身份验证和授权方法。我们讨论了如何使用用户名和密码或通过 IAM 服务进行联邦授权用户,然后通过 IAM 策略对他们进行身份验证。AWS Organizations还向我们展示了如何通过使用 SCP 进一步限制授权设置。我们查看了与 AD、AWS SSO 和 Cognito 等服务的不同联邦模型。我们还了解了如何使用 Secrets Manager 或 SSM Parameter Store 安全地存储密钥,以便在开始与应用程序工作时使用。
在下一章中,我们将通过介绍 NoSQL 服务 DynamoDB 来总结 AWS 基础知识部分。
复习问题
-
在 AWS 为 IaaS 提出的共享责任模型中,谁负责操作系统的安全性和补丁管理?
-
在此处提供的选择中,用户和角色之间的主要区别是什么?
a. 角色可以由多个主体假定;用户不能被假定。
b. 角色使用长期凭证。
c. 角色可以是一个组的成员。
d. 角色不使用长期凭证。
-
授权和身份验证哪个先进行?
-
AWS 中哪个原生服务存储密钥并提供自动密钥轮换?
-
一家公司希望将当前的 AD 扩展到 AWS 云中,但不想管理更多的服务器。对于他们来说,哪个服务是最佳选择?
a. AWS 简单目录服务
b. AWS Cognito
c. AWS 用户池
d. AWS AD 连接器
复习答案
-
客户负责操作系统的补丁和安全性。
-
a 和 d。
-
认证。
-
AWS Secrets Manager。
-
d.
第四章:Amazon S3 Blob 存储
Amazon S3 是 Amazon Web Services 的核心组成部分之一。然而,在 DevOps 专业人员的上下文中,有一些关于该服务的细微差别,你不仅需要熟悉它们,还需要在实施时感到得心应手。
亚马逊的简单存储服务(S3)是许多用户和公司进入云计算的入口。它提供的一些主要特点是高度可用、极其耐用、性能卓越并且易于管理,同时具备彻底的安全性。S3 的一个主要特点是其 11 个 9 的耐用性(99.999999999%),这意味着它不会丢失对象或数据。一旦你上传一个对象,在返回 200 成功状态之前,该对象必须复制到多个系统和多个可用区,以防止在各种场景下的数据丢失。
在本章中,我们将涵盖以下主要内容:
-
S3 概念
-
在 S3 中使用生命周期策略
-
使用 S3 事件触发其他 AWS 服务
-
S3 访问日志
-
S3 端点
S3 概念
在深入了解 S3 之前,让我们简要了解一下三种不同类型的云存储:
-
对象存储 – 数据作为对象保存,并与该对象的相关元数据一起打包。
-
文件存储 – 数据作为单个信息存储在文件夹结构中。
-
块存储 – 数据和文件被分隔成块。每个块作为独立的数据片段进行存储。
S3 是一种对象存储服务,尽管它看起来有文件夹结构,但实际上这只是附加到对象上的元数据,通过键/值对的方式,使数据可以更高效地分类。
一旦创建了 S3 桶,不仅可以存储数据,而且此时它几乎是无限可扩展的。AWS 还创建了许多辅助服务,帮助你将数据迁移到 S3。它们包括像 Amazon Kinesis 这样的流式解决方案、AWS SFTP 等 SSH 文件传输协议(SFTP)替代方案,甚至像 AWS Snowball 和 Snowball Edge 这样的批量数据加载服务:

图 4.1 – 数据传输的 S3 选项
默认情况下,AWS 账户最多可以创建 100 个 S3 桶。这是一个软性限制,如果需要更多的桶,可以通过提交服务限制提升请求来增加该数量。
与 S3 的交互
用户有几种与 S3 交互的方式,从 AWS 控制台开始。通过它,你可以图形化地列出你的桶,并根据你为不同对象指定的标签,以文件夹形式展示你的对象。
随着您对 S3 及其功能的熟悉,您可能会发现,控制台需要多个点击才能执行诸如删除文件之类的简单操作,这时 CLI 和掌握其命令可以成为您的有力助手。
在 AWS CLI 中,有一些基础命令可以用来与 S3 交互:
-
还有基础的
aws s3命令——该命令使您能够执行九种基本操作,例如创建桶、列出桶或其内容,甚至创建一个预签名 URL 以访问桶。 -
还有
aws s3api命令——该命令为基础s3命令中的项目提供了一组不同的二级命令。 -
aws s3control命令允许您对 S3 控制面板进行精细化访问。 -
最后,还有
aws s3outposts命令——该命令提供对 AWS Outposts 上 S3 的访问。
S3 命名指南
所有 AWS 上的 S3 桶名称必须是唯一的,不仅仅是在您的账户中。
创建桶时,您必须遵循一些规则,以确保名称符合 S3 的要求:
-
桶名称的长度必须至少为 3 个字符,最多不超过 63 个字符。
-
桶名称只能由数字、小写字母、点号 (.) 和连字符 (-) 组成。
-
桶名称必须以数字或字母开头和结尾。
-
桶名称不能以
xn–开头。 -
桶名称不能像 IP 地址那样格式化(例如
192.168.2.1)。
亚马逊还建议,除非您将 S3 桶用于静态网页托管,否则不要在桶名称中使用点号 (.)。
企业的桶名称
前述规则是命名 S3 桶的最低标准。随着您进入实际应用,大多数已经在 AWS 云中的大型组织都有桶命名方案。某些中小型企业仍然没有关于如何命名 S3 桶的组织标准,但这可能是一个错误。
S3 桶非常容易创建,不仅开发人员可以创建,几乎任何有权限访问该服务的人都可以创建。问题出现在您开始遇到像 mytest-bucket123 这样的桶名称时。再一次,这与最初的原则有关,即如何弄清楚谁是这些数据的拥有者,以及是否需要为了安全存储而复制这些数据,或是否可以安全删除。
随着您进入企业命名方案,您和您的组织需要就负责账户中桶的统一命名标准达成共识:

图 4.2 – 企业桶命名示例
使用如 <region>-<environment>-<department>-<product>-<identifier> 这样的简化模式,可以为每个桶创建一个唯一的名称,并且仍然符合 AWS 的命名标准。
这有助于快速识别每个存储桶的所有者,并允许团队和账户管理员快速、轻松地排序和搜索资源,不仅能按产品或项目区分谁创建了存储桶。这在 图 4.2 中显示,并且存储桶名称为 oh-d-devops-pip-cont1。这个存储桶名称是 ohio-development-devops-pipeline-containers 的简写。
创建 S3 存储桶
如果您想备份实例,无论是为了恢复目的还是用于自动扩展中的启动配置,则需要创建一个 AMI 镜像:
-
启动一个
EC2实例。 -
我们需要一个实例来备份并创建 AMI:
$ aws s3 MB s3://devopspro-beyond –region us-east-2注意
您需要使用与示例中不同的存储桶名称。只要遵守 S3 命名规则,您可以随意命名存储桶。
-
如果成功,您应该看到以下输出:
make_bucket: devopspro-beyond现在您有了一个我们可以操作的存储桶。如果你想在命令行中查看存储桶,可以使用以下命令列出它:
$ aws s3 ls我们刚刚创建的这个存储桶现在已经准备好存放文件、媒体、日志或您希望存储的任何内容。
将数据迁移到 S3
到此为止,我们至少创建了一个存储桶。随着后续操作的进行,您会注意到一些 AWS 服务会在您的账户中创建存储桶,例如 CloudFormation。
如果我们只是尝试一次迁移一个项目或一个文件夹,那么我们可以使用 AWS 管理控制台或 CLI 中的 aws s3 copy 命令。
如果我们有一台生成日志的服务器,并且希望将这些日志存储到 S3 存储桶中,用于存储、备份、分析或这些选项的组合,那么我们可以使用aws s3 sync命令。s3 sync命令将同步指定文件夹中的所有对象与 S3 中指定的存储桶。这与 cron 或类似的计划任务一起使用时效果极佳,可以按照预定计划执行该命令。
当试图迁移整个服务器或数据中心时,尝试通过网络推送所有文件和对象可能会非常耗时。在这种情况下,Snowball 系列服务就派上用场了。Snowball Edge 存储优化版(SESO)允许安全地传输最多 80 TB 可用硬盘存储的数据,数据上传到设备后,再运送到 AWS,最终被卸载到您指定的 S3 存储桶中。
S3 清单
使用列出命令查看存储桶中不同对象非常有用,直到你开始拥有成千上万到百万级别的对象。当达到这个数量时,拥有一个更强大的工具就显得尤为重要。S3 清单就是为这个目的而创建的。S3 清单工具会创建一份报告,然后将其交付到另一个存储桶中,并提供有关您的对象的各种信息,如以下内容:
-
创建日期
-
存储类
-
加密状态
-
复制状态
-
对象大小
您可以选择使用 SSE-S3 或 密钥管理服务(KMS)密钥对报告进行加密。
一旦报告生成完成,您可以使用 Amazon Athena 等工具使用标准 SQL 查询报告,寻找趋势或异常。
S3 清单报告生成需要小额费用(每百万个对象少于 0.003 美分);但不应假定该工具是免费的,它是 S3 服务的一部分。
S3 存储层
亚马逊 S3 服务有一系列不同的存储层,可以满足不同的需求以及不同的成本结构。默认存储层是标准存储层,尽管这并不总是存储数据的正确选择,特别是当您的组织需要长期存储和/或寻求节省成本时。
您可以创建生命周期策略,将对象从一个存储层移动到另一个存储层,或者在一段时间后如果对象不再需要则删除它。
S3 Standard
一旦您初次设置了一个存储桶,默认情况下,除非指定其他存储层,否则它将位于 S3 Standard 层。这是一个高可用性的通用访问存储策略,提供毫秒级别的对象访问。尽管这是所有存储层中最昂贵的,但与其他类型的存储服务(如文件存储和块存储)相比,S3 Standard 存储非常便宜。
需要记住的关于 S3 Standard 的要点:
-
Standard 层提供高吞吐量、低延迟和对象上传与下载的性能。
-
如果没有指定其他存储层,则 Standard 是默认的存储类。
-
设计为每年 99.99% 的可用性。
-
适合需要频繁访问的对象。
-
适合用于数据湖、云原生应用、网站和内容分发等用例。
S3 智能分层(Intelligent-Tiering)
有时您可能认为亚马逊推导出来的将对象移动到不同存储层的算法,比您自己提出的任何方法都更有效。这时选择 S3 智能分层是一个完美的案例。使用智能分层,AWS 将根据您的使用情况自动在频繁访问层和不频繁访问层之间移动您的对象,并根据使用情况向您收费。
需要记住的关于 S3 智能分层的要点如下:
-
设计为通过自动将对象移动到最具成本效益的存储层来优化存储成本。
-
设计用于至少 30 天的长期存储(最低 30 天的充电时间),并且智能分层(Intelligent-Tiering)需要 30 天才能开始分析访问模式。
-
它将对象存储在两个访问层中,并基于频繁访问和不频繁访问的对象优化存储。
-
当智能分层在不同层级之间移动对象时,不会影响性能,也不会产生额外费用。
-
设计为每年 99.99% 的可用性。
-
针对数据湖和其他访问模式不确定的数据集进行了优化。
S3 标准低频访问(S3 Standard-IA)
如果您有不常访问但仍需要实时检索的数据,Standard-IA 是一个值得考虑的选项。考虑此存储选项时需要注意一些要点,例如文件需要至少存储 30 天才可以删除(或者需要为这 30 天支付费用),并且文件的最小大小为 128 KB。
关于 S3 Standard-IA,需记住的关键点如下:
-
设计用于大于 128 KB 的文件(小于 128 KB 的文件将按 128 KB 计费)。
-
设计用于至少存储 30 天(最低 30 天费用)。
-
相比标准存储,S3 One Zone-IA 在 GET、PUT、COPY、POST、LIST 和 SELECT 操作上的费用较高,但存储成本较低,因此它是为低频访问而设计的,正如其名称所示。
-
对象可以实时访问,且没有延迟。
-
为保证一年内 99.99% 的可用性而设计。
-
数据的副本存储在多个可用区中。
S3 单区低频访问(S3 One Zone-IA)
S3 One Zone-IA 具有与 Standard-IA 相同的许多功能,但由于数据只存储在一个可用区而不是至少三个可用区,因此价格更低。这对于关键数据并不是一个好选择,但对于不常访问且可以在必要时重新创建的文件来说,可以大幅节省成本。
关于 S3 One Zone-IA,需记住的关键点如下:
-
适用于可重新创建的数据或在设置跨区域复制时的对象副本。
-
设计用于至少存储 30 天(最低 30 天费用)。
-
对象可以进行实时访问。
-
为保证一年内 99.95% 的可用性而设计。
-
数据可能会因灾难性事件(如洪水或地震)导致的数据中心停机而丢失。
S3 Glacier
S3 Glacier 存储层提供低成本、持久的存档存储选项,并且数据检索费用低。与 AWS Glacier 服务不同,您无需等待数天才能将对象恢复到 S3 存储桶中。S3 Glacier 有 3 种检索速度等级:第一种是加急等级,可在 1-5 分钟内恢复对象;第二种是标准检索等级,可在 3-5 小时内恢复对象;第三种是批量等级,恢复对象大约需要 12 小时。
关于 S3 Glacier,需记住的关键点如下:
-
设计用于至少存储 90 天(最低 90 天费用)。
-
为保证一年内 99.9% 的可用性而设计。
-
对象可以通过VAULT LOCK功能进行锁定。
-
Glacier 检索时间可以配置为几分钟到几小时不等。
-
适合低成本的数据归档,尤其适用于合规目的,不常访问的对象。
S3 Glacier 深度归档
像 Glacier 服务一样,如果你有很少检索的数据但需要保存,那么 Glacier Deep Archive 可以成为一个切实可行的存储解决方案。通常,有一些场景比如从磁带备份系统迁移到数字磁带备份系统,数据每年只需要检索一到两次,并且可以接受等待 12 小时来检索数据。这些控制提供了巨大的节省,因为 Glacier Deep Archive 的存储费用仅为每月每 TB 1 美元。
关于 S3 Glacier Deep Archive,有几个关键点需要记住:
-
设计用于长期数字存储,可能在某一年内仅访问一次或两次
-
旨在保证每年 99.9% 的可用性
-
设计用于至少存储 180 天(最低 180 天的费用)
-
是本地磁带库的替代方案
注意
S3 Glacier 和 S3 Glacier Deep Archive 是 S3 中的存储类,因此,对象将一直保存在 S3 服务内。
在 S3 中使用生命周期策略
正如我们刚才讨论过的,S3 提供不同的存储类,并非所有存储在 S3 中的数据都需要始终处于标准存储层,如下所示:

图 4.3 – 一个示例 S3 生命周期策略
根据你定期访问数据的频率,你可以通过对象生命周期将你的对象移动到不同的存储层。
创建生命周期策略
以下练习将使用 AWS 控制台和我们在本章前面创建的桶:
-
登录 AWS 控制台(使用你在本章中创建的 S3 桶所在账户)。确保你已使用具有 S3 完全访问权限的用户登录账户。
-
访问 S3 页面(
s3.console.aws.amazon.com/)。 -
如果你有多个 S3 桶,请点击你在前面的练习中创建的桶。
该桶当前应没有任何对象,也没有与其关联的生命周期策略。
-
当你进入桶的主页时,点击主屏幕上的 管理 选项卡。
这将把 生命周期规则 部分显示在主屏幕的中间,并且在 生命周期规则 后面会有一个 (0),意味着当前没有与此桶关联的 生命周期规则:
![图 4.4 – 通过管理选项卡查看 S3 生命周期规则]()
图 4.4 – 通过管理选项卡查看 S3 生命周期规则
-
现在我们可以点击 生命周期规则 部分中的 创建生命周期规则 按钮。这将引导我们进入创建生命周期规则的界面。
我们将创建一个规则,在一天后删除存储桶中的对象。我们可以创建多个规则,遵循图 4.2中的路径,但如果你记得低频访问存储层的关键点,任何未保存至少 30 天的对象将会被收取 30 天的存储费用。在测试如何创建生命周期规则时,我们将创建一个规则,删除对象,而不是测试期间产生额外的费用。
-
将规则命名为
devopspro-1day-delete。 -
在规则范围下,点击选项此规则适用于存储桶中的所有对象。
-
勾选出现的框,标明我确认此规则将适用于存储桶中的所有对象:
![图 4.5 – 配置生命周期规则]()
图 4.5 – 配置生命周期规则
-
在生命周期规则操作下,勾选标有过期当前对象版本的框。
-
当
1。 -
点击页面底部的创建规则按钮:

图 4.6 – 创建规则按钮
我们现在已经创建了生命周期规则,为了测试它,我们需要上传一个文件到存储桶中,然后等待一天,以便看到它被自动删除。
S3 终端节点
在 S3 终端节点创建之前,所有访问 S3 的数据都必须经过公共互联网。如果你有私人信息从私有 S3 存储桶传输到 VPC 中私有子网的资源,那么不仅存在一些安全风险,还需要额外的网络配置,使得私有子网中的资源能够与互联网通信,以便可以上传和下载你想要访问的 S3 存储桶。
如果我们的 VPC 中的资源位于一个私有子网,并且没有通过 NAT 实例或 NAT 网关与互联网建立公共路由,那么我们将无法访问 S3 存储桶中的项目,除非设置那个 NAT 实例,或者我们可以通过使用 S3 终端节点来建立更安全的连接。
S3 终端节点,作为一个网关终端节点,允许我们向VPC的路由表中添加一条入口。通过添加这个终端节点,我们现在可以绕过公共互联网,既可以通过公共实例,也可以通过私有实例,同时保护我们数据沿路由传输过程中的隐私。这比使用公共路由更安全,是从 EC2 实例和其他在 VPC 中的服务传输数据的更好解决方案。
S3 访问控制
一旦你将数据和对象上传到桶中,除非你的桶具有公共访问权限,否则你可能希望限制谁可以访问桶中的对象。刚开始时,你可能只允许具有帐户授权的任何人访问。这些人可以访问任何非公开的桶中的数据。当你进入大多数企业环境时,数据的某些部分可能需要在不同业务部门之间进行隔离。一个产品团队很可能没有必要访问另一个数据团队存储的数据。类似地,财务和业务部门存储的数据可能需要限制任何技术人员访问,甚至可能删除这些数据。
这时,S3 的访问控制就发挥了作用。实现访问控制有两种主要方法:一种是使用 S3 桶策略来限制谁和什么可以访问单个对象,另一种是使用 IAM 控制来限制可以单独访问桶的用户、组和资源,或者使用基于属性的控制模型(如标签)等控制。
通常,选择一种访问方法而非两者混合使用是个好主意,因为混合使用可能会导致一些非常令人沮丧的排错会话,试图解决权限问题:

图 4.7 – S3 资源与基于用户的策略
你还应该知道,必须显式地将 S3 桶设置为公共访问,因为所有 S3 桶默认都是私有的,并且阻止公共访问。
基于资源的策略
如果你和你的组织更倾向于在对象级别进行限制,那么你可以在桶访问级别或对象访问级别使用访问控制列表(ACLs)。
基于用户的策略
另一方面,许多人更愿意通过 IAM 策略来控制对 S3 桶的访问。这使你能够控制从桶和文件夹级别的权限,并且可以根据标签、VPC-id、source-IP 地址和其他因素在 IAM 策略中构建更复杂的条件。
跨账户访问
如果你需要一个账户中的用户或资源能够访问另一个账户中的对象,那么你可以设置跨账户访问角色,就像我们在 IAM 练习中所做的那样,见 第三章,AWS 中的身份与访问管理和密钥管理。
S3 访问日志
当你在 S3 中存储不同的对象时,尤其是那些需要被各种用户和组下载的对象,你可能希望知道谁在何时从什么位置访问了不同的文件。
用户可以通过 S3 中一个简单的设置捕获所有访问日志和谁在访问桶中不同对象的记录。你不能将日志存储在与正在跟踪的项目相同的桶中,因此你需要创建一个全新的桶,专门用于捕获日志,或者指定当前账户中已创建的桶来存储这些日志。
与 Web 服务器上的日志不同,日志不会在访问项目时实时推送到该桶。亚马逊会以批量的形式推送日志,尽力而为。
如果你不想设置一个完全不同的桶来捕获这些日志,并且你已为该账户启用CloudTrail 日志,那么你可以收集 IAM 用户对 S3 API 调用的信息。
S3 的加密选项
S3 允许对其存储的对象进行静态加密。存储对象时,默认选项是将其以未加密的形式存储。如果你在任何需要合规性的环境中工作,那么你很可能需要加密你存储的对象。
如果你已经决定将存储在 S3 中的对象进行加密,那么你确实有选择。你可以在服务器端加密和客户端加密之间进行选择。在做出这个决定之前,有几个关键问题需要考虑:
-
你需要管理加密密钥吗?
-
加密密钥将存储在哪里?
-
谁将负责数据的加密和解密?
服务器端加密
AWS 通过其服务器端加密选项使得加密存储在 S3 中的对象和数据变得简单:
-
SSE-S3:使用SSE-S3选项可以让你使用 AWS S3 主密钥来加密你的对象和数据。这使得你的数据可以在静态存储时进行加密,而无需在设置过程中做过多管理或额外配置。你只需将对象上传到你选择的 S3 桶,一旦成功接收,S3 服务会处理这些对象的加密。类似地,当服务或用户请求一个对象时,只要该服务或用户有权限访问该对象,S3 服务就会解密该请求的对象。 -
SSE-K:MS:将密钥管理服务(KMS)集成到服务器端加密中,会增加少许费用,但相较于仅使用 S3 服务提供的默认加密密钥,它带来了一些额外的功能和好处。你现在可以更细粒度地控制客户密钥以及哪些 IAM 实体可以访问该密钥。KMS 还提供了密钥访问的审计记录。其主要特点之一是,你可以根据需要旋转密钥。
客户端加密
选择客户端加密时,完全的加密和解密责任由您,客户端承担。这种方法涉及在对象到达 S3 之前进行加密。您还需要负责任何主密钥/子密钥的管理及密钥轮换。如果您的组织需要完全控制主密钥和加密算法,客户端加密是一个不错的选择。
我们将在第十九章,《保护传输中的数据和静态数据》中深入探讨数据的传输和存储保护。
使用 S3 事件触发其他 AWS 服务
S3 服务可以在存储桶中的对象发生特定变化时通知其他服务。最常见的两种场景是对象被上传或对象从某个特定存储桶中删除。然后,S3 存储桶可以通知其他三种 AWS 服务发生了什么事情,以及事件发生的存储桶。允许 S3 事件通知的三种服务如下:
-
AWS Lambda
-
亚马逊 简单队列服务 (SQS)
-
亚马逊 简单通知服务 (SNS)
当向存储桶添加或覆盖新对象时,您可以安排将通知发送到 SQS 或 SNS。通知也可以传递到 AWS Lambda,由 Lambda 函数处理:

图 4.8 – S3 事件流
让我们从 DevOps 的角度来思考这个问题,看看如何使用它。AWS Lambda 是一个极其强大的工具,我们将在第十二章,《Lambda 部署与版本管理》中详细探讨,它可以用于调用几乎任何其他的 AWS 服务。在我们当前的场景中,我们可能有一个客户正在使用 AWS SFTP 服务将文件上传到 Amazon S3 存储桶。该存储桶可以触发一个存储桶事件到 AWS Lambda。Lambda 函数可以启动一个 AWS Pipeline 构建来处理文件,处理结果无论是成功还是失败,都会向开发团队发送通知,告知有新的构建可供部署。
注意
为了使用 S3 事件,必须授予 S3 相关权限,以便使用请求的服务。这包括发布到 SNS 队列或 SQS 主题的权限,以及调用 Lambda 的能力。
触发 S3 事件
我们将通过一个示例来使用我们之前创建的存储桶,在每次上传对象到存储桶时添加事件触发器。这个事件一开始会是一个简单的操作:向我们自己发送电子邮件通知。为了发送这封邮件,我们需要创建一个 SNS 主题,并用我们的电子邮件订阅该主题。然后,我们可以返回到存储桶并添加存储桶事件配置,这样每当上传一个对象时,就会发送通知给我们。
既然我们知道需要设置一个 SNS 主题,让我们使用 CLI 创建该主题并订阅,以便上传到我们的存储桶时能够收到邮件:
-
打开终端并输入以下命令,创建该主题:
$aws sns create-topic --name s3-event如果主题创建成功,那么应该返回如下内容:
{ "TopicArn": "arn:aws:sns:us-east-2:470066103307:s3-event" } -
现在我们已经有了主题,需要使用我们的电子邮件地址进行订阅:
$ aws sns subscribe \ --topic-arn arn:aws:sns:us-east-2:470066103307:s3-event \ --protocol email \ --notification-endpoint devopsproandbeyond@gmail.com这应该返回一条 JSON 语句,告诉你订阅正在等待中:
{ "SubscriptionArn": "pending confirmation" } -
现在我们需要进入我们的电子邮件账户,找到 SNS 服务刚刚发送的邮件,然后点击上面写着确认订阅的链接。
现在让我们登录到我们的账户,进入我们的 S3 存储桶,以便配置事件通知。
-
我们的 SNS 主题准备就绪的最后一步是添加一个 IAM 角色,允许它接收来自 S3 存储桶的通知事件。
我们将使用以下策略,并在保存到文件之前填写以下值:
-
账户编号
-
区域
-
存储桶名称
我们将创建以下策略,然后在登录 AWS 控制台后将其添加到访问部分的主题中:
{ "Version": "2012-10-17", "Id": "s3-event-sns-ID", "Statement": [ { "Sid": "s3-publish-ID", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": "SNS:Publish", "Resource": "arn:aws:sns:region:account-num:sns-topic", "Condition": { "StringEquals": { "aws:SourceAccount": "account-num" }, "ArnLike": { "aws:SourceArn": "arn:aws:s3:::bucket-name" } } } ] } -
-
现在让我们登录到我们的 AWS 账户,进入 SNS 服务,以便更新我们的访问策略。这样,SNS 主题就能拥有正确的权限来与 S3 事件通知交互。
-
一旦进入 SNS 服务,选择主题。
-
在主题菜单中,你应该能够看到我们通过CLI – s3events创建的主题。点击主题名称以进入配置页面。
-
进入主题后,我们需要点击页面右上方的编辑按钮:
![图 4.9 – 页面顶部的编辑按钮]()
图 4.9 – 页面顶部的编辑按钮
-
现在在这一部分找到我们之前创建的
JSON策略。一旦将之前的值替换为新的访问策略,点击页面底部的橙色保存更改按钮。 -
现在我们可以进入 S3 控制台(
s3.console.aws.amazon.com/)。 -
找到你在本章中创建的存储桶(我们的存储桶名为
devopspro-beyond)。如果你还没有创建存储桶,你可以选择账户中已有的任何存储桶,或者快速创建一个新存储桶。点击该存储桶名称进入主存储桶页面。 -
一旦进入主存储桶页面,点击主窗口框中的水平菜单中的属性菜单项:
![图 4.10 – S3 水平菜单,属性高亮显示]()
图 4.10 – S3 水平菜单,属性高亮显示
-
现在向下滚动页面,直到找到名为事件通知的面板:
![图 4.11 – 没有创建通知的 S3 事件通知]()
图 4.11 – 没有创建通知的 S3 事件通知
-
现在点击创建事件通知按钮。
-
使用以下配置进行我们的 S3 事件测试:
-
S3 测试 -
.txt -
事件类型 – 勾选标记为 Put 的复选框:
-

图 4.12 – 配置 S3 事件通知
-
向下滚动到页面底部,直到看到 目标。
-
选择位于
s3-event旁边的单选按钮:![图 4.13 – 选择 S3 事件通知的目标]()
图 4.13 – 选择 S3 事件通知的目标
-
点击橙色的 保存更改 按钮。
-
现在是上传文本文件并测试我们是否能收到邮件通知的时候了。
-
我们需要测试的只是一份文本文件(记住,我们配置的事件仅限于
.txt文件,其他类型的文件不适用)。我们将使用 CLI 上传文件:$aws s3 cp test.txt s3://devopspro-beyond/test.txt如果你成功上传了文件,应该会看到如下输出:
upload: ./test.txt to s3://devopspro-beyond/test.txt -
文件上传后,你应该会收到一封邮件通知,通知会发送到你订阅 SNS 主题时使用的邮箱地址。
现在我们已经看到如何触发其他服务(如 Lambda、SNS 和 SQS)的操作,我们可以思考一下这种方式如何在现实世界中对我们有帮助。以 SNS 为例,你可能有一个客户,他有一个账户,并希望在他们的客户上传一个或多个文件到他们的个人 S3 存储桶时收到通知,以便查看这些文件。对于 Lambda 来说,你可能会收到另一个部门的发票,需要在将其存储到一个或多个数据存储中之前提取数据,使用 S3 事件,这一切都可以在文件上传到存储桶后自动发生。
在接下来的部分,我们将了解 S3 批量操作,看看如何借助清单文件,我们可以一次处理少量或几千个文件,仅使用 S3 服务。
S3 批量操作
拥有良好的标签策略是推荐的 AWS 账户管理的一部分。就像其他举措一样,这些策略中的许多会随着时间的推移而不断发展。也许会有某个时刻,你或你的组织会觉得需要更改当前 S3 存储桶中对象的某些强制性标签。如果你已经在 AWS 中运行了一段时间,那么很可能有太多对象需要手动重新标记,因此你需要想办法制定一个解决方案。这时,AWS S3 批量操作的强大功能就能派上用场了。它可以轻松地对文件和存储桶执行批量操作。
S3 批量操作不仅仅是修改标签。以下操作可以通过 S3 批量操作来执行:
-
修改对象和元数据属性。
-
在 S3 存储桶之间复制对象。
-
替换对象标签集。
-
修改对敏感数据的访问控制。
-
从 Glacier 恢复归档对象。
-
调用 AWS Lambda 函数。
作业创建后,会经历一系列法规,然后达到完成或失败状态。以下表格描述了 Amazon S3 批处理作业可用的不同状态:

S3 批处理实例
为了测试 S3 批处理的功能,我们将取 75 个文件,上传到我们的存储桶,然后使用 AWS 批处理几乎即时为每个文件添加一个标签。
注意
如果不想重新创建此练习的所有文件,只需转到本书的 GitHub 仓库;在第四章,Amazon S3 Blob Storage,批处理子文件夹中有 75 个小文件可用。
另外,由于所有文件都具有.txt扩展名,您可能希望在将所有练习文件上传到 S3 存储桶之前,关闭 S3 事件通知或取消订阅主题。
我们现在将使用 S3 批处理的实际示例一次性更新多个文件的标签。如果您有强制性的标签策略,并且文件缺少其中一些标签,则这可能是管理这些更改的有效方式,而不是尝试编写自定义脚本执行任务或手动更改文件的标签:
-
在开始之前,为了使作业能够执行,我们需要确保有一个 IAM 角色。让我们首先登录 AWS 管理控制台,并导航到 IAM 服务。
-
为 AWS 服务创建角色,选择S3,然后在页面底部选择S3 批处理操作:
![图 4.14 – 在 IAM 中选择 S3 权限的用例]()
图 4.14 – 在 IAM 中选择 S3 权限的用例
-
点击标有下一步:权限的蓝色按钮。
-
到达策略时,从 GitHub 中点击
S3_batch_IAM.json的JSON代码。您需要在所有需要变量的地方替换您的 S3 存储桶名称。(变量名称标记为<<TargetResource>>,<<ManifestBucket>>和<<ResourceBucket>>)。完成后,您可以点击标有下一步:标签的蓝色按钮。此时不需要任何标签,只需点击标有下一步:审核的蓝色按钮。 -
现在可以命名和保存我们的角色;一个好的描述性名称可以是
S3-Batch-Tagging-Role。如果需要,添加描述,然后点击蓝色的创建策略按钮。 -
返回到创建角色的其他标签页,并搜索我们刚刚创建的名为
S3-Batch-Tagging的策略。创建完角色后,我们需要记下 ARN,以便稍后在batch命令中使用。 -
从 GitHub 目录下载 75 个
.txt文件(或创建您自己的文件集),放入单个目录中,以便可以将它们上传到您之前创建的 S3 存储桶。 -
接下来,我们将使用
s3 sync命令快速将文件从本地目录移动:$aws s3 sync . s3://devopspro-beyond -
我们还需要从 GitHub 仓库下载清单(
.csv文件),以便开始我们的批处理任务。在清单中,你需要将当前的存储桶名称devopspro-beyond替换为你上传对象的存储桶名称。更改这些值后,确保将清单上传到 S3 存储桶,因为当使用CSV文件时,S3 批处理需要从 S3 位置读取清单,而不是从本地文件读取。 -
最终报告还需要一个文件夹来存放。我们将使用
s3 cp命令将文件移动到新文件夹,并使其准备好接收最终报告:$aws s3 cp manifest.csv s3://devopspro-beyond/final-reports/manifest.csv -
现在我们的对象和清单已经上传,我们可以返回到 AWS 管理控制台并开始批处理任务。返回到你之前创建 IAM 角色的浏览器窗口,导航到S3 服务。
-
在左侧菜单中,点击批处理操作:
![图 4.15 – 批处理操作菜单项]()
图 4.15 – 批处理操作菜单项
-
点击右侧的橙色按钮,标签为创建任务。
-
在清单页面,选择 S3 存储桶中标记为
manifest.csv文件的单选按钮。清单的 ETag 会自动填充:![图 4.16 – S3 批处理的清单信息]()
图 4.16 – S3 批处理的清单信息
-
点击页面底部的橙色下一步按钮。
-
在操作下,选择替换所有标签旁边的单选按钮。
-
这会使另一个选项集出现。选择
TAG和Chapter4。完成后,点击橙色的下一步按钮:![图 4.17 – 添加要更改的键和值]()
图 4.17 – 添加要更改的键和值
-
对于完成报告,通过 CLI 上传
manifest文件副本后,浏览到我们之前创建的final-reports文件夹:![图 4.18 – 选择 S3 批处理报告的目的地]()
图 4.18 – 选择 S3 批处理报告的目的地
-
在权限下,选择现有的 IAM 角色,然后在下拉框中选择你在本次练习开始时创建的S3-Batch-Tagging-Role。点击页面底部的橙色下一步按钮。
-
在审查页面,滚动到底部并点击橙色的创建任务按钮。
-
一旦你创建了任务,你将被带回 S3 批处理主界面。任务创建可能需要一两分钟,但创建完成后,你可以选择左侧的单选按钮,然后点击标有运行任务的按钮。这将开始处理清单中所有文件的标签。
-
现在,我们可以返回 AWS 管理控制台并导航到我们的 S3 存储桶,查看我们的文件,看看是否已经添加了删除标签。
注意事项
在 GitHub 存储库中上传的清单包含了 S3 示例存储桶的名称。在上传和运行批处理作业之前,您需要更改清单中的存储桶名称,修改为您创建的 S3 存储桶名称。
S3 复制
即使在其高耐久性保证下,仍然有许多情况需要您制定计划以保护数据,以防出现区域性故障或数据丢失。您甚至可能希望将受访问策略限制的原始数据复制到其他地方,以便另一个团队可以访问这些数据。这时,S3 复制功能就派上用场了。它使您能够异步地将数据复制到另一个存储桶中。S3 复制有两种版本可用:
-
跨区域复制(CRR):这意味着存储桶中的对象会被复制到一个在与原始存储桶所在区域不同的区域中创建的独立存储桶中。
-
单区域复制(SRR):在 SRR 中,对象仍然会被复制到一个新的独立存储桶中,但两个存储桶都位于相同的地理区域。
S3 版本控制
在 S3 服务中,您可以使用版本控制功能跟踪文件随时间的变化。虽然该功能确实会增加额外的成本,但它在帮助恢复被删除对象时特别有用。
一旦启用版本控制,S3 存储桶中的每个对象都会获得一个版本 ID。如果您没有在存储桶上启用版本控制,那么存储桶中对象的版本 ID 将被设置为 null:

图 4.19 – 启用版本控制的 S3 存储桶,显示版本 ID
一旦您上传启用了版本控制的对象的新版本,亚马逊会为该新版本生成一个新的版本 ID,并将该新版本的对象放入存储桶中。
总结
本章我们介绍了 AWS S3 服务及其众多功能。我们不仅讲解了创建存储桶的基础知识,以及如何通过不同类型的访问策略保护存储桶,还介绍了如何使用 AWS 的不同加密方法对静态数据进行加密。我们还看到了如何通过存储桶事件触发工作流,例如启动我们的 DevOps 流水线。现在我们对对象存储有了更深入的了解,接下来我们将继续学习无服务器的 NoSQL 数据库 DynamoDB。
复习题
-
您公司有一个部门需要配置一个 S3 存储桶,该存储桶中的对象每周都会被访问,并且需要具备高耐久性和可靠性。您应该使用哪个 S3 存储类型来配置该存储桶?
-
您的组织有五个部门。其中三个部门是产品团队,一个是会计部门,另一个是人力资源部门。会计部门决定将其文件从数据中心迁移到 S3 以节省成本。如何确保只有会计部门的成员可以访问会计文件,而其他人无法访问?
-
一家医疗保健公司正在准备内部审计。他们需要确保存储在 S3 中的所有文件都已加密,并且密钥每年至少轮换一次。该公司成立已超过 15 年,并在最近 5 年内推动了大量文件转移到云上。这导致存储了超过 150 万份文件,包括账单记录、患者信息、业务信息和其他文档。最有效的持续检查方法是什么?
检查答案
-
S3 标准。
-
确保为会计部门的成员创建了一个 IAM 组。创建一个 IAM(基于用户)策略,允许会计组的成员对会计桶具有完全权限。您还可以进一步创建一个策略边界,明确拒绝其他所有组访问会计桶。
-
创建一个 S3 清单报告。使用 AWS Athena 查询未加密的文件。
第五章:Amazon DynamoDB
随着应用架构对可扩展性的需求增加,并将重点转向无服务器设计模式,开发人员开始寻找灵活、可扩展且管理开销低的数据存储。DynamoDB 已成为满足这些特性需求的一个经过验证且值得信赖的解决方案。然而,它一直在不断发展,许多从该服务衍生出来的功能在 DevOps 专业认证考试中具有重要意义。
虽然在专业级考试中,计算 DynamoDB 数据库的读写比率并不是重点,但理解该核心 AWS 服务如何融入部署和场景是非常重要的。对 DynamoDB 的功能和特性有扎实的理解,将帮助你回答考试问题,也能帮助你在职业生涯中实施解决方案。
在本章中,我们将涵盖以下主要主题:
-
理解 DynamoDB 的基础和背景
-
理解 DynamoDB 数据建模
-
在 DynamoDB 中插入和访问数据
-
理解 DynamoDB 流
-
使用 DynamoDB 加速器 (DAX)
-
在 DynamoDB 中进行身份验证和授权
-
监控 DynamoDB
理解 DynamoDB 的基础和背景
DynamoDB 是一个 NoSQL 数据库。这意味着它不仅仅是 SQL,更重要的是,DynamoDB 不需要完全结构化的模式来插入数据。它的灵活性和性能是许多人选择 DynamoDB 的原因,此外,还有其按需付费的定价模式以及高可用性和可扩展性。
DynamoDB 的起源
在 2007 年,亚马逊发布了一篇由未来 AWS 首席技术官 Werner Vogels 和其他人共同撰写的白皮书,名为 Dynamo: Amazon 的高可用键值存储。
你仍然可以在今天找到这篇论文,链接在这里:www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf。
当亚马逊构建其电商平台时,试图解决如下问题:
-
分区
-
写操作的高可用性
-
处理临时故障
-
从永久故障中恢复
-
成员资格和故障检测
当时的数据库性能不够强大,电商网站开始在数据库层面遇到瓶颈。
NoSQL 与关系型数据库
关系型数据库自 1970 年代以来就存在。当你需要强制数据完整性并使用结构化查询语言(SQL)来组织数据时,关系型数据库是非常合适的。关系型数据库的优化基于存储是你最有限的资源这一前提。一旦存储或磁盘空间用尽,你就需要购买更多的存储空间。知道这一点是使用关系型数据库时采用主键和连接的原因之一。通过使用数据的 ID,然后通过表连接检索实际需要的列,数据可以只存储一次,从而节省系统的存储空间,如下所示:

图 5.1 – 关系型数据库表
随着云存储的普及,存储及其相关成本不再是限制性因素。这就引出了 NoSQL,或称非 SQL(有时称为不仅仅是 SQL)。与其将数据存储在表中,NoSQL 系统则采用不同的方式存储数据,常见的如 DynamoDB,它将数据存储在JSON文档中。
NoSQL 数据库提供了关系型数据库无法提供的灵活性。如今的现代应用程序,如 Web 应用、游戏系统和移动应用,都需要这种灵活性,同时需要具备可扩展性,以满足用户需求,并在检索和插入数据时提供高性能。
与传统的关系型数据库不同,DynamoDB 更像一个键值存储,它在数据的检索和存储方面非常高效。
Dynamo 的核心组件
让我们来看一下 DynamoDB 的主要组成部分:
-
表及其属性
-
主键
-
次级索引
让我们开始吧。
表及其属性
DynamoDB 中的表类似于其他数据库系统中的数据库,而不仅仅是关系型数据库系统中的表。一个表是关于某一特定主题的数据集合。Dynamo 中的每个表都是单独存储项目的地方,数据就存储在这里。
每个表包含零个或多个项目。项目有不同的字段和属性。
以下是一个包含项目的 DynamoDB 表:

图 5.2 – Dynamo DB 表和项目
如果你查看上面的表格,你会看到以下几点:
-
每个项目都有一个主键。这是该项目的唯一标识符(
CarID)。 -
项目没有固定的模式。只要主键存在,其他任何属性可以存在,也可以不存在。
-
大多数属性只有一个值。然而,最后一项有一个特性字段。这是一个嵌套值,可以包含多个属性。
主键
在创建 DynamoDB 表时,必须指定主键。这个主键是每个表项的唯一标识符,这意味着没有两个项可以拥有相同的主键。
使用主键,你可以引用表中的不同项。DynamoDB 使用主键作为其内部哈希算法的数据。这个哈希值用来确定应该使用哪个分区来存储该属性。
二级索引
二级索引是可选的键,可以用来进行查询。DynamoDB 支持两种类型的二级索引:
-
全局二级索引
-
本地二级索引
我们将在本章后面深入探讨二级索引。
其他相关的 Dynamo 信息
当你开始思考你的表时,重要的是要注意,Dynamo 并不是由单一的服务器实例或机器托管的。一旦添加数据,它会分布到多个实例中,这使得 DynamoDB 可以利用其关键的扩展性和性能特点。写操作在数据被冗余存储之前不会被认为成功。
理解 DynamoDB 数据建模
如果你曾经设计过关系型数据库,那么你会熟悉诸如星型模式这样的架构。每个表都需要有一个指定的属性,如果该属性没有值,那么会保留一个空值。
DynamoDB 使用分区。这些分区可以是热分区,也可以是冷分区。
DynamoDB 中的每个项目至少需要一个属性,即分区键。Dynamo 使用该分区键对数据进行哈希并将其放置在内存中。为了在 DynamoDB 中实现最佳性能,我们需要选择一个能够使 DynamoDB 将搜索分散到磁盘上的分区键,而不是让单个分区过于热点。
这最好通过一个不好的分区键示例来演示,比如日期。如果你尝试收集所有来自同一天的数据,那么这个日期的哈希值将存储在同一个分区中。不同的日期可能会存储在不同的分区中,因为它们的哈希值不同;然而,当查询某一天发生的所有事件时,这个单一的分区将变得过热,这可能会导致性能问题。
高质量分区键的示例如下:
-
位置 ID
-
部门 ID
-
客户 ID
-
姓氏的首字母
在前面的示例中,数据在读取和写入时会分布到不同的分区,如下所示:

图 5.3 – 键均匀分布在分区中
读取和写入容量
创建表时,必须同时指定读和写容量值。一旦指定,DynamoDB 将保留处理该容量所需的资源,并将其平均分配到各个分区。
需要指定两种不同类型的容量单位:
-
读取容量单位(RCU):这是您的表每秒可以处理的强一致性读取次数。它可以包含最大 4 KB 大小的项。
-
写容量单位(WCU):这是您的表每秒可以处理的每 1 KB 单位的写入次数。
自适应容量
如果您的工作负载本质上不平衡,DynamoDB 提供了一个名为 自适应容量 的功能,帮助最大限度减少限流。这个功能的最佳之处在于,它会自动为每个 DynamoDB 表启用,无需额外费用。您无需进入设置去打开或关闭自适应容量设置。
虽然您可以为每个分区预配置 10 个 写容量单位(WCUs),但可能会有一个分区的写入操作比其他分区更多。如果表的总容量没有被超出,那么 DynamoDB 可以使用自适应容量功能,允许 热 分区继续接收写入,而不进行限流:

图 5.4 – 自适应容量示例
上图显示了一个包含 4 个分区的 DynamoDB 表的示例。创建时,我们为整个表分配了 40 个 WCS(写容量单位)。分区 2、分区 3 和 分区 4 每个只消耗了 5 个 WCUs,总共消耗了 15 个 WCUs,剩余的 25 个 WCUs 是从我们初始预配置中分配的。分区 1 则有最多的活动,消耗了 15 个 WCUs,比每个分区分配的 10 个 WCU 超出了 5 个。自适应容量功能考虑到还有额外的 WCU 容量,并在不限制表的情况下进行调整。
DynamoDB 表中可用的数据类型
DynamoDB 允许将各种类型的数据插入到属性中。
数字、字符串、布尔值、二进制数据(需要 base64 编码)和空值都是支持的属性数据类型。这些都是可以插入到属性字段中的单一值示例。
DynamoDB 还允许将一组项插入到属性中。这些集合可以包含数字、二进制数据或字符串。集合必须是相同类型的,因此不能将数字和字符串混合在一个集合中,且集合不保留顺序。
类似于文档数据库,DynamoDB 允许将 JSON 文档作为属性添加,并且这些文档可以最多嵌套 32 层。
注意
主键必须是字符串、数字或二进制。
在 DynamoDB 中插入和访问数据
现在我们已经介绍了 DynamoDB 的历史和理论,接下来是时候动手操作,真正开始处理数据了。
对于我们的示例,我们将创建一个虚构的数据库,用来跟踪我们公司中的项目。这些信息可能包括 ProjectID、项目名称、项目负责人、项目或团队的联系邮箱,甚至其他信息如构建和语言信息。由于 DynamoDB 具有灵活的模式,并非所有行都需要这些信息。然而,我们确实需要声明我们的主键,然后根据查询需求,再声明次级键。
我们的模式将如下所示 JSON:
{
Project_ID,
Department,
Owner,
< optional information (like language or build id) >,
Contact_Email
}
定义好我们的模式后,我们可以开始创建表格。
在 DynamoDB 中创建表格
现在我们可以打开终端,使用以下命令创建我们的表格:
$aws dynamodb create-table --table-name projects \
--attribute-definitions AttributeName=Project_Name,AttributeType=S \
--key-schema AttributeName=Project_Name,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
如果你将之前的命令与我们的模式进行对比,你会发现我们只定义了一个列:Project_Name。这是因为这个列是我们的哈希键(主索引)。其他字段可以稍后定义,不是必须的。这些字段将在数据插入后,无论是批量插入还是逐行插入时填充。需要注意的是,现在 Project_Name 字段中的所有字符串必须是唯一的,否则它们将因为重复值而被拒绝插入。
你可能也注意到,在语句的末尾,我们为表格最初分配了五个读取容量单位和五个写入容量单位。
向 DynamoDB 插入数据
在本书的 GitHub 目录下,在 chapter five 中,我们有几个文件需要上传到我们创建的表格中。为了这个练习,我们需要下载三个不同的 JSON 文件:
-
project_item.json -
projects.json -
projects_bulk.json
我们将通过 CLI 执行所有插入操作。虽然你可以在 Amazon 管理控制台 (AMC) 中进行单行和批量插入,但我们希望集中精力编写脚本命令,以便将来在需要时可以自动化执行。
我们将进行的第一种插入操作是将单个项目插入到表中。为此,我们需要 project_item.json 文件,如果你还没有下载该文件,请查看它的结构,如下所示,看看这个 JSON 文件的内容:
{
"Project_ID": {"N": "0100"},
"Dept": {"S": "Test Team"},
"Dept_ID": {"N": "0001"},
"Project_Name": {"S": "Serverless Forms"},
"Owner": {"S": "Jerry Imoto"},
"Builds": {"NS": ["2212121"] },
"Language": {"S": "python" },
"Contact": {"S": "test_team@testcompany.com" }
}
在上传文件之前,我们想先查看一下文件的一些标注。你会注意到每个字段前都有数据类型标注。这里我们使用了字符串类型字段,标注为 S,数值类型字段标注为 N,最后,对于我们的构建,使用 NS 来表示一个数值列表。
现在我们可以打开终端,运行以下命令将项目添加到我们之前创建的 DynamoDB 表格中。在运行以下命令之前,请确保你已导航到下载文件所在的目录:
aws dynamodb put-item \
--table-name projects \
--item file://project_item.json \
--return-consumed-capacity TOTAL
执行完上述命令后,你应该会收到类似以下内容的返回信息:
{
"ConsumedCapacity": {
"TableName": "projects",
"CapacityUnits": 1.0
}
}
恭喜!现在你在 DynamoDB 表中已经有了一个项。不过,仅有一个项对于查询来说并不理想,因此我们需要添加更多数据。通过 CLI 向表格添加多于一个项需要使用不同的命令和文件格式。
在projects.json文件中,我们提供了10项,你可以通过batch-write-item命令将它们快速添加到表中。你还会注意到,在batch-write-item命令中,与put-item命令不同,你不需要指定表格。这个信息已经在表格中指定。
扫描数据
现在我们已经将测试数据加载到表格中,我们可以使用表扫描来查看这些数据项。扫描操作将返回表格中的所有项,或者在指定的索引中返回。
如果你还没有这样做,请返回到本书的 GitHub 仓库,并下载名为scan-values.json的文件,因为我们将在下一个练习中使用这个文件。
返回到终端(如果之前关闭了,重新打开)并输入以下命令:
aws dynamodb scan \
--table-name projects \
--filter-expression "Dept = :d" \
--expression-attribute-values file://scan-values.json
我们不会显示此命令的所有输出,但需要关注的是命令底部的部分,它会显示计数(Count),即返回的行数,以及扫描计数(Scanned Count),即扫描的总行数。
注意
这是一个高消耗的操作,因为你需要读取表格中的所有数据。如果你已经知道需要的数据,最好执行查询,只返回你需要的项和记录。
什么是 DynamoDB 中的扫描?
当你在 DynamoDB 表中执行scan命令时,表格或二级索引中的每一项都会被读取。如果你没有指定任何筛选条件,那么扫描将一次性返回所有项,只要结果数据不超过 1 MB。
查询数据
如果我们只想从表中检索某些值,或者希望 DynamoDB 告诉我们符合某个条件的记录数该怎么办呢?在这种情况下,与其使用扫描,使用查询会更高效。
在我们开始查询之前,确保你已经从本书的 GitHub 仓库下载了名为query-values.json的文件,该文件位于chapter five目录下。
让我们再次打开终端,这样我们就可以执行查询并查看返回的结果:
-
首先,确保你处在下载了
query-values.json文件的同一目录下,或者将该文件复制到当前工作目录中。 -
第二,确保你已经创建了
projectsDynamoDB 表;否则,查询将不会成功。 -
在你的终端窗口中,输入以下命令:
aws dynamodb query \ --table-name projects \ --projection-expression "Dept" \ --key-condition-expression "Project_Name = :v1" \ --expression-attribute-values file://query-values.json \ --return-consumed-capacity TOTAL You should receive a result like the following one:{ "Items": [ { "Dept": { "S": "Training" } } ], "Count": 1, "ScannedCount": 1, "ConsumedCapacity": { "TableName": "projects", "CapacityUnits": 0.5 } }
请注意,在projection-expression的值中,我们标注了希望从表中返回的字段。我们已经知道了项目名称(因为它是我们的主键),所以我们是在查找这个项目所属的部门。这就是查询相比扫描所有数据在 DynamoDB 中查找和返回值时效率更高的方式之一。
DynamoDB 中的二级索引,包括全局和本地
如你所见,在我们之前的查询中,我们必须在执行命令时使用主键。在我们表的情况下,我们使用的是主键(Project_Name)。DynamoDB 中的表可以有多个不同的索引,这允许你的应用程序拥有多种不同的查询模式,而不必依赖扫描操作。这些索引可以包含表中所有数据或只是其中的一个子集。
注意
你必须在查询中声明索引,以便 DynamoDB 知道你是针对那个特定的索引执行操作。如果你没有声明特定的索引,查询将会直接作用于表本身。
本地二级索引(LSI)
本地二级索引(LSI)使你有机会更改表中最初定义的排序键。LSI 必须始终使用与其创建的表相同的主键。
LSI 也共享与创建它的表相同的吞吐量。关于 LSI 的最后一点,它们只能在表创建时进行创建。如果在创建表时没有创建 LSI,那么你需要删除并重新创建表,或者创建一个新表然后迁移数据,或者改用全局二级索引(GSI)。此外,你不能在不删除基础表的情况下删除本地二级索引。
GSI
如果我们想使用不同的主键进行搜索,那么我们必须创建一个 GSI。GSIs 和 LSIs 之间的另一个关键区别是,LSI 必须在表创建时声明和创建,而 GSI 可以在任何时间创建。如果你发现查询没有请求正确的信息,想要返回只包含部分信息的 GSI,或者某些查询需要更多的 RCU 或 WCU 配额时,GSI 尤其有用。
现在,如果我们想在创建完 GSI 后查看它,我们可以运行以下命令:
aws dynamodb describe-table \
--table-name projects \
--query "Table.GlobalSecondaryIndexes"
这将显示我们表上创建的任何 GSI(如果有的话)。
理解如何创建索引以优化查询性能是利用 DynamoDB 强大功能的关键概念之一。接下来,我们将继续了解 DynamoDB 的其他功能,例如使用流复制项目。
理解 DynamoDB 流
有时,您在 DynamoDB 中有一张表,您想要在变更发生时进行更新,或者发生事件驱动的流程。这正是 AWS 创建Dynamo Streams 的确切原因。流是项目修改的按时间顺序排列的序列,例如插入、更新和删除操作。
当 DynamoDB 中的流写入数据时,它会按严格的排序格式进行。这意味着当您向表中写入数据时,根据流的配置设置,它将按照写入到表中的顺序推送项目。
全局表
有时候,您需要在出现服务(如 DynamoDB)的区域性中断时设置高可用性计划,或者除了您最初创建数据的区域外,还需要更快的本地访问您的数据。
全局表,即使它们是原始表的副本,也都由单个账户拥有。
在设置全局表时,第一步是在您的主要区域创建一个初始表。
接着,您需要在初始表上启用 DB 流。
然后,对于您希望复制全局表的每个区域,您必须在不同的区域中设置启用流的同一表。
然后,在原始区域中,您可以定义全局表的设置,AWS 管理控制台使这一切变得轻而易举。
如果您的组织有通过服务级别协议(SLA)传达的需求,需要保持一定的运行时间,那么您可以使用流和全局表的组合来处理这些问题。接下来,我们将介绍如何通过 DynamoDB 加速器加快查询时间。
使用 DynamoDB 加速器(DAX)
即使有成千上万的请求,DynamoDB 本身也能以毫秒级的延迟响应时间提供服务。这满足了许多公司和客户的需求,但有一些应用程序需要微秒级的性能,这就是DynamoDB 加速器(DAX)的用武之地。
DAX 几乎等同于 DynamoDB 表的涡轮按钮。它缓存最常请求的结果,然后通过端点提供这些结果。无需启动第三方缓存,也无需管理节点,实现起来非常简单。您只需转到 DynamoDB 主页下的 DAX 菜单,然后启动您的 DAX 集群:

图 5.5 – DAX 示例架构
在设计和实施系统以进行数字广告竞价时,广告技术等行业可以利用 DAX 的缓存属性和速度。在竞标时的毫秒级延迟可以等同于该行业中的实际资金。
知道如何处理在 DynamoDB 中执行时间超过预期的查询,这正是我们刚刚通过 DAX 的缓存功能介绍的。现在,我们将看看如何在 DynamoDB 中授权访问。
在 DynamoDB 中进行身份验证和授权
与 AWS 中的其他服务一样,DynamoDB 通过 IAM 服务允许精细的访问控制。你可以根据你如何构建 IAM 策略,选择在服务、表或属性级别允许或拒绝用户访问。
AWS 推荐作为最佳实践,使用最小权限原则,仅允许用户访问他们需要的数据表,而不是提供通用访问权限。
Web 身份联合
DynamoDB 是一个特别受移动应用和游戏开发者欢迎的后端数据库。这可能导致成千上万的用户需要访问单一的表。在这种使用场景下,为每个用户创建一个 IAM 用户是不可行的:

图 5.6 – Web 身份联合到 DynamoDB 表
理解通过 Web 身份提供者(如 Facebook 或 Google)进行身份验证的用户如何访问 DynamoDB 表中的数据,最好的方法是查看授予授权的步骤:
-
应用程序通过如 Amazon 等 Web 身份提供者进行身份验证。身份提供者然后返回一个身份令牌。
-
然后,应用程序调用安全令牌服务,以基于之前定义的角色获取临时访问凭证。
-
该角色应当不仅仅提供对整个 DynamoDB 表的访问权限,还应通过 IAM 策略授予用户对其项目的访问权限。
由于 DynamoDB 是托管在 AWS 上的移动应用的首选数据存储,我们探讨了如何通过 IAM 和 STS 令牌的组合授权 Web 身份用户访问特定数据。接下来,我们将继续监控我们的 DynamoDB 表,以确保不会被限流所困扰。
监控 DynamoDB
当你查看在监控 DynamoDB 时需要关注哪些指标,有几个指标会特别突出:
-
我们的
GET和PUT请求在我们预期的范围内 -
我们没有受到读写容量的限制
从 DynamoDB 控制台本身,我们可以获得关于表健康状况的许多指标。
首先,我们可以一眼看到读写容量。
你选择的任何表的指标中也有一个关于基本延迟的部分,显示四个关注点:GET、PUT、查询和扫描延迟。
让我们登录到 Amazon 管理控制台,亲自查看这些基本指标:
-
使用你之前为 DynamoDB 中的项目表创建的账户登录到 Amazon 管理控制台。
-
在顶部的搜索框中,输入
DynamoDB,以便服务名称出现在搜索结果中。点击 DynamoDB 进入 DynamoDB 服务。在右上角,仔细检查你是否处于创建表的正确区域。 -
一旦您到达 DynamoDB 主屏幕,单击左侧菜单中的Tables。单击后,您应该可以看到之前创建的名为projects的表:
![图 5.7 – 显示左侧菜单中的 DynamoDB 表选项]()
图 5.7 – 显示左侧菜单中的 DynamoDB 表选项
-
单击主窗口中名为Projects的表。这将打开另一个窗格,添加更多有关您的表的信息。
-
在这里,我们可以从最右侧窗格的顶部选项卡栏中选择指标标签:
![图 5.8 – 进入 DynamoDB 表后,顶部菜单栏]()
图 5.8 – 进入 DynamoDB 表后,顶部菜单栏
-
如果在指标显示中,您没有看到太多活动,那么可以尝试运行我们在本章中先前创建的 CLI 查询。这应该会促使指标计量器开始显示更多的数据 PUT 和 GET 对象。
贡献者洞察
启用贡献者洞察,可以让您更好地了解正在访问和受限的项。这使您能够在需要时相应地调整表或模式。
一旦启用贡献者洞察,如果您只有主键,DynamoDB 会为您创建两个规则:
-
最常访问的项(分区键)
-
最多受限的键(分区键)
如果您有全局二级索引或排序键,DynamoDB 将为您创建两个附加规则。这些规则是针对二级索引的:
-
最多访问的键(分区键和排序键)
-
最多受限的键(分区键和排序键)
总结
在本章中,我们了解了被称为 DynamoDB 的 NoSQL 服务。我们探讨了如何创建和分区表,以及如何从 DynamoDB 写入和查询数据。我们还研究了如何将数据从表流向其他源,并使用DynamoDB 加速器(DAX),一种专门的缓存,来加速查询。
我们现在已经完成了第一部分,建立基础,在这一部分中,我们回顾了亚马逊 Web 服务。接下来,我们将进入第二部分,开发、部署和使用基础设施即代码。在接下来的章节中,我们将整合我们刚才讨论的许多服务,并将它们付诸实践。
复习问题
-
我们的应用程序正在将项目数据存储在 DynamoDB 表中。您需要运行查询,找出上个月由特定部门执行的所有构建。您会在查询中使用哪些属性?
a.
Build_Date的分区键和Department的排序键b. 由
Department和Build_Date组成的复合主键c.
Department的分区键和Build_Date的排序键d.
Build_Date的分区键和Dept_ID的排序键 -
以下哪项 AWS 服务提供了一个针对 DynamoDB 优化的内存写通缓存?
a. ElastiCache
b. CloudFront
c. DAX
d. Athena
-
DynamoDB 中的扫描操作适用于以下哪种场景?
a. 返回表的所有内容,并根据主键或排序键进行过滤
b. 基于主键属性在表中查找项
c. 基于排序键属性在表中查找项
d. 返回表中的所有项
-
您的开发人员创建了一个 DynamoDB 表,并发现他们的性能总是在测试过程的 20-25 分钟后变慢。通过 AWS 控制台的基本监控,他们看到请求被限制。您可以做什么来帮助找出问题的根本原因?
a. 增加表上的读取容量单位(RCUs),以使查询不再受限制。
b. 在表上启用Contributor Insights,以便显示被限制最多的键。
c. 添加增强的Cloud Watch监控,并在发生限制时触发警报。
d. 向表中添加自适应容量,使额外的读取容量单位(RCUs)均匀分布到变热的分区中。
-
以下哪一项适合作为分区键?
a.OrderIDb.Ship_From_Locationc.Totald.Product_Brand
查看答案
-
b
-
c
-
d
-
b
-
a
第二部分:开发、部署和使用基础设施即代码
在本部分中,我们将应用自动化 CI/CD 流水线所需的概念。你将学习如何进行测试、管理工件以及部署/交付策略。
本书的这一部分包括以下章节:
-
第六章,理解 CI/CD 和 SDLC
-
第七章,使用 CloudFormation 模板部署工作负载
-
第八章,使用 CodeCommit 和 CodeBuild 创建工作负载
-
第九章,使用 CodeDeploy 和 CodePipeline 部署工作负载
-
第十章,使用 AWS Opsworks 管理和部署你的应用栈
-
第十一章,使用 Elastic Beanstalk 部署你的应用
-
第十二章,Lambda 部署与版本控制
-
第十三章,蓝绿部署
第六章:理解 CI/CD 和 SDLC
软件开发生命周期(SDLC)是考试中最重的部分。理解 SDLC 的概念,以及 持续集成(CI)和 持续部署(CD)是通过 亚马逊 Web 服务(AWS) 开发运维(DevOps)考试的关键。SDLC 包括多个阶段,AWS 和第三方服务与这些阶段相对应。
了解 AWS 服务所扮演的角色—以及关键的第三方工具—不仅对通过考试至关重要,也是作为 DevOps 工程师日常工作中的必备知识。
在本章中,我们将讨论以下主要内容:
-
SDLC 介绍
-
开发团队
-
了解不同类型的部署
SDLC 介绍
SDLC 包括以下六个基本周期或阶段:
-
源代码
-
构建
-
测试
-
部署(发布)
-
监控
-
计划
以下是这些阶段的示意图:

图 6.1 – CI/CD 阶段
这四个阶段属于 DevOps 的开发侧。第五个阶段属于运维侧,最后一个阶段是团队合作完成的。你可能注意到,前面的示意图中没有规划阶段。再次强调,虽然规划阶段是 SDLC 的重要部分,但它不属于 CI 或 CD 流程的一部分。
在本节的讨论中,我们需要理解的一个重要概念是缩写 CI/CD 的使用。我们在讨论 CI 阶段时,实际上是在谈论管道的前三个步骤。
CI
CI 是一种软件开发实践,开发人员定期将代码更改合并到中央仓库中。然后,启动一个或多个自动化构建,并对已提交的代码以及之前的现有代码库运行测试。
AWS 原生 CI 工具
接下来,我们将看看 AWS 在其生态系统中提供的一些工具,以帮助实现 CI。
AWS CodeCommit
AWS CodeCommit 允许你以高度可扩展的方式托管私有源代码控制仓库。
以下是 CodeCommit 的主要优势:
-
协作能力:软件团队可以使用已知的 Git 功能,如拉取请求、分支和合并,共同协作开发代码库。
-
加密:CodeCommit 仓库使用 AWS 密钥管理服务(KMS)在静态时自动加密。代码在往返仓库的传输过程中,也会通过 安全超文本传输协议(HTTPS)或 安全外壳协议(SSH)加密。
-
访问控制:与 AWS 身份与访问管理(IAM)服务完全集成,允许你指定哪些用户可以访问哪些仓库,而无需通过第三方系统进行管理。
-
高可用性:AWS CodeCommit 由亚马逊简单存储服务(Amazon S3)和亚马逊 DynamoDB支持,用于代码和提交存储。这是一种高度冗余且可扩展的设置,确保你的仓库可访问。
-
通知:CodeCommit 可以与亚马逊简单通知服务(Amazon SNS)集成,使得与仓库相关的重要事件可以广播到正确的渠道。CodeCommit 发送的通知包括状态信息和指向相应仓库的链接。
AWS CodeBuild
当你准备编译你在源代码控制仓库中提交的代码并为部署创建软件包时,AWS CodeBuild 允许团队使用 YAML Ain't Markup Language(YAML)语言自定义他们的构建和测试过程。
这些是 AWS CodeBuild 的主要优点:
-
完全托管:使用 CodeBuild,无需设置单独的构建服务器。这意味着不再需要进行软件修补或更新,也无需管理任何东西。作业设置好并提交后,便会运行。
-
安全:CodeBuild 与 IAM 服务集成,因此用户只能被分配到特定的构建项目。CodeBuild 生成的任何工件都使用 AWS KMS 进行加密。
-
可扩展:CodeBuild 会根据提交的作业数量自动进行扩展。当有大量构建作业或测试即将发生时,无需考虑垂直或水平扩展,因为 CodeBuild 会自动处理所有这些。
-
支持 CI 和 CD:作为AWS 开发者服务的一部分,CodeBuild 自然地集成到其他提供的 CI/CD 工具中,例如 CodeCommit 和 CodePipeline。它还与生态系统中的其他工具进行了集成——例如,Jenkins 可以将 CodeBuild 作为可扩展的工作节点使用。
AWS CodeArtifact
随着软件构建变得越来越规范化,公司和团队开始寻找一种方式,确保每个人都在使用相同的已批准的软件包及其版本。这就是托管工件库CodeArtifact的作用所在。
如果你对构建过程的安全性感兴趣,CodeArtifact 提供了许多功能,帮助开发团队创建一个更安全的环境。首先,构建过程中所需的包和工件可以通过使用 AWS PrivateLink 终端节点从虚拟私有云(VPC)中访问。这意味着,如果你在 CodeArtifact 服务中存储了构建所需的库和文件,那么这些文件可以传输到你的函数和实例中,而无需穿越公共互联网。
其次,通过 CodeArtifact 服务,作为账户管理员的你可以批准使用特定的包。这个批准过程也可以通过结合使用 CodeArtifact 应用程序编程接口(API)和 Amazon EventBridge 服务来自动化。
第三,许多包仓库最近开始对其服务器设置下载限制。由于仓库当前不接受来自当前互联网协议(IP)地址的下载请求而导致部署或构建失败,不仅令人沮丧——它还可能成为部署的真正障碍。例如,如果你是在实时构建实例,而不是使用预先构建的Amazon 机器镜像(AMI),并且需要从公共Node Package Manager(npm)服务器获取某些节点包,那么如果你处于自动扩展状态并且试图扩大规模以满足客户的流量需求,这种情况就不仅仅是个小问题。然而,如果你将包存储在 AWS CodeArtifact 上,那么你就不受任何第三方服务器的限制,可以根据需要多次下载所需的包,正如下图所示:

图 6.2 – AWS CodeArtifact 与外部仓库的连接
你可以配置 CodeArtifact 从公共仓库获取流行的包,并为你的团队进行存储和版本控制。CodeArtifact 可以与许多开发者熟悉并且舒适使用的包管理工具协同工作,包括pip、yarn、npm、Maven和Gradle。
这些是 CodeArtifact 的主要优点:
-
安全存储和共享制品:如果与 KMS 服务集成,你在 CodeArtifact 中存储的制品可以被加密。
-
减少运营开销:CodeArtifact 消除了设置和维护制品服务器的需求。它是一个高度可用的服务,可以根据存储的制品数量自动扩展。
-
发布和共享包:CodeArtifact 为你提供了一个中心位置来发布你的团队创建的包,消除了在互联网上到处寻找的需求。
-
只需点击几下,便可连接
npm注册表、NuGet.org和Maven Central,无需复杂的脚本。
持续交付
如果生产环境的部署是通过持续交付完成的,那么很可能会有一个手动批准的过程,而不是自动部署。
AWS 原生工具用于持续交付
让我们简要了解一些用于持续交付的 AWS 工具。
AWS CodeDeploy
这些是 CodeDeploy 的主要优点:
-
自动化部署:CodeDeploy 完全自动化软件部署。
-
易于采用:CodeDeploy 可以轻松集成到你现有的部署工具中,如 Jenkins、GitHub 或 AWS CodePipeline。
-
集中控制:在一个视图中,CodeDeploy 可以同时显示你的部署状态,并提供向一个或多个团队成员发送推送通知的功能,告知他们构建的通过或失败状态。
-
最小化停机时间:CodeDeploy 允许你逐步引入更改,从而帮助保持应用程序的可用性。如果发现问题,它还可以帮助你回滚到之前的版本。
AWS CodePipeline
AWS CodePipeline 允许你自动化构建、测试和部署步骤,以及你在生产软件和 基础设施即代码(IaC)过程中经过的各个阶段。它还可以与 GitHub 等第三方服务集成。
这些是 CodePipeline 的主要优势:
-
快速交付:CodePipeline 在你将代码通过结构化流程推进到部署过程中,快速地向你和你的团队提供反馈。缺陷可以在没有太多努力的情况下被发现并修复。
-
易于集成:如果你已经在 CI/CD 流程中使用了现有的组件,CodePipeline 允许你轻松集成这些组件。包括已经设置好在云端或本地运行测试的 Jenkins 服务器,或者甚至是像 GitHub 这样的第三方源代码库。
-
可配置工作流:每个软件发布的过程都有些微不同,取决于配置的测试或所部署的服务。CodePipeline 使你能够以多种方式自定义步骤,包括使用 AWS 管理控制台 界面、命令行界面(CLI)或可用的 AWS 软件开发工具包(SDKs),甚至可以通过编写 CloudFormation 模板 来构建管道。
-
提高质量:CodePipeline 使你能够自动化所有流程,按照易于遵循的步骤执行,从而确保在部署过程中不会遗漏任何步骤。自动运行的测试确保了代码的一致性,并为开发者提供即时反馈。
CD
使用 CD,不需要手动批准流程,因为代码修订会被推送到生产环境中。相反,依赖于测试实践和指南来确保代码的完整性,在被自动部署到生产环境之前,必须通过质量检查。任何不符合这些指南的修订将会作为构建过程失败,并且会将反馈提供给开发者或开发团队。最初的反馈可能非常简单,比如通知构建失败,可以通过电子邮件或 短消息服务(SMS)消息的形式发送,甚至可以使用 SNS 服务 发送。另一种选择是通过 Slack 或 Microsoft Teams 等消息服务发布,结合使用 SNS 和 AWS Lambda 来发布消息。
注意
持续交付并不是CD。这是许多人常犯的错误。然而,你需要理解的是,持续交付意味着每次提交都必须通过一组自动化测试,然后才会推送到生产环境中。
让我们看看 SDLC 如何在 AWS 提供的不同开发工具中得以实现。从以下图示中,你可以看到几乎每个阶段都有自己的专用服务。例外的是构建和测试阶段,AWS CodeBuild 可以同时执行这两项任务:


图 6.3 – AWS 工具在 CI/CD 中的应用
从Amazon 代码工具的角度来看,CI 和持续交付有几个工具可以帮助你完成这些任务。
测试
测试在软件开发生命周期(SDLC)中起着至关重要的作用。它可以帮助你提升应用程序的可靠性、可扩展性、性能和安全性。
注意
你有没有注意到测试所提供的许多内容正是 AWS 的支柱?尽管将测试排除在最初的管道设计之外看似更快,但它是确保工作负载稳定性、安全性和能力的关键部分。
如果你的代码中存在潜在的弱点,测试是发现其中许多问题的途径之一。这可以防止你将致命缺陷部署到生产环境中。作为一名 DevOps 工程师,在自动化这个过程时,构建管道的初期投入可能会有些费力。一旦管道和测试建立完成,随后多种类型的代码——包括基础设施即代码(IaC)和应用程序代码——都可以以快速和可重复的方式进行测试和部署。
相关测试类型
有多种不同类型的测试可以确保你的代码库按预期运行。每种类型的测试执行特定任务,有些测试需要的时间较长。以下是一个展示不同测试阶段的图示:


图 6.4 – 测试的不同阶段
通过查看图 6.4,我们可以看到测试执行的相对速度。现在我们可以更详细地查看每种测试类型。
单元测试
单元测试虽然覆盖的代码量较小,但为开发者提供即时反馈,尤其是因为它们可以直接在开发者的个人机器上运行。它们可以添加到 CI/CD 管道中,主动防止已知缺陷进入代码库。
服务集成和组件测试
集成测试用于检查系统中不同组件是否能够协同工作。这些测试也可以包括对任何第三方服务或 API 的测试。例如,集成测试可能会测试 Web 层是否将一个测试值插入数据库以确保连接正常,或在事件发生后发送通知。
性能和合规性测试
一旦你构建了应用程序,你需要知道它能够有效地处理你预计的流量。这包括根据需要扩展或缩减资源,并在系统承受较大负载时进行检查。性能测试将帮助完成这项任务,揭示系统在正常使用或高负载情况下可能表现出的性能问题或瓶颈。两种最常见的性能测试类型是压力测试和浸泡测试。压力测试会在短时间内或设定的例程数量内模拟大量用户使用资源,比如回放 web 服务器日志以模拟过去的用户。浸泡测试则会在更长时间内(如一周或更长)持续提供稳定的用户流,尝试揭示如内存泄漏或在短时间内未能显示的问题。
添加安全性和合规性测试,如静态应用安全测试(SAST)和动态应用安全测试(DAST),可以揭示已报告和发现的已知漏洞。将这些类型的测试添加到你的 CI/CD 管道中,是开发-安全-运维(DevSecOps)框架的一部分。
用户界面测试
在金字塔的顶端是用户界面(UI)测试。这些测试不仅测试图形用户界面(GUI),还测试整个系统。测试可以涵盖像确保用户能够正确登录或重置密码的例程。它们可能包括上传和下载文件或访问特定页面,这些页面涉及数据存储和中间件组件。
虽然在这个阶段可能出于必要性引入手动测试,但最好将手动测试保持在最低限度。
在整个过程中不断成熟
当你最初开始构建 CI 系统时,可能只有几个步骤,比如从源代码仓库拉取代码并部署到测试服务器。
随着时间的推移,代码库将获得更广泛的测试覆盖,设置也将调整,以便团队成员对部署过程更加自信,甚至依赖它作为日常工具之一。
随着你的成熟,你会发现自己开始获得以下几个好处:
-
速度:团队通过自动化管道和发布过程变得更加自给自足。无需再等待特定人员或团队来安装已开发的软件包或更新。
-
可靠性:自动化过程消除了对单个了解流程的人的依赖。任何启动过程的团队成员都会有信心每次启动时都能得到相同的结果。
-
一致性:创建具有标准步骤的部署管道可以使每次启动过程时都保持一致的流程。这可以防止测试等步骤被遗忘或跳过。
-
可扩展性:随着组织的扩展,更新的频率通常会增加。自动化流水线拥有构建、测试和部署到不同环境的步骤,帮助你在不增加额外人员的情况下实现扩展。
-
效率:将测试从手动过程转移到自动化过程,不仅可以加速测试过程,还可以使测试团队将精力集中在开发新的和改进的测试上,而不是花时间手动测试系统。
现在我们已经了解了实际的 SDLC 过程,接下来我们将讨论如何优化 CI/CD 过程中的团队设置。
开发团队
AWS 建议在实现 CI/CD 环境时,拥有三个开发团队:应用团队、基础设施团队和工具团队。亚马逊推崇“两块披萨团队”的概念,即任何团队的规模都不应超过两块披萨能够喂饱的程度。较小的团队有助于更好的协作,完全拥有自己的特性或应用程序,承担完整的责任,最后但同样重要的是,这一切与 DevOps 的敏捷模型一致。
应用团队
应用团队成员负责创建应用程序本身。该团队的成员精通一种或多种编程语言,并且深入理解平台和系统配置。
应用团队成员负责创建待处理的事项清单,以及为工作中的故事创建任务。除了具备创建和维护应用程序的编程技能外,该团队还应该掌握自动化技术,以便在工具链创建完成后,团队成员可以创建自己部分的流水线。
基础设施团队
为了使应用团队成员能够运行他们的应用程序,必须有一些基础设施来支持它们的运行。即便是无服务器应用,它仍然需要在 IAM 中创建权限。如果不是无服务器设置,则需要配置和管理服务器。
与基础设施团队合作,这一过程通过 IaC(基础设施即代码)完成,可以通过 CloudFormation,使用 AWS CLI 脚本,或使用 AWS 的云开发工具包(CDK)。
许多时候,工具团队还需要负责例如Active Directory(AD)服务器和单点登录(SSO)集成等任务,特别是因为它们与 IAM 权限紧密相连。
工具团队
工具团队负责构建和管理 CI/CD 流水线。该团队必须熟练构建和集成流水线的各个部分和组件,以确保依赖的应用团队能够顺利进行工作。虽然工具团队不是“两块披萨团队”的一部分,但它负责创建使其他团队能够执行任务的工具和系统。
团队可能会选择实现诸如 AWS CodeCommit、CodePipeline、CodeBuild 和 CodeDeploy 等工具和服务,以及 Jenkins、GitHub、Bitbucket、Artifactory 等第三方工具。
许多组织会将工具团队归类为 DevOps 团队,但这是一个误称,因为 DevOps 更多的是一种人和过程的实践,而不是单纯的工具使用。
并非每个工具团队都已经准备好完全采用 AWS 工具集,AWS 也理解这一点。甚至有一份关于自动化服务器 Jenkins 的完整白皮书。了解第三方工具如何与 AWS 生态系统交互并互补,是 DevOps 专业考试的必备知识。
随着团队成员现在可以集中精力在各自的领域中,以最大化其效率,我们将继续讨论部署类型,并了解如何选择最适合我们需求的部署策略。
了解不同类型的部署
当你考虑部署时,尤其是我们一直在讨论的软件开发生命周期(SDLC),你可能会认为我们在讨论应用程序代码。然而,当你在 AWS 中自动化更多系统时,部署可能会有多种含义。部署可以指应用程序代码,但也可以指基础设施代码、配置代码或其他层级。
在处理 AWS 上的部署时,有五种主要的部署策略需要考虑。每种方法都有其优缺点。
在选择部署策略时,以下是你需要考虑的主要事项:
-
你能多快完成部署?
-
是否需要任何域名系统(DNS)的更改?
-
如果部署失败,会有什么影响吗?
-
回滚过程将是什么样的?
-
代码会链接到哪里?(新实例还是现有实例?)
考虑到这一点,让我们深入研究五种不同的部署策略。
就地部署
当你执行就地部署时,你是在更新已经部署到环境中的实例。可以使用负载均衡器在部署过程中注销每个实例,进行健康检查,然后将健康的实例重新投入服务。就地部署可以一次性完成,也可以以滚动部署的方式进行。
让我们来看一下就地部署的优缺点,如下所示:

表 6.1 – 就地部署的优缺点
不可变部署和蓝绿部署
在蓝绿部署中,会创建一个全新的基础设施,并且通常在进行 DNS 切换之前进行测试。这是最安全的部署方法,但它需要时间并且成本最高,因为你需要为一段时间同时搭建两个完整的环境,直到进行 DNS 切换。切换后,你可以选择在第二个环境不再使用时将其关闭以节省成本,或者将其保持运行以节省部署时间,并将其用作故障转移环境。如果部署失败,客户将完全感知不到任何问题,因为使用蓝绿部署时,只有当第二个(或绿色)环境上线并健康时,才会切换 DNS。
不可变部署指的是使用新的配置或新应用程序代码部署整个资源集。这项任务在云端比在本地硬件上简单得多,因为资源可以通过简单的 API 调用进行配置。
以下表格显示了不可变部署的优缺点:

表 6.2 – 蓝绿部署的优缺点
参见第十三章,蓝绿部署,深入了解蓝绿部署的更多内容。
金丝雀部署
在新的实例规范名称(CNAMEs)上为 0%,或者通过将新实例从负载均衡器中移除来实现。此时,新实例将被下线,任何先前更新过的启动配置都可以更新为使用一个之前工作的 AMI 版本。
在下表中,我们对比了使用金丝雀部署方法的优缺点:

表 6.3 – 金丝雀部署的优缺点
滚动部署
使用滚动部署时,并非所有实例都会同时更新。这一策略可以防止停机,因为如果某个进程失败,只有部分实例会在某个特定时间进行升级。当初始实例部署时,它们必须在进一步部署其他实例之前确保健康并在线。
需要注意的是,由于无论是应用程序代码还是系统升级,组内的所有成员并非同时部署,因此用户可能会体验到多个版本。在部署过程中,使用粘性会话有助于提供尽可能无缝的客户体验,但无法完全消除这种体验的差异。
尽管优缺点列表不长,但请看下表,了解使用滚动部署方法的利弊:

表 6.4 – 滚动部署的优缺点
线性部署
在线性部署中,流量会按照预设的多个增量平等地切换到不同的资源上。线性部署是蓝绿部署的一种子集。与直接部署到应用当前运行的实例或资源不同,你首先需要搭建一套新的基础设施,然后在一段时间内将流量从旧的代码库迁移到新的代码库,可以使用如 Route 53 和加权路由这样的服务。这样,你可以密切监控新环境,如果出现问题,能够迅速将所有流量切换回原始环境,从而避免停机。
线性部署还可以通过 Lambda 别名和 Fargate 容器来实现,将部分流量切换到新版本的代码。
例如,如果你的部署窗口是 1 小时,并且希望在该小时内将 100% 的流量平均分配到新资源上,那么你的线性部署策略可能如下:
-
最少 0-16% 的流量切换到新资源
-
最少 10-32% 的流量切换到新资源
-
最少 20-48% 的流量切换到新资源
-
最少 30-64% 的流量切换到新资源
-
最少 40-80% 的流量切换到新资源
-
最少 50-96% 的流量切换到新资源
-
最少 60-100% 的流量切换到新资源
使用线性部署方法有优缺点,因此我们在此进行比较:

表 6.5 – 线性部署的优缺点
我们将在 第十二章 中深入探讨 Lambda,Lambda 部署与版本管理。
一次性全部部署
在这种部署方式中,所有流量会同时从原始环境切换到新环境。这是所有部署方法中最快的。这也意味着,如果需要回滚,所需的时间将是最长的,因为代码需要重新部署到所有实例上。如果遇到问题,你可能会有停机时间,因为你需要等待回滚过程完成后才能恢复在线状态。
使用 一次性全部部署方法 的优缺点在下表中列出:

表 6.6 – 一次性全部部署的优缺点
注意
一次性全部部署也可以称为就地部署。请熟悉这两个术语,因为它们都可能出现在测试题中。
复习问题
-
一家中型软件公司聘请你作为 DevOps 顾问,帮助搭建其部署流水线。员工希望能够快速将经过测试的代码推送到生产环境,但又不想面临客户停机的风险。他们的 DNS 托管在第三方服务商上,DNS 的变更需要提交变更工单。你会推荐哪种部署方式?
a. 蓝绿部署
b. 原地部署
c. 一次性部署
d. 滚动部署
-
一家医疗设备公司希望通过 Jenkins 设置其开发流水线,以自动化部署代码库。由于这只是开发环境,他们希望保持成本最低,并且如果部署失败,应用团队重新部署也是可以接受的。应该使用哪种策略?
a. 蓝绿部署
b. 原地部署
c. 一次性部署
d. 滚动部署
-
一家移动游戏公司正在努力加快其最受欢迎游戏的生产时间,以便开发新的功能。员工注意到,在最近两次发布的日期,用户在社交媒体上抱怨出现了更多的故障。有些故障是已知的,由负责游戏开发的团队处理。该游戏公司已经设置了一个自动化部署流水线,使用 AWS CodePipeline,并将代码存储在 AWS CodeCommit 中。最具成本效益的方式是什么,以减少每次发布时出现的故障数量?
a. 启动一个新环境,并在将代码发布到生产环境之前运行完整的 UI 测试。
b. 在当前的 CodePipeline 中添加一个步骤,启动一个运行 Jenkins 软件的 EC2 实例,并使用 Simple Systems Manager (SSM) Parameter Store 下载当前的 CodeCommit 仓库,然后运行单元测试来判断构建是否通过。
c. 在当前的 AWS 流水线中添加一个 CodeDeploy 步骤,该步骤运行当前的一组单元测试,并将其连接到 AWS SNS 主题,以便在测试失败时,当前构建失败,并通知开发团队。
d. 在当前的 AWS 流水线中添加一个 CodeBuild 步骤,该步骤运行当前的一组单元测试,并将其连接到 AWS SNS 主题,以便在测试失败时,当前构建失败,并通知开发团队。
-
一家研究公司正在进行一个机密项目,管理团队希望能够在任何进展发生时立即了解情况。开发人员使用 AWS CodeCommit 进行源代码版本控制,并使用 CodeBuild 运行单元测试。你可以采取哪些措施来让管理团队获得他们想要的更新?(选择所有适用项)
a. 为管理团队创建一个 SNS 主题,并添加他们所有的电子邮件。
b. 让 AWS CodeCommit 在每次提交或功能分支与主分支合并时,将通知推送到 SNS 主题。
c. 让 CodeCommit 创建每日提交活动报告,并将报告推送到 S3,以便管理团队可以从他们有权限访问的存储桶中查看该报告。
d. 在 AWS CodeBuild 上启用通知,当作业通过或失败时,通知推送到 SNS 主题。
-
一家正在成长的公司目前有一个在 EC2 上运行的 Jenkins 服务器。开发人员抱怨他们等待构建启动和完成的时间太长。你被要求帮助工具团队提出一个能够随着开发团队的增长和速度扩展,但又能以最快和最具成本效益的方式实施的解决方案。哪种解决方案最不需要工具团队的管理?
a. 从 Jenkins 服务器创建一个 AMI,并使用该 AMI 创建三个额外的工作节点,当前的 Jenkins 系统作为主节点。
b. 使用
1将 Jenkins 服务器重建为一个容器化系统。d. 从 Jenkins 服务器创建一个 AMI,并使用该 AMI 创建一个启动配置,用于自动扩展组,当队列超过
1时启动新的 Jenkins 实例。
回顾答案
-
d
-
b
-
d
-
a, b, d
-
c
总结
在本章中,我们讨论了SDLC、CI、持续交付和CD。我们还开始了解 AWS 提供的工具,这些工具可以帮助我们在 SDLC 的不同阶段中发挥作用。接着,我们探讨了不同类型的团队及其职责。最后,我们回顾了 AWS 中可用的不同类型的部署策略,以及如何最佳地使用它们。
在下一章中,我们将深入探讨 AWS 的 CloudFormation 基础设施即代码(IaC)服务。我们将看到如何创建可重用的资源,以及在 CloudFormation 模板中可用的脚本方法。
第七章:使用 CloudFormation 模板部署工作负载
CloudFormation 模板为 DevOps 工程师提供了一种简单的方法,能够自动创建、管理和配置相关资源。它们还允许你快速地重复搭建相同的基础设施,无论是用于开发、测试、生产还是灾难恢复。它们不仅是一个重要的概念,也是 DevOps 专业认证考试中需要理解的内容。
在本章中,我们将涵盖以下主要主题:
-
CloudFormation 的基本主题
-
创建带有依赖关系的嵌套堆栈
-
向 CloudFormation 模板添加辅助脚本
-
了解如何检测以前创建的堆栈中的漂移
-
使用 Cloud Development Kit(CDK)作为开源框架
技术要求
在处理 CloudFormation 模板时,本章比前几章更加注重实践,而前几章更多关注理论。你应该对 YAML 语法感到熟悉,并且此时你应该对 AWS 管理控制台以及 CLI 都有一定的了解。本章讨论的大多数模板由于过于庞大,无法在接下来的页面上完全列出,因为一些 CloudFormation 模板可能会有几千行。我们已经将这里讨论的模板包含在本书的 GitHub 仓库中的 Chapter-7 部分:github.com/PacktPublishing/AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/tree/main/Chapter-7。
CloudFormation 的基本主题
在我们希望构建可重复的基础设施并通过自动化实现的过程中,拥有正确的 基础设施即代码(IaC)工具,可以实现这些可重复的流程。正是这些可重复的流程使 CloudFormation 服务发挥作用。CloudFormation 是一种 IaC,可以检查到源代码管理系统,如 CodeCommit 或 GitHub。它作为一段代码的特点,使得它可以进行版本控制,并且可以与多个团队成员协作。它也可以作为 CI/CD 过程的一部分,添加到自动化构建管道中。
CloudFormation 模板可以使用 JSON 或 YAML 编程语言构建。使用 YAML 允许在模板中添加注释并使用简短的代码。然而,你确实需要遵循严格的 YAML 格式化规则。
一旦你创建了一个模板,特别是一个包含正确映射且没有硬编码引用的模板,它就具备了反复使用的能力。这意味着你可以在多个区域和多个账户中使用它。
CloudFormation 模板的结构
一个 CloudFormation 模板可以包含许多不同的部分。在创建 CloudFormation 模板时,只有一个强制性的部分,那就是资源部分。部分不一定需要按照特定顺序添加;然而,当你查看不同的示例时,会发现部分的结构有一个逻辑顺序,因为某些部分引用了其他部分。
格式版本
这是 CloudFormation 遵循的版本。它是一个可选部分。如果添加,通常是模板的第一个部分。
描述
描述是一个小段文本,告诉用户有关模板的信息。它必须始终位于模板的格式版本之后。描述非常有用,尤其是当你开始收集更多的模板时,它能帮助你快速了解模板的目的以及它将创建哪些类型的资源。这是一个可选部分。
元数据
该部分包含提供有关模板的附加信息的对象。这是一个可选部分。
参数
这是一个值的部分,可以在运行时传递到模板中。默认值也可以定义,以替代需要用户输入的值。这些值在创建资源时可以使用。你也可以引用模板中的资源和输出部分的参数。这是一个可选部分。
规则
规则用于验证在运行时传递到模板的一个或多个参数。规则可以帮助强制执行一些要求,比如确保在生产环境中启动一个足够大的 EC2 实例,或者使用特定的子网。规则通常用于验证参数的输入。这是一个可选部分。
映射
使用内建的 Fn:FindInMap 函数,CloudFormation 可以找到与匹配值对应的键。映射部分最常见的使用场景之一是声明特定区域使用的正确Amazon 机器映像(AMI),确保模板可以在多个区域中重用。这是一个可选部分。
当我们查看内建的 Fn:FindInMap 函数时,我们将深入了解映射。
条件
尽管 CloudFormation 模板没有很多可用的逻辑编程,但模板中的条件允许基于某些值的存在,分配特定值或创建特定资源。一个好的例子是,如果堆栈在测试环境中创建,那么它会创建一个数据库。然而,如果在生产环境中创建,它就不会创建。这是一个可选部分。
资源
本部分实际上声明了将由 CloudFormation 模板创建的资源及其属性。资源可以是各种各样的 AWS 服务,从 EC2 实例到 IAM 用户,甚至是聊天机器人和Step Functions。AWS 提供的几乎所有服务都可以通过 CloudFormation 模板创建。这个部分是必需的。
输出
输出允许声明一个键值对及其对应的描述,该描述可以在堆栈创建完成后供最终用户使用,或者供另一个堆栈使用。在最终用户的情况下,你可能想要输出刚刚启动的 EC2 实例的 URL 或 IP,以便你不需要在控制台中四处寻找。或者,在为其他堆栈创建输出供其使用时,Amazon 资源名称(ARNs)是可以在其他堆栈中作为参考点使用的主要项之一。这是一个可选部分。
启动 CloudFormation 模板
一旦你准备好了模板,就可以通过 AWS 管理控制台或SQSqueues.yml来启动它。如果你想跟随以下练习,请去仓库并下载这个模板。或者,你可以使用你自己的 CloudFormation 模板,但要记住,参数和资源会有所不同,尽管过程仍然遵循相同的步骤:
-
将下载的模板上传到你的 S3 存储桶,我们在第四章中创建了该存储桶,Amazon S3 Blob 存储。(在我们的例子中,存储桶的名称是
devopspro-beyond):$aws s3 cp sqs-queues.yml s3://devopspro-beyond/sqs-queues.yml -
现在模板已上传,登录到 AWS 管理控制台并导航到 CloudFormation 服务页面:
us-east-2.console.aws.amazon.com/cloudformation/。 -
点击右侧标有创建堆栈的橙色按钮。
-
在前提条件 – 准备模板下,确保已选择模板已准备好选项的单选按钮:
![图 7.1 – CloudFormation 前提条件]()
图 7.1 – CloudFormation 前提条件
-
在指定模板下,确保已选择Amazon S3 URL选项,然后在 URL 字段中输入模板所在位置的值,在我们的例子中是
devopspro-beyond.s3.us-east-2.amazonaws.com/sqs-queues.yml:![图 7.2 – CloudFormation 指定模板屏幕]()
图 7.2 – CloudFormation 指定模板屏幕
-
点击页面底部的橙色下一步按钮。
-
我们现在需要填写一些细节,才能继续操作。我们从
SQSqueue开始(不允许有空格)。 -
接下来,填写其余的参数,为AlarmEmail字段添加你的地址,为QueueName字段添加队列的名称。你可以将另外两个值保持为默认值。完成后,点击页面底部的橙色下一步按钮:
![图 7.3 – 输入模板的参数]()
图 7.3 – 输入模板的参数
-
在下一页,标记为配置堆栈选项,向下滚动到页面底部并点击橙色的下一步按钮。
-
我们现在可以查看我们输入的内容,如果一切看起来正确,向下滚动到页面底部并点击橙色按钮,标签为创建堆栈。
一旦我们开始创建过程,我们将被带到Stacks屏幕,在那里我们可以看到CREATE_IN_PROGRESS通知,表示我们的堆栈正在创建中。
在这一部分的顶部有一个菜单,允许你查看每个堆栈创建的具体资源、堆栈的具体信息、堆栈创建后你声明的任何输出、创建堆栈时输入的参数、用于创建堆栈的实际模板以及在堆栈上使用的变更集。
当你启动一个 CloudFormation 模板时,该模板会保存在一个 S3 桶中。如果你之前没有将模板保存到 S3 桶中,AWS 会在你启动模板的区域创建一个 S3 桶。每次你更新模板或启动新版本时,模板的一个新副本会被添加到这个桶中。
使用 CLI 启动模板
在通过管理控制台启动模板的所有步骤之后,我们可以看到,如果我们打算将部署自动化为 CI/CD 流水线的一部分,那么每次都这样做显然是不实际的。AWS CLI 确实有一个deploy命令,它允许我们通过一条命令启动一个堆栈。在运行该命令之前,确保你已经从 GitHub 仓库的Chapter-7文件夹中下载了 YAML 模板。下载后,打开你的终端窗口,并将模板复制或移动到你的工作目录中,或者将工作目录更改为你下载模板的位置:
启动模板的 CLI 命令示例如下所示:
$aws cloudformation deploy --template my-template.json --stack-name CLI-stack --parameter-overrides Key1=Value1 Key2=Value2
通过这一条命令,我们已经复制了之前经历的所有步骤。正如前面所提到的,我们的模板应该存储在一个随机命名的 S3 桶中,因为我们在创建过程中上传了它,而 CloudFormation 服务为我们存储了它。
使用变更集
如果你的 CloudFormation 堆栈需要更新,有时你可能希望了解并理解当前正在运行的现有资源会如何受到影响。变更集允许你预览更改如何影响当前运行的资源,在任何更改发生之前,然后如果更改对当前资源有害,你可以取消更新,或者如果更改按预期执行,则可以继续。
注意
变更集不能告诉你 CloudFormation 执行时是否会成功运行。它们无法预见你可能遇到的账户限制更新,也无法判断你是否具备更新资源所需的正确 IAM 权限。
执行变更集的步骤
让我们看看执行变更集所需的强制性步骤和可选步骤:

图 7.4 – CloudFormation 变更集
在掌握了如何执行变更集的基础之后,我们将使用变更集来更新原始的 CloudFormation 堆栈——SQSqueue。
使用变更集更新我们的堆栈
如果你还没有这样做,那么从 GitHub 仓库的 Chapter-7 文件夹中下载名为 sqs-queues_change_set.yml 的模板。这就是我们将用来创建变更集的文件。还要确保你已经打开浏览器,进入 AWS 管理控制台,并导航到 CloudFormation 服务,然后按照以下步骤操作:
-
在 CloudFormation 堆栈页面,你应该会看到你的
SQSqueue堆栈处于CREATE_COMPLETE状态。点击堆栈名称,进入堆栈的详细信息页面。在这里我们可以执行变更集:![图 7.5 – 我们之前创建的 CloudFormation 堆栈]()
图 7.5 – 我们之前创建的 CloudFormation 堆栈
-
在堆栈名称下方的横向菜单中,你会看到多个选项,包括最右侧的变更集。点击变更集选项:
![图 7.6 – CloudFormation 堆栈菜单,右侧高亮显示变更集选项]()
图 7.6 – CloudFormation 堆栈菜单,右侧高亮显示变更集选项
-
进入变更集部分后,点击标记为创建变更集的按钮。
-
此时,将出现一个新屏幕,标题为先决条件 – 准备模板。你将看到三个选择。选择中间的选项,标题为替换当前模板:
![图 7.7 – CloudFormation 变更集准备模板屏幕]()
图 7.7 – CloudFormation 变更集准备模板屏幕
-
这将使另一组选择项出现在初始单选按钮下方。这一次,我们不是在创建变更集之前将模板上传到 S3,而是使用我们之前从 GitHub 仓库下载的
YAML文件(sqs-queues_change_set.yml)在此处上传模板。上传文件后,点击橙色的下一步按钮。 -
下一屏幕,参数,应确认我们在首次创建模板时输入的参数。此时我们不会更改任何参数,因此只需点击页面底部的橙色下一步按钮。
-
在下一屏幕,配置堆栈选项,我们不进行任何更改。您可以向下滚动到页面底部,然后点击橙色的下一步按钮。
-
现在,最终在审查页面,我们需要在页面底部勾选一个选项,确认我们的新堆栈将创建一个 Lambda 函数所需的 IAM 角色。在权限标题下,勾选确认此新模板正在创建 IAM 权限的复选框。完成后,您可以点击标有创建变更集的橙色按钮。
-
此时应该会弹出一个窗口,允许您在实际创建变更集之前为其命名。如果愿意,您可以为变更集命名,或者只需点击右下角的橙色创建变更集按钮。
-
一旦变更集创建完成,您应该会看到
CREATE_PENDING状态,因为 CloudFormation 正在根据您使用变更集创建的新模板计算当前堆栈实际要更改的内容。完成后,橙色的执行按钮将出现在右上菜单中。向下滚动并查看变更标题下,查看将在堆栈上执行的两个更改。确认更改无误后,向上滚动并点击橙色的执行按钮:![图 7.8 – 变更集将在堆栈上执行的更改]()
图 7.8 – 变更集将在堆栈上执行的更改
-
现在,您将被带回到
SQSqueue堆栈,并看到UPDATE_IN_PROGRESS状态,直到更新完成。
仅仅因为您创建了一个变更集并不意味着您必须执行它。您可以在变更集标签中有多个变更集,等待执行,直到您和您的团队决定应该实施哪些更改。值得注意的是,除非您删除变更集,否则任何拥有堆栈权限的人都可以执行它。
到目前为止,我们已经更新了原始堆栈,添加了 Lambda 函数以及该 Lambda 函数操作所需的 IAM 角色。我们的操作非常顺利,但如果模板中有冲突、缺失信息或错误会发生什么呢?接下来我们将讨论 CloudFormation 的回滚功能。
CloudFormation 的回滚功能
如果在创建或更新 CloudFormation 堆栈时操作失败,堆栈将回滚到之前的状态。此外,还有一个叫做 回滚触发器 的功能。通过这些触发器,你可以设置用户定义的警报,CloudWatch 可以监控这些警报,并在发生故障时回滚堆栈。
在创建堆栈或更新更改集时,监控周期可以设置为 0 到 180 分钟。接下来我们将看一个包含回滚触发器的更改集更新示例。
我们可以使用以下类似的 CLI 命令创建一个 CloudWatch 警报来监视我们的堆栈:
aws cloudwatch put-metric-alarm --alarm-name "SQS_stack_errors" \
--alarm-description "example alarm" --namespace "SQS_log_errors" \
--metric-name Errors --statistic Maximum --period 10 \
--evaluation-periods 1 --threshold 0 \
--treat-missing-data notBreaching \
--comparison-operator GreaterThanThreshold
一旦我们创建了警报,就可以使用返回的 ARN 在回滚触发器中使用。如果需要查找 ARN,可以使用 CloudWatch 的 describe-alarms 命令:
aws cloudwatch describe-alarms --alarm-names "SQS_stack_errors"
我们需要创建一段 JSON 代码并将其推送到变量中,以便将 ARN 传递给命令行选项:
RB_TRIGGER=$(cat <<EOF
{
"RollbackTriggers": [
{
"Arn": "arn:aws:cloudwatch:us-east-2:470066103307:alarm:SQS_stack_errors",
"Type": "AWS::CloudWatch::Alarm"
}
],
"MonitoringTimeInMinutes": 5
}
EOF
)
这将为我们提供创建回滚触发器所需的信息:
aws cloudformation create-change-set \
--change-set-name "SQS-UPDATE" \
--stack-name "SQSqueue" \
--template-url "https://devopspro-beyond.s3.us-east-2.amazonaws.com/sqs-queues_change_set.yml" \
--change-set-type "UPDATE" \
--parameters ParameterKey=QueueName,ParameterValue=chapter7 \
--capabilities CAPABILITY_IAM \
--rollback-configuration "$RB_TRIGGER"
目前,回滚触发器仅支持使用 CloudWatch 警报作为监控工具。
我们将在 第十五章 中更详细地讨论 CloudWatch 警报,CloudWatch 指标和 Amazon EventBridge。
CloudFormation 中的内置函数
CloudFormation 内置了多个函数,这些函数可以与 JSON 和 YAML 模板一起使用,扩展模板的功能和能力。我们可以堆叠或组合内置函数。
注
内置函数只能在 CloudFormation 模板的某些部分使用。根据本书出版时的情况,内置函数可以在资源属性、输出、元数据属性和更新策略属性中使用。
接下来我们将看一些常见的内置函数,并提供一些使用示例。YAML 模板中还可以使用其他函数。在函数标题中,如果有短格式,原始代码后面会用管道符号分隔并显示短格式:
-
Fn::FindInMap | !FindInMapFindInMap函数根据Mappings部分中的键返回一个值:Mappings: RegionMap: us-east-1: HVM64: "ami-032930428bf1abbff" us-east-2: HVM64: "ami-027cab9a7bf0155df" us-west-1: HVM64: "ami-088c153f74339f34c" eu-west-1: HVM64: "ami-015232c01a82b847b" ap-southeast-1: HVM64: "ami-0ba35dc9caf73d1c7" ap-northeast-1: HVM64: "ami-0b2c2a754d5b4da22" Resources: EC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: !FindInMap - RegionMap - !Ref 'AWS::Region' - HVM64 InstanceType: t2.small -
Fn::GetAZs | !GetAZsGetAZs函数将返回给定区域中的可用区列表。这对于创建跨区域动态模板特别有帮助:PublicSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: "" -
Fn::GetAttGetAtt函数对于获取资源的属性(特别是 ARN)非常有用,尤其是在模板中之前已创建的资源。这个函数特别适用于使 CloudFormation 模板具有更高的动态性:SourceSecurityGroupName: !GetAtt EC2.SourceSecurityGroup.GroupName
条件函数
可选条件部分包含定义在基于动态选项的情况下,资源是否可以或不可以创建或配置的语句。
在 CloudFormation 模板中使用条件的场景包括以下内容:
-
您正在尝试使用相同的模板为 DEV 和 PROD 环境提供支持,而不需要更改任何内容,除了可能的参数值。
-
您希望通过下拉列表指定要挂载的 EBS 卷数量。
-
您希望根据用户选择来创建或不创建 CloudWatch 仪表板。
注意
在堆栈更新过程中,您不能单独更新条件。您只能在包含添加、修改或删除资源的更改时更新条件。
您可以使用条件函数帮助评估诸如 AWS 提供的变量或从参数收集的输入项,并在某些条件适用时创建额外的资源:
-
Fn::And如果所有传入的指定条件返回
true,则此函数返回true。 -
Fn::Equals此函数比较两个不同的值,并在值相等时返回
true。在以下示例中,模板将根据在模板的
Parameters部分传递的值,决定是否创建Public Subnets:Conditions: PublicSubnetsCondition: Fn::Equals: [ !Ref CreatePublicSubnets, "true" ] NoPublicSubnetsCondition: Fn::Equals: [ !Ref CreatePublicSubnets, "false" ] -
Fn::If如果指定的条件评估结果为
true,则此函数返回一个值;如果指定的条件评估结果为false,则返回另一个值。 -
Fn::Not如果条件评估结果为
false,则返回true,如果评估结果为true,则返回false。 -
Fn::Or如果任何指定条件的评估结果为
true,则返回true。
CloudFormation 最佳实践
当您开始在 CloudFormation 模板中构建基础设施即代码(IaC)时,AWS 提供了一些最佳实践和建议。这些建议有助于您更有效地组织和规划资源创建,同时最大限度减少在模板初次运行时的故障排除时间。
不要在模板中嵌入敏感信息。
与其直接在 CloudFormation 模板中放置可能会泄露的机密信息,不如将机密存储在 AWS Secrets Manager 中。更好的做法是使用动态引用。动态引用允许您引用Systems Manager(SSM)参数存储或 AWS Secrets Manager 中的外部值。对于 SSM 参数存储,它支持ssm(明文值)和ssm-secure(加密值)。
因此,您可以像这样在 RDS 资源块中使用数据库用户名和密码,而不是使用基于模板的参数:
MySQLInstance:
Type: 'AWS::RDS::DBInstance'
Properties:
DBName: MyRDSInstance
AllocatedStorage: '20'
DBInstanceClass: db.t2.micro
Engine: mysql
MasterUsername: '{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}'
MasterUserPassword: '{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}'
使用 AWS 特定的参数类型
为了简化 AWS 特定参数输入,尤其是在请求可能需要在账户中查找的项目时,可以定义 AWS 特定类型的参数,而不是使用字符串表示参数类型。这些参数可能包括安全组 ID、VPC ID 或 Route53 托管区域 ID。一个很好的例子是AWS::EC2::KeyPair::KeyName,这将提供一个可用 EC2 密钥对的下拉菜单。
利用参数约束
如果你没有使用 AWS 特定的参数,而是使用字符串参数,则使用参数约束可以帮助在模板开始创建之前捕捉用户在输入参数时的错误,避免浪费时间进行回滚。参数约束的构造方式类似正则表达式,还可以为用户提供描述,帮助他们更好地理解需要输入的内容。
了解如何使用 AWS::CloudFormation::Init 将软件部署到 EC2 实例
当你从 CloudFormation 模板启动 EC2 实例时,可以使用cfn-init助手脚本和AWS::CloudFormation::Init资源来安装和配置运行在该实例上的软件。使用这些助手脚本不仅可以安装系统脚本,还可以通过操作系统包管理器(如apt或yum)安装必要的系统包。
模块化你的模板
使你的模板模块化可以同时完成几件事。首先也是最重要的是使模板可重用。随着我们开始讨论嵌套模板,这变得尤为重要。第二点是让多个团队成员集中精力在他们具有更多专业知识的小模板上。
在尝试启动之前对模板进行 Lint 检查
就像任何其他形式的代码一样,CloudFormation 模板应该经过验证过程,确保模板没有格式问题,然后再尝试启动。AWS CLI 中有一个内置的模板检查器,你可以使用它来发现模板中可能存在的任何问题。
AWS CloudFormation Linter(cfn-lint)是一个开源工具,可以集成到大多数 IDE 中,也可以通过命令行、IDE 内部或集成到 CI/CD 管道中运行。该工具将验证 JSON 和 YAML 模板,并包括符合 CloudFormation 最佳实践的附加检查。
注意
尽管这些最佳实践通常不会出现在测试题目中,但它们对于日常使用 CloudFormation 并让你成为最优秀的 DevOps 专业人士来说更为重要。
创建具有依赖关系的嵌套堆栈
当你开始按逻辑组织你的模板时,你会发现将更大的模板拆分成更小、更易管理的部分是一种明智的策略。这不仅会使它们更容易使用,还能通过使每个模板具备特定目的来提高重用性,例如创建一个带有子网的 VPC 或一组可重用的 IAM 角色。为这些较小的模板添加输出可以使其他模板使用其他模板之前创建的资源,就像一个个堆叠在一起的积木,最终构建出一个完整的解决方案。这也使得多个团队成员可以在云基础设施的不同部分独立工作,因为每个人可以集中精力在自己擅长的领域。如果你有一位擅长网络的团队成员,他们可以专注于堆栈中的 VPC 和网络部分。如果你有另一位具有数据库背景的团队成员,他们可以专注于创建和配置数据库(包括特定数据库引擎的任何特殊参数组)的嵌套部分。
嵌套堆栈始于根堆栈或父堆栈,如图 7.9中所示,标有字母A。根堆栈接着将其他子堆栈作为其资源,而不是其他 AWS 服务。我们还可以在图中看到,标有B的堆栈提供的输出被C级堆栈消费。C级堆栈创建了另一个子堆栈,并创建了资源,其输出被D级堆栈消费:

图 7.9 – CloudFormation 嵌套堆栈
嵌套堆栈还提供了一个额外的好处,即能够突破 CloudFormation 模板的 200 个资源限制。
注意
嵌套堆栈在故障排除时可能更加复杂。如果在创建和部署嵌套 CloudFormation 堆栈时遇到错误,可以尝试只部署单个导致问题的模板,然后更新你的更改。
为部署打包你的嵌套堆栈
一旦你准备好所有要上传到 S3 的模板,你可以使用 AWS CLI 将它们打包在一起。由于嵌套堆栈需要其子模板在 S3 中以供部署,这样可以节省你单独上传每个模板的时间。然后,它将为我们生成一个新模板,并为我们提供使用该新模板部署完整嵌套堆栈的命令。创建 CloudFormation 包的通用代码如下所示:
$aws cloudformation package \
--template-file /path_to_template/template.json \
--s3-bucket bucket-name \
--output-template-file packaged-template.json
当我们通过 AWS CLI 创建嵌套模板的练习时,我们将更深入地查看此命令。
让我们回顾一下package命令的作用:
-
它创建一个 ZIP 文件,包含所有子模板文件和额外代码,例如
lambda代码。 -
它将这些项目上传到你指定的 S3 桶中。
-
它生成一个新的模板,将本地模板替换为 S3 URI。
使用 AWS CLI 创建嵌套堆栈
在下面的练习中,我们将使用 GitHub 存储库中Chapter-7/nested目录下的一组模板创建嵌套堆栈。在开始以下练习之前,请下载所有这些 YAML 模板。还要记下要部署包的 S3 存储桶。正如我们之前在展示示例命令时所指出的,CLI 命令的一部分需要 S3 存储桶:

图 7.10 – 创建嵌套堆栈练习中的项目
图 7.10 中的图示显示了我们即将使用嵌套模板打包和部署的内容:
-
打开终端,以便您可以访问 AWS CLI。
-
现在导航到您已下载所有文件以创建嵌套堆栈的文件夹。如果您已经下载了整本书的 GitHub 存储库,则路径将为
Chapter-7/nested。 -
由于嵌套堆栈的打包只能工作一层深,我们必须手动上传我们的
nested_dynamo.yml模板(确保在执行以下命令时替换自己的存储桶名称):aws s3 cp nested_dynamo.yml s3://devopspro-beyond/ -
打开
nested_root.yml文件,并编辑您放置nested_dynamo.yml文件的存储桶的 HTTPS 值的默认值。 -
进入嵌套目录后,执行以下命令:
aws cloudformation package \ --template-file nested_root.yml \ --s3-bucket devopspro-beyond \ --output-template-file packaged_template.yml -
完成后,
package命令应告诉您成功,并提供一个剪切和粘贴命令供您运行,需要在命令的最后替换堆栈名称:成功打包工件并将输出模板写入文件
packaged_template.yml。执行以下命令以部署打包的模板:
aws cloudformation deploy --template-file /AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/Chapter-7/nested/packaged_template.yml --stack-name <YOUR STACK NAME> -
运行以下命令以创建您的嵌套堆栈,但请确保更改堆栈名称并添加
--capability CAPABILITY_IAM标志:aws cloudformation deploy --template-file /AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/Chapter-7/nested/packaged_template.yml --stack-name Chapt7 --capabilities CAPABILITY_IAM -
登录 AWS 控制台并转到 CloudFormation 服务。此时,您应该能够看到您创建的根堆栈和嵌套堆栈。通过单击资源选项卡,您可以看到刚刚创建的所有资源。
-
如果不想产生费用,则删除堆栈。
使用 DependsOn 来排序资源
虽然 CloudFormation 按照模板中指定的顺序创建资源,但在开始构建下一个资源之前,并不等待任何一个资源的完成,除非有特别的指示。DependsOn结构允许您暂停特定资源的创建,直到其他资源完成。
存在许多情况需要调用DependsOn。第一组场景涉及需要访问互联网的资源,因此在继续之前需要完成互联网网关。
将等待条件添加到模板中
WaitCondition 会在模板执行堆栈任务时添加一个暂停,直到接收到成功信号,表示可以继续进行。
每当将 WaitCondition 作为资源添加到 CloudFormation 模板中时,必须将其与 WaitConditionHandle 资源结合使用。
注意
尽管 DependsOn 构造和 WaitCondition 资源在功能上似乎相似,但它们在几个方面有所不同。首先,DependsOn 是一个更简单的实现,因为它不需要辅助脚本。DependsOn 还不会在资源创建后检查其是否成功或失败,因此仅仅控制模板中项目的顺序。而 WaitCondition 则需要显式接收成功信号,模板(或变更集)会在收到该信号前暂停。
使用 curl 进行信号传递
当使用 curl 向 WaitCondition 发出信号,表明资源(大多数情况下是 EC2 实例)已经完成配置时,这可以动态完成。第一步是创建 WaitHandle,然后构建 CloudFormation 在 curl 命令中使用的 URL。此时,我们可以在模板的 UserData 部分内调用 curl 命令。接下来,我们将看到一个简化模板片段中的示例:
ServerWaitCondition:
Type: 'AWS::CloudFormation::WaitCondition'
DependsOn: Server
Properties:
Handle: !Ref ServerWaitHandle
Timeout: '1200'
…
UserData: !Base64
'Fn::Join':
-"
- - |
#!/bin/bash -v
- |
# Send Wait Condition URL
- '/usr/local/bin/aws s3 cp s3://'
- !Ref BucketFolder
- |
/templates/success.json /tmp/a
- SignalURL=
- !Ref ServerWaitHandle
- |+
- |
echo $SignalURL
- curl -T /tmp/a "
- !Ref AdminServerWaitHandle
- |
"
WaitCondition 是与 CloudFormation 中提供的少数几个辅助脚本之一一起使用的信号。接下来,我们将查看 CloudFormation 模板中可用的不同辅助脚本。
将辅助脚本添加到 CloudFormation 模板
在 CloudFormation 中,有一些不同的辅助脚本,它们是用 Python 编写的,可以在请求和配置 EC2 实例作为模板的一部分时安装软件并启动服务:

表 7.1 – CloudFormation 助手脚本
如你所见,使用 CloudFormation 提供的这些辅助脚本可以大大简化 EC2 配置。接下来,我们将看到如何在 CloudFormation 模板中检测漂移,如果你的基础设施与模板代码发生偏离。
了解如何检测 CloudFormation 模板中的漂移
CloudFormation 模板允许你以代码的形式在你管理的多个 AWS 账户中创建和管理基础设施与资源。采用这种将资源作为代码进行配置的方式,能够进行版本控制,且是最佳实践,因为它是可重复的,而不是像传统方式那样手动构建和维护云资源。
你能阻止他人更改你以这种方式配置的资源吗?除非你使用了 IAM 策略来防止小组修改通过 CloudFormation 模板或代码部署管道提交的资源,否则有可能会出现由 CloudFormation 模板创建的某些资源发生漂移的情况。
当您启动漂移检测时,CloudFormation 服务会将当前堆栈和当前配置的资源与当初用于创建或更新该堆栈的模板中指定的内容进行比较。然后,它会报告所发现的任何差异。
在我们对 CloudFormation 模板有了深入了解之后,现在我们将讨论一个补充服务——AWS 服务目录。服务目录是 AWS 管理工具箱中的另一个工具,它允许您的用户快速、轻松地配置已预先创建并设置了相关保护措施的资源。
使用服务目录管理模板
在继续讨论 CloudFormation 模板的过程中,我们开始研究在组织中管理模板的其他方法。AWS 的服务目录产品允许我们使用 CloudFormation 模板,并为用户创建一个自服务门户,以便他们可以在获得适当访问权限的情况下配置已知的项目模式。这些模板现在成为我们服务目录中的产品,甚至可以进行参数化,这样用户就可以选择项目,例如在 EC2 的情况下,经过验证的、预定义的 EC2 实例大小和 AMI。
首先,您需要理解与服务目录相关的一些概念。第一个概念是产品。产品是您希望在 AWS 上提供的 IT 服务。它可以是一个简单的 S3 存储桶,也可以是一个复杂的 EC2 实例,配备 RDS 数据库和预定义的 CloudWatch 警报。接下来,您需要理解服务目录中的另一个概念——产品组合。产品组合是特定产品及其配置信息的集合。产品组合还与特定的用户组关联,并赋予这些用户组启动产品的权限。
查看 图 7.11,我们可以看到从管理员和用户的角度出发,服务目录中提供的两种不同工作流。顶部视图展示了管理员如何加载一个包含 EMR 集群、S3 存储桶和 CloudWatch 警报的模板,作为数据用户组的产品供重复使用。
数据用户组中的任何用户都可以迅速配置不仅是 EMR 集群,还可以配置相应的 S3 存储桶及相关的 S3 警报,只需在服务目录界面中输入几项相关信息:

图 7.11 – 服务目录工作流
服务目录还允许您更新包含产品的模板,并发布带有更新功能的新版。这可以让您的用户选择使用哪个版本:他们熟悉的版本,或是包含新功能的版本。
在许多情况下,这种方法可能会变得非常有用:
-
当解决方案架构师需要快速配置一个演示环境以供客户销售电话使用时。
-
QA 团队希望搭建一个用于测试的 QA 环境。
-
在营销部门,他们希望一个促销应用程序在特定的时间段内运行。
-
一位数据科学家需要一套专门的软件进行配置,比如 EMR 集群或配置有 R Studio 的服务器,但他没有系统管理员的背景,无法安装、配置和正确地确保所有必要的软件安全。
服务目录中的访问控制通过 IAM 进行处理。服务目录管理员为目录中的产品创建特定的 IAM 角色,以便用户仅拥有运行目录中预配置服务所需的足够权限。
在您的服务目录中,您可以对产品设置多种不同类型的约束,以便应用治理。
有基于模板的约束,可以减少用户在启动产品时可用的选项数量。例如,EC2 实例或 RDS 实例的大小,或者允许用于 Lambda 产品的语言。
基于标签的约束要么强制要求在启动产品时填写特定标签,要么禁止用户使用任何除预定义标签外的附加标签。
您可以指定一个特定的 SNS 主题,通过通知约束接收有关产品的更新。
定义哪些 IAM 角色可以用于运行特定产品,并通过启动约束进行控制。这为服务目录管理员提供了一组额外的控制手段,指明哪些服务允许由服务目录产品进行治理。
我们刚刚发现,服务目录能够让非开发人员快速启动预定义的 AWS 基础设施模式供用户使用。这些用户无需担心如何配置底层资源,因为这一切都由底层的 CloudFormation 模板处理。
接下来,我们将探讨另一种创建 CloudFormation 模板的方法,它比仅使用 JSON 或 YAML 的 Cloud Development Kit 提供了更大的灵活性。
使用 Cloud Development Kit
开发人员习惯于创建可重用的库并使用循环等技术来处理重复任务。Cloud Development Kit (CDK) 允许具备编程背景的人使用多种语言(TypeScript、JavaScript、Python、Java 和 C#)创建 CloudFormation 模板,使用他们熟悉的技术,具体如以下几种:
-
逻辑(
if语句、for循环) -
面向对象的技术
-
通过逻辑模块进行组织
这与 CloudFormation 模板形成对比,后者要求您、开发人员或 DevOps 人员以 JSON 或 YAML 格式编写模板,尽管这两种选项在本质上都有一定的普遍性,并且无论是否有编程背景,都可以在短时间内掌握。CloudFormation 模板在创建堆栈时,提供的编程选项和逻辑也非常有限:

图 7.12 – CDK 工作流程
在图 7.12中,你可以看到开发人员如何使用 CDK 创建应用程序的工作流程。这个应用程序随后创建一个堆栈,将 CloudFormation 模板部署到 AWS 云环境中。
AWS CDK 的概念
在 AWS CDK 中,有三个基本组件——应用程序(apps)、堆栈(stacks)和构造体(constructs)——开发人员可以利用这些组件来创建云服务。
应用程序(Apps)
使用 AWS CDK 时,你是在构建一个应用程序,该应用程序本身就是一个应用,并由 CDK App 类组成。
堆栈(Stacks)
在 AWS CDK 中,部署单元是堆栈,堆栈范围内定义的所有资源都作为一个单一单元进行提供。由于 CDK 堆栈是作为 CloudFormation 堆栈实现的,因此 CloudFormation 堆栈需要遵守的任何边界或限制同样适用于 CDK 堆栈。
构造体(Constructs)
AWS CDK 的构建模块是构造体。这些构造体可以是像负载均衡器这样的单个 AWS 资源,或者是由多个资源组成的单一组件,例如 VPC 和子网。构造体创建可重用的组件,可以像其他代码片段一样共享。
使用 AWS CDK 的优点
我们将探讨使用 CDK 相较于普通 CloudFormation 模板的一些优势。
更快的开发过程
使用 AWS CDK,你可以使用你熟悉的编程语言,如 Python、TypeScript、.NET、Go 和 Java。在这些语言的帮助下,你可以创建对象、循环和条件,而无需学习特定领域的函数和解决方法。
在 IDE 中进行代码补全
使用流行的 IDE(如 Visual Studio Code)可以在编程时根据你选择的语言实现代码补全功能,尤其是在使用 AWS CDK 时。
同步部署代码和基础设施即代码(IaC)的能力
由于 AWS CDK 使用的是与编写代码时相同的原生语言,因此将基础设施组件与运行应用程序的代码结合起来变得更加简单,无需切换上下文。
总结
在本章中,我们探讨了如何使用 CloudFormation 模板和 CDK 创建基础设施即代码(IaC)。我们研究了模板构建和组织的一些最佳实践,并通过 AWS 管理控制台和命令行界面(CLI)亲手实现了将 CloudFormation 模板部署和更新为堆栈。
在下一章中,我们将开始研究一些属于 SDLC 过程的 AWS 代码工具,从 CodeCommit 和 CodeBuild 开始。我们将使用 CodeCommit 创建一个代码库并提交,然后使用 AWS CodeBuild 构建代码。最后,我们将看到如何通过从 CodeCommit 仓库的推送触发 CodeBuild 作业来将这两项服务结合在一起。
复习问题
-
CloudFormation 的两个主要组件是什么?
-
一家公司雇佣你帮助审查和优化其 CI/CD 流程,特别是在基础设施即代码(IaC)方面。该公司目前有一个 CloudFormation 模板,经过一段时间的开发,用于创建 IAM 账户角色、VPC、子网、Lambda 函数、CloudWatch 警报、SNS 主题及其他资源,包括数据库和 EKS EC2 实例及其相应的 AutoScaling 组。你会如何着手为他们的流程优化提出建议?
a. 检查当前模板,确保其嵌入了正确的
DependsOn和WaitCondition,以便所有资源可以顺利启动,不会发生冲突。b. 创建一个计划,说明如何拆分他们的大模板。
c. 使用 CloudFormation 的
package命令将所有模板打包在一起。d. 将较小的模板打包并通过一个
deploy命令进行部署。 -
在评估客户的需求后,你决定构建一个 CloudFormation 模板,作为交付成果交给客户,该模板适用于可重复使用的三层 Web 应用程序。中间件 Linux 服务器有一个复杂的用户数据脚本,需要一段时间才能完全安装。它们位于网络负载均衡器资源之后,在添加之前需要完全操作并配置好。你如何确保这些服务器在连接到网络负载均衡器资源之前已经完全操作并正确配置?(选择两个。)
a. 确保网络负载均衡器资源位于模板中的中间件服务器后面,在 CloudFormation 资源部分中。
b. 添加一个依赖于中间件服务器的
WaitCondition。一旦用户数据完成,它会使用cfn-signal通知表示已准备好。c. 从嵌套模板中启动所有内容,其中中间件服务器位于从负载均衡器模板启动的模板中。
d. 添加一个依赖于中间件服务器的
WaitCondition。一旦用户数据完成配置中间件服务器,它会使用curl命令通知预签名的 URL,表示它们已经准备好。 -
你在一家大型企业公司工作,背后有多个待部署的项目,需要将它们部署到不同的 AWS 云环境中。为了最小化每次部署所需的时间,你希望创建一套可重用的组件集合,可以根据每个项目的架构轻松替换。当前已有一个基本的 CodePipeline 服务实例用于添加测试和部署步骤。无论你选择什么解决方案,都应该能够提交到代码版本控制系统,并且易于测试。你应该如何组织资源以实现最佳的可重用性?
a. 使用 AWS CDK 创建由共享组件库组成的应用程序。添加测试库,并在 CodePipeline 中部署到开发环境之前运行测试。
b. 创建一个小型资源特定的 CloudFormation 模板库,可以根据架构指南轻松嵌套和打包。使用
yamllint和cfn-lint命令对 CloudFormation 模板进行语法检查,作为 CodeBuild 中的测试步骤,以捕捉任何错误。c. 开发 5-10 个蓝图模式的基础,这些模式适用于所有项目。使用这些蓝图,开发一个包含参数和条件的 CloudFormation 模板库,以满足大多数项目的需求。使用
cfn-lint命令对 CloudFormation 模板进行语法检查,作为 CodeBuild 中的测试步骤,以捕捉任何错误。d. 为每个解决方案创建 CloudFormation 模板,包含必要的参数值和条件,以确保它们能够在任何区域无缝工作,并可用于任何环境(DEV、TEST 和 PROD)。将模板上传到 CodeCommit 进行版本控制。
审查答案
-
模板和堆栈
-
b
-
b 和 d
-
a
第八章:使用 CodeCommit 和 CodeBuild 创建工作负载
AWS 提供了一套值得称赞的工具,帮助开发人员和组织完全依赖 Amazon 生态系统来运行他们的 CI/CD 操作。
持续集成从源代码版本控制过程开始,然后以可重复、自动化的方式构建和测试代码。AWS 代码服务套件中的两个工具,CodeCommit 和 CodeBuild,帮助工程师实现这些目标。
在本章中,我们将涵盖以下主要主题:
-
使用 CodeCommit 进行代码版本控制
-
设置你的 CodeCommit 仓库
-
CodeCommit 中的审批
-
使用 AWS CodeBuild
-
创建
buildspec文件
技术要求
当我们开始这条路时,假设有几个前提,尤其是在追求专业 DevOps 认证时。第一个前提是你对使用软件版本控制系统 Git 有基本的了解。这个基本知识包括创建一个裸仓库、创建一个分支、对该分支进行提交,然后将提交推送到远程仓库。如果你需要熟悉 Git,建议使用教程 《Git 和 AWS CodeCommit 入门》。你可以在 docs.aws.amazon.com/codecommit/latest/userguide/getting-started.html 找到该教程。
第二个假设是你已经在笔记本电脑或工作站上安装了 Git。假设你还没有安装 Git,或者由于缺乏管理员权限而无法访问它,完美的替代方案是启动一个 Amazon EC2 实例,在你的 AWS 账户中安装 Git,这样你就可以跟随练习进行操作。
如果 Git 没有安装在你的本地工作站上,并且你无法安装它或不想安装它,AWS 提供了 Cloud9 开发环境,它允许你在浏览器窗口中创建代码。
使用 CodeCommit 进行代码版本控制
关于存储代码的地方,无论是在本地还是在 SaaS 解决方案中,你有很多选择。功能和价值是驱动决策的因素,决定使用哪种产品。AWS CodeCommit 提供了强大的功能集,并且是按使用付费的服务,包含与 AWS 服务的原生连接,以及符合多个保证计划,如 SOC2、PCI、HIPAA 等。
在 第六章,了解 CI/CD 和软件开发生命周期 (SDLC) 中,我们讨论了软件开发生命周期的四个主要阶段:源代码、构建、测试和部署。初始阶段,即源代码阶段,是我们将在本节中集中讨论的内容。简要回顾一下,源代码阶段允许你将代码检查到中央仓库,并且允许多人在同一代码库上进行协作。
什么是 CodeCommit?
CodeCommit 是一个安全、高度可扩展的托管源代码控制服务,承载私有 Git 仓库。这听起来可能有些陌生,但如果你使用过 BitBucket 或 GitHub 私有仓库,你可能已经使用过类似的 SaaS 服务来托管代码。
CodeCommit 中的基本对象是仓库。仓库是用户存储代码和任何类型、大小对象的地方。CodeCommit 还存储和跟踪对上传文件所做的更改,以及对文件所做的更改。你可以配置仓库,以便在发生事件时发送通知,例如分支合并或向代码中添加评论。它还允许用户在本地系统上工作,然后将更改推送到 CodeCommit 存储系统。
CodeCommit 的好处
作为 AWS 生态系统的一部分,CodeCommit 可以与 KMS 等服务集成以实现加密,还可以与 CloudWatch 集成,以便为我们的仓库整合指标和警报,甚至不包括与 CodeCommit 服务紧密集成的某些开发工具。除了与众多其他 AWS 服务紧密耦合外,CodeCommit 还提供许多其他好处:
-
CodeCommit 的 IAM 提供高服务可用性和耐久性。
-
CodeCommit 仓库在静态和传输过程中都进行了加密,因此你可以放心,代码始终是安全的。
-
它可以轻松扩展,并且对仓库的大小、以及你可以存储的文件类型和大小没有限制。
-
无缝集成多个 AWS 服务(Lambda、SNS、CodePipeline)。
-
允许你轻松地从其他远程 Git 仓库迁移。
-
允许你使用你已经熟悉的 Git 工具和命令。
在了解了 AWS CodeCommit 的概述和好处之后,我们将查看可用的访问控制功能,然后再创建我们的仓库和专门用于 CodeCommit 访问的新用户组。
控制对仓库的访问
在我们开始创建 CodeCommit 仓库的过程之前,我们需要做一些权限方面的预先工作。直到这一点为止,我们大部分操作都是以管理员用户身份进行的。现在我们开始将开发人员和开发团队加入其中,其中一些只需要访问 CodeCommit 仓库而不需要访问其他服务。我们将创建一个新的 IAM 用户组,然后将一个开发者实体添加到该用户组。这将演示良好的 GitFlow 实践,即开发者提交代码后,请求将其分支合并到主分支。
当所有开发者都属于同一个账户时,可以顺利创建 CodeCommit 仓库。然而,还有其他一些场景需要注意。例如,当另一个账户中的开发者需要访问我们账户中的 CodeCommit 仓库时该怎么办?CodeCommit 可以为另一个 AWS 账户中的用户和角色提供跨账户访问。这可以解决不必将外部开发者添加到 IAM 用户列表中的问题,前提是他们已经拥有 AWS 账户。
设置你的 CodeCommit 仓库
可以通过 CLI 创建 CodeCommit 仓库。然而,当使用 AWS 管理控制台时,有一些附加功能,如信息面板,这些功能只有在该环境中才可用。
在创建仓库之前,确保打开浏览器访问 AWS CodeCommit 主页,console.aws.amazon.com/codesuite/codecommit/home,并在提示时登录。
一旦你登录,我们可以开始创建 CodeCommit 仓库的过程:
-
一旦你进入了你所在地区的
CodeCommit主页(在我们的示例中,我们使用的是俄亥俄地区/us-east-2),点击右上角的橙色创建仓库按钮,开始创建新仓库的过程:![图 8.1 – 创建仓库按钮]()
图 8.1 – 创建仓库按钮
-
在
chapter8中设置仓库名称。如果你愿意,可以为仓库添加描述,但这不是必要的。你可能希望此时启用 CodeGuru 审阅器;然而,由于这是一个新功能,我们将不进行讨论:![图 8.2 – 新的 CodeCommit 仓库设置]()
图 8.2 – 新的 CodeCommit 仓库设置
注意
Amazon CodeGuru 审阅器是一个可选功能,是 AWS 的附加服务,在发布时仅支持 Java 和 Python 语言。未来可能会支持更多语言。
-
创建仓库后,你将看到一个显示连接步骤的页面,这些步骤展示了如何通过多种方式连接到你的新仓库,包括 HTTPS、
SSH和通过 HTTPS 的 git-remote-connect 协议。花一点时间浏览这些步骤。我们将在开发者账户创建完成,并且使用其权限集时,更加深入地使用这一部分。向下滚动,越过连接步骤,页面底部会看到一个名为创建文件的按钮。点击该按钮以便设置我们的主分支:![图 8.3 – 为我们的 CodeCommit 仓库创建初始文件]()
图 8.3 – 为我们的 CodeCommit 仓库创建初始文件
-
在
Welcome to my repository。完成此操作后,在sample.txt中,你还需要为提交输入一个名称和一个电子邮件地址,如以下截图所示:![图 8.4 – 通过 Web 界面提交更改到 CodeCommit]()
图 8.4 – 通过 Web 界面提交更改到 CodeCommit
-
输入这些信息后,你可以点击橙色的 Commit changes 按钮。接下来,你将被带到仓库中的文件,但更重要的是要注意,在屏幕的右上角,我们已经成功创建了 main 分支:

图 8.5 – 我们的 CodeCommit 仓库的主分支
现在我们已经创建了仓库和主分支,我们可以开始创建开发人员用来将代码推送到仓库的权限集。根据你的组织结构,你可能会赋予所有开发人员创建新仓库和将拉取请求合并到主分支的权限。
在我们的示例场景中,当我们进行练习时,我们将区分开发人员可以做的事情与管理员或 DevOps 高级用户的职责。准备考试时,考虑如何划分责任是非常重要的,此外,还有一些可能出现的问题和场景需要注意。
为开发人员创建 IAM 组
在我们开始之前,请确保从本书的 GitHub 仓库下载文件,路径是 Chapter-8 文件夹。我们将首先为开发人员创建 IAM 策略。一旦策略上传完毕,我们将创建开发人员组,并将策略附加到新创建的组上:
-
打开终端,以便可以访问你的 AWS CLI。
-
我们想为我们的代码提交开发人员创建一个组。你可能以前创建过一个开发人员组,但我们现在要为本章创建一个新的组:
aws iam create-group --group-name CC_Developers -
现在你已经创建了组,我们将把策略附加到该组。我们需要从之前创建的
CC_Developers策略中获取策略 ARN:aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitPowerUser –group-name CC_developers -
既然我们已经创建了
CC_Developers组,我们可以创建我们的开发人员,并允许他们登录并添加他们的SSH密钥以开始使用CodeCommit。
创建你的开发人员
在本节中,我们将创建一个虚拟的开发人员,名为 Mariel。如果你愿意,你可以将开发人员的名称从 Mariel 改为其他名字。如果你还没有下载,先下载 change-password.json 文件并按照以下步骤操作:
-
如果你的终端仍未打开,请重新打开它,以便可以在 AWS CLI 中执行命令。使用
iam的create-user命令:$aws iam create-user --user-name mariel -
当这个命令运行完成后,它应该返回一个
JSON语句,显示包括用户 ID 在内的其他信息,如以下示例所示:{ "User": { "Path": "/", "UserName": "mariel", "UserId": "AIDAW24Q7QQFVGQHQJM3Y", "Arn": "arn:aws:iam::000066100007:user/mariel", "CreateDate": "2021-05-02T11:06:47+00:00" } } -
我们创建的用户,可以将其添加到
CC_Developers组,并允许他们继承该组的所有权限:$aws iam add-user-to-group --user-name mariel --group-name CC_Developers -
现在我们已经创建了用户并将其添加到
CC_Developers组中,我们需要为该用户创建一个初始密码,以便他们可以登录到管理控制台并上传他们的SSH密钥。要求他们重置密码也是一个好主意:aws iam create-login-profile --user-name mariel --password Dev0psPRO123! --password-reset-required
这样,我们就为用户创建了一个初始密码,以便他们能够在控制台中配置SSH密钥设置,并通过控制台查看 CodeCommit 分支。
现在我们已经使用 AWS CLI 创建了开发者用户,我们可以切换上下文并继续假设为开发者角色。
添加开发者的 SSH 密钥
现在我们已经创建了开发者用户,我们将从 CLI 切换到工作环境中的SSH密钥对,以便在创建代码时用于身份验证。
小贴士
当为账户、客户或特定用途使用特定的仓库或仓库集时,最好为该项目、账户或客户创建一个专用的密钥。使用不同的密钥是整体风险管理策略的一部分,以防服务器、SaaS 服务或工作站出现任何问题。
我们首先创建一个专门供开发者使用的SSH密钥对,以便能够将其添加到 AWS IAM 控制台中。
在终端中,使用以下命令为 Linux 或 macOS 用户生成一个新的密钥对文件:
$ ssh-keygen -t rsa -b 4096
运行此命令时,会首先要求你回答一些提示问题,第一个问题是你希望将密钥保存在哪里。默认情况下应该保存在本地的.ssh文件夹中,但名称为id_rsa。我们将使用一个自定义的密钥名称,以便我们知道这是专门为我们的代码提交项目准备的:
Enter file in which to save the key (/Users/abook/.ssh/id_rsa): /Users/abook/.ssh/cc_developer
选择保存密钥的位置和名称后,你将看到一个提示,要求输入passphrase:
Enter passphrase (empty for no passphrase):
我们不需要设置密码,因此只需按Enter键两次以保持空白。此时,你应该会看到一些信息,说明你的身份和公钥已保存,并显示类似 ASCII 艺术的内容。
你需要使用cat命令查看你的公钥,并在登录 AWS 控制台时准备好它,作为开发者用户进行登录。
生成密钥后
现在我们已经生成了密钥,需要使用我们刚创建的开发者用户名和凭证登录 AWS 控制台(而不是我们一直在使用的具有管理员权限的 DevOps 用户)。
小贴士
你可能需要使用不同的浏览器,或者开启隐身/私密会话,以确保没有遗留的 Cookies。
在新的浏览器中,登录为我们刚刚创建的开发者用户:
-
现在我们将使用开发者账户,而不是管理员账户。请登录到
aws.amazon.com/,并使用开发者的名字(mariel,在我们的例子中)和密码(Dev0psPRO)首次登录 AWS 管理控制台。 -
登录后,系统会立即提示您将初始密码更改为您选择的密码。如果您之前在 IAM 账户 设置中设置了密码策略,则必须在更改密码时遵守这些指南:
![图 8.6 – 开发者用户强制密码更改]()
图 8.6 – 开发者用户强制密码更改
-
一旦您更改了密码,您将进入 AWS 管理控制台的主页。现在,我们需要在搜索框中输入 IAM,以进入 IAM 服务。
-
一旦您进入了 IAM 服务,您会发现似乎没有权限进行任何操作。然而,这只是因为开发者角色的权限范围有限。这个用户可以列出用户并更新他们的用户信息。在左侧菜单中点击 用户 菜单项。
-
进入用户菜单后,您将看到一列用户。点击我们创建的开发者的名字(在我们的例子中是
mariel):![图 8.7 – IAM 用户列表]()
图 8.7 – IAM 用户列表
-
在用户的 概览 页面上,您会看到一些红框,但这里我们感兴趣的是 安全凭证 标签。点击此标签,您可以开始修改 安全凭证 页面:
![图 8.8 – IAM 用户概览顶部菜单]()
图 8.8 – IAM 用户概览顶部菜单
-
向下滚动,确保
SSH公钥 不仅已准备好,而且已经复制到剪贴板,随时可以粘贴。点击SSH公钥 按钮继续。 -
当弹出窗口出现时,将您的公钥粘贴到文本框中,然后点击蓝色的
SSH``SSH密钥 ID 列表。请注意这一点,因为我们接下来会用到这个 ID 来进行本地设置:![图 8.9 – 一旦上传了 SSH 公钥,IAM 控制台将显示 SSH 密钥 ID]()
图 8.9 – 一旦上传了 SSH 公钥,IAM 控制台将显示 SSH 密钥 ID
-
返回到您的工作站,我们需要创建一个
.ssh/config文件,或者通过添加几行与代码提交相关的内容来修改现有的config文件。使用您喜欢的编辑器创建或打开~/.ssh/config,然后添加以下几行。确保将示例的用户 ID 替换为您在上传密钥后 AWS 控制台返回的 ID。另外,如果您为SSH密钥创建了不同的名称,您需要在IdentityFile行中替换成该名称:Host git-codecommit.*.amazonaws.com User APKAW24Q7QQFSRFEETDF IdentityFile ~/.ssh/cc_developer -
返回到浏览器和 AWS 管理控制台,我们现在将切换到 CodeCommit 服务,以便获取仓库信息并克隆该仓库。在顶部的搜索框中输入
CodeCommit,然后点击图标进入 CodeCommit 服务页面。![图 8.10 – AWS 管理控制台搜索栏中的 CodeCommit 图标]()
图 8.10 – AWS 管理控制台搜索栏中的 CodeCommit 图标
-
一旦在右侧的
SSH链接上复制了 克隆 URL 属性:![图 8.11 - CodeCommit 仓库在开发者用户端的显示方式]()
图 8.11 - CodeCommit 仓库在开发者用户端的显示方式
-
切换回终端,进入你的主文件夹根目录。然后,将复制的 URL 粘贴到
git clone命令后,如下所示:$cd ~ $git clone ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/chapter8 -
最后,进入
chapter8目录。现在,你准备好开始添加一些代码或对象了。
此时,我们已经创建了一个SSH密钥并将其添加到我们的开发用户中。然后,我们更新了本地的SSH配置,告知 CodeCommit 在处理代码提交时使用哪个用户和密钥对。最后,我们下载了管理员用户之前创建的仓库。现在我们准备创建开发者分支并开始提交一些更改。
创建开发者分支并将提交推送到该分支
现在我们已经成功将仓库克隆到本地工作站,接下来是创建一个分支并提交。所有这些操作将在你克隆仓库所在的目录中进行。如果你遵循了前面的命名约定,那么你应该进入你的主目录,并找到 chapter8 文件夹。
我们做的第一件事是从主分支创建一个特性分支:
$git checkout -b feature1
Switched to a new branch feature 1
现在我们已经在自己的分支中,可以开始添加一些文件来进行提交。GitHub 仓库的 Chapter-8 文件夹中有两个示例文件(hello.py 和 loops.py)。你可以查看这些文件,然后将原始内容剪切并粘贴到我们下载的 chapter8 CodeCommit 仓库中新创建的同名文件中。
在我们进行提交之前,我们应该检查目录中文件的状态:
$git status
使用status命令后,我们应该看到类似以下的输出:
On branch feature1
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.py
loops.py
nothing added to commit but untracked files present (use "git add" to track)
现在,我们需要将这两个文件添加到提交中。由于它们都是相同类型的文件,我们可以在提交命令中使用通配符。或者,你也可以使用纯粹的通配符,一次性将所有未跟踪的文件添加到提交中:
$git add *.py
此时,我们需要将文件提交到我们的特性分支:
$git commit -m "adding python files for feature 1"
最后,将这两个文件提交到特性分支后,就可以将该特性分支推送到 CodeCommit:
$git push origin feature1
成功推送新特性分支后,你应该会从命令行收到确认信息:
* [new branch] feature1 -> feature1
现在我们已经将提交推送到我们的功能分支,并上传到了 CodeCommit 仓库,接下来是发起合并请求。这个合并请求将允许我们的代码成为主分支的一部分,供其他所有使用相同代码仓库的开发者使用,同时保持与主分支同步。
我们将作为开发者用户返回到 AWS 控制台以创建拉取请求。如果你仍然打开着开发者的单独会话,可以切换回该浏览器会话;否则,请登录aws.amazon.com/,然后使用开发者的用户名(在我们的例子中是mariel)和你为开发者用户更改的新密码:
-
在顶部的搜索框中,输入
CodeCommit,然后点击CodeCommit图标,进入服务页面。 -
你应该能看到你的仓库,如图 8.7所示。点击仓库名称(
chapter8)。 -
在顶部菜单中,你会看到一个下拉框,当前显示为main。点击该下拉框,选择你的分支(feature1)。完成后,你上传的两个文件将会显示出来。
-
现在你在顶部菜单中看到了你的分支名称,应该会看到一个名为创建拉取请求的按钮。点击这个按钮开始合并请求:
![图 8.12 – 创建拉取请求按钮与分支名称一起显示]()
图 8.12 – 创建拉取请求按钮与分支名称一起显示
-
应该会出现一个绿色框,显示我们目前没有分支与主分支之间的冲突。在创建合并请求之前,你需要在
Python 文件中添加一些内容。填写标题后,点击屏幕底部的橙色创建拉取请求按钮:![图 8.13 – 显示没有冲突的拉取请求]()
图 8.13 – 显示没有冲突的拉取请求
-
一旦你创建了拉取请求,系统将带你进入一个页面,在那里你可以查看当前打开的拉取请求的详细信息。
现在我们已经进入了拉取请求页面,这就是开发者用户停止的地方。我们分配的 IAM 策略不会允许他们合并分支,这是有意设计的。
接下来,使用我们的管理员身份,我们将学习如何将请求合并到主分支中。
CodeCommit 中的审批
随着开发者更新代码并将这些更新推送到 CodeCommit 仓库,尤其是当他们使用自己的功能分支时,需要有一个过程将他们的更改合并到主分支中。让我们一起看看如何将开发者在分支上创建的代码合并到主分支。
将开发者分支与主分支合并
此时,我们还没有为仓库启用任何通知,但在实际情况下,这是一个很好的方法,用来添加通知,当有人创建拉取请求时。我们的开发者已经在仓库中创建了一个分支,现在可以进行合并。作为具有合并权限的帐户用户,我们将登录并合并功能分支和主分支:
-
打开你的控制台,并以你到目前为止使用的主管理员用户登录Amazon Web Console,而不是开发者用户。
-
在屏幕中间的顶部搜索栏中导航到
CodeCommit。一旦CodeCommit图标显示出来,点击它:![图 8.14 – 在服务的顶部搜索框中搜索 CodeCommit]()
图 8.14 – 在服务的顶部搜索框中搜索 CodeCommit
-
一旦进入主 CodeCommit 屏幕,只要你处于正确的区域,你应该能看到我们之前由开发者用户创建的名为chapter8的仓库。点击此仓库名称,即可进入该仓库:
![图 8.15 – CodeCommit 中的 chapter8 仓库]()
图 8.15 – CodeCommit 中的 chapter8 仓库
-
点击仓库名称后,屏幕左侧会出现一组菜单选项,位于Repositories下。这里,你会看到一个子标题叫做Pull requests,它会展示我们任何未完成的拉取请求,包括之前由开发者用户创建的那个。点击Pull requests菜单项,进入拉取请求屏幕:
![图 8.16 – CodeCommit 仓库菜单中的拉取请求]()
图 8.16 – CodeCommit 仓库菜单中的拉取请求
-
我们的拉取请求名称应该是Python 文件,并以数字 1 为前缀。Python 文件是我们的开发者用户在最初创建拉取请求时使用的名称。我们还应该在拉取请求名称的右侧看到蓝色状态标记开放。点击拉取请求名称1:Python 文件,进入合并屏幕:
![图 8.17 – 带状态的拉取请求]()
图 8.17 – 带状态的拉取请求
-
现在,在拉取请求屏幕上,屏幕顶部会显示1:Python 文件,在标题下方你应该能看到三个彩色标签:开放(蓝色),无审批规则(深灰色),以及无合并冲突(绿色)。后者表示我们可以轻松地将拉取请求合并到主分支。点击屏幕右上角的橙色合并按钮来完成此操作:
![图 8.18 – 关于 CodeCommit 拉取请求的通知]()
图 8.18 – 关于 CodeCommit 拉取请求的通知
-
目前,我们将进入合并拉取请求屏幕。这个屏幕主要是关于合并策略,但在这个练习中,我们将保持默认设置不变。包括保持底部勾选框,该框将删除被合并的分支,并使用快速前进合并策略。点击页面右下角的橙色合并拉取请求按钮,将功能分支合并到主分支。
-
最后,你应该会看到屏幕顶部有一个绿色的通知,告诉你你的
feature1分支已经合并到主分支。
我们刚刚彻底了解了 CodeCommit 服务,并从多个团队成员的角度看了如何进行提交和合并。整理好源代码后,我们将来看一个可以生成软件包和测试软件的 AWS 服务:AWS CodeBuild。
使用 AWS CodeBuild
当buildspec文件和任务启动时,CodeBuild 将分配指定的资源。
这与其他构建系统不同,在其他系统中,你需要手动为工作节点配置计算资源,或者执行复杂的设置,以确保在高负载构建和测试期间有自动扩展的环境可用。
你可以将 AWS CodeBuild 作为独立服务运行,或者将其与其他服务(如CodeCommit和AWS CodePipeline)集成,创建一个可重复的、自动化的过程,成为你持续集成生命周期的一部分。
了解 CodeBuild 的功能
以下是你应该了解的一些 CodeBuild 的功能:
-
它是一个完全托管的构建服务:无需设置、修补或更新任何服务器或软件。
-
它可以根据需求进行扩展:CodeBuild 能够根据你的需求进行自动扩展和收缩。
-
它由 AWS 提供安全保障:通过 KMS 支持的可选加密功能,以及通过 IAM 对特定任务的权限控制,你可以放心地确保你的构建环境的安全性。
-
它是 AWS 开发者工具之一,能够与 CodeCommit、CodeDeploy 和 CodePipeline 紧密集成。
-
CodeBuild 与CloudWatch Events原生集成,以便触发失败的构建和项目,例如发送 SNS 消息。
-
日志可以设置为输出到 S3 或CloudWatch 日志。
-
可以使用 CloudWatch 指标和警报来监控 CodeBuild 的阈值。
创建 CodeBuild 任务
CodeBuild 在执行任务时非常灵活。以我们的例子为例,我们将创建一个buildspec文件来创建一个 Docker 镜像,然后将该 Docker 镜像推送到 ECR:

图 8.19 – 示例 CodeBuild 任务的布局
如果你还没有从本书的 GitHub 仓库下载Chapter-8文件,那么现在正是最佳时机,因为我们将在第一个 CodeBuild 练习中使用docker目录:
-
导航到您下载
Chapter-8文件的目录。不要进入docker目录,因为我们将使用递归命令一次性上传所有文件:$ aws s3 cp docker s3://{yourS3bucket}/docker/ --recursive -
首先,我们将创建我们的 ECR 仓库,以便容器在构建完成后有地方存放:
$aws ecr create-repository \ --repository-name chapter8 -
创建了 ECR 仓库后,我们将打开 AWS 控制台,完成 CodeBuild 项目的其余部分。确保使用管理员用户而不是开发者用户进行此操作。一旦 AWS 控制台打开,搜索框中输入
CodeBuild,然后点击图标以进入 CodeBuild 服务。 -
在 CodeBuild 服务中,点击右上角的橙色按钮,按钮上写着创建构建项目。
-
为了创建我们的项目,我们将从初始部分开始:
chapter8_dockerb.
chapter 8 的一个示例构建:![图 8.20 – CodeBuild 创建构建项目页面上的项目配置]()
图 8.20 – CodeBuild 创建构建项目页面上的项目配置
-
接下来,我们将移动到
devopspro-beyond。最后,我们将提供请求的密钥,这是我们上传文件所在的文件夹。在我们的例子中,这将是docker/。我们没有对存储桶进行版本控制,因此可以将此字段留空:![图 8.21 – CodeBuild 项目中的源声明]()
图 8.21 – CodeBuild 项目中的源声明
-
接下来,我们将进入
b.
aws/codebuild/standard:5.0e. 镜像版本:始终使用此运行时版本的最新版本
f. 环境类型:Linux
g. 服务角色:新建服务角色
注意
对于 CodeBuild 项目中的镜像,我们在这里指定了版本 5.0。然而,您可能想查找 AWS 提供的最新版本。
-
在这一点上,您可以将其余选项保持不变,滚动到页面底部,然后点击橙色的创建构建项目按钮。
-
现在,您应该进入到构建项目的页面。顶部会看到一条绿色横幅,显示您的构建项目已创建:
![图 8.22 – 在 AWS CodeBuild 中创建的成功项目]()
图 8.22 – 在 AWS CodeBuild 中创建的成功项目
-
现在,我们可以尝试运行我们的任务,看看结果如何。如果您想运行任务并开始构建,请点击屏幕右上角的橙色开始构建按钮。
这只是一个基础项目,并不需要是停止点。如果我们愿意,仍然可以编辑任务和 buildspec 文件,向任务添加增强功能。
通过控制台使用 S3 存储桶作为源创建项目后,我们将仔细查看实际运行 CodeBuild 任务的文件:buildspec 文件。
构建 buildspec 文件
buildspec 文件是驱动 CodeBuild 过程的文件,并且有一些严格的要求:
-
它必须命名为
buildspec.yml,不能使用其他名称。 -
它必须位于源代码文件夹的
root directory中。 -
它必须使用 YAML 语言。
如果你在完成前面的练习后打开 buildspec 文件进行检查,你会注意到它包含了三个主要部分:
-
Version:此字段告诉 CodeBuild 服务你正在使用的语法版本,它是少数几个必需的部分之一。
-
Install:此步骤仅用于在构建环境中安装软件包。如果你需要安装测试框架,例如pytest或Mocha,可以在此步骤执行此操作。b.
pre-build:这是在实际构建命令运行之前执行的命令。预构建命令可以包括登录到Build:在此阶段,会运行一些构建命令、创建容器,或者执行测试软件的命令。d.
post-build:一旦构建完成,这些是随后的命令,可以包括将软件打包成.jar或.war文件,或创建 Python 的 egg 文件。它甚至可能涉及将容器上传到 ECR 或 DockerHub 等仓库。 -
Artifacts:这是构建输出。这可以包括文件的名称、文件本身,或两者兼有。工件阶段还允许你保留文件创建时的目录结构,或者将其去除,仅保留文件本身。
根据你的使用场景,buildspec 文件中还提供了许多其他选项。你可以使用环境变量、生成报告,甚至以特定用户或 Linux 操作系统身份运行。完整选项列表,请参考 AWS 构建规范文档:docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html。
我们刚刚深入了解了如何构建 buildspec 文件以及它包含的组件。接下来,我们将重点讨论 CodeBuild 生成的工件,以及如何将它们导出并存储到其他地方。
存储 CodeBuild 工件
当你创建一个软件包时,可以让 AWS CodeBuild 自动将该工件保存到 S3 存储桶中,以便在部署过程中使用。
在 buildspec 文件中,如果你打算创建工件,你可以声明一个工件,也可以声明多个工件。在 创建 CodeBuild 作业 部分,buildspec 文件在最后声明了一个工件。
注意
虽然 CodeArtifact 的名称可能会让您认为可以在构建后自动存储 CodeBuild 构建产物,但实际上不能。CodeArtifact 可以与 CodeBuild 配合使用,提供语言包,就像 NuGet、PyPi 或 npm 服务器 在构建过程中提供的那样,帮助您的团队使用标准化的包,并避免来自公共服务器的下载限制。
使用 CodeBuild 进行测试
虽然人们首先想到使用 AWS CodeBuild 可能是为了创建用于部署的包和构建 Docker 容器,但这个服务还可以在软件开发生命周期(SDLC)过程中发挥双重功能,那就是进行测试。CodeBuild 允许您运行预定义的单元测试,并在控制台中查看图形和文本形式的报告,了解测试结果。
报告在创建后 30 天过期,一旦过期,您和任何有权限访问报告的人都无法查看报告。如果您需要将报告的结果保留超过 30 天,您可以选择将报告的原始结果导出到 S3 存储桶中,这样它们就不会过期,只会根据存储桶的生命周期策略逐步淘汰。
CodeBuild 支持以下测试报告文件格式:
-
Cucumber JSON
-
Junit XML
-
NUnit XML
-
TestNG XML
-
Visual Studio TRX
在您的 buildspec 文件中指定一个报告组名称,并提供关于测试用例的信息,如果尚未存在,CodeBuild 会为您创建一个报告组。
测试创建后,AWS CodeBuild 可以在控制台上显示报告,快速总结所有测试的状态。
通过 CodeCommit 触发 CodeBuild 作业
AWS CodeCommit 可以用作构建的输入源。CodeCommit 本身不能原生地向 CodeBuild 发出信号,告诉它已经收到新的提交或合并到分支中。然而,借助 Lambda 服务,您可以添加触发器来启动 CodeBuild 作业。
拥有像这样的自动化过程,无需手动干预,帮助团队更迅速地找到 bug 和已部署的软件。创建一个触发器,自动向 CodeBuild 项目发出信号启动构建,是为您的软件开发生命周期(SDLC)添加持续反馈的好方法:

图 8.23 – 从 CodeCommit 触发 CodeBuild 作业
现在我们已经了解了如何使用 CodeCommit 服务自动启动 CodeBuild 作业,我们也知道如何在新代码成功合并到项目中时自动启动 CodeBuild 作业。
在下一章,第九章,使用 CodeDeploy 和 CodePipeline 部署工作负载 中,我们将学习如何使用 CodePipeline 服务启动来自 CodeCommit 的构建过程。
接下来,我们将了解 AWS CodeBuild 的一些高级功能。
AWS CodeBuild 的高级功能
本节中我们将讨论的一些功能对于 DevOps 专业考试不是强制要求的。由于本书标题中有 beyond,以下是一些有助于让服务使用更便捷的功能。它们也是一些可以与团队成员和客户分享的好技巧。
使用 AWS Session Manager 帮助排查构建问题
如果你在排查构建问题时遇到困难,而不是寻找 ssh 进入基于 AWS 的 Docker 镜像会话管理器,AWS Session Manager 将允许你进入构建环境并尝试排查发生了什么。你可以通过在 buildspec 文件中添加 codebuild-breakpoint 来暂停构建:
phases:
pre_build:
commands:
- echo Entered the pre_build phase...
- echo "Hello World"> /tmp/test.txt
- codebuild-breakpoint
完成故障排除后,你可以通过命令提示符传递 codebuild-resume,以便从 buildspec 文件中中断的位置继续。
总结
在这一章中,我们讨论了如何使用 AWS 原生的源代码工具 CodeCommit 让团队共享代码。我们还探讨了如何使用 CodeBuild 工具对软件进行打包、构建和测试。
在下一章中,我们将继续讨论 AWS Developer Tools。这包括使用 CodeDeploy 部署工作负载,然后通过 AWS CodePipeline 将一切串联起来。
复习题
-
你被要求为你的组织设置一个 CodeCommit 仓库,供开发团队使用。开发人员需要能够将提交推送到他们的分支,但不能将提交合并到主分支,也不能将提交推送到主分支。项目经理还需要在合并或提交到主分支时收到通知。哪个步骤组合能以最短时间保护主分支并发送通知?
为 CodeCommit 仓库附加一个资源策略,拒绝 IAM 开发者组成员对主分支执行推送提交、合并请求和添加文件的操作。
b. 为开发者 IAM 开发者组附加一项 IAM 策略,拒绝其对主分支执行推送提交、合并请求和添加文件的操作。
配置 AWS CloudTrail 将日志事件发送到 Amazon CloudWatch 日志。创建一个基于定义的度量标准过滤器的 CloudWatch 警报,以识别 CodeCommit 仓库事件。使用 SNS 主题作为目标,项目经理已订阅该主题以接收 CloudWatch 警报。
d. 创建一个 Amazon CloudWatch Events 规则,该规则会在主分支的 CodeCommit 仓库状态更改事件触发时运行。使用一个项目经理已订阅的 SNS 主题作为目标。
e. 创建一个 Lambda 函数,检查仓库的变更,如果发现变更,则将事件发送到项目经理已订阅的 SNS 主题。让 AWS CloudWatch Events 每 15 分钟运行一次 Lambda。
-
你在账户中有一个 CodeCommit 代码库,开发者对该代码库有有限的操作权限。来自不同组织单元的两位新开发者需要访问这个 CodeCommit 代码库,但他们的用户位于不同的 AWS 账户中。授予这两位新开发者访问权限的最有效方式是什么?
a. 为代码库启用公开访问权限。
b. 为每个新开发者创建 IAM 用户,并授予他们对代码库的访问权限。
c. 为外部开发者创建一个 IAM 组,添加 IAM 用户,然后为其提供对代码库的访问权限。
d. 在你的账户中创建一个跨账户角色,为该角色分配必要的权限,然后将角色 ARN 提供给开发者,以便他们可以假设该角色。
-
一位客户正在寻找一个新的代码版本控制服务,并且不再希望管理自己服务器的麻烦。目前,他的团队规模较小,预计在接下来的四个季度不会急剧增长,但他非常关注任何他考虑的服务是否具备加密功能。关于 AWS CodeCommit 如何保护对象和代码的加密能力,你能向他解释什么?
a. 所有传输内容在传输过程中都是加密的,并且只能通过 HTTPS 或
SSH协议进行。b. 通过
SSH协议发送时,传输内容在传输过程中是加密的。c. CodeCommit 代码库会自动使用 KMS 进行加密。
d. CodeCommit 代码库可以使用 KMS 进行加密。
-
你正在设置一个新的构建过程,使用 S3 作为代码源。你希望对你和其他开发者之前创建并放置在名为
test/的目录中的代码进行单元测试,该目录位于主源代码目录的子目录中。你计划在这个构建过程中工作 60 天,并希望能够查看历史的测试报告,甚至是第一次构建的报告。你如何通过原生 AWS 服务配置这一过程?a. 测试报告将在
buildspec文件中提供。b. 在每次构建后将 CodeBuild 测试数据导出到 S3,并使用 AWS QuickSight 创建测试报告。
c. 如果你在
buildspec文件中指定了报告部分,则测试报告将可在控制台的 CodeBuild 部分的 Reports 选项卡中查看。创建一个 Lambda 函数,该函数由 CloudWatch 事件触发,导出从测试报告中获取的原始数据,并将其保存到 S3 存储桶中,供后续查看。d. 使用原生的 AWS 服务无法实现此操作。
查看答案
-
b, d
-
d
-
a, c
-
c
第九章:使用 CodeDeploy 和 CodePipeline 部署工作负载
团队们正在寻找一种易于使用的工具,能够自动化发布过程,并提供一致的发布流程。我们将介绍如何将CodePipeline与第三方工具 Jenkins 结合,来自动化我们的部署发布周期,进而与CodeDeploy集成,实现实际的代码部署。
本章我们将讨论以下主要内容:
-
关于 AWS CodePipeline
-
设置代码管道
-
使用 Jenkins 构建工作负载
-
关于 AWS CodeDeploy
-
AWS CodeDeploy 使用案例
技术要求
如果你打算跟随本章中的练习进行操作,需要注意,前一章的内容 第八章,《使用 CodeCommit 和 CodeBuild 创建工作负载》是本章的前提。如同现实世界中一样,我们在前面章节中所做的工作基础上继续构建。因此,如果你没有在上一章创建开发者用户,你需要为该用户设置相应的身份与访问管理(IAM)权限。
关于 AWS CodePipeline
AWS CodePipeline 可以被看作是一个管弦乐团中的指挥。通过代码或 AWS 控制台,你可以将软件开发生命周期过程以可视化方式组织起来,过程可以是完全自动化的,也可以在某些阶段设置手动检查,确保每个阶段顺利通过。整个过程会以图形化的方式呈现给你的团队成员(包括开发者、测试人员和其他人员),让他们了解哪些部署成功,哪些部署失败。
AWS CodePipeline 帮助你自动化发布软件和基础设施更改的步骤,实现持续交付,如下图所示:

图 9.1 – CodePipeline 及其与其他 AWS 开发工具的集成
不同的 AWS 开发服务,其中 CodePipeline 是其中之一,如图 9.1所示,并展示在系统开发生命周期(SDLC)的各个阶段下。
CodePipeline 动作结构
CodePipeline 结构包括几个不同的类别,允许原生 AWS 服务进行操作,或允许支持的第三方服务集成并执行必要的操作。
这里列出了六个有效的动作类别:
-
源
-
构建
-
测试
-
部署
-
审批
-
调用
每个动作类别都有一组可以调用动作或允许从该资源调用动作的提供者,如下表所示:

表 9.1 – CodePipeline 源动作和动作提供者
除了动作集成外,还有一些其他 AWS 服务无需特定的动作类别即可集成,具体如下:
-
Amazon CloudWatch:CloudWatch 可以监控使用管道构建的资源,或者监控正在测试并集成到管道中的资源。
-
Amazon CloudWatch Events:CloudWatch Events 可以检测整个管道的变化,甚至可以检测管道某些阶段的变化。CloudWatch Events 甚至可以监听其他外部服务,并在特定情境发生时触发 CodePipeline 运行,例如当有人更新了 CloudFormation 堆栈时。这时可能需要重新部署软件。
-
AWS Cloud9:Cloud9 是一种基于云的集成开发环境(IDE),可以通过网页浏览器访问。
-
AWS CloudTrail:如果 CloudTrail 服务在特定区域处于激活状态,任何通过 AWS 控制台、软件开发工具包(SDK)或命令行接口(CLI)进行的应用程序编程接口(API)操作都会被捕获并记录。
-
AWS KMS:密钥管理服务(KMS)可以与 AWS CodePipeline 集成,用于源 S3 存储桶和工件,这些存储桶和工件要么是加密的,要么需要加密。假设工件来自与执行 CodePipeline 的帐户不同的帐户,那么加密该存储桶和对象的密钥将需要是客户管理的密钥。
从表 9.1中可以看到,既有原生的 AWS 服务,也有您可能已经在使用的第三方合作伙伴工具,这些工具可以集成到您的代码管道阶段中。
我们刚刚查看了不同的操作以及相应的 AWS 服务和第三方服务,这些服务可以帮助执行这些操作。接下来,我们将看看一些 AWS CodePipeline 的使用案例,包括真实世界的使用案例。
AWS CodePipeline 的使用案例
在考虑使用 CodePipeline 能做什么时,有一些特定场景已经确定 CodePipeline 作为工具是最合适的选择。接下来我们将看看这些场景中的一些。
自动化您的构建和发布过程
CodePipeline 允许开发人员专注于他们正在编写的代码,然后将代码提交到 Amazon 托管的代码库或第三方代码库,如 GitHub 或 Bitbucket Cloud。开发人员推送的新代码提交将触发构建过程。
为开发人员创建一致的工具集
在组织中让新开发人员快速上手并提高生产力的最具挑战性部分之一是入职过程。CodePipeline 通过提供一致的工具集来帮助这个过程,无论团队成员位于哪个时区,或使用什么操作系统。
使用 CodePipeline 与第三方提供商集成
假设你的团队当前使用像 Jenkins 这样的第三方工具进行代码构建或测试,BlazeMeter 进行负载测试,或 StormRunner 进行测试过程,那么 CodePipeline 可以帮助将所有这些工具统一协调展示。
使用一个服务账户从 CodePipeline 服务中调用,而不是每个个人或团队请求自己的许可证,也可能会带来成本节约的好处。
使用 Elastic Beanstalk 和 CodePipeline 持续部署你的 Web 应用程序
尽管 Elastic Beanstalk 常被认为是一个帮助开发者快速启动代码、并且接触较少 AWS 基础设施的服务,但这些代码可以成为组织中的成功项目。集成 CodePipeline 使得不再依赖于 Elastic Beanstalk CLI 或在 AWS 管理控制台中追踪部署,而是采用一种更结构化、可追踪的方式。
现在我们已经检查了一些 CodePipeline 成功使用的不同场景,接下来我们可以进入实际操作示例。在这里,我们将按照步骤设置我们自己的 AWS CodePipeline,并利用 CodeCommit 仓库。
设置代码管道
体验 AWS CodePipeline 的最佳方法之一是通过设置代码管道的练习。通常,这些管道的设置工作会由指定工具的团队成员完成。这些工具团队成员拥有与开发人员不同的独特权限集。
我们需要设置工具团队组并为他们分配正确的权限集。之后,我们可以创建工具团队成员并将其关联到工具团队 IAM 组。然后,我们可以以该工具团队成员身份登录,并让他们构建管道。
在设置管道之前创建我们的代码库
在设置我们的代码管道之前,我们将先创建一个全新的 CodeCommit 仓库。事先创建仓库将使我们能够拥有一套新的代码,用来执行管道中的各个步骤。
在我们 GitHub 仓库的chapter9部分,会有一个名为code的文件夹。这个文件夹将包含我们需要上传到即将创建的 CodeCommit 仓库的源代码,具体步骤如下:
-
打开浏览器,访问 AWS CodeCommit 首页,
console.aws.amazon.com/codesuite/codecommit/home,如果出现提示,请登录。 -
点击屏幕右上方的橙色创建仓库按钮。
-
在
chapt9中设置仓库名称。我们将添加描述,说明这个仓库是用于CodePipeline的,以便与在上一章节中创建的chapt8仓库区分开来,后者是作为测试创建的,参见第八章,使用 CodeCommit 和 CodeBuild 创建工作负载,如以下截图所示:![图 9.2 – chapt9 仓库的 CodeCommit 仓库设置]()
图 9.2 – chapt9 仓库的 CodeCommit 仓库设置
-
点击橙色的创建按钮。
-
由于我们已经在第八章中创建了一个可以上传文件的用户,使用 CodeCommit 和 CodeBuild 创建工作负载,现在只需点击左侧菜单中的Repositories(仓库)菜单项,如以下截图所示。这样就会显示我们在 CodeCommit 中的所有仓库名称,并允许我们复制需要的链接,以便将仓库克隆到本地工作站:
![图 9.3 – CodeCommit 的侧边菜单,仓库部分高亮显示]()
图 9.3 – CodeCommit 的侧边菜单,仓库部分高亮显示
-
现在,点击
chapt9仓库右侧的SSH链接,如以下截图所示。此时会弹出一个小对话框,确认该链接已被复制,你可以准备将仓库克隆到本地工作站:![图 9.4 – 已复制到剪贴板的 SSH 克隆统一资源定位符(URL)]()
图 9.4 – 已复制到剪贴板的 SSH 克隆统一资源定位符(URL)
此时,我们暂时完成了 AWS 控制台的操作,接下来将切换到本地工作站的终端,进行下一组命令操作。
-
现在,打开终端,进入到你的主目录根目录。在 Linux 系统中,你可以通过
$cd ~命令快速进入该目录。接下来,执行以下命令将仓库克隆到本地。现在,我们可以使用剪贴板中的 URL 来克隆仓库:$ git clone ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/chapt9一旦你成功克隆了仓库,你应该会收到一条确认消息,表示你已经克隆到一个空的仓库。
-
尽管我们有一个空的代码库,我们将从 GitHub 仓库的
/code目录中获取示例代码,然后将其复制(或者如果你不希望在本地机器上有两个代码副本,可以选择移动)到这个新的本地CodeCommit仓库,这样我们就可以将其推送到CodeCommit。确保你从已经克隆了 GitHub 示例代码的目录开始,如以下代码片段所示:
$ cp -R * ~/chapt9/如果你不想通过命令行复制文件,也可以使用文件资源管理器(File Explorer)或 Finder,将文件复制到新的 git 仓库中。
-
现在我们已经将文件复制到
CodeCommit本地目录中,接下来我们需要将所有文件添加到提交中。添加文件并编写commit消息后,我们将文件推送到代码库。我们可以通过几个简单的命令完成这一切。首先,我们需要从克隆的示例代码所在的目录切换到本地CodeCommit代码库,如下所示:$ cd ~/chapt9 -
由于我们当前在本地目录中,我们现在可以添加所有文件并将其推送到远程的
CodeCommit代码库。我们通过使用git add、git commit和git push命令来完成,操作如下:$ git add * $ git commit -m "adding sample code to CodeCommit" [master (root-commit) f85e8f2] adding sample code to CodeCommit 2 files changed, 52 insertions(+) create mode 100644 buildspec.yml create mode 100644 src/app.py $ git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 825 bytes | 825.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 To ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/chapt9 * [new branch] master -> master
现在,示例代码已经准备好,我们可以继续进行下一步,即创建工具团队成员。我们的工具团队成员是专注于创建和管理管道及流程的人,而不仅仅是编写代码的人。
创建我们的工具团队成员
就像我们之前创建了开发组和成员一样,我们也需要为工具团队成员做同样的事情。重要的是要区分团队成员的职责,并只赋予每个人执行其工作职责所需的权限。在创建工具成员之后,我们将以该工具团队成员的身份登录,然后运行名为pipeline1.yml的 CloudFormation 模板来构建管道。
让我们继续设置工具团队成员的组,如下所示:
-
打开你的终端并输入以下命令,以便我们创建新的组:
$aws iam create-group --group-name Tools运行命令后,你应该看到类似下面的确认信息:
{ "Group": { "Path": "/", "GroupName": "tools", "GroupId": "AGPAW24Q7QQFSHYZHE6N6", "Arn": "arn:aws:iam::470066103307:group/tools", "CreateDate": "2021-05-14T01:25:58+00:00" } }注意返回的组名称对应的 ARN。你需要将其保存到记事本中,或者滚动到上方进行复制和粘贴,方便我们下一步将创建的策略附加到该组时使用。
-
接下来,我们需要使用预先制作的策略文档来创建策略,该文档应该已从 GitHub 仓库的
Chapter9文件夹中下载,文件名为IAM_Tools.json,如下所示:JSON after creation, as in the following statement:{
"Policy": {
"PolicyName": "Tools_Members",
"PolicyId": "ANPAW24Q7QQF6FPOCHV5V",
"Arn": "arn:aws:iam::470066103307:policy/Tools_Members",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2021-05-16T19:32:41+00:00",
"UpdateDate": "2021-05-16T19:32:41+00:00"
}
}
-
创建策略后,我们将把策略附加到组中,操作如下:
policy-arn field use the value which was returned to you in step 1:--policy-arn arn:aws:iam::470066103307:policy/Tools_Members \
--group-name tools
If the policy attachment is successful, then there will be no confirmation message. -
现在我们已经创建了
tools组,可以创建一个用户成为工具团队成员。这个工具团队成员将是我们用于创建实际代码管道的用户。让我们继续创建我们的新用户,如下所示:aws iam create-user --user-name peter -
现在,我们可以将新用户添加到
tools组中,使其拥有该组的权限,如下所示:aws iam add-user-to-group --user-name peter --group-name Tools -
就像我们在第八章中创建的开发者用户一样,使用 CodeCommit 和 CodeBuild 创建工作负载,我们需要为工具用户设置一个初始密码,该密码将在第一次登录时由用户重置,具体如下:
aws iam create-login-profile --user-name peter --password Dev0psPRO --password-reset-required
到此为止,我们已经创建了工具用户,并且准备好以工具用户身份登录 AWS 控制台,搭建 AWS 管道。
创建管道
在创建了我们的工具用户(在我们这个例子中是 Peter)后,我们将从使用 AWS CLI 切换到浏览器和管理控制台,并假装这些操作是由工具用户执行的。在开始之前,你需要确保从本书的 GitHub 仓库中的Chapter9文件夹下载pipeline1.yml文件。
打开一个新的浏览器窗口,不带有任何 cookie 或会话,这样我们就可以作为 Peter 登录 AWS 控制台。你可能需要打开一个隐身窗口或使用一个不同的浏览器。例如,如果你一直在 Chrome 中使用管理员权限,则可以在 Firefox 或 Edge 中打开一个新会话,按以下步骤操作:
-
使用你的账号号码或账号别名以及用户名称
peter和我们之前创建的Dev0psPRO密码,登录 AWS 控制台。 -
系统会立刻提示你更改用户
peter的密码。将此密码更改为你喜欢的任何密码,但请记下或者设置一个你能记住的密码,因为你可能需要稍后访问此用户。以下截图显示了该过程:![图 9.5 – 工具用户 peter 的密码更改]()
图 9.5 – 工具用户 peter 的密码更改
-
更改密码后,AWS 控制台将带你进入主控制台页面。使用顶部的统一搜索框搜索CloudFormation服务。服务出现后,点击服务图标,进入主 CloudFormation 页面,如下图所示:
![图 9.6 – CloudFormation 服务图标]()
图 9.6 – CloudFormation 服务图标
-
在主CloudFormation服务页面上,点击橙色的创建堆栈按钮。
-
在创建堆栈页面,使用以下选项:
a. 准备堆栈—确保选中模板已准备好
b. 指定模板—选择标有上传模板文件的复选框
-
然后,点击
pipeline1.yml文件并打开它。选中文件后,点击屏幕底部的橙色下一步按钮,如下图所示:![图 9.7 – 创建 CodePipeline 堆栈]()
图 9.7 – 创建 CodePipeline 堆栈
-
一旦点击
C9-demo并输入你希望接收堆栈通知的电子邮件地址。你可以将电子邮件地址留空,或者输入你自己的电子邮件地址。如果你创建的分支名为main,则无需做任何更改;但是,如果你创建的分支名为master(如我们的示例),则需要在master中更改默认值,然后再继续,否则管道将无法立即执行。填写完这些值后,点击屏幕底部的橙色下一步按钮,如下图所示:![图 9.8 – 添加值到指定堆栈详细信息屏幕]()
图 9.8 – 添加值到指定堆栈详细信息屏幕
-
在配置堆栈选项屏幕上,我们不会添加任何标签。只需滚动到页面底部,点击橙色的下一步按钮。
-
现在,在审查 C9-demo页面上,滚动到页面底部,并勾选蓝色区域中的框,确认该堆栈将创建一个 IAM 角色,在功能标题下显示。勾选框后,你可以点击橙色的创建堆栈按钮,如下图所示:
![图 9.9 – 在审核中的“功能”部分检查确认信息]()
图 9.9 – 在审核中的“功能”部分检查确认信息
-
一旦点击,你将被带到
CREATE_IN_PROGRESS状态,直到我们的代码管道创建完成。完成后,我们就可以继续进行下一步了。 -
在 CloudFormation 过程完成后,我们将能够返回统一搜索栏,搜索
CodePipeline服务。一旦CodePipeline的图标出现,如下图所示,点击它即可进入当前的管道:![图 9.10 – 从统一搜索栏中的 CodePipeline]()
图 9.10 – 从统一搜索栏中的 CodePipeline
-
你应该能够看到刚刚创建的管道,名称为
C9-demo。点击此名称查看管道的详细信息。
我们可以从我们创建的管道中看到,现在已经创建了一个包含三个阶段的管道:源、构建和部署。在部署阶段包含了集成过程,包括手动审批流程,以及 CloudFormation 创建过程。
注意
如果你没有完成前面的练习,即创建名为chapt9的 CodeCommit 仓库,那么你将遇到管道问题。这个chapt9仓库是我们 AWS 代码管道的代码源。如果你将仓库命名为其他名称,你需要修改 CloudFormation 模板,或者进入 AWS 控制台修改源阶段。
现在,随着我们构建了 AWS 代码管道,我们可以继续让我们的开发者测试提交,并查看管道在实际操作中的各个阶段,就像它在现实生活中运行一样。然而,在此之前,我们需要为开发者用户提供更多的 IAM 权限,因为他们在最初创建时,只拥有 CodeCommit 权限并且只能修改自己的密码。
更新我们的开发者用户
在上一章,第八章,使用 CodeCommit 和 CodeBuild 创建工作负载,我们为开发者创建了一个用户组。我们为他们提供了一组权限,限定在 AWS CodeCommit 和 CodeBuild 服务内。由于现在我们要加入 CodePipeline 和 CodeBuild,因此我们需要扩展他们的权限,以便他们也能使用这些服务。在 GitHub 的 Chapter9 仓库中,有一个名为 IAM_Developers.json 的文件——请务必下载该文件,以便更新开发者的权限。在更新命令时,您需要使用管理员用户。我们将按以下步骤进行:
注意
在执行这些命令之前,请确保您已经从 GitHub 仓库的 Chapter9 文件夹下载了 IAM_Developers.json 文件,并且位于下载该文件的同一目录下。
-
我们需要做的第一件事是找到附加到开发者的策略的 ARN。我们在 第八章,使用 CodeCommit 和 CodeBuild 创建工作负载 的练习中创建了该策略。登录到终端并运行以下命令,提取开发者组的 ARN:
aws iam list-policies --query 'Policies[?PolicyName==`CC_Developers`].Arn' --output text执行此命令后,我们应该会得到当前用于 Code Commit 开发者组的 ARN 返回结果。接下来,我们将在下一步中使用该 ARN 更新我们的策略。
-
在获得 ARN 后,我们可以创建一个新的策略版本,并将该版本设置为
默认,如下所示:aws iam create-policy-version \ --policy-arn arn:aws:iam::470066103307:policy/CC_Developers \ --policy-document file://IAM_Developers.json --set-as-default如果成功,我们将返回一个JavaScript 对象表示法(JSON)消息,显示我们现在正在使用策略的第二个版本,如以下代码片段所示:
{ "PolicyVersion": { "VersionId": "v2", "IsDefaultVersion": true, "CreateDate": "2021-05-16T19:01:09+00:00" } }
更新我们的开发者用户组,以允许访问 CodePipeline,允许开发者查看之前创建的管道,并查看在管道各个步骤中可能遇到的错误。这些权限的范围被限制为不允许开发者创建或修改任何新的或现有的管道。
CodePipeline 概念
使用 AWS CodePipeline 时,需要了解几个基本概念和术语,如下图所示:

图 9.11 – CodePipeline 转换表示
理解 CodePipeline 和阶段需求
在开始构建管道时,有一些规则和要求是应该了解的,因为这有助于你避免在调试错误时遇到麻烦。请查阅接下来的清单,了解最佳实践,并记住考试时的知识点:
-
管道中的所有阶段名称必须是唯一的。
-
只有管道中的第一个阶段可以包含源操作。
-
一个管道必须至少包含两个阶段。
-
单个阶段中的所有操作必须是唯一的。
-
阶段的输入操作必须与前一阶段的输出操作完全匹配。
-
输出工件名称必须在管道中唯一。如果某个阶段的输出工件名为
TestPackage,则该管道中的其他阶段不得有名为TestPackage的输出工件。 -
对于所有支持的操作类型,唯一有效的所有者字符串是
AWS、ThirdParty或Custom。
有其他更复杂的要求;然而,如果你理解了这些要求,那么你就为使用 CodePipeline 服务打下了坚实的基础,并且对 DevOps 专业考试中的阶段细节有了深入理解。
现在我们已经整体了解了 AWS CodePipeline 中的各个阶段,让我们来看看一个未被自动化的方面:审批操作。
CodePipeline 中的审批操作
在 CodePipeline 中,可以在阶段之间使用审批操作进行暂停。审批操作允许在继续进入管道的下一个阶段之前,手动审核操作。
经审核人批准的操作将进入管道的下一个阶段。如果审批被拒绝,则管道不会继续到下一个阶段。你也有 7 天时间来批准管道操作,否则管道将失败。
在 AWS CodePipeline 中使用审批操作的常见原因如下:
-
在进入下一阶段之前,进行手动质量保证(QA)测试
-
在继续之前,允许进行代码审查或变更管理审查
-
允许在发布到生产环境之前手动审核网页
使用 Jenkins 构建你的工作负载
AWS 提供的开发者工具几乎可以为你提供所有所需的功能,而无需额外的配置或设置。有些情况下,团队已经围绕现有工具构建了部分持续集成/持续部署(CI/CD)流程,并且可能希望保留已经投入时间和精力精细化的部分工作。
使用 Jenkins 服务器的团队可以属于这种情况之一。借助其庞大的插件生态系统,Jenkins 能够为 CI/CD 流程提供极大的功能支持。
许多团队在 CI 过程的构建阶段使用 Jenkins,因为在 Jenkins 中,构建步骤可以通过 Shell 脚本来实现,无需创建额外的buildspec文件。
下图展示了 Jenkins 与 CodePipeline 一起使用的情况:

图 9.12 – Jenkins 与 CodePipeline 一起使用
Jenkins 本身有插件,可以与许多 AWS 服务兼容,包括开发者服务套件。
现在我们已经了解了 CodePipeline 服务,包括如何将 Jenkins 构建服务器等第三方工具集成进来,接下来看看如何使用 AWS CodeDeploy 部署我们的工作负载,不论是单独部署还是作为管道的一部分。
关于 AWS CodeDeploy
AWS CodeDeploy 是一个帮助自动化将应用程序代码和文件部署到 EC2 实例、本地服务器、Lambda 函数和运行在 AWS ECS 上的容器的服务。
CodeDeploy 是一个服务,它使以下事项变得更加简便:
-
更新 Lambda 函数并创建新版本。
-
在应用程序部署期间避免停机
-
快速发布新功能
-
在部署失败的情况下,及时回滚到已知的良好版本。
AWS CodeDeploy 专注于以下三个平台的部署:
-
EC2/本地实例
-
Lambda 函数
-
ECS 容器化应用程序
使用这三个平台作为基础,你需要在名为 appspec 的文件中描述你的部署。这个文件可以使用 JSON 或 YAML Ain't Markup Language(YAML)格式编写。
CodeDeploy 可以分发多种类型的文件和组件,包括以下内容:
-
可执行文件
-
包
-
脚本
-
多媒体文件
现在我们已经掌握了 CodeDeploy 的基础知识,接下来看看在使用 CodeDeploy 服务时需要理解的基本概念。
需要理解的基本 CodeDeploy 概念
当我们开始使用 CodeDeploy 服务时,有一些组件需要首先理解。
应用程序
这是一个唯一的名称,CodeDeploy 使用它来标识你想要部署的应用程序。它使用这个唯一名称来确保在特定部署过程中引用的是正确版本的部署、部署组、修订版或回滚。
计算平台
这是 CodeDeploy 实际部署应用程序的平台。CodeDeploy 部署有很多选择。只要满足操作系统要求,部署可以发生在 EC2 实例或本地服务器上。这些部署可以包括配置文件、镜像、可执行文件及其他类型的文件。
CodeDeploy 还可以用于更新 Lambda 函数。CodeDeploy 还具备将流量从一个版本的 Lambda 函数转移到新版本的能力,支持多种部署选项,包括 金丝雀、线性 和 一次性全部部署。
如果你在 ECS 平台上使用容器,则可以使用 CodeDeploy 来更新任务,采用 蓝绿部署 策略,首先安装新版本的任务集,然后将流量切换到任务集的最新版本。与 Lambda 部署一样,这些部署可以采用金丝雀、线性或一次性方式进行。
部署配置
使用一组成功或失败标准以及部署规则,CodeDeploy 会根据每次部署的部署配置来进行引导。在部署配置中,特别是在 EC2 或本地部署的情况下,你可以设置成功的最小健康实例数量,以确保部署成功。如果你部署的是 Lambda 应用程序或 ECS 任务,则可以在部署配置中指定流量在部署过程中如何路由。以下是可用的部署方式:
-
金丝雀:流量分两次进行转移,并且你可以指定在第一次转移前初始转移的流量百分比,剩余流量会在指定的分钟数后进行转移。
-
线性:流量按相等的增量进行转移。你可以预定义可以转移的百分比和转移之间的时间间隔。
-
一次性:所有流量会同时从原始的 Lambda 函数或 ECS 任务转移。
部署组
部署组适用于 EC2 实例,无论是单独的还是在自动扩展组(ASGs)中,并且会明确标记用于指定部署目标。
部署组可以简单地通过一个标签来指定部署组,或者你可以通过在一个部署组中使用多达 10 个标签来进行更复杂的配置。
部署类型
部署类型是 CodeDeploy 用来将最新版本的应用程序部署到部署组中的技术。有两种不同类型的部署方式:就地部署和蓝绿部署。
在就地部署中,虽然可能更具成本效益,但部署组中当前实例上的应用程序会被停止,同时安装最新版本的应用程序。新版本的应用程序会重启并进行验证。就地部署仅适用于 EC2 实例或本地部署。
蓝绿部署会配置一组新的资源。这可以包括创建新的 Lambda 函数版本,ECS 中创建新的任务集,或者在 EC2 中创建新的实例。
蓝绿部署不适用于本地部署。
修订版
AWS Lambda 部署的修订版是一个 YAML 或 JSON 格式的文件,包含有关要部署的 Lambda 函数的信息。Lambda 的修订版存储在 S3 存储桶中。
对于 EC2 或本地部署修订版,这不仅仅是一个文件,而是一个包含组件(如网页、可执行文件、源代码和部署脚本)的文件集合,以及应用程序的规范,然后将其打包成归档格式。EC2 或本地实例的修订版可以存储在 S3 存储桶或 GitHub 仓库中。
目标修订版
这是已经上传到代码仓库中的应用程序的最新版本,将被作为目标进行部署。
安装 CodeDeploy 代理文件
当使用 CodeDeploy 与 EC2 实例时,代理文件会被放置在这些实例上,使得实例能够从 CodeDeploy 服务进行部署。同时,配置文件也会被放置在实例上,并且该文件指定了代理如何工作。这些实例不仅必须在 AWS 云中,还可以位于本地数据中心的特定操作系统上。
查看以下列表,了解哪些操作系统已经使用 AWS CodeDeploy 代理进行过测试:

表 9.2 – 测试过的操作系统,用于使用 AWS CodeDeploy 代理
任何你希望与 CodeDeploy 一起使用的 EC2 实例,也需要附加一个服务角色,以授予它足够的权限,以便 CodeDeploy 服务能够执行其职责。
理解 appspec 文件
应用程序规范文件,或者通常所说的 appspec 文件,在大多数情况下是一个 YAML 文件(虽然它也可以格式化为 JSON 格式),它有特定的几个部分,以及一些可选的部分,具体取决于你要执行的部署类型。
appspec 文件详细说明了在部署过程中你希望执行的部署操作。
如果你正在为容器做 ECS 部署、为 EC2 或本地实例部署,或者试图部署到 Lambda 实例,那么 appspec 文件有不同的类型。
以下是一个 appspec 文件的示例:
version: 0.0
Resources:
- myLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Name: "myTestFunction"
Alias: "myTestFunctionAlias"
CurrentVersion: "1"
TargetVersion: "2"
Hooks:
- BeforeAllowTraffic: "LambdaFunctionToValidateBeforeTrafficShift"
- AfterAllowTraffic: "LambdaFunctionToValidateAfterTrafficShift"
在我们示例中的 appspec 文件中,重要的项目包括版本、资源和钩子。
部署回滚和内容重新部署
AWS CodeDeploy 可以回滚一个已经被手动停止或在部署过程中失败的部署。严格来说,这些回滚是新的部署,并且会接收新的部署标识符(ID)。回滚确实会恢复一组代码的先前版本。回滚可以通过自动回滚或手动过程两种方式进行。
自动回滚
您的部署组可以配置为在部署失败时或在部署过程中达到某些监控阈值时自动回滚。如果设置了其中一个阈值并在部署过程中触发了自动回滚,那么部署将回到上一个已知的良好配置。
您还可以选择在开始新的部署时,通过配置部署组的高级配置选项来覆盖先前设置的自动回滚选项。
手动回滚
即使您没有设置自动回滚部署,使用 AWS CodeDeploy,您仍然可以推出之前版本的部署。这将创建一个新的部署版本。如果您的部署失败,或者实例进入未知状态,您可以通过推送应用程序和配置更新来修复它们。
回滚和重新部署工作流
如果回滚是自动或手动触发的,那么 CodeDeploy 将开始尝试删除在部署过程中成功安装的所有文件。
清理文件(如果存在)是一种日志文件,CodeDeploy 会保存它,以便知道哪些文件已被安装,并在开始新的部署之前删除这些文件。
在部署过程中,CodeDeploy 代理会记录正在部署的文件名,以便在需要回滚时有记录。
在回滚的情况下,CodeDeploy 会参考清理文件,以便知道需要删除哪些文件。然后,它可以在自动回滚的情况下继续执行之前的版本部署。
现在了解了部署和回滚的工作原理,让我们来看一下 AWS CodeDeploy 的一些使用案例。
AWS CodeDeploy 的使用案例
在我们了解了 AWS CodeDeploy 服务之后,让我们思考一些在什么情况下该服务最适合我们使用。
将应用更新部署到本地数据中心的服务器
如果您的本地硬件上运行的是兼容的操作系统,则可以使用 AWS CodeDeploy 来协调部署,并通过单一界面查看成功和失败。安装 AWS CodeDeploy 代理是必要的前提条件。这些操作系统包括 Windows Server、Ubuntu Server 或 RHEL。
将应用更新部署到 AWS 云中的 Windows 或 Linux 服务器
如果您正在将应用程序部署到 Linux EC2 实例上的 NGINX 或 Apache 服务器,或 Windows 服务器上的 Internet Information Services (IIS) 实例,则可以使用 CodeDeploy 代理来协调文件的放置,并重新启动任何需要更新文件的服务。
使用一次部署推送将应用更新部署到多个区域
当您寻找一种方法来构建解决方案,以在多个区域中为部署创建自动化端到端(E2E)发布流程时,AWS CodeDeploy 可以通过 AWS CodePipeline 的帮助来实现此目标。在尝试保持 Lambda 部署以实现高可用性(HA)或灾难恢复(DR)策略时尤为如此。在以下图表中,您可以看到 CodeDeploy 被用来在多个区域进行部署:

图 9.13 – 使用 CodePipeline 和 CodeDeploy 进行多区域部署
使用 S3 作为源代码的起点将通过 AWS 代码流水线启动部署。如果流水线成功,则它将进入一个调用阶段,其中 Lambda 函数将源代码复制到复制区域的 S3 存储桶中。
将源代码复制到B区域的 S3 存储桶将在第二个区域设置的另一个流水线上重新启动该过程。
以蓝/绿方式将新任务部署到 ECS
CodeDeploy 可以让您无缝切换网络或应用负载均衡器后面的任务集。它通过部署任务集的新版本,然后在负载均衡器级别切换监听器到新版本来实现这一点,如以下图表所示:

图 9.14 – 使用 CodeDeploy 进行蓝/绿部署
注意
我们将更深入地探讨第十三章,蓝绿部署。
在将任务部署到 Amazon ECS 并在切换流量之前使用 Lambda 进行验证
使用 CodeDeploy 部署组以及 Lambda 函数的帮助,您可以创建一个测试,以确保新任务成功运行。这个 Lambda 函数可以在部署appspec文件中指定,如果验证失败,则部署将停止并回滚。如果验证成功,则继续部署。
监控 CodeDeploy 作业
无论您的 CodeDeploy 作业是作为 CodeDeploy 服务的独立运行还是作为部署流水线的一部分运行,监控它们的状态并在发生故障时及时通知,对于及时解决问题至关重要。
将 CodeDeploy 与 CloudWatch 的监控功能结合使用,可以在部署过程中监控特定的指标。利用这些指标,您可以创建 CloudWatch 警报。最多可以将 10 个 CloudWatch 警报与一个 CodeDeploy 部署组关联。触发任何一个警报将导致部署停止,并且部署状态将显示为 Stopped。为了使用 CloudWatch 服务监控 CodeDeploy,您必须授予 CodeDeploy 服务角色权限以使用 CloudWatch 服务。
CloudWatch 事件可以帮助不仅检测,而且根据您创建的规则反应 CodeDeploy 作业的故障。一旦创建了这些规则,CloudWatch 事件将启动针对特定目标的动作。以下目标将与来自 CodeDeploy 作业的规则的 CloudWatch 事件配合使用:
-
AWS Lambda 函数
-
Kinesis 流
-
Amazon 简单队列服务 (SQS) 队列
-
CloudWatch 警报动作
-
Amazon 简单通知服务 (SNS) 主题(和通知)
CodeDeploy 监控用例
如果您的团队使用 Slack 作为通讯渠道,那么您可以通过 Lambda 函数集成 Slack 通知,每当 CodeDeploy 部署失败时。
如果在部署过程中发生特定事件,可以使用 CloudWatch 警报动作以编程方式重启、停止或终止 EC2 实例。
现在我们已经了解了如何监控我们的 CodeDeploy 部署,让我们回顾一下本章中学到的内容。
总结
在本章中,我们介绍了将要深入探讨的其他 AWS 开发者工具。我们了解了如何使用 AWS CodeDeploy 将软件部署到不同的环境,包括云端和本地环境。我们研究了如何使用 CodeDeploy 不仅推送应用程序的新版本,还能在部署过程中控制流量。我们还学习了 AWS CodePipeline 编排工具,它作为一项服务,不仅能够整合我们从开发角度看到的其他三个服务,还能整合其他第三方合作伙伴工具。
在下一章中,我们将介绍 AWS OpsWorks 服务,以及它如何帮助通过堆栈管理基础设施和应用服务,尤其是当您的团队成员熟悉 Chef 或 Puppet 时。
复习问题
-
一家公司的开发团队成员进行了多次部署。最后一次部署覆盖内容失败。您被要求回滚到之前的正常版本,并且包含应用程序所需的所有文件。您会选择哪种方式来尽可能迅速地完成此任务?
a. 手动回滚到最后一个已知的应用版本,并添加修订所需的文件。
b. 手动回滚到上一个部署版本,然后手动添加应用程序修订所需的文件。
c. 自动回滚到最后一个已知版本,并添加应用程序修订所需的文件。
d. 自动回滚到最后一个已知的应用版本,并手动添加应用程序修订所需的文件。
-
你已经构建了一个执行代码发布过程的 AWS 代码管道。这个管道有两个阶段:源阶段和部署阶段。源阶段使用第三方提供商 GitHub 来提供部署所需的代码。AWS CodeDeploy 被用来将新版本的应用程序部署到目标组中的多个 EC2 实例。最近的几次部署都没有成功,且在 CodeDeploy 阶段出现了失败。你需要增加监控和通知的能力,以缩短平均修复时间(MTTR)。如何在检测到问题时尽快创建通知?
a. 为 CodeDeploy 和 CodePipeline 设置 CloudWatch 事件。使用 Amazon Inspector 创建评估目标来评估代码部署问题,并创建一个 SNS 主题,以便在发生部署问题时能够收到通知。
b. 为 CodeDeploy 和 CodePipeline 设置 CloudWatch 事件。使用 AWS Lambda 函数帮助评估代码部署问题,并创建一个 SNS 主题,以便在发生部署问题时能够收到通知。
c. 为管道运行所在的区域设置一个新的 AWS CloudTrail 路径。使用 AWS Config 来评估任何代码部署问题,并创建一个 SNS 主题,以便在发生部署问题时能够收到通知。
d. 设置一个新的 AWS CloudTrail 来捕获来自 CodeDeploy 和 CodePipeline 的 API 事件。使用 AWS Lambda 函数帮助评估代码部署问题,并创建一个 SNS 主题,以便在发生部署问题时能够收到通知。
审查答案
-
d
-
b
第十章:使用 AWS OpsWorks 管理和部署您的应用堆栈
如果您的运营团队已经使用 Puppet 或 Chef 管理基础设施和应用,那么您应该已经听说过 OpsWorks。我们将查看堆栈如何使用预定义的代码为您创建基础设施应用,甚至是数据层。需要对应用进行更新?我们也会讨论这个问题。
本章我们将涵盖以下主要内容:
-
OpsWorks 基础
-
可用的 OpsWorks 平台
-
OpsWorks 与 Chef Automate
-
创建和部署食谱
技术要求
虽然不是必需的,但熟悉 Chef 或 Puppet 平台会在阅读本章时有所帮助。您需要了解完整堆栈应用的不同组件及它们之间如何相互作用。
OpsWorks 基础
在 第七章,使用 CloudFormation 模板部署工作负载 中,我们介绍了 基础设施即服务(IaaS)的 Amazon Web Services(AWS)提供的服务。现在我们将看看 AWS 提供的 平台即服务(PaaS)之一——OpsWorks。
OpsWorks 本质上是 Chef 和 Puppet 自动化包的封装。为什么要使用 OpsWorks?以下要点概述了您选择将 OpsWorks 作为客户或企业解决方案的原因:
-
简单:OpsWorks 使用简单。
-
高效:OpsWorks 通过使用脚本化配置帮助减少错误。
-
灵活:使用 OpsWorks 可以简化任何规模的部署。
-
强大:OpsWorks 有助于减少部署时间和部署成本。
-
安全:OpsWorks 服务允许细粒度的访问控制。
重要提示
OpsWorks 是少数不需要特定区域的服务之一。它是一个全球服务,显示所有已创建的堆栈,无论您的云资源当前所在的区域是哪个。
如果您的团队精简,负责所有或大部分组件,OpsWorks 特别有用:

图 10.1 – OpsWorks 从应用中为用户提供服务
通过一系列事件,您可以使用 AWS OpsWorks 构建和管理您的应用:

图 10.2 – OpsWorks 操作概览
首先,您需要为您的应用创建一个堆栈。多个应用可以共存于同一个堆栈中,它们应该都是同一系统的组件,例如 LAMP 堆栈、Rails 部署,或甚至是单层或双层应用。
其次,在您的堆栈被配置后,您需要定义您的层。在 LAMP 堆栈的情况下,这些层包括带有 PHP 页面和 MySQL 数据存储的 Apache Web 服务器。
第三,你将通过代码版本库和部署代码(如 Puppet 清单或 Chef 配方)来定义你的应用程序。
第四,必须定义 EC2 实例的数量和大小,以便为我们的应用提供一个部署位置。
最后,在第五步中,我们需要为不同的层选择一个部署策略。这个策略可以根据你是进行手动部署还是自动化部署而有所不同。
了解 OpsWorks 的组件
当我们开始讨论 OpsWorks 时,理解一些特定的关键词将是至关重要的。现在让我们看看构成 OpsWorks 各个部分的组件。
堆栈
堆栈表示你希望管理的云基础设施和应用程序。
你不能在一个堆栈中混合使用 Windows 和 Linux 实例。不过,你可以在同一个堆栈中运行不同版本的 Linux。
你的堆栈可以包含自定义的亚马逊机器映像(AMIs),只要映像所基于的操作系统是支持的操作系统之一。OpsWorks 不支持自定义 Windows AMIs。
层
层定义了如何设置和配置一组实例,以及相关的资源。OpsWorks 中的每个堆栈都包含一个或多个层。你可以把层看作是 OpsWorks 用来配置一组或多组 EC2 实例的蓝图。
在层级中,你可以定义如何配置实例,安装哪些软件包,以及定义在生命周期中会发生的关键事件。
在 OpsWorks 中,你可以定义几种不同类型的层:
-
负载均衡器层。
-
数据库层。
-
应用服务器层。
-
自定义 OpsWorks 层(当没有预定义的层能满足你的需求时)。
-
其他层:Linux 堆栈可以创建用于监控的 Ganglia 层,或者用于缓存的 Memcached 层。
实例
OpsWorks 中的实例包括计算资源,如 EC2 实例或本地服务器。
用户可以通过两种方式将实例添加到 OpsWorks 堆栈中:
-
你可以使用 OpsWorks 来配置实例。
-
对于基于 Linux 的堆栈,你可以注册一个已创建的 EC2 实例或本地服务器,这样就能让 OpsWorks 管理这个实例。
AWS OpsWorks 支持 AWS EC2 平台上几种操作系统的 64 位版本,包括 Ubuntu、Amazon Linux 以及 Windows Server。
应用
在 OpsWorks 中,应用表示你想应用于应用服务器的代码。代码本身将存储在应用程序库中,如 GitHub 或 S3。当你部署应用时,OpsWorks 会触发一个部署事件。
OpsWorks 中的生命周期事件
在 OpsWorks 管理的实例生命周期中,会发生五个系列的事件。这些事件如下:
-
设置
-
配置
-
部署
-
卸载
-
关闭
让我们更详细地看看一些事件:
-
设置:每次实例启动时都会触发此事件。它还用于软件包的初始安装。
-
部署:此事件在部署新软件版本时触发。部署事件还允许进行可定制的软件部署。
-
配置:当实例发生状态变化时,所有实例都会触发配置事件。此事件用于确保所有实例的配置是最新的。
OpsWorks 中的访问管理
如果你需要为每个用户提供访问实例的权限,无论是 Linux 还是 Windows 实例,那么 OpsWorks 可能是你在寻找的解决方案。AWS OpsWorks 服务提供了一种简单的方法,让用户可以使用自己的凭证登录到服务器,而无需使用自定义脚本。
如果你曾经创建过 EC2 实例并尝试通过 SSH 访问,那么你很可能会使用 EC2 用户或 Ubuntu 用户,具体取决于你用来配置实例的操作系统类型。如果你希望自定义用户能够访问单个 EC2 实例,那么这可能会变成一个复杂的设置,需要为每个用户配置并通过 LDAP 或 Active Directory 服务器进行身份验证。
如果你在 AWS 上分配 Windows 服务器,也是如此。你需要使用创建实例时所用的密钥对,然后使用该密钥对解密管理员密码。
重要说明
所有 AWS OpsWorks 堆栈的用户必须来自身份与访问管理(IAM)用户。
OpsWorks 让你可以为用户提供快速、轻松访问堆栈中实例的权限,而无需设置 Active Directory 或 LDAP 服务器。
OpsWorks 中的用户类型
AWS OpsWorks 服务中有两种类型的用户:管理员用户和常规 OpsWorks 用户。
OpsWorks 中的常规用户不需要附加策略或任何特殊的 OpsWorks 权限。根据每个堆栈,你可以指定以下四个权限中的一个或多个:
-
查看:此权限允许用户仅查看堆栈。
-
部署:部署权限还包括查看权限,并为用户添加额外的权限,以便更新和部署应用程序。
-
管理:管理权限包括部署权限,并增加了堆栈管理权限,例如添加层或实例。
-
拒绝:拒绝权限用于在堆栈中拒绝特定权限。
将用户导入到 OpsWorks
在我们迄今为止执行的所有操作中,我们已经在使用的帐户中创建了多个 IAM 用户。我们将在下一次练习中使用这些用户来练习将用户导入到 OpsWorks 中:
-
以管理员用户身份登录到 AWS 终端。
-
登录后,在顶部搜索框中导航到
OpsWorks。一旦OpsWorks出现,点击OpsWorks图标进入OpsWorks服务:![图 10.3 – AWS 控制台顶部搜索栏中的 OpsWorks 服务]()
图 10.3 – AWS 控制台顶部搜索栏中的 OpsWorks 服务
-
即使导入用户后,他们出现在 OpsWorks 服务的任何一个部分,我们还是将用户导入到OpsWorks Stacks中。点击右下角的蓝色按钮,该按钮标记为前往 OpsWorks Stacks。
-
现在,在 OpsWorks Stacks 服务中,查看左侧菜单,找到名为用户的菜单项。点击用户,进入用户管理界面:
![图 10.4 – OpsWorks Stacks 侧边菜单栏中的用户菜单项]()
图 10.4 – OpsWorks Stacks 侧边菜单栏中的用户菜单项
-
在主窗口面板中,在任何现有用户下方,找到标记为导入 IAM 用户到 US East(俄亥俄州)的链接。点击该链接进入导入页面。
-
一旦点击此链接,新的菜单将会出现,允许你选择要导入到 OpsWorks 的用户。选择一个或多个你想要导入到 OpsWorks 的用户,然后点击蓝色的导入到 OpsWorks按钮:
![图 10.5 – 在 OpsWorks 服务中选择要导入的用户]()
图 10.5 – 在 OpsWorks 服务中选择要导入的用户
-
现在,我们应该可以看到已导入到 OpsWorks 中的用户列表。如果我们想添加更多用户或限制他们的权限(例如,给予某个用户自我管理的权限以添加自己的 SSH 密钥,或更改自己的密码),我们可以通过编辑该用户来做到这一点。让我们编辑一个用户。点击开发者 Mariel 旁边的编辑链接。
-
在另一个终端窗口中,打印出你之前为第八章中的练习所创建的开发者公钥的内容,创建使用 CodeCommit 和 CodeBuild 的工作负载。将此公钥复制到剪贴板,以便在下一步中使用:
$cat ~/.ssh/cc_developer.pub -
切换回 AWS 控制台,现在在用户 Mariel 的屏幕上,向下滚动,直到你看到位于公钥 SSH左侧的多行文本框。将你之前复制的公钥粘贴到此框中:
![图 10.6 – 将开发者的公钥添加到 OpsWorks 用户]()
图 10.6 – 将开发者的公钥添加到 OpsWorks 用户
-
添加公钥后,我们的开发者可以使用以下方式登录到实例:
$ ssh -i ~/.ssh/cc_developer mariel@INSTANCE-DNS
我们现在已经完成了将之前创建的 IAM 用户导入到 OpsWorks 的练习,并且设置了开发者之前创建的 SSH 密钥,以便他们可以使用自己的用户名轻松登录到 OpsWorks 实例。
接下来,我们将探讨一些你可能希望使用 OpsWorks 服务的场景。
AWS OpsWorks 的使用案例
看完这一部分,你可能会想,怎样的情况适合将这个服务投入实际使用。我们将探讨几个场景,详细说明在何种情况下使用 OpsWorks 服务是有意义的。你需要明白,在评估测试题目或实际场景时,OpsWorks 是 AWS 提供的一系列部署和管理工具中的一种。Elastic Beanstalk 也是一个可以用来配置、部署和管理实例和代码的工具。我们将在下一章 第十一章 中更深入地讨论 使用 Elastic Beanstalk 部署你的应用程序。
可用的 OpsWorks 平台
OpsWorks 本质上是一种配置管理服务,提供受管的 Chef 和 Puppet 实例。这两种软件包都是行业认可的自动化平台,可以让你通过代码和自动化配置服务器。
现在,让我们更深入地了解 OpsWorks 提供的三种平台。
OpsWorks Stacks
OpsWorks 的最初服务提供形式是 OpsWorks Stacks。通过使用层,它帮助你管理和组织 EC2 实例。
OpsWorks for Chef Automate
如果你的团队熟悉 Chef 食谱的创建,并且知道如何使用 Chef 的一些高级功能,如 Knife,但又不想处理维护自己的 Chef 服务器的麻烦和头痛问题,那么 Chef Automate 可以成为你团队的合理选择。
如果你当前使用 Chef 管理一些本地基础设施,OpsWorks for Chef Automate 可以被配置为从单一来源管理混合环境。
OpsWorks for Chef Automate 还具有执行合规性扫描的功能。这些合规性扫描允许你定期审计应用程序,以检测漏洞和不符合要求的配置。
你无需担心 Chef 服务器的补丁、更新或备份问题,因为这些正是 OpsWorks 为你处理的任务之一。OpsWorks for Chef Automate 还允许你通过 Chef 控制台或通过命令行工具 Knife 来管理 Chef 实例。
OpsWorks for Puppet Enterprise
Puppet 帮助通过其工具集强制执行基础设施的期望状态。
如果你是现有的 Puppet 用户,那么 OpsWorks for Puppet Enterprise 将是最合适的选择。使用 OpsWorks for Puppet Enterprise,你可以在几分钟内启动一个 Puppet 主服务器,然后让 OpsWorks 服务处理诸如备份、软件升级和恢复等操作任务。
使用 OpsWorks 的 Puppet Enterprise 版本时,Puppet 主服务器将为需要运行 Puppet Agent 的实例提供并配置所有 Puppet 模块。
现在我们已经查看了 OpsWorks 的不同选项,包括两个基于 Chef 食谱的选项,以及一个基于 Puppet 清单的选项。接下来,我们将查看一个快速示例。这个示例将帮助我们更好地理解当我们在为客户选择最佳解决方案时,OpsWorks 的不同组件如何协同工作,同时也有助于我们准备 DevOps 专业考试。
创建并部署一个食谱
在这个示例中,我们将使用 OpsWorks 来设置一个 stack,并创建一个层。在我们创建好层之后,将使用一个公开的食谱将其部署到我们的应用程序:
-
作为管理员用户登录到 AWS 控制台,并使用统一搜索框搜索
OpsWorks服务。当你看到 OpsWorks 图标出现时,点击图标进入 OpsWorks 主页面:![图 10.7 – 通过统一搜索框访问 OpsWorks 服务]()
图 10.7 – 通过统一搜索框访问 OpsWorks 服务
-
在 OpsWorks Stacks 页面上,点击左下角的蓝色 前往 OpsWorks Stacks 按钮。这是 OpsWorks 的原始提供选项:
![图 10.8 – OpsWorks 服务页面上的 OpsWorks Stacks 选项]()
图 10.8 – OpsWorks 服务页面上的 OpsWorks Stacks 选项
-
一旦进入 OpsWorks Stacks 页面,点击页面右上方的蓝色 创建 stack 按钮。此时将开始创建一个新的 OpsWorks stack。
-
接下来,我们将创建一个名为
Chef-11的 stack,并选择以下选项:-
chapt-10 -
美国东部 (俄亥俄) -
11.10 -
是 -
Git -
仓库 URL –
github.com/amazonwebservices/opsworks-example-cookbooks.git
-
-
保持其他设置不变。
-
点击蓝色的 添加 Stack 按钮。
-
请参见下图:
![图 10.9 – 添加选项以创建 stack]()
图 10.9 – 添加选项以创建 stack
-
现在我们应该看到一个 恭喜!您的 stack 已创建 的通知。接下来的步骤是向我们的 stack 中添加一个层。我们可以点击 添加一个层 链接并点击添加层:
![图 10.10 – 显示添加层链接的恭喜横幅]()
图 10.10 – 显示添加层链接的恭喜横幅
-
现在在层的页面上,我们将从下拉列表中选择 PHP 应用服务器。选择后,我们可以点击蓝色按钮 添加层:
![图 10.11 – 在 OpsWorks 中添加层]()
图 10.11 – 在 OpsWorks 中添加层
-
有了我们的层,接下来需要向该层添加一个实例。在 PHP 应用服务器 页面上,我们需要点击最右侧的 Add instance 链接:
![图 10.12 – 在 OpsWorks 中显示我们创建的层]()
图 10.12 – 在 OpsWorks 中显示我们创建的层
-
现在,使用以下信息添加实例:
php-app1c5.large子网 – (保持选定的默认子网)
当你填写完所有这些选项后,点击选择窗口右下角的蓝色 Add Instance 按钮:
![图 10.13 – 向 OpsWorks 层添加实例]()
图 10.13 – 向 OpsWorks 层添加实例
-
添加实例后,您可以启动实例。您会注意到在屏幕上该实例类型被指定为 24/7 实例。点击 Actions 列下的 start 链接来启动实例。
-
大约一分钟后,实例状态应从
stopped或booting变为online。
恭喜,你现在已经成功启动了堆栈!
现在我们已经了解了如何创建 OpsWorks 堆栈,包括其层、实例和应用,接下来我们将更详细地了解 OpsWorks 中的部署。我们将继续使用我们刚刚创建的堆栈,利用该堆栈创建一个应用并将其部署到堆栈中。
OpsWorks 中的部署
当你在 OpsWorks 中部署应用时,其主要目的是将应用代码和所有文件部署到服务器实例上。我们之前在 OpsWorks 中创建了一个堆栈、一个层和一个实例。现在我们将添加一个应用并将其部署到堆栈中:
-
返回到 OpsWorks 控制台并进入我们之前创建的堆栈——命名为
chapt-10。你可以通过点击堆栈名称进入该堆栈。 -
进入堆栈后,在左侧菜单中点击名为 Apps 的项,进入应用页面。在该页面顶部,点击蓝色的 Add App 按钮以创建一个新的应用:
![图 10.14 – OpsWorks 左侧菜单中的应用和部署]()
图 10.14 – OpsWorks 左侧菜单中的应用和部署
-
使用以下值来填充你的应用:
-
SampleAPP -
PHP -
Git -
仓库 URL –
github.com/awslabs/opsworks-demo-php-simple-app.git
其他所有值可以留空。在填写完这些值后,点击屏幕底部的蓝色 Add App 按钮:
![图 10.15 – 添加应用设置]()
图 10.15 – 添加应用设置
-
-
您现在应该看到一个显示我们应用程序的屏幕。现在是时候使用 OpsWorks 部署应用程序了。OpsWorks 通过在应用程序右侧的Actions列下方直接提供deploy链接来简化这一过程。点击deploy链接开始部署过程:
![图 10.16 – 应用程序创建后,已准备好部署]()
图 10.16 – 应用程序创建后,已准备好部署
-
在部署屏幕上,在您部署之前,点击当前已选择Deploy的下拉菜单,查看所有不同的部署选项。在这一部分,您不仅可以部署应用程序,还可以让 OpsWorks 撤销部署、回滚、启动或停止 Web 服务器。确保保留部署设置,并保持所有默认选项。然后点击屏幕底部的蓝色Deploy按钮。
我们刚刚使用自定义配方完成了应用程序的配置,并将该应用程序部署到我们之前创建的实例上。
监控 OpsWorks
您可以通过多种方式监控您的 AWS OpsWorks 堆栈:
-
使用 Amazon CloudWatch
-
使用 Amazon CloudWatch Logs
-
使用 Amazon CloudWatch Events
-
使用 Amazon CloudTrail
使用 Amazon CloudWatch,有 13 个自定义指标用于详细监控堆栈中每个实例的状态。OpsWorks 中还创建了一个自定义监控页面,总结了这些数据,并使这些指标易于理解。如果您运行的是 Windows 实例,监控页面将不会显示这些 Windows 实例的指标。指标将显示整个堆栈的数据,但您也可以专注于特定的层或特定的实例。
如果您仍在运行上一个练习中的部署,您可以点击Monitoring菜单图标,进入仪表盘。这将为您提供关于应用程序状态的快速见解:

图 10.17 – OpsWorks 中的监控仪表盘
我们刚刚覆盖了从创建堆栈到监控堆栈的完整 OpsWorks 流程。现在让我们回顾一下我们学到的内容。
总结
在本章中,我们讨论了 OpsWorks 服务如何帮助我们同时提供和部署我们的基础设施和应用程序。它通过使用堆栈和层来实现这一点。我们还了解到,OpsWorks 是将当前使用 Chef 或 Puppet 来提供服务器和/或应用程序的团队迅速过渡到其当前环境的一个好方法。
在下一章中,我们将学习 Elastic Beanstalk 服务及其如何帮助您将应用程序部署到环境中,为这些应用程序创建版本,并使用多种不同的编程语言来监控这些应用程序。
复习问题
-
你被引入到一家公司,该公司正在启动迁移到 AWS 云的工作。他们有一个庞大的 Chef 配方库,目前用于管理他们的本地系统。这些配方已经迁移到一个私有 GitHub 仓库。负责管理和维护 Chef 服务器的人员大约在一个月前离职。公司目前没有足够的资源在本财年内重写所有配方。你会推荐哪些 AWS 服务来帮助他们迁移?
a) 使用 AWS 服务器迁移服务将当前的 Chef 服务器迁移到 AWS 云。
b) 在 EC2 上启动最新版本的 Chef,并设置自动扩展以保证冗余。在本地托管区域的 Route 53 中添加一个记录指向 Chef 服务器。创建一个基础 AMI,已经预安装了 Chef 代理,并且连接到在 Route 53 中配置的 DNS 记录。
c) 将应用程序设置为 OpsWorks 中的堆栈。创建所有不同的用户作为 IAM 用户,然后将它们导入到 OpsWorks 中。接着根据需要将 OpsWorks 用户分配到各个堆栈中。
d) 创建一个 CodePipeline 实例,根据需要安装和配置应用程序,使用无头 Chef 在用户的
init脚本中进行配置。 -
一家公司开发了一个 PHP 购物车平台。该平台目前由 AWS OpsWorks 管理和部署,开发、QA 和生产环境分别使用不同的堆栈。由于最初开发该平台的 PHP 开发人员大多已经离开公司,管理层已批准开始用 Python 重新开发该平台。公司应如何管理部署?
a) 创建一个新的 OpsWorks 堆栈,包含一个新的层和新的 Python 代码。为了过渡到新堆栈,组织应使用蓝绿部署。
b) 创建一个新的 OpsWorks 堆栈,使用新的 Python 代码管理应用程序的独立部署,放置在次要堆栈中。
c) 使用新的 Python 应用程序代码更新现有的堆栈,并通过 Deploy 生命周期事件部署该应用程序。
d) 在 OpsWorks 堆栈上创建一个新的层,并使用新的 Python 代码。为了顺利过渡到新的堆栈,组织应使用滚动部署。
-
一家企业在其本地数据中心管理一组 Windows 服务器和 Linux 服务器(Red Hat Enterprise Linux 和 Amazon Linux),并且还管理着 AWS 账户。在最近的审计中,首席技术官被告知没有针对核心应用程序补丁和操作系统更新的流程。无论是在本地数据中心还是 AWS 云中,所有服务器的补丁管理都没有基准级别。你被召来帮助解决这个问题。你会推荐什么解决方案,既能够提供和维护操作系统和核心应用程序补丁的最一致性,又能确保最可靠性?
a) 使用 AWS Systems Manager 将凭证存储在参数存储中,然后为实例创建资源组。允许 Systems Manager
Run命令使用存储在参数存储中的凭证远程部署补丁。b) 在所有服务器上安装 OpsWorks 代理,包括本地服务器和 AWS 账户中的服务器。使用一个堆栈,为不同的操作系统创建不同的层。每当需要应用操作系统或核心应用程序补丁时,创建维护窗口。
c) 在所有服务器上配置 AWS Systems Manager 代理,包括本地服务器和 AWS 账户中的服务器。为实例创建资源组,然后允许 Systems Manager Patch Manager 在预配置的基准下运行,并使用设置的维护窗口。
d) 在所有服务器上安装 OpsWorks 代理,包括本地服务器和 AWS 账户中的服务器。创建两个不同的堆栈,一个用于 Windows,另一个用于 Red Hat Linux 实例。创建一个 Lambda 任务,每天两次请求 RSS 源,检查是否有新的补丁更新。如果发现更新,将触发 OpsWorks 层上的部署。
审查答案
-
c
-
a
-
c
第十一章:使用 Elastic Beanstalk 部署你的应用程序
了解并理解 Elastic Beanstalk 对于 DevOps Pro 考试至关重要。如何使用该服务的细微差别、该服务的局限性,特别是 Beanstalk 与容器的交互方式,对于通过考试和快速让应用团队在现实世界中启动应用程序都是至关重要的知识。
在本章中,我们将涵盖以下主要主题:
-
理解 Elastic Beanstalk 的内建功能
-
在 IAM 控制台中创建服务角色
-
安装并使用 Elastic Beanstalk 命令行接口(EB CLI)
-
理解通过 .ebextensions 进行高级配置选项
-
使用 Elastic Beanstalk 部署应用程序
-
Elastic Beanstalk 的应用场景
技术要求
由于 Elastic Beanstalk 需要一些本地开发,并且我们将在本章中用 Python 编写示例程序,因此你需要在工作站本地安装 Python 3.x。在撰写本文时,Elastic Beanstalk 支持的最新 Python 版本为 3.8.5,因此我们将在本章使用该版本的 Python。作者建议你安装 pyenv Python 运行时管理器,以帮助你在本地工作站上开发和管理多个 Python 版本。你可以在该项目的 GitHub 页面找到有关信息及安装方法,网址为 github.com/pyenv/pyenv。
理解 Elastic Beanstalk 的内建功能
Elastic Beanstalk 是一个灵活的平台,允许开发人员在如 Python、Java、Ruby、.NET、PHP(超文本预处理器)、Go 甚至 Docker 容器等语言中开发并快速扩展他们的应用程序。Elastic Beanstalk 是一个平台即服务(PaaS),这意味着它作为所有其他服务的抽象层,帮助协调和管理这些服务。这使得那些急于开始使用 Amazon Web Services(AWS)云的开发人员,虽然可能对设置基础设施或监控等内容了解不多,仍然能够顺利开始,并专注于他们所选择语言中的应用程序开发。
Elastic Beanstalk 持续更新其支持的语言和平台。尽管它并不总是支持语言的最新版本,但它确实尽力保持更新并逐渐淘汰旧版本。记住这一点很重要,因为旧版应用程序不能直接推送到云端并一直运行下去。有时候,应用程序需要升级,以便保持 Elastic Beanstalk 服务的功能。以下是 Elastic Beanstalk 集成的一些服务:

图 11.1 – 一些 Elastic Beanstalk 集成的服务概览
在 Elastic Beanstalk 服务可供使用之前,开发人员必须弄清楚哪些服务可以协同工作,不仅仅是计算、负载均衡和路由,还需要——无论是手动还是借助像 CloudFormation 模板这样的服务——将安全性、存储和监控集成到他们的应用程序中。对于那些希望快速启动并运行 AWS 云服务的开发人员来说,这可能是一个挑战,因为他们习惯于创建应用程序代码,而不是配置环境。
Elastic Beanstalk 中的不同环境
使用 Elastic Beanstalk 构建并部署的任何类型应用程序都允许你将该应用程序中包含的所有不同组件作为单一环境进行管理。通过 Beanstalk 框架运行的环境主要分为两类:Web 服务器环境和工作环境。
Web 服务器环境
在 Web 服务器环境中,Elastic Beanstalk 管理三项内容:负载均衡器、自动扩展组(ASG)以及请求的 弹性计算云(EC2)实例数量。即使你的应用程序已被容器化,这些容器仍然需要 EC2 实例来运行,因此 Web 服务器环境将启动一组相应的 EC2 实例来运行容器。
Web 服务器环境还会创建一个 53 服务,因此它具有高度可用性和可扩展性。如果需要,你可以注册自己的域名,并使用 Route 53 服务将其指向负载均衡器,这样你可以使用自定义的 URL 而非原本为你创建的通用 CNAME,从而驱动流量访问你的 Web 应用程序。
工作环境
Elastic Beanstalk 提供的工作环境与 Web 服务器环境的主要区别在于,在工作环境中,53。Beanstalk 会自动安装一个守护进程,用于自动扩展,以下图所示:

图 11.2 – Elastic Beanstalk 中的 Web 服务器和工作环境
接下来,我们将介绍构成 Elastic Beanstalk 的不同组件。
构成 Elastic Beanstalk 的不同组件
无论你正在使用 Beanstalk 服务构建哪种类型的环境,它都将由多个组件组成。
应用程序
在 Elastic Beanstalk 中,组件的逻辑分组称为 应用程序。这包括环境和环境配置以及版本。所有这些项目都被组合成类似文件夹的结构,而这个文件夹就是应用程序。
应用版本
Elastic Beanstalk 允许将特定版本的应用程序打包并标记。每个特定打包的应用程序版本被称为应用版本。这些版本会被打包并发送到背后的简单存储服务(S3)服务,用于部署到一个或多个环境,如下图所示:

图 11.3 – 应用版本只能部署到单个环境
你可以在 Elastic Beanstalk 中运行多个版本的应用,分别运行在不同的环境中,例如在生产环境中运行当前稳定版本,在测试环境中运行最新版本。每次只能将一个版本部署到单个环境。
环境
在 Elastic Beanstalk 中运行特定应用版本的一组运行资源被称为环境。
环境配置
当你定义环境的参数和设置时,这些就构成了环境配置。当你对应用进行迭代,并更改环境的底层配置设置时,Beanstalk 会自动部署这些更改,并根据你的配置添加或删除项目,如下图所示:

图 11.4 – 更深入地了解 Elastic Beanstalk 配置
配置模板
Elastic Beanstalk 中的配置模板是创建自定义环境配置的起点。
已保存的配置
已保存的配置是存储在 S3 中的YAML Ain't Markup Language(YAML)文件,可以在其他运行中的环境或环境创建过程中使用。保存的配置定义了以下值:
-
平台版本
-
层级
-
配置选项设置
-
标签
平台
当你选择操作系统和编程语言时,所有的网页和应用服务器都构成了你的平台。
现在我们已经了解了 Elastic Beanstalk 的组件和平台,接下来我们将进行一个练习,创建一个 Elastic Beanstalk 应用,从创建必要的权限开始。
在 IAM 控制台中创建服务角色
在开始之前,我们需要为 Beanstalk 创建一个服务角色,供其在推送环境和应用时使用。如果没有这样做,或者没有更新几年前创建的服务角色,可能会在本章后续操作中出现错误并带来挫败感。
首先,使用管理员用户登录到AWS 管理控制台,然后按照以下步骤操作:
-
登录后,导航到IAM 服务。
-
在左侧菜单中,点击角色。
-
在创建角色页面,保持信任实体为AWS 服务,然后在页面中间,选择Elastic Beanstalk作为您希望创建服务角色的服务。点击Elastic Beanstalk服务。
-
选择Elastic Beanstalk服务后,屏幕底部会出现一组新的选项,供您选择使用案例。选择Elastic Beanstalk的使用案例。点击Elastic Beanstalk用例后,该选项会以蓝色高亮显示,如下图所示,然后您可以点击屏幕右下角的蓝色按钮下一步:标签:
![图 11.5 – 在身份与访问管理(IAM)中选择 Elastic Beanstalk 用例]()
图 11.5 – 在身份与访问管理(IAM)中选择 Elastic Beanstalk 用例
-
点击下一步后,进入角色页面,默认的 Beanstalk 策略应该已经为您填充。点击屏幕底部的蓝色按钮下一步:标签,继续到下一个页面。
-
标签是可选的,您可以根据需要添加;否则,点击屏幕底部的蓝色下一步:审查按钮。
-
在
AWSServiceRoleForElasticBeanstalk页面,点击页面底部的蓝色创建角色按钮以创建此角色。
现在我们已经创建了服务角色,可以继续使用 Elastic Beanstalk 服务。
安装和使用 Elastic Beanstalk 命令行界面(EB CLI)
AWS CLI 提供了多个命令,允许用户利用 Elastic Beanstalk。
EB CLI 提供的基本命令包括从在本地环境中创建正确的项目结构,到快速高效地拉取实例的日志文件以供审核的命令。我们将回顾 EB CLI 提供的基本命令,并简要说明其功能,如下所示:
-
eb create:此命令将在 Elastic Beanstalk 中创建一个新的本地环境,并将初始应用版本部署到该目录结构中。 -
eb status:此命令返回您的环境状态,包括应用程序名称、区域、CNAME 和健康状态等信息。 -
eb health:此命令返回环境中实例的健康状态,每 10 秒更新一次。 -
eb events:此命令返回当前 Elastic Beanstalk 环境的日志语句列表,列出最近的事件。事件示例包括资源的创建,如实例或负载均衡器,或环境状态更改为不同的健康级别。 -
eb ssh:如果您没有为特定的无类域间路由(CIDR)地址范围配置端口22,此命令将临时打开安全组的22端口,允许所有传入流量。然后,它会提示您连接到正在运行的实例,或者允许您选择要通过安全外壳(SSH)连接的实例。 -
eb logs:此命令可以执行两个与文件日志相关的明确命令,如下所示:a. 它可以切换日志流到 CloudWatch Logs 服务。
b. 它可以获取实例日志,供您本地查看。
-
eb open:此命令将使用您的默认浏览器打开应用程序的公共 URL。 -
eb deploy:此命令将使用当前的源包将您的应用程序部署到 Elastic Beanstalk 服务。 -
eb config:此命令将允许您更改环境配置设置。 -
eb terminate:此命令将关闭并停止您的实例和环境,以免产生额外费用。
安装 EB CLI
获取 eb-cli-setup 脚本的最简单方法是通过 GitHub:github.com/aws/aws-elastic-beanstalk-cli-setup。
如果您使用的是 Mac 并且喜欢通过 brew 包管理器安装软件,则也可以通过这种方式安装 EB CLI。在尝试安装 EB CLI 之前,请确保您当前的 brew 版本是最新的。以下是您需要的代码:
$ brew update
$ brew install awsebcli
无论您选择哪种方法,安装完成后,您应该能够从终端提示符直接访问 EB CLI,只需输入简单的 $ eb 命令。
注意
如果您之前曾在计算机上安装过 EB CLI,在继续之前最好使用 pip3 install --upgrade awsebcli 命令更新该软件包。
现在,安装了 CLI,我们来看看如何使用 EB CLI 创建和部署一个项目。
使用 EB CLI 创建项目
我们将使用终端来调用 eb cli 命令,并创建我们的 Elastic Beanstalk 项目。首先,打开终端窗口。然后,按照以下步骤操作:
-
打开终端窗口后,使用 EB CLI 创建一个新文件夹来开始我们的项目。最好从家目录的根目录开始,这样如果需要稍后返回,文件夹更容易找到。我们将把本地文件夹命名为
11-beanstalk。以下是您需要的代码:$ cd ~ $ mkdir 11-beanstalk -
我们需要确保已在系统上安装
virtualenv程序,以支持 Python 3.x 编程语言。我们将使用pip来完成此操作,如下所示:$ pip3 install -U virtualenv -
现在,创建好文件夹后,我们可以进入该文件夹以创建 Python 的虚拟环境。一旦启用了虚拟环境,你会看到提示符稍作变化,命令提示符前会添加 11,如下代码片段所示。这表示你已经进入虚拟环境:
$ cd ll-beanstalk $ virtualenv eleven -
如果虚拟环境创建成功,你应该会看到类似以下内容的输出:
created virtual environment CPython3.9.1.final.0-64 in 767ms creator CPython3Posix(dest=/Users/abook/11-beanstalk/eleven, clear=False, no_vcs_ignore=False, global=False) seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/abook/Library/Application Support/virtualenv) added seed packages: pip==21.1.2, setuptools==57.0.0, wheel==0.36.2 activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator -
既然我们已经创建了虚拟环境,我们现在需要激活它,如下所示:
$ source eleven/bin/activate -
在虚拟环境提示符显示时,我们将安装
flask本地,以便使用 Python 创建一个快速的 Web 应用,如下所示:flask package will also install a number of dependent packages that flask needs, including flask is a lightweight web application framework written in Python. It uses Jinja templates for rendering pages but can also just parse text or HyperText Markup Language (HTML). It can also be combined with other Python libraries to do more complex calculations and then render the results. -
在环境设置好后,我们可以将从
Chapter-11GitHub 仓库获取的文件移动并复制到我们的11-beanstalk目录。首先进入克隆了 GitHub 仓库文件的目录,这样复制命令会更简短,如下所示:application.py file that runs the application but also the templates folder (this holds the Jinja templates) along with the static folder (this holds the Cascading Style Sheets (CSS) style sheet). -
现在,让我们使用
pip freeze命令捕获我们在远程环境中安装时所需的所有依赖,并将其输出到一个名为requirements.txt的文件中,如下所示:$ pip freeze > requirements.txt -
此时,我们应该在本地测试我们的
flask应用程序,确保它运行正常并准备好部署。使用以下命令测试你的应用:$ python3 application.py假设应用程序启动成功,你应该看到类似以下内容的返回:
* Serving Flask app 'application' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 688-856-306显示本地 URL 后,你可以打开网页浏览器查看应用程序的运行情况。
测试完本地应用后,按Ctrl + C在终端窗口停止本地服务器的运行。
-
在本地测试应用程序后,我们现在可以使用 EB CLI 创建环境。使用你仍然打开的命令提示符,我们将启动 Elastic Beanstalk 环境。确保在运行下一个命令之前,你仍然在
11-beanstalk文件夹内,如下所示:us-east-2 -
flask-quiz -
(Y)es -
Python 3.8 -
(Y)es -
DevOps-pro(无密码)
创建好环境后,我们将继续学习如何使用 .ebextensions 自定义环境。
了解使用 .ebextensions 的高级配置选项
Elastic Beanstalk 允许你向应用程序的源代码添加配置文件,以自定义和配置环境中的 AWS 资源。
我们可以在目录中创建一个隐藏文件夹,用于创建和存储我们的自定义配置。
在11-beanstalk目录中,我们将创建一个.ebextensions目录,如下所示:
$ mkdir .ebextensions
我们现在可以运行一个 tree 命令,设置级别为 1,并要求它显示所有文件(以便显示隐藏的 .ebextensions 文件夹),查看我们当前的工作环境结构,如下所示:
$ tree -a -L 1
这应该显示如下的当前结构:
.
├── .ebextensions
├── .elasticbeanstalk
├── .gitignore
├── application.py
├── eleven
├── requirements.txt
├── static
└── templates
接下来,我们将把所有其他名为cloudwatch.config的文件一起复制到.ebextensions文件夹中,如下所示:
$ mv cloudwatch.config .ebextensions/.
如果需要,您也可以在 GitHub 的Chapter-11文件夹中找到此文件。
在创建了额外资源后,我们现在可以查看 Elastic Beanstalk 中为应用程序提供的部署类型,然后再开始部署应用程序。
Elastic Beanstalk 的部署类型
Elastic Beanstalk 支持多种部署类型,让我们详细了解每种部署方式。
一次性部署
使用一次性部署策略时,Elastic Beanstalk 会将指定版本的应用程序部署到环境中的所有实例中,所有实例同时进行部署。
这种部署方式需要的时间最短,相关成本也最低;然而,它也伴随最大的风险。如果部署过程中出现问题,应用程序可能会出现停机。这种部署策略最适用于开发和测试环境,生产环境中应很少甚至不应使用。
滚动部署
滚动部署将把应用程序的新版本推送到现有的 EC2 实例,但不同于一次性将应用推送到所有实例,它采用批次的方式来控制每次更新多少实例。
虽然这种部署方式不如“一次性部署”方法快速,但它同样可以保障在应用出现问题时,不会导致所有实例同时宕机。与蓝绿部署方式相比,滚动部署实例的成本也较低,因为你正在利用已经启动并运行的 EC2 实例,而不需要创建全新的环境。
附加批次滚动部署
尽管与滚动部署非常相似,附加批次滚动部署有一个明显的区别。这个区别在于,它确保在整个部署过程中保持应用的全部容量。
这种部署类型将在开始实际部署之前启动一组额外的实例。如果您需要保证流量持续稳定,并确保在执行应用程序更新时不影响容量,这将是一个不错的选择。
不可变部署
当你想到不可变基础设施时,你应该想到的是不对当前实例进行更新。这与不可变部署的概念相同,因为我们会设置一整套新的实例并部署到这些实例上,在它们变为健康状态后,才会将 Elastic Beanstalk 的域名系统(DNS)从旧环境切换过来,具体示意图如下所示:

图 11.6 – 部署期间的不可变部署
这是部署应用程序最安全的方式之一,但也可能是最昂贵的,因为你需要设置双倍数量的实例,如下图所示:

图 11.7 – 部署后的不可变部署
在对新版本的实例完成健康检查后,旧版本的实例会被关闭,流量会被引导到新版本的应用程序。如果任何实例存在问题,流量在一开始就不会被引导到这些实例。
流量拆分
流量拆分部署与不可变部署有些相似,因为它会创建一整套新的实例。主要的区别在于,在流量拆分部署中,旧的实例不会在新版本启动并健康后立即终止。相反,流量会按照你在控制台或通过 CLI 设置的控制节奏,逐步从一个版本转移到下一个版本,如下图所示:

图 11.8 – 显示流量百分比的流量拆分部署
现在我们已经了解了不同的部署策略,我们将使用 EB CLI 和我们的终端来创建并部署一个 Beanstalk 应用程序。
使用 Elastic Beanstalk 部署应用程序
理解这些服务的最佳方式是通过动手示例来测试它们。Elastic Beanstalk 尤其如此,因为你需要在阅读 DevOps 专业考试中的问题和答案时,能够考虑到服务的功能。
我们将继续使用本章前面开始的示例代码。如果你没有做第一部分的练习,并且想要部署应用程序,建议你回到本章标题为使用 EB CLI 创建项目的部分。
如果你之前关闭了终端窗口,你需要重新打开它,并导航回11-beanstalk文件夹。我们之前已经在本地初始化了环境,现在可以继续按照以下步骤进行:
-
由于我们之前已经初始化了环境,我们可以按以下方式创建我们的初始环境——
development:$ eb create development终端应显示类似于以下的返回信息:
Creating application version archive "app-210606_181258". Uploading: [##################################################] 100% Done... Environment details for: development Application name: flask-quiz Region: us-east-2 Deployed Version: app-210606_181258 Environment ID: e-mscggmggrw Platform: arn:aws:elasticbeanstalk:us-east-2::platform/Python 3.8 running on 64bit Amazon Linux 2/3.3.0 Tier: WebServer-Standard-1.0 CNAME: UNKNOWN Updated: 2021-06-06 22:12:41.224000+00:00 Printing Status: 2021-06-06 22:12:40 INFO createEnvironment is starting. 2021-06-06 22:12:41 INFO Using elasticbeanstalk-us-east-2-182968331794 as Amazon S3 storage bucket for environment data. -
尽管新环境的设置可能需要几分钟的时间,但一旦完成,你可以通过使用
ebopen命令查看运行中的 Web 应用程序,如下所示:$ eb open -
你可以通过在 EB CLI 中使用
events命令查看应用程序的所有事件,像这样:$ eb events -
如果你想检查环境的健康状况,你可以登录 AWS 控制台查看可视化仪表板,或者你也可以使用
eb health命令快速查看环境的统计信息,如下所示:$ eb health或者,如果你从控制台查看 Beanstalk 应用程序的健康状况,你将看到一个非常易于阅读的用户界面(UI),如下图所示:
![图 11.9 – 查看 Elastic Beanstalk 监控仪表板]()
图 11.9 – 查看 Elastic Beanstalk 监控仪表板
-
如果你愿意,你可以直接通过命令行使用
eb logs命令检查日志文件。 -
完成后,你应该通过运行以下命令来停用虚拟环境:
zip ../eleven.zip -r * .[^.]* command to use as the source bundle to upload.
如果在部署过程中遇到问题,请按照下一节的指导来帮助排查问题。
使用 EB CLI 排查部署问题
如果在部署环境时遇到问题,请执行以下步骤:
-
找到声明Web 服务器网关接口(WSGI)路径的那一行。以下是一个示例:
WSGIPath: application -
在冒号后编辑这一行,确保
.py出现在“应用程序”一词后面。 -
保存并关闭文件。
-
尝试使用
eb deploy命令再次部署你的应用程序。
现在我们已经完成了部署我们的 Beanstalk 应用程序并查看应用程序日志和事件的练习,我们将接下来讨论使用 Elastic Beanstalk 的使用案例和反模式。
Elastic Beanstalk 使用案例
Elastic Beanstalk 使开发人员能够轻松地在云端启动和运行,而无需担心底层基础设施或底层组件的管理。接下来,我们将看看使用 Elastic Beanstalk 的一些最佳使用案例。
你有一个小型的开发团队,需要快速启动
如果你有一个较小的团队,需要快速启动 AWS,但对其他组件、服务和相互连接不太熟悉,那么 Elastic Beanstalk 可以成为一个很好的选择,帮助按时完成任务。
你没有内部的 DevOps 专业知识
类似于之前的示例,如果一个公司或开发团队有一个需要快速部署到 AWS 的应用程序,那么 Elastic Beanstalk 提供了一个非常可行的解决方案,而无需任何高级 DevOps 专业知识。由于该产品本身可以与 Git 配合使用,这是大多数开发人员都熟悉的工具,因此在最短的时间内启动和运行是一项简单的任务。然后,Beanstalk 负责处理诸如 DNS、自动扩展、应用程序日志的轻松访问,甚至是无需额外设置的环境度量仪表板。
Elastic Beanstalk 反模式
正如我们刚才看到的,Elastic Beanstalk 在某些情况下非常适用,但也有一些情况它并不是一个好的选择。在这里,我们将探讨一些已知的使用 Elastic Beanstalk 的反模式,了解在哪些情况下你应该考虑选择 AWS 的其他服务。
需要大量环境变量的应用程序或项目
Elastic Beanstalk 的一个限制是它只有 千字节 (KB) 的存储空间用于存储所有的键值对。考虑到这一点,如果你有很多环境变量,例如不同数据库连接字符串、用户名和密码,适用于每个你创建的环境,那么你可能会遇到这个硬性限制,Elastic Beanstalk 对你的应用程序来说就不再是一个好的选择。
非常大的应用程序
Elastic Beanstalk 部署包的最大大小只能是 512 .ebextensions 目录。如果你有大量静态资源,比如图片或媒体文件,可以将它们存储在 S3 中,并在应用程序或动态存储(如 DynamoDB)中存储指针,这样可以减少源包的大小。
总结
本章中,我们介绍了 Elastic Beanstalk 服务,这是 AWS 提供的另一种部署服务。我们介绍了 Elastic Beanstalk 提供的不同部署选项,并使用 EB CLI 工具创建和部署 Beanstalk 应用程序。我们还探讨了使用 Elastic Beanstalk 的最佳情况,以及一些反模式,说明在这些情况下 Elastic Beanstalk 并不适合。
在下一章中,我们将探讨如何使用 Lambda 函数和步骤函数,以无服务器的方式部署我们的代码。
复习问题
-
你被引入了一家公司,该公司有一个应用团队,他们的应用程序是两层架构——一个是 Web 层,另一个是数据库层。应用团队需要一种快速地在 AWS 上配置和部署环境的方法。以下哪种选项是最快且最理想的设置方式?
a. 使用 Elastic Beanstalk 服务来配置一个环境,然后将应用程序推送到该环境。
b. 创建一个带有两个层的 OpsWorks 堆栈,一个用于应用程序,另一个用于数据库。将应用程序部署到应用层。
c. 使用 CloudFormation 创建一个 S3 存储桶、一个 RDS 数据库和一个 EC2 实例。使用用户数据脚本从 S3 存储桶加载应用程序,并传递 RDS 连接字符串、用户名和密码等参数。
d. 创建一个 RDS 数据库,然后使用 Lambda 部署应用程序。
-
你被引入了一家公司,这家公司正在尽可能快地自动化迁移到 AWS 云。该公司要迁移的应用程序是使用多种不同编程语言构建的。你如何才能尽快将这些应用程序迁移并部署到云端?
a. 创建一个主 CloudFormation 模板,利用嵌套堆栈设计来部署应用程序。在为每个应用程序创建 Docker 容器后,创建每个应用程序的子模板。
b. 在一个 Docker 容器中开发每个应用程序,并使用 Elastic Beanstalk 进行部署。
c. 在一个单独的 Docker 容器中开发每个应用程序,并使用 Elastic Beanstalk 进行部署。
d. 使用 OpsWorks 创建堆栈。为每个应用程序创建一个单独的层,然后将每个应用程序部署到对应的层。
-
如果你的应用程序需要较长时间完成其活动或工作流,Elastic Beanstalk 可以为你提供哪项服务?
a. Beanstalk 可以管理 Elastic Load Balancing(ELB)服务,并在每个实例上运行守护进程。
b. Beanstalk 可以管理一个简单通知服务(SNS)主题,并在每个实例上运行守护进程。
c. Beanstalk 可以管理 Lambda 函数,并在每个实例上运行守护进程。
d. Beanstalk 可以管理一个 SQS 队列,并在每个实例上运行守护进程。
-
你被邀请加入公司,帮助在主要区域发生故障时自动化恢复策略。该公司优先考虑减少恢复策略的成本,但同时也需要在必要时能够快速恢复完整的基础设施。你会如何建议公司以最低成本实现这一目标?
a. 在另一个区域创建一个试点灯基础设施,并根据 CloudWatch 事件自动调整大小。
b. 通过在灾难恢复(DR)区域使用 Elastic Beanstalk 创建一个全新的环境来创建重复的基础设施。在发生故障时,将 Route 53 记录切换到 DR 区域的负载均衡器。
c. 使用 Elastic Beanstalk 创建另一个环境,作为应用程序的副本,以防发生故障。
d. 使用 CloudFormation 在发生故障时在另一个区域启动资源。
审核答案
-
a.
-
c.
-
d.
-
d.
第十二章:Lambda 部署和版本控制
随着越来越多的应用架构走向无服务器,越来越多的云预算受到审视,AWS Lambda 成为开发者和运维人员工具箱中越来越可行的选择。了解如何利用 Lambda 和 Step Functions 的灵活性和强大功能是当今 AWS 环境成功的关键。
本章将涵盖以下主要内容:
-
AWS Lambda 概述
-
Lambda 函数
-
Lambda 触发器和事件源映射
-
使用 Lambda 部署版本
-
使用 Lambda 层
-
监控 Lambda 函数
-
Lambda 最佳使用案例和反模式
-
使用 Lambda 协调 Step Functions
技术要求
与前几章一样,我们将使用 Python 编程语言创建 Lambda 函数。建议具备基本的 Python 工作知识,以便跟随示例并在必要时进行调试和故障排除。
AWS Lambda 概述
AWS Lambda 是一种允许您将代码作为函数运行的服务,无需设置任何服务器或进行容器编排。它会自动根据接收到的请求数量进行扩展。Lambda 函数最吸引人的特点之一是它们仅按运行时间收费。这意味着您可以在一个或多个区域内配置平台,等待请求,而不必担心因空闲资源而产生的账单。
Lambda 让您专注于代码,而不是服务器,因为它是一个无服务器的 PaaS(平台即服务)产品。作为 PaaS 也意味着,除非 AWS 向您暴露,否则您无法访问底层计算平台进行调整,例如运行时(编程语言)、您的环境、函数需要使用的内存量以及分配的 CPU 数量:

图 12.1 – 带触发器的 Lambda 架构
许多 Lambda 函数是由其他 AWS 服务触发的事件。这也是该服务如此有吸引力的原因之一。Lambda 函数可以用于基于 S3 存储桶事件进行后台处理。然后,您可以将它们放入一个解耦的架构中,使用消息队列,如简单队列服务(Simple Queue Service)或Amazon MQ,由一个或多个并发的 Lambda 函数进行处理,将数据存入后端数据存储中。
然后,可以使用诸如API 网关的服务通过 GraphQL 和AppSync来检索数据。
无服务器而非服务器
无服务器这一术语应立刻让人联想到一些关键概念。在 AWS 的世界中,这可以归结为四个基本原则:
-
无需配置服务器:不需要实际配置或维护任何服务器或实例。您也不需要对容器进行编排。
-
系统和架构随使用情况自动扩展:随着请求、数据或事件的到来,底层平台和基础设施应自动进行扩展以满足所需的需求。
-
按价值付费:那些处于空闲状态、等待被使用的资源不应产生费用。只有在资源被实际使用时才会产生费用。
-
系统是为可用性和容错性而构建的:一旦您启动平台,它应该自动跨多个可用区扩展,从而提高您的可用性和容错性。
与那些在实际应用中使用过无服务器平台的人交谈时,他们通常会感觉从转向无服务器架构中获得了诸多好处。一个这样的好处是更高的灵活性和更快的行动能力,因为他们不再花费大量时间来设置和配置基础设施。将自己从实例和容器配置中解脱出来,能够更好地专注于他们的业务以及客户想要且认为有价值的功能。他们还觉得与以前数据中心的客户使用的容量相比,他们的规模增加了。这是因为 Lambda 会根据某个特定函数的调用次数自动扩展。
同步与异步调用
当您调用 Lambda 函数时,可以选择两种方式之一:同步或异步。
Lambda 将在同步调用中运行该函数,等待响应,然后返回响应代码以及函数返回调用中包含的任何数据。您可以使用 AWS CLI 中的invoke命令来同步调用函数。
使用异步调用时,您将事件推送到 Lambda,但不会等待即时响应。Lambda 会先将事件排队,然后再将其发送到函数:

图 12.2 – Lambda 中的异步调用
Lambda 管理着函数的事件队列,并在收到错误时,会尝试重试事件。如果重试失败,它会再尝试两次,每次重试的间隔时间会更长。
现在我们初步了解了如何调用 Lambda 函数,让我们深入研究一下 Lambda 函数本身。
Lambda 函数
您编写的代码就是运行的函数,无需配置或管理任何服务器。该函数本身就是资源,可以接收传递给它的事件,无论是您自己还是其他 AWS 服务传递的事件。
您可以使用几种支持的语言来创建 Lambda 函数,包括 Python、Node.js、Ruby、Java、Go 和.NET。您甚至可以通过使用容器来创建自定义运行时。
Lambda 的基本概念
当你启动 Lambda 函数时,这个过程称为 调用 函数。Lambda 函数处理事件。事件可以通过几种不同方式发送到你的函数:你可以手动调用函数,如使用测试事件,或者可以配置 AWS 资源或服务来调用它并启动进程。
由于我们正在讨论 Lambda 函数,有几个关键概念需要理解。
函数
函数是你处理事件的代码。当你通过事件、计划任务或手动调用 Lambda 进程时,函数会被调用。
标识符
Lambda 函数可以有版本和别名。一旦版本创建,它就是代码的固定版本,并且末尾带有一个数字标识符。虽然 $LATEST 版本是你可以不断更新的 Lambda 代码版本,但如果你想调用某个快照版本,如 test-function:1,则需要在版本号后追加版本号。
运行时
Lambda 中的运行时允许你选择语言以及语言版本,以便执行你的函数。这个运行时并不包含在函数内部;它位于 Lambda 服务和函数代码之间。你不仅可以使用 Lambda 服务提供的运行时,还可以在服务本身不支持的语言和版本下构建自己的运行时。
事件
Lambda 中的事件是一个包含待处理数据的 JSON 文档。事件可以是简单的和单层的,如下例所示:
{
"URL": https://packtpub.com
}
它们也可能是复杂的,来自 AWS 服务,并且包含需要复杂解析的嵌套键值对。这些复杂的事件可以包含有价值的数据,能够自动化流程并使你作为 DevOps 专业人员的工作变得更轻松,只要你学会如何利用它们的力量。
Lambda 处理器
处理器可以是任何名称,但默认名称,尤其是在 AWS 控制台中创建函数时,是 Lambda_function.Lambda_handler:
def Lambda_handler(event, context):
greeting = 'I am a DevOps Pro and my name is {} {}'.format(event['firstname'], event['lastname'])
print(message)
return {
'greeting': greeting
}
在我们示例的 Lambda 代码中,我们可以看到有两个参数被传递给 Lambda 处理器:event 和 context。
event 参数是一个 JSON 格式的文档,其中包含 Lambda 函数需要处理的数据。虽然它通常是一个字典对象,但也可以是列表、字符串、整数或浮动点数。
通过事件处理器和解析器的组合,你可以获取有关哪些特定资源调用了 Lambda 函数的信息,然后从那里执行必要的操作。通过使用 returns,例如之前简单示例中的问候语,你可以基于找到的信息调用函数内部的其他方法。你甚至可以让整个函数返回一个值。这在 Step Functions 中尤其有用,我们将在本章后面讨论这个。
context参数在运行时传递给 Lambda 函数。此参数包含有关调用、运行时环境和函数本身的信息。
Lambda 的限制
在创建 Lambda 函数时,了解 Lambda 服务的一些限制是很有帮助的。一个函数的最小内存为 128 MB,最大为 3,008 MB。Lambda 函数允许的最长执行时间为 15 分钟或 900 秒。环境变量最大只能有 4 KB。每个函数的并发执行限制为 1,000 次。如果你在提取数据或使用/tmp磁盘空间时,有 512 MB 的限制。
创建 Lambda 函数
了解 Lambda 函数的工作原理后,我们将开始创建我们的 Lambda 函数。我们将创建的函数会接收一个传入的 URL,并计算该网页上的单词数。由于我们需要外部包,因此我们首先需要创建一个 ZIP 包,然后将其上传到 Lambda 服务中。
有时,你可以直接在 AWS 管理控制台中使用 Lambda 服务内置的编辑器编写一个简单的函数。这包括 Python 语言及其boto和botocore模块,它们允许你利用 Python 的random来帮助生成随机数和随机值,OS允许你调用操作系统功能,math、gzip和logging模块,以及其他许多模块。
按照以下步骤构建我们的 Lambda 包,以便上传:
-
让我们首先打开终端并为我们的 Lambda 函数创建一个角色。终端打开后,我们将导航到目录的起始位置,然后为我们的 Lambda 创建一个新目录。创建后,进入该目录:
$ cd ~/ $ mkdir my-wc-function $ cd my-wc-function -
我们将使用以下 JSON,保存为名为
Lambda-role-policy.json的文件;你也可以在本书的 GitHub 仓库中的Chapter-12文件夹里找到这个文件:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "Lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } -
使用此文件在以下命令中创建我们 Lambda 函数将使用的角色:
$ aws iam create-role --role-name Lambda-12 --assume-role-policy-document file://Lambda-role-policy.json -
该命令应返回一个 JSON 格式的输出,显示角色创建成功,类似于以下输出:
{ "Role": { "Path": "/", "RoleName": "Lambda-12", "RoleId": "AROAW24Q7QQF5NLSQX3L5", "Arn": "arn:aws:iam::470066103307:role/Lambda-12", "CreateDate": "2021-06-15T01:06:06+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "Lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } } -
我们的角色已经为 Lambda 创建好了;然而,由于目前没有附加任何策略,它不能做太多事情。我们不会编写自定义策略,而是使用 AWS 为 Lambda 创建的预定义策略:
$ aws iam attach-role-policy --role-name Lambda-12 --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole -
在我们的角色创建并准备好使用后,让我们删除当前目录中的文件,以防它被随后的
zip包一起部署。如果你希望保存它,我建议使用copy或move命令将其转移到/tmp目录或Downloads,以便稍后访问:$ rm Lambda-role-policy.json -
现在,我们将创建一个新的文件,名为
Lambda_function.py。在这个函数中,我们将剪切并粘贴(或者如果你敢的话,直接输入)以下代码。或者,你也可以在本书的 GitHub 仓库中的Chapter-12目录找到完整的文件:import requests from bs4 import BeautifulSoup from collections import Counter from string import punctuation # already included in Lambda modules def Lambda_handler(event, context): # get the URL from the event r = requests.get("https://aws.amazon.com/blogs/compute/using-Lambda-layers-to-simplify-your-development-process/") #demo bs = BeautifulSoup(r.content) # gather all the words within the paragraphs p_txt = (''.join(s.findAll(text=True))for s in bs.findAll('p')) count_p = Counter((x.rstrip(punctuation).lower() for y in p_txt for x in y.split())) # gather all the text in the divs d_txt = (''.join(s.findAll(text=True))for s in soup.findAll('div')) count_div = Counter((x.rstrip(punctuation).lower() for y in d_txt for x in y.split())) # create a sum total of the words word_sum = p_txt + d_txt # return the number of words return word_sum -
现在,你的
my-wc-function目录结构应该是这样的:my-wc-function$ | Lambda_function.py -
此时,我们可以开始使用
–target在本地安装我们的依赖模块::pip install --target ./package requests pip install --target ./package bs4 -
现在,让我们来制作部署包。首先,我们将进入刚刚创建的
package目录,然后创建初始的zip文件。注意zip命令中的两个点,它们是告诉zip文件要在当前目录中创建,而不是在package目录中:$ cd package $ zip -r ../my-wc-package.zip . -
创建好我们的初始
zip文件后,我们可以将 Python 文件添加到zip文件中:$ cd ../ $ zip -g my-wc-package.zip Lambda_function.py -
运行此命令后,你应该看到
Lambda_function.py文件已经被添加到之前创建的zip包中。 -
现在,我们已经创建了部署包,准备继续使用 AWS 管理控制台上传并测试我们的函数。所有这些也可以从 CLI 继续,但控制台有一些 CLI 中没有的功能。
-
打开你的浏览器,登录管理账户后访问 Lambda 服务。你可以通过直接访问
console.aws.amazon.com/Lambda来进入该服务。 -
找到并点击主屏幕右上方的橙色创建函数按钮。
-
一旦你进入
my-word-count_python。 -
python 3.8。 -
我们之前创建的
Lambda-12角色:

图 12.3 – 在 Lambda 创建函数屏幕上选择我们创建的现有角色
-
填写完所有值后,点击橙色的创建函数按钮。
-
一旦你创建了你的函数(这应该会将你带到该 Lambda 函数的主屏幕),我们需要上传我们创建的 ZIP 文件。因此,在你的本地系统中找到
my-wc-package.zip。点击保存按钮将 ZIP 文件及其代码发送到 AWS Lambda:![图 12.4 – 将我们之前创建的.zip 文件上传到我们的 Lambda 函数]()
图 12.4 – 将我们之前创建的.zip 文件上传到我们的 Lambda 函数
-
一旦你上传了 ZIP 文件,多个文件夹应该出现在
Lambda_function.py文件的左侧。 -
为了查看我们新创建的函数的效果,我们需要创建一个测试事件。点击橙色的
Test1,然后点击对话框底部的橙色创建按钮。 -
创建好测试事件后,我们可以运行测试。点击测试按钮旁边的箭头,出现时选择Test1选项。选中正确的测试事件后,我们可以再次点击橙色的测试按钮开始测试。
运行测试后,你应该能在执行结果页面看到我们演示 URL 中所有单词的计数。
本次练习带领我们从头创建和测试一个 Lambda 函数,该函数依赖于第三方库。接下来,我们将学习如何为我们的函数设置触发器和源映射,以便在特定事件发生时自动运行。
Lambda 触发器和事件源映射
Lambda 触发器特别适用于当一段数据上传到特定的 S3 桶时启动多个应用程序。AWS 在许多讲座和演示中提供了将图像上传到桶的示例。然后,这张图像会触发 Lambda 函数,该函数会调整图像大小,使其更加压缩,然后将其放入 GIF 文件夹中。很多时候,这个函数还会在 DynamoDB 表中为新调整大小的图像放置一个指针。这些调整大小的图像对最终用户来说更易于访问并且下载更快,这一切都在上传源图像后自动发生:

图 12.5 – 上传图像到 S3 桶的流程,触发 Lambda 函数进行图像调整大小
我们可以通过桶触发器做的不仅仅是图像调整大小,尤其是在企业和 DevOps 环境中。记住,S3 可以作为源代码存储,因为它具有版本控制功能(如果已启用)。假设一个新文件已上传到某个特定文件夹,并具有特定的文件扩展名(例如*.py)。在这种情况下,这次上传可以触发我们的 CodePipeline 作业来构建一个新的容器,并将该容器通过我们设定的所有步骤,直到遇到任何手动审批步骤。
现在我们已经看过触发器如何调用 Lambda,让我们看看如何将流式数据推送到不同的队列服务,以便 Lambda 可以异步处理数据。
查看事件源映射
由于 Lambda 是一个自动可扩展的服务,它可以接收来自其他服务的某些信息并处理这些信息。这些信息可能会直接进入 Lambda 函数,也可能不会。这些中介服务,例如消息队列,接收数据流,然后触发 Lambda 函数。
Lambda 可以从事件源读取的服务
以下服务可以为 Lambda 服务提供事件源映射:
-
DynamoDB
-
Kinesis
-
亚马逊 MQ
-
亚马逊托管的 Apache Kafka 流媒体服务
-
亚马逊 SQS
现在我们已经了解了 Lambda 函数如何被不同的 AWS 服务甚至其他源调用,让我们学习如何通过版本来更新我们的函数。
使用 Lambda 部署版本
如果你有一个已知的 Lambda 函数的良好状态,你可以通过发布该函数的版本来冻结它,避免未来的更改。一旦发布,这个版本将被用户和服务独立调用并使用,不受未来版本更改或更新的影响,包括对 $Latest 函数进行的迭代。
当你发布一个 Lambda 函数的版本时,它包含以下信息:
-
函数代码以及与之相关的所有依赖项。
-
调用函数的 Lambda 运行时。
-
所有的函数设置,如内存、VPC 关联和 IAM 角色。
-
添加到函数中的任何环境变量。
-
一个唯一的 Amazon 资源名称(ARN),以便可以识别该函数的特定版本:

图 12.6 – Lambda 版本及其如何映射到别名
版本可以通过两种方式之一来引用:通过限定 ARN 或通过未限定 ARN。
一个限定的 ARN 会在函数 ARN 末尾有版本后缀:
arn:aws:Lambda:us-east-2:470066103307:function:my-word-count_python:5
一个未限定的 ARN 将不会在函数 ARN 末尾有后缀:
arn:aws:Lambda:us-east-2:470066103307:function:my-word-count_python
现在我们已经了解了 Lambda 函数的版本,接下来我们来看一下如何将别名与版本一起使用。
在 Lambda 中使用别名
别名允许你为 Lambda 部署的特定版本创建命名指针。如果你已经将 Lambda 函数的 ARN 传递给用户或其他应用程序,这尤其有用。
除非你处于测试环境中,否则你不会想要传递基础的 Lambda ARN,因为那会指向 $Latest 版本。这个 $Latest 版本会不断变化,并且在测试和部署新功能和修复时可能会出现错误和漏洞。相反,通过使用别名,你可以将用户指向一个特定的、稳定的函数版本,并且在发布、测试并准备好发布新版本时,可以无缝过渡到新版本。
使用 Lambda 层
Lambda 层是一个预先发布的代码依赖项和库的集合。如果你发现你(或你的团队)在多个函数中使用相同的代码片段,可以创建一个层,利用 Lambda 层的好处。首先,当其中一个依赖项发生变化时,你不再需要更新每个函数;而是只需要维护一个单一的层,所有函数都可以利用这个层,并且只需要维护一次:

图 12.7 – 带有和不带有层的 Lambda 函数
层是加速团队之间开发的好方法。共享功能,如日志记录、网络或甚至数据库连接,可以一次性编写并打包成层,然后从各个函数中调用。
将 Lambda 层添加到我们的函数中
我们已经有了一个来自上次练习的 Lambda 函数。现在,让我们通过添加一个不仅适用于这个特定函数,而是可以在我们的代码库和组织中多个函数间共享的层来扩展函数的功能。
我们已经完成了为 Lambda 函数添加层的过程。接下来,我们将学习如何使用原生 AWS 服务来监控我们的函数,以及哪些指标最有效。
监控 Lambda 函数
一旦你开发并部署了 Lambda 函数,你的工作并没有完成。为了确保其在运行时能够正确工作,应当监控特定的指标。幸运的是,Lambda 可以与多个其他 AWS 服务集成,帮助你不仅监控你的函数,还能在需要时排查它们。
如果你前往 AWS 控制台所在区域,并且你的 Lambda 函数已经部署,你会发现垂直菜单栏中有一个名为 Monitor 的菜单项,点击它可以进入监控功能:

图 12.8 – 来自 Lambda 函数控制台的 Monitor 菜单项
一旦进入 Lambda 控制台的 Monitor 部分,你会立即看到一个预先构建的仪表盘,它允许你一目了然地查看 Lambda 函数的基本但重要的图形化指标。以下是呈现的指标:
-
调用次数
-
持续时间
-
错误计数和成功率
-
限制
-
异步传输失败
-
迭代器年龄
-
并发执行
仪表盘的默认时间范围为 3 小时;然而,也有从 1 小时到 1 周的预设迭代。你还可以选择自定义时间范围,查看仪表盘上的监控数据。
关于 AWS 管理控制台中 Monitoring 部分的另一个非常实用的功能是,它有一些按钮,可以让你直接跳转到函数的 CloudWatch 日志、使用 ServiceLens 查看函数的 X-Ray 跟踪,或者如果你启用了该附加功能,还可以通过 CloudWatch 查看 Lambda Insights。
使用 X-Ray 帮助排查你的函数
当你尝试排查应用程序问题,尤其是找出在应用程序执行过程中或其调用的其他服务中出现瓶颈的地方时,你可能需要比当前的指标和日志提供的更多信息。这时,AWS 服务可以变得特别有用。
X-Ray 会收集有关你应用程序请求的数据,然后提供详细信息,包括每个过程的逐步时间。每次调用函数时,Lambda 都会运行 X-Ray 守护进程。该 X-Ray 守护进程监听 UDP 端口 2000 的流量并收集分段数据。然后,这些分段数据会被传递到 X-Ray API 进行展示。
注意
我们将深入探讨 X-Ray 服务,以及它如何在第十四章《CloudWatch 与 X-Ray 在 DevOps 中的角色》中更详细地用于监控和观察 Lambda 函数。
现在我们已经了解了如何监控我们的 Lambda 函数,接下来我们将讨论 AWS Lambda 的最佳使用场景和反模式。
Lambda 的最佳使用场景和反模式
现在我们已经详细了解了 AWS Lambda 作为代码服务的功能,接下来让我们看看什么时候使用 Lambda 最为合适,以及 Lambda 在哪些情况下不是最佳选择。这些信息对 AWS 专业人士和追求 AWS DevOps 认证的人来说都至关重要。
AWS 的 Lambda 服务非常灵活、经济实惠,并与大量 AWS 服务进行交互。它还允许你使用你熟悉的多种语言编写代码,并将其作为你的运行时环境。
那么,让我们继续前进,看看在什么场景下 Lambda 最能发挥作用。
AWS Lambda 的最佳使用场景
随着越来越多的团队开始关注无服务器解决方案和模式,我们来看看使用 Lambda 服务在哪些地方是合理的。
你希望专注于代码,而不是底层的基础设施
如果你或你的团队希望专注于功能和代码库,而不是配置和修补服务器,无服务器 Lambda 函数是一个非常好的选择。你只需要专注于代码,选择运行时、内存大小、函数的最大运行时间以及一些其他选项,Lambda 服务会处理其余的工作。这包括按需扩展和管理底层硬件。
作为专注于代码的回报,你确实会放弃一些功能。你将无法登录到底层的计算实例,实际上这些实例是容器,无法查看进程或在日志生成时进行监视。相反,你需要添加日志语句或日志库,以便通过 CloudWatch 日志调试代码。
你需要一个具有成本效益的解决方案
成本优化是我们在第一章《Amazon Web Service 基础》提到的五大服务支柱之一。组织总是寻找如何让他们的解决方案更加具有成本效益,而使用 Lambda 通常是一个不错的选择。Lambda 服务没有空闲费用,因为费用是按使用量计算的。该服务还提供一个每月一百万次调用的永久免费层。
其中一个特别有用的场景是,如果你正在构建 DevOps 管道,在每次部署时将应用程序部署到主区域和次区域(或灾难恢复区域),而无需担心额外费用。在次区域进行的部署不会产生费用,因为除非主区域发生区域或服务故障,否则不会调用该区域。如果发生问题,你将比其他人领先一步,因为你无需搭建任何基础设施或资源。相反,你只需要重新指向正在调用哪个区域的 Lambda 函数。
Lambda 反模式
既然我们刚刚讨论了 Lambda 在平台中的最佳使用场景,接下来我们将看看 Lambda 不太适合的场景。
在应用程序开发完成后,你不想更新运行时环境
使用 AWS Lambda 服务时,支持特定数量的运行时。不过,这些语言和版本并不是一成不变的。由于某些语言版本因缺乏支持而被弃用,AWS 将不再支持这些运行时,也不允许部署使用这些运行时的新 Lambda 函数。
很多时候,解决方法可能只是将 Lambda 控制台中的运行时版本从旧版本切换到新支持的版本。如果存在依赖于旧版本运行时的包、库或模块,那么可能需要更新或替换这些内容。如果原始开发人员或承包商不再在场,这可能会成为一个问题。
你需要从你的函数中调用一个异步调用
当你需要调用外部服务,比如外部 API 来执行任务时,这是一个异步调用。Lambda 可以成功地实现这一点。然而,调用到初始服务的请求可能并不会立即返回响应。让函数等待服务的响应并不是最佳模式,因为 Lambda 服务的计费是基于资源消耗的。
现在我们已经了解了何时使用和不使用 Lambda 函数,接下来我们将学习如何使用 Step Functions 协调多个 Lambda 函数。
使用 Lambda 协调 Step Functions
有时你需要将多个 Lambda 函数协调在一起执行一个更大的任务。Step Functions 可以根据状态机接收到的输入做出决策,执行并行步骤,甚至与其他服务(如 SNS)连接,以请求人工输入。
Step Functions 还会创建一个可视化工作流,让你看到流程中的每个步骤。当 Step Functions 运行时,你可以看到状态机的成功或失败。
理解 Step Functions 中的状态机
状态机是 Step Function 的编排功能。它定义了步骤的执行顺序,以及从前一个状态接收到的任何数据,并将其传递给其他状态以供使用。
状态机命令始终以 JSON 格式编写。即使你已经使用 YAML 格式编写了 CloudFormation 模板,你仍然需要以 JSON 格式创建你的状态机及其各种状态。
以下是一个状态机的示例:
{
"Comment": "A Sample State Machine",
"StartAt": "StepOne",
"States": {
"StepOne": {
"Type": "Pass",
"Result": "Hello World!",
"End": true
}
}
}
现在我们理解了什么是状态机以及它们如何与 Step Functions 区别开来,让我们看看 Step Functions 是如何工作的。
Step Functions 是如何工作的?
Step Functions 通过使用三步流程来工作:
-
定义你应用中的步骤。
-
验证任何状态变化。
-
运行你的应用并根据需要进行扩展。
注意
你知道吗,与 Lambda 函数不同,你不能从
S3存储桶事件触发 Step Function?相反,你需要让存储桶事件调用一个单独的 Lambda 函数,然后再调用 Step Function。
现在我们已经了解了 Step Functions 的基本原理,接下来让我们更仔细地看看 Step Functions 中可用的不同状态。
Step Functions 中可用的状态
当你开始配置你的 Step Functions 状态时,你开始创建一个 状态机。你通过使用 Amazon 状态语言 来实现这一点,Amazon 状态语言是一种基于 JSON 的语言,用于定义状态机中的不同状态。有些状态可以执行操作,有些是过渡状态,还有一些在任务失败或成功时停止:

图 12.9 – Step Functions 中可用的不同状态
让我们仔细看看这些状态及其执行的功能。
任务状态
当你创建一个由状态机执行的单个工作单元时,你正在创建一个 task 状态。task 状态是你可以调用 Lambda 函数的地方。
选择状态
choice 状态允许状态机根据逻辑评估在不同的分支之间进行选择。你提供一组选择规则,这些规则评估输入或输出变量。根据这些值是否为真,状态机的下一步将被定义。
虽然默认选择不是必需的,但建议这样做,以防没有任何选择与逻辑匹配。否则,你的状态机会停止并报错。
并行状态
顾名思义,parallel 状态可用于创建状态机的多个分支,这些分支同时执行。对于那些彼此独立的任务,这可以显著加快执行时间。
失败状态
一个fail状态会停止你的状态机的执行,但可以选择在字段中输入Cause(原因)、Error(错误)或两者。这些字段在调试较大和更复杂的状态机时尤其有用,与其在代码中硬编码错误代码,不如传递一些系统信息。
Succeed 状态
Succeed状态是一个终止状态,没有下一个字段。
等待状态
如果你需要在步进函数中添加暂停,可以添加一个wait状态。wait状态可以通过暂停的秒数或恢复的时间戳来定义。
创建步进函数
理解步进函数的最佳方式之一是创建一个,然后观察它的执行过程。我们已经创建了一个S3存储桶,用于存储已被步进函数调用的 Lambda 函数。如果你完成了初始的 Lambda 函数练习,你应该已经拥有以 ZIP 格式保存的 Lambda 函数,准备上传到这个新的存储桶。模板文件可以在本书的 GitHub 仓库中找到,在Chapter-12文件夹中,名为step_function.yml:
-
在运行模板之前,我们需要上传
my-wc-package.zip文件。这可以是我们至今一直使用的S3存储桶。我们将通过命令行使用 S3 复制命令来完成此操作。确保你在包含 ZIP 文件的相同目录中,或者已将 ZIP 文件移动到当前工作目录:$aws s3 cp my-wc-package.zip s3://devopspro-beyond/ -
打开终端并转到你从
Chapter-12文件夹下载 CloudFormation 模板的目录。使用以下 CLI 命令从step_function.yml模板创建步进函数。我们需要知道我们上传文件的存储桶,以便将其作为参数传递。我们还将把我们的堆栈命名为stepTest:$aws cloudformation create-stack --stack-name stepTest --template-body file://step_function.yml --parameters ParameterKey=LambdaFunctionBucket,ParameterValue=devopspro-beyond --capabilities CAPABILITY_IAM -
设置好步进函数和 Lambda 函数后,我们将使用管理员用户登录到 AWS 管理控制台。登录后,导航到步进函数服务。
-
一旦进入步进函数服务页面,你应该能看到一个名为第十二章的状态机。点击该状态机的名称,进入它:
![图 12.10 – 创建的第十二章状态机]()
图 12.10 – 创建的第十二章状态机
-
现在,在第十二章状态机中,点击开始执行按钮。这将打开一个对话框,你可以在其中命名执行。只需保持默认值不变,并点击对话框底部的橙色开始执行按钮。
-
一旦你开始执行,你应该能够看到状态机的映射和步骤的流动。你可以点击任何单个步骤来查看输入和输出值:

图 12.11 – 由 AWS 生成的状态机图形视图
通过这一章的学习,你不仅了解了创建 Step Function 的过程,还将之前创建的 Lambda 函数融入到了我们的状态机中。现在,让我们快速回顾一下这一章的内容。
总结
在这一章中,我们了解了 Lambda 服务及其在无服务器架构中的应用。我们考察了 Lambda 函数的不同组件,从事件到运行时环境。我们查看了 Lambda 可以被调用的不同方式,甚至可以从头开始构建一个函数。之后,我们了解了如何使用 Step Functions 来编排多个 Lambda 函数。
在下一章中,我们将深入探讨蓝绿部署及其变体。我们还将讨论它们在 DevOps 过程中扮演的重要角色,因为这可以在不同的测试问题中以多种方式提出。
问题
-
你团队中的一位开发人员创建了一个由 S3 桶事件触发的 Lambda 函数。该函数应该在对象放入桶中时被调用。然而,函数并没有正常工作。这个问题需要进行调试和修复。开发人员如何简单快速地完成这一任务?
a. 使用 Lambda 监控控制台帮助调试问题。
b. 使用 AWS CloudTrail 日志。
c. 打开 AWS 支持案例,注明 Lambda 函数的 ARN 和 S3 桶的名称。
d. 使用 AWS CloudWatch Logs。
-
你被要求帮助构建一个使用 AWS Lambda 的无服务器应用程序。这个应用程序需要进行监控,但公司不希望引入任何第三方服务进行监控。虽然记录和跟踪调用其他函数的功能可能会比较棘手,但 AWS 有哪些服务可以帮助你完成这项任务?(选择 3 项)
a. AWS CloudTrail
b. AWS CloudWatch
c. AWS Inspector
d. AWS X-Ray
-
你被引入一家公司,帮助他们处理无服务器架构。公司目前有一个架构,包含多个 Lambda 函数,这些函数互相调用,并充当状态机。公司使用了过时的编码模式来协调状态机,并发现当代码出错时修复起来很困难。你可以建议他们使用什么服务来帮助重构他们的应用并管理状态机?
a. AWS Data Pipeline
b. AWS Step Functions
c. AWS Cognito
d. AWS Beanstalk
答案
-
d
-
a, b, d
-
c
第十三章:蓝绿部署
通过在两个相同的环境之间切换流量来发布应用,更广为人知的就是使用蓝绿部署。了解如何通过不同的 AWS 服务进行蓝绿部署,可以帮助减少发布新版本应用时的风险。掌握各种服务的技术并理解每种服务的使用,对于通过 AWS DevOps 专业认证考试至关重要。
在本章中,我们将涵盖以下主要内容:
-
理解蓝绿部署的概念
-
你可以在蓝绿部署中使用的 AWS 服务
-
蓝绿部署在 AWS 中的优势
-
更新自动扩展组启动配置
-
在数据层中使用蓝绿部署的最佳实践
理解蓝绿部署的概念
当你使用蓝绿部署技术时,你在降低停机时间和风险方面采取了一个有效的措施。你通过运行一个复制环境,其中一个环境承担活跃流量,另一个环境接收更改。一旦更改完成并进行测试后,之前指向初始环境(蓝色环境)的流量可以切换到绿色环境。这个切换可以一次性完成,也可以分阶段进行,这取决于你的部署计划和所使用的服务。如果部署出现问题,你可以快速将流量重新引导回已知的稳定环境,即蓝色环境,同时修复新的环境。
蓝绿部署的基础是两个独立的环境。一个环境,即蓝色环境,指的是当前应用或工作负载运行的环境。第二个环境,即绿色环境,是一个复制的环境,你可以在其中部署更新的应用代码或工作负载更改。使用这两个独立环境的协作可以实现接近零停机时间的发布和回滚能力。
执行蓝绿部署时,你正在使用不可变的基础设施。这意味着你不会在现有基础设施上进行升级或更新,而是为每个部署过程创建一套新的资源。
部署过程不容易
传统的部署方式倾向于就地升级。然而,使用就地升级时,需要考虑许多风险因素:
-
资源限制
-
潜在的停机时间
-
来自其他系统的依赖
-
回滚不成功部署的困难
由于部署过程中的成本和复杂性,团队有时会选择部署到现有基础设施。这是一种可行的部署策略,但它存在固有的风险,特别是在执行像一次性全量部署这样的操作时,所有实例或应用程序都会同时更新。如果在部署过程中出现问题或故障,这通常会导致停机、收入损失、品牌信任度丧失和客户信心下降,具体情况取决于停机时间的长短。
问题
在开始规划部署时,尝试问自己,哪些解决方案能够减少停机时间、处理依赖关系,并且能以更高效的方式协调工作负载?
在执行部署时,有多个风险需要规避,包括以下几点:
-
应用程序故障
-
基础设施故障
使用蓝绿部署策略有助于减轻这些风险和业务影响,因为它可以实现几乎无缝的从一个环境切换到另一个环境。
在谈论部署,尤其是蓝绿部署时,环境这个术语经常被使用。理解“环境”定义对于理解哪些资源会发生变化至关重要。知道什么被定义为环境,在处理 AWS DevOps 专业考试的一些问题时也非常重要。
环境是一个事物变化的边界,也是需要部署事物的地方。这可以是你应用程序的一个组件,也可以是应用程序的一个完整层级,例如 Web 层。
可用于蓝绿部署的 AWS 服务
AWS 提供了许多原生工具,可以让你执行蓝绿部署。这些工具提供了多种部署选项,从使用像 CloudFormation 这样的服务全面控制环境的各个方面,到对 Route 53 或 Auto Scaling 等服务进行细粒度的更改。这些更细粒度的选项只允许你对应用程序的特定部分进行修改,但在实施蓝绿部署时,它们同样有效。
让我们来看一下 AWS 提供的不同服务,它们可以帮助我们进行蓝绿部署。
AWS CloudFormation
使用 AWS CloudFormation,你可以利用该服务的模板功能,既可以描述你正在部署的 AWS 资源,又可以快速创建包含所需更新的环境副本。所有这些都可以通过 CloudFormation 支持的两种语言之一:JSON 或 YAML 来完成。
模板可以是更广泛基础设施中的小组件。通过 CloudFormation 模板,您可以创建一组相关的项目,例如自动扩展组,然后使用该组的输出更新先前创建的模板,该模板包含负载均衡器,并更新其指向的位置,或者使用新创建的自动扩展组手动进行切换。
AWS Elastic Beanstalk
Elastic Beanstalk 是一项服务,帮助开发者集中精力于代码,而由它管理底层基础设施。这包括如 ELB、EC2 实例、带有 EBS 卷的 EC2 实例存储、弹性 IP、自动扩展组、安全组,甚至通过 CloudWatch 指标进行监控等内容。
在 Elastic Beanstalk 中执行蓝绿部署时,您可以轻松克隆环境。这些克隆可以是当前应用程序代码库的精确副本,或者如果自上次部署以来您推送了功能和更改,它们甚至可以是代码的最新版本。Elastic Beanstalk 使使用该服务的用户可以轻松地通过“交换环境 URL”功能从一个环境切换到另一个环境。此功能会在后台进行 DNS 切换,并将流量从先前的(蓝色)环境重定向到新的(绿色)环境。
AWS CodeDeploy
AWS CodeDeploy 是一项托管部署服务,帮助自动化将您的软件部署到本地服务器、EC2 实例、AWS Lambda 函数和 AWS Fargate 容器。当使用 AWS CodeDeploy 创建部署时,您可以选择就地部署或蓝绿部署。
使用蓝绿部署选项,您可以在环境配置中设置 CodeDeploy 自动复制您的 EC2 自动扩展组,或手动配置实例进行蓝绿部署。还可以启用负载均衡选项。此外,还可以选择在部署完成后自动重定向流量,或者允许在部署到新实例或自动扩展组后手动重定向流量。
甚至可以使用 CodeDeploy 服务将 CloudFormation 模板集成在一起,以执行蓝绿 ECS 部署。
AWS ELB
AWS ELB(ELB)是一项计算服务,允许您将流量路由并分发到多个实例、IP 地址、Lambda 函数、容器,甚至虚拟容器。由于 ELB 是一项托管服务,它还可以执行健康检查,以确定哪些实例健康,哪些实例需要停止接收流量:

图 13.1 – 应用程序负载均衡器使用目标组同时将流量部署到两个版本的应用程序
使用应用负载均衡器的目标组,你可以通过金丝雀部署(蓝绿部署的一种变体)将应用的新版本推送到部分用户。通过使用多个与同一应用负载均衡器连接的目标组,你可以确定将多少流量引导到应用程序的每个版本。
Amazon ECS
亚马逊 ECS (ECS) 使用任务使 Docker 容器的分组在 AWS EC2 实例上更易于运行、停止和管理。通过 ECS,你可以使用服务调度程序安排容器何时被放置在实例上。ECS 还允许你在同一区域但不同的可用区内,将运行相同任务的多个容器分布在多个 ECS 兼容实例上:

图 13.2 – 使用 ALB 在 ECS 中从目标组 1 切换到目标组 2
容器的使用使得部署,特别是蓝绿部署,更加简便。容器不像完整的实例那么复杂,多个容器可以在同一个 EC2 实例中运行,即使它们运行的是不同版本的应用程序。
Amazon 弹性 Kubernetes 服务
亚马逊 弹性 Kubernetes 服务 (EKS) 允许你在 AWS 云和本地环境中运行和扩展 Kubernetes 应用程序。它通过提供安全的集群来帮助管理集群,并允许集群具有高可用性。
EKS 可以在专用的 EC2 实例上运行,也可以在 AWS Fargate 上运行,后者为容器提供按需计算能力。使用 Fargate 无需为实例进行配置,选择服务器类型或管理虚拟机。
你可以借助 AWS Fargate 上的 EKS 和 CodeDeploy 服务的蓝绿部署功能来执行蓝绿部署。当你为 EKS 创建新的蓝绿部署时,指定一个前端 Kubernetes 任务的应用负载均衡器名称,CodeDeploy 服务会处理新绿色服务的部署,然后逐步淘汰旧的蓝色任务。
AWS OpsWorks
AWS OpsWorks 是一项配置管理服务,允许你根据 Chef 或 Puppet 框架来配置堆栈。
使用 OpsWorks,蓝绿部署变得更简单,只需克隆整个堆栈。
Amazon CloudWatch
Amazon CloudWatch 是一项指标和监控服务,允许用户跟踪和观察已部署的资源。CloudWatch 服务还具有设置警报并通过其他服务(如 Amazon SNS 或 Amazon SES)发送通知的能力。
当在蓝绿环境中的资源上设置了指标时,你就可以在开始将流量导向新环境时评估该环境。保持关注你在 CloudWatch 中设置的指标,并确保所有服务在切换到新环境时保持稳定状态,这有助于缓解切换到新环境时的焦虑。
亚马逊 Route 53
亚马逊 Route 53 是一种 DNS 服务,可以在蓝绿部署中使用,通过将 DNS 记录指向新的绿色环境。这使得 DevOps 专业人员和网络管理员可以通过更新 DNS 记录快速且轻松地重定向流量。Route 53 还包括高级功能,例如调整资源记录的 生存时间(TTL),以及使用加权策略等先进技术,使得流量可以逐步转移到新环境,而不是一次性全部重定向。
现在我们已经了解了可以用来实现蓝绿部署的不同服务,让我们来看一下使用蓝绿部署的好处。
使用 AWS 的蓝绿部署的好处
使用蓝绿部署策略相比于原地部署提供了多重好处。需要注意的是,尽管这些好处相当显著,但在蓝绿过程中新创建的附加环境会带来额外的成本。验证完部署后,副环境可以被拆除,或者如果部署失败,回滚完成后副环境也可以被移除。
在 AWS 中执行蓝绿部署的技术
在 AWS 中实现蓝绿部署可以通过多种方式进行。已经出现了一些经过验证的模式,用于成功实现这些部署。在我们查看每种技术时,将重点介绍所使用的具体服务。不同的应用程序倾向于采用不同的模式。
使用 Route 53 更新 DNS 路由
Route 53 服务允许你在启动新环境后使用托管区域。将额外的记录添加到记录集中,然后就可以为终端用户创建无缝过渡到新的应用程序部署:

图 13.3 – 显示使用 Route 53 托管区域的蓝绿部署
这种切换可以一次性完成,将所有流量强制导向新的绿色环境。你也可以使用加权记录将一部分流量发送到绿色环境,最初作为金丝雀测试。这些金丝雀用户将生成日志和指标,可以在一段时间内进行评估。如果在新环境中没有报告错误,那么你可以改变策略的权重,使得 100%的流量现在都被引导到绿色环境。
这种技术不仅限于在相同的可用区集或甚至相同的区域内创建新的绿色环境。您可以在完全不同的区域创建新的绿色环境。如果您计划在环境中切换区域,请确保已考虑到您的数据层以及在区域切换期间可能受到的影响。
这也不限于实例或服务在负载均衡器后监听请求的情况。使用 Route 53 的 DNS 路由切换可以应用于以下所有场景:
-
由 ELB 管理的 EC2 实例组或集群
-
由 ELB 管理的 Auto Scaling 组中的实例
-
具有公共地址或弹性 IP 地址的单个实例
-
在指定环境中的 Elastic Beanstalk Web 应用程序
-
在 ECS 或 EKS 中运行的服务
部署过程 – DNS 路由
使用 Route 53 切换托管区实现蓝/绿部署的过程详见以下内容:
-
开始时将所有流量的 100%引导到蓝色环境,使用当前版本的应用程序部署。
-
部署应用程序的新版本到绿色环境。
-
测试绿色堆栈部署是否成功,可以通过运行一系列手动或脚本化的测试来进行验证。
-
更新 Route 53 托管区中的加权记录,将一部分流量引导到新的绿色环境。
-
监控新环境以检测错误或失败。
-
更新 Route 53 托管区中的加权记录,将剩余流量转移到绿色环境。
-
如果部署出现问题,请更新 Route 53 记录,将所有流量重新导向蓝色环境。
现在我们已经看到如何使用 DNS 和 Route 53 进行蓝/绿部署,接下来让我们看看如何在不改变 DNS 设置的情况下进行蓝/绿部署。
在 ELB 后面交换自动缩放组
在我们的第二个蓝/绿部署选项中,我们将排除 DNS 选项。在许多组织中,负责应用部署的团队与处理包括由 Route 53 服务托管的 DNS 记录在内的网络配置的团队并不相同。因此,我们需要为这些情况做好准备:

图 13.4 – 通过交换自动缩放组部署蓝/绿环境
一旦启动了新的自动缩放组,您需要在注册新的自动缩放组(即绿色自动缩放组)到 ELB 之前,在新的绿色堆栈上执行一系列测试。
重要说明
我们将进行创建和部署自动缩放启动模板的实际操作练习,详见第十八章,自动缩放和生命周期挂钩。
这里需要注意的一个重要事项是,ELB 仅在注册和注销方面参与部署过程。在部署软件的新版本时,你并没有部署一个新的负载均衡器。
部署过程 – 替换自动伸缩组
通过替换自动伸缩组来执行蓝绿部署的过程如下:
-
在开始之前,确保你的 ELB 实例不属于你的部署环境。
-
开始时,ELB 实例指向蓝色自动伸缩组。
-
部署新的绿色自动伸缩组。
-
测试绿色自动伸缩组。
-
将绿色自动伸缩组注册到 ELB 实例。
-
从 ELB 实例中注销蓝色自动伸缩组。
现在我们已经了解了如何通过替换自动伸缩组来执行蓝绿部署,接下来我们将探讨另一种也使用自动伸缩组的蓝绿部署技术。
更新自动伸缩组的启动配置
每个自动伸缩组都与一个启动配置相关联。启动配置包含在伸缩事件发生时启动新实例所需的信息。
创建一个新的启动模板(或启动配置)。这个新的启动配置包含更新的 AMI、更新的用户数据,或者两者:

图 13.5 – 通过替换启动配置部署蓝绿环境
部署过程 – 更新自动伸缩组启动配置
通过更新自动伸缩组启动配置来执行蓝绿部署的过程如下:
-
确保你的 ELB 实例不参与部署过程。
-
从将流量导向当前使用蓝色启动配置的自动伸缩组开始。
-
创建一个新的启动配置(绿色启动配置),并将其附加到自动伸缩组。
-
将自动伸缩组扩展为其原始大小的两倍。
-
一旦绿色自动伸缩组的实例启动并变得健康,将自动伸缩组缩减回原始大小。
更新 ECS
将你的应用程序打包到容器中可以让部署变得更容易。
使用目标组,可以让你在单个负载均衡器后运行多个服务。一个可以是蓝色服务,另一个可以是绿色服务。
执行蓝绿部署的关键环节之一是应用程序负载均衡器。ECS 任务是在应用程序负载均衡器上注册的:

图 13.6 – 使用 ECS 服务更新进行蓝绿部署
在使用这种方法时,你需要考虑以下事项:
-
你的代码需要是完全无状态的。
-
不支持金丝雀部署。
-
在任务切换期间,长期运行的连接将被突然终止。
部署过程——更新 ECS
通过更新 ECS 进行蓝绿部署的过程如下:
-
从一个定义了任务定义并指向应用负载均衡器的蓝色服务开始。
-
接下来,创建一个新的任务定义,该任务定义基于新创建的容器中的新应用版本;这个版本就是你的绿色版本。
-
使用绿色任务定义扩展绿色服务,并将该绿色服务映射到应用负载均衡器。
-
通过将任务数设置为零来缩减蓝色服务的规模。
现在我们已经了解了如何使用容器和 ECS 执行蓝绿部署,让我们看看如何使用 Elastic Beanstalk 服务在蓝绿部署中快速交换应用版本。
交换 Elastic Beanstalk 应用程序的环境
如果你打算使用蓝绿部署策略与 Elastic Beanstalk 配合使用,则必须确保你的应用环境与数据库分离:

图 13.7 – 通过交换 Elastic Beanstalk 应用程序进行蓝绿部署
部署过程——交换 Elastic Beanstalk 环境
执行交换 Elastic Beanstalk 环境以进行蓝绿部署的过程如下:
-
打开 AWS 管理控制台,进入 Elastic Beanstalk 服务,确保你处于正确的区域来管理你的 Beanstalk 应用。
-
克隆你的环境。你可以在不对当前平台做任何更改的情况下进行克隆,或者选择
Clone with latest platform来使用平台 Git 分支的最新版本。这个新平台将成为你的绿色环境。 -
如果你仅克隆了环境,你将需要将应用的新版本部署到绿色环境。
-
你现在可以使用绿色环境 ELB 所赋予的唯一 DNS 名称测试新环境。
-
在环境概览页面,选择
Environment Actions | Swap URLs。 -
来自 Route 53 的流量现在将被定向到绿色环境。
我们已经看到如何使用 Elastic Beanstalk 服务的 Swap URLs 功能轻松进行蓝绿部署。接下来,让我们看看如何通过克隆 OpsWorks 堆栈在 OpsWorks 服务中执行蓝绿部署。
克隆 OpsWorks 堆栈并更新 DNS 记录
当你在 AWS OpsWorks 中创建应用时,你需要首先创建一个堆栈。一个 OpsWorks 堆栈由一个或多个层组成。堆栈创建后,可以轻松克隆为其精确副本,从而创建一个全新的环境。在这个新环境中,你可以更新你的配方并部署应用的新版本。你甚至可以在 ELB 上使用本地 DNS 名称,在将任何流量路由到新堆栈之前测试应用的新版本。
将托管应用程序的 OpsWorks 堆栈与 Route 53 服务结合使用,指向你的 CNAME 流量,你可以在部署新版本应用程序时,快速轻松地在堆栈之间切换。

图 13.8 – 克隆 OpsWorks 堆栈
部署过程——克隆 OpsWorks 堆栈
通过克隆 OpsWorks 堆栈来进行蓝绿部署的过程如下:
-
从你当前的堆栈开始,这是你的蓝色堆栈,包含当前版本的应用程序。
-
接下来,通过克隆堆栈创建新的堆栈,这就是你的绿色环境。你可以通过在控制台中点击克隆链接或使用 CLI 来完成此操作。
-
将新版本的应用程序部署到绿色环境的应用程序层。此时,应该没有任何流量被指向绿色环境。
-
如果需要,预热你的 ELB,以便它能处理你的客户基础的流量。
-
当你准备将绿色堆栈提升为用于生产的堆栈时,更新 DNS 记录,指向通过 Route 53 的 ELB。这可以一次性完成,也可以逐步进行。
-
当你对部署感到满意时,你可以停用蓝色堆栈。
现在我们已经讨论了使用各种 AWS 服务进行的不同蓝绿部署技术,接下来我们将讨论数据层。
在蓝绿部署中使用最佳实践来管理数据层
部署新版本应用程序时可能出现的一个更重要的风险是对数据库进行更改。尤其是在执行蓝绿部署时,这一点尤为重要,因为蓝绿部署的核心目的是减轻风险,并能够快速回滚。
如果你使用的是 Amazon RDS,建议在开始部署之前创建数据库快照,特别是如果你将执行任何数据库更改。这将允许你在数据部署没有按计划进行时从快照中恢复,并尽可能减少停机时间。
将模式更改与代码更改分开
在进行部署时,将任何数据库更改(例如模式更改)与应用程序部署分开是至关重要的。你执行某些数据库更新的顺序可能取决于你正在执行的模式更改类型。
通常,当需要进行模式更改时,你可以采取两种方法,而何时使用其中一种方法取决于模式更改是否向后兼容,并且能否与当前版本的应用程序一起工作:

图 13.9 – 在蓝绿部署期间进行数据库模式更改的过程
第二种方法是在进行部署后进行模式更改竞争。这种方法最适合那些与当前应用版本不兼容的更改,如果在部署之前进行,将导致当前版本应用的错误。
有时你需要执行两个独立的模式更改。这种情况发生在你既有一组非破坏性更改,也有一组破坏性更改。通过将更改分为两个独立的部署,你对数据库进行了较小的增量更改,因此通过将步骤分解为较小、易于管理的部分,从而减少了风险。
总结
在本章中,我们讨论了蓝绿部署,它们是什么,以及如何成功地进行蓝绿部署。我们还谈到了在 AWS 中可以用来成功执行蓝绿部署的服务,以及使用每项服务执行部署的过程。最后,我们探讨了在实施部署时如何处理数据更新,重点讲解了哪些模式更改应该首先进行。
在下一章中,我们将开始关注环境和工作负载的监控与日志记录。这从了解 CloudWatch 和 X-Ray 服务在 DevOps 中的角色开始。
复习题
-
一家公司聘请你帮助他们在 AWS 上设计应用架构。该公司要求有一个可以自动扩展的硬化 AMI,作为应用的一部分。该应用同时监听 HTTP 和 TCP 端口,因此你决定使用可以处理这两种协议的经典负载均衡器。还有一个虚拟 CNAME,托管在 Route 53 上。蓝绿部署必须是此架构的一部分。你可以在 Route 53 中使用哪种路由策略来实现蓝绿部署?
a. 多选
b. 延迟
c. 加权
d. 简单
-
你正在执行蓝绿部署,更新 Elastic Beanstalk 中的应用环境。创建了一个与现有的蓝色环境相同的绿色环境,并将新版本的应用程序部署到绿色环境后,接下来应该做什么来切换到新的绿色环境?
a. 更新 DNS 记录,指向绿色环境。
b. 使用 Amazon Route 53 将流量重定向到新的绿色环境。
c. 替换当前指向环境负载均衡器的自动扩展启动配置。
d. 选择交换环境 URL 选项。
-
一家公司聘请了你,因为他们需要帮助在 AWS 上实施蓝绿部署流程。在新环境部署后,他们希望能够逐步将流量从蓝色环境切换到新的绿色环境。应用程序已经部署在 EC2 实例上,这些实例位于一个自动扩展组中,背后有应用程序负载均衡器。Route 53 正在将消费者流量路由到负载均衡器。最后,应用程序的数据层由 PostgreSQL RDS 多可用区数据库实例组成。
哪三个步骤可以成功实现蓝绿部署过程?
a. 创建一个新的应用程序负载均衡器和一个新的自动扩展组。
b. 在当前负载均衡器后创建一个新的自动扩展组。
c. 在 Route 53 中创建一个新的别名记录,指向绿色环境,并为两个记录设置故障转移策略。
d. 在 Route 53 中创建一个新的别名记录,指向绿色环境,并在两个记录之间使用加权路由。
e. 在你的新自动扩展组中,设置 EC2 实例使用相同的 RDS 实例。
f. 在你的新自动扩展组中,设置 EC2 实例使用 RDS 的故障转移节点。
查看答案
-
C
-
D
-
A、D 和 E
第十四章:监控和日志记录您的环境和工作负载
在本节中,您将了解 AWS 中可用的本地监控选项,以及如何通过不同的可访问日志接收来自您的环境和应用程序的反馈。
本书的这一部分包括以下章节:
-
第十四章,CloudWatch 和 X-Ray 在 DevOps 中的作用
-
第十五章,CloudWatch 指标和 Amazon EventBridge
-
第十六章,生成的各种日志(VPC 流日志、负载均衡器日志、CloudTrail 日志)
-
第十七章,高级和企业级日志记录场景
第十五章:CloudWatch 和 X-Ray 在 DevOps 中的作用
一旦你的应用程序在云中运行,你就需要一个方法来监控它,以确保它保持健康并有效地运行。CloudWatch 可以汇总你的服务和应用程序的日志,但将其与X-Ray结合使用,可以追踪应用程序的性能,找出进一步提升性能的地方。
在本章中,我们将涵盖以下主要内容:
-
CloudWatch 概述
-
使用 CloudWatch 汇总你的日志
-
CloudWatch 告警
-
为应用程序追踪添加 X-Ray
CloudWatch 概述
监控有许多重要原因,从运营角度到商业角度都很重要。首先,它让你不仅可以看到环境中运行的内容,还能了解这些资源的性能。其次,从运营角度来看,当你尝试实时解决问题时,监控非常关键。从商业角度来看,监控让你知道一些关键事项,比如你的部署是否已成功完成,客户是否没有看到任何负面影响。
在今天这个信息可以迅速通过互联网,尤其是社交媒体渠道传播的时代,任何影响客户体验的事情都可能并且通常会迅速传播。这会影响你的品牌和商业利润。通过 CloudWatch 监控你的资源可以让你走在前面,采取主动而非被动的应对方式:

图 14.1 – 监控如何持续演变
你今天监控系统和资源的方式可能与 5 到 10 年前监控方式有所不同。诸如基础设施变化和瀑布式部署哲学等因素决定了需要监控的内容。
过去,你可能需要配置一台服务器,并且这台服务器会运行长达十年才会被淘汰。然而,随着云服务的发展,如自动扩展,根据需求不断增加和移除实例,所监控的指标不仅要与系统健康相关,还要与客户体验的性能相关:

图 14.2 – AWS CloudWatch 的功能
亚马逊 CloudWatch 是一项 AWS 原生服务,帮助你监控服务和资源。它是 AWS 提供的管理工具的一部分。CloudWatch 的主要功能是帮助你跟踪和监控资源和应用程序的性能。在监控过程中,CloudWatch 服务可以通过 SNS 服务通知人员,或通过事件触发自动化响应这些告警。CloudWatch 还可以用于收集和监控日志文件。CloudWatch 包括三个主要组件:指标、告警和事件。
了解和使用 CloudWatch 统一代理
AWS 提供了一个统一的 CloudWatch 代理,可以帮助你处理多种事情,无论是对本地服务器还是 EC2 实例。让我们回顾几个使用 CloudWatch 统一代理的常见场景。
以不同用户身份运行
在 Linux 服务器上运行 CloudWatch 代理时,CloudWatch 代理默认作为 root 用户运行。如果你的公司不允许代理和程序以 root 用户身份运行,那么你可以为 CloudWatch 代理创建一个自定义用户,并在配置文件中告诉代理 run_as_user。
拥有多个 CloudWatch 代理配置文件
基于经批准的Amazon 机器映像(AMI)构建的组织,必须用于任何开发或生产构建,可以将 CloudWatch 配置文件预先配置到实例中。这个配置文件将允许跨所有实例收集标准配置。开发团队可以添加另一个配置文件,CloudWatch 代理可以在启动时读取并处理,其中包括任何特定的应用程序指标或日志。
一个例子是,如果应用团队正在运行一个 NGINX 服务器来为其 Web 应用提供前端,或者他们可能使用 NGINX 的代理功能来重定向流量。他们的自定义配置文件可以指定查找 NGINX 的 4XX 和 5XX 错误,同时也可以配置消费这些日志并将其发送回 CloudWatch Logs。
将指标和日志发送到与实例运行所在账户不同的账户
CloudWatch 代理具有灵活性,可以通过在配置中指定 role_arn 将指标、日志或两者发送到另一个 AWS 账户进行监控。
向 CloudWatch 代理收集的指标添加自定义维度
CloudWatch 会创建它收集的指标的汇总。这些汇总可能并不总是最适合你和你的团队,因此,可以通过使用 append_dimensions 字段自定义分组方式。
我们刚刚看到,无论是在 AWS EC2 实例还是本地服务器上使用的统一 CloudWatch 代理,都可以在多种场景下收集日志和指标。现在,让我们通过在 EC2 实例上安装 CloudWatch 代理的过程。
在 EC2 实例上安装 CloudWatch 代理
了解 CloudWatch 统一代理的最佳方法是通过在 EC2 实例上安装代理的过程。以下教程将带你完成搭建 EC2 实例的步骤,然后安装和配置代理。最后,我们将向 EC2 实例发送一些流量,以便查看生成的指标和日志。
注意
在下一章中,我们将更深入地探讨 CloudWatch 指标。第十五章,CloudWatch 指标和 Amazon EventBridge,将讨论通用指标和自定义指标。
到目前为止,我们在示例中一直使用 Amazon Linux 作为任何 EC2 实例的操作系统。Amazon Linux 是一个优秀的操作系统,并且预安装了许多在 AWS 云计算环境中使用的软件包。这正是我们在本示例中使用不同操作系统——Ubuntu——的原因。Ubuntu 操作系统默认并不会安装一些软件包,例如 CloudWatch 统一代理。这使得我们可以在这个 EC2 实例上通过安装过程来进行操作,但如果你在数据中心有一个 EC2 实例,过程是一样的,只不过你需要使用密钥对对实例进行身份验证,而且这个密钥对会定期轮换。而 EC2 实例可以扮演角色,因此不需要将访问密钥和秘密密钥存储在实例上,实际上,扮演角色是一种更安全的做法。让我们开始吧:
-
首先,让我们为实例创建 IAM 角色;我们需要确保实例具有 CloudWatch 和 AWS Systems Manager 的权限。要创建角色,我们需要在本地保存一个初始的
JSON策略文件,然后附加所需的两个托管策略。将JSON策略复制到名为STS.json的文件中:{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" } } -
保存好初始策略后,我们现在可以创建角色并附加这两个托管策略:
aws iam create-role --role-name CW-EC2 --assume-role-policy-document file://STS.json aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore --role-name CW-EC2 aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy --role-name CW-EC2 -
由于我们将通过 CLI 启动我们的实例,因此需要创建一个实例配置文件。一旦实例配置文件创建完成,我们就可以将新的角色附加到
instance profile:aws iam create-instance-profile --instance-profile-name CW_SSM aws iam add-role-to-instance-profile --role-name CW-EC2 --instance-profile-name CW_SSM -
然后,我们需要查询
SSM参数存储中的 AMI,我们希望使用该 AMI 来启动我们的镜像:AMI='aws ssm get-parameters --names \ /aws/service/canonical/ubuntu/server/16.04/stable/current/amd64/hvm/ebs-gp2/ami-id \ --query 'Parameters[0].[Value]' --output text --region us-east-2'如果你想查看返回的 AMI 值,可以使用以下命令:
echo $AMI -
我们稍后需要进入我们的实例,但与其创建密钥对,不如添加以下脚本,该脚本将安装 SSM 代理和统一的 CloudWatch 代理,适用于 Debian 操作系统。我们将创建此脚本并将其保存为名为
agents.sh的文件,这样我们就可以在稍后通过user-data参数启动 EC2 实例时使用它。安装 SSM 代理和
theunifiedCloudWatchagent的脚本如下:Chapter-14 folder of this book's GitHub repository under the same name – agents.sh. -
一旦我们将
AMI值存储到变量中,就可以使用以下命令启动我们的镜像:user-data script, which we just created, as well as a Name tag for our instance. This name will help us identify our instance when we try to find it later. -
当我们的实例正在启动并运行我们提供给它的启动脚本时,我们可以登录到 AWS 控制台,并直接使用以下网址访问 SSM 会话管理器:
console.aws.amazon.com/systems-manager/session-manager。登录后,在右上角检查确保您所在的区域正确。我们指定我们的实例启动在俄亥俄州区域(us-east-2),如果列出了其他区域,请切换到您创建实例的区域。作为替代,您也可以通过EC2屏幕选择实例,然后从操作下拉菜单中选择连接。在连接到实例屏幕中,选择会话管理器,然后点击橙色的连接按钮。连接到实例时,应该会弹出一个包含您会话的新窗口。 -
现在我们已经成功地通过 SSM 连接到实例,而不需要使用密钥,我们可以配置代理。我们已经使用
user-data脚本中的一些命令安装了 CloudWatch 代理。为了将一些日志流传输到 CloudWatch Logs,我们需要告诉代理具体要推送哪些日志。我们需要以sudo用户身份运行配置脚本,脚本位于/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard。为了简化命令,我们将通过sudo su命令切换到 root 用户:sudo su /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard -
运行 CloudWatch 代理配置管理器时,您将被提示回答一些问题,但设置应该不会超过 5 分钟。这里显示的问题是那些没有选择默认值的:
-
您想要选择哪个默认的指标配置?标准(2)日志文件路径:
/var/log/amazon/ssm/amazon-ssm-agent.log。 -
您是否想指定任何其他日志文件进行监控?不(2)。
-
您是否希望将配置存储在 SSM 参数存储中?不(2)。
-
-
配置向导完成后,由于我们使用的是 Ubuntu 操作系统,我们将把新生成的
config文件复制到代理预期的位置,并将文件所有权授予cwagent用户:cp /opt/aws/amazon-cloudwatch-agent/bin/config.json /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json chown cwagent /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -
现在我们的 CloudWatch 代理文件已经配置完成,我们需要重新启动代理以使更改生效。我们可以通过以下命令实现这一点:
& symbol at the end of the command will put the script in the background so that you can do other things, and the script will still be running. -
我们生成日志的首要方式之一是点击橙色的
CloudWatch服务。服务名称出现后,点击CloudWatch将带您进入该服务。 -
一旦进入
amazon-ssm-agent.log,点击该日志组的名称,将带您进入日志流。 -
日志组中应该只有一个日志流。该日志流的名称将是您 AWS EC2 实例的标识符。点击这个日志流,以便我们查看日志:
![图 14.3 – 我们 CloudWatch 日志组中的单个日志流]()
图 14.3 – 我们 CloudWatch 日志组中的单个日志流
-
如果您已经退出了您的
Sessionworkerclosed。任何在 CloudWatch 代理运行期间退出会话管理器的情况,都应该出现在日志列表中。您可以点击日志左侧的小三角形来展开内容,查看完整的日志条目。注意
我们将继续使用此实例进行本章的进一步练习。如果您打算稍后继续操作,我建议您将此实例置于休眠状态,这样您就不会因此而产生费用。这样,等到您准备好再次操作时,就无需重新配置一切。
现在,我们已经将统一的 CloudWatch 代理添加到非 Amazon 实例上,接下来我们将看一下 CloudWatch Logs 的一些其他功能。如果您打算在短时间内完成下一次使用 CloudWatch 警报的练习,我建议您要么保持此实例运行,要么仅仅停止实例,这样您可以访问 CloudWatch 代理汇总并推送的指标,供警报使用。
使用 CloudWatch 聚合日志
亚马逊的 CloudWatch 服务不仅是一个强大的监控工具,还允许您将操作系统、应用程序、自定义日志文件甚至 CloudTrail 日志等多种类型的日志路由到 CloudWatch Logs 的可靠存储中。
CloudWatch Logs 允许您将来自相同来源(日志流)的日志进行分组,然后使用筛选模式在这些组中进行搜索。筛选模式类似于 CloudWatch 版的正则表达式,允许您在日志流和日志组的不同字段中进行搜索。
使用订阅,您可以将特定日志流中的所有日志或仅符合特定筛选模式的日志推送出去。您可以将订阅数据推送到 Amazon Kinesis 流进行实时数据处理,或推送到 Lambda 函数进行事件驱动处理。您甚至可以使用 Lambda 函数将通过日志推送到一个或多个 CloudWatch 日志组的日志,直接推送到托管的 Elasticsearch 服务,以便通过 Kibana 界面进行更轻松的搜索和图形趋势分析。
在简要了解 CloudWatch Logs 之后,接下来让我们深入了解一下我们刚才提到的一些术语,以及它们在 CloudWatch Logs 中是如何协同工作的。
CloudWatch Logs 术语
当我们深入探讨 CloudWatch Logs 时,有一些术语是我们需要熟悉的,尤其是在接下来的练习和专业考试的上下文中:
筛选模式:限制哪些日志会被转发到 AWS 目标资源的过滤表达式。
日志事件:在 CloudWatch Logs 中记录的某项活动的记录被称为日志事件。事件消息必须是 UTF-8 格式。
日志流 和 日志组:共享相同来源的一组日志流在 CloudWatch Logs 控制台中被归为日志组。一个日志组中可以包含任意数量的日志流。
指标过滤器:通过使用指标过滤器,你可以从接收到的事件中提取数据。然后,你可以将这些数据转换为 CloudWatch 指标上的数据点。指标过滤器被分配给日志组。特定日志组中的所有日志流都会分配这些特定的指标过滤器。
保留设置:你的日志文件在 CloudWatch Logs 中的保留时间由保留设置决定。默认情况下,日志会被永久保存,不会过期。如果你不需要保存日志超过指定时间,这可能会导致额外的费用。你可以为每个日志组选择 1 天至 10 年之间的保留期限,一旦达到该保留期限,日志将自动删除:

图 14.4 – 从资源到 CloudWatch Logs 的日志流动
使用我们刚刚学到的术语,在前面的图示中,我们可以看到从 AWS 资源生成的日志如何成为日志流。一个或多个日志流会被合并形成一个日志组。日志流然后根据保留设置被保留或删除。
接下来,我们将学习如何使用 CloudWatch Logs 的一个功能 —— Insights,来分析 CloudWatch Logs 服务所捕获的数据。
CloudWatch 警报
除了将日志发送到存储并进行搜索,监控系统的另一个方面是当出现问题时接收警报。这些警报可以是简单的通知,让你知道某个服务或服务器没有响应。也可以是主动警报,提醒你所运行应用的平台的 CPU 或内存即将耗尽,需要在更大问题发生之前进行扩展。
你可以使用 CloudWatch 服务来监控单一指标或多个条件以创建警报。当基础资源的指标满足某个标准时,可以触发这些警报。在 CloudWatch 中,你可以创建两种类型的警报:指标警报和复合警报。
指标警报 监控 CloudWatch 的特定指标。它有一个监控阈值,该阈值在初次创建时设置,同时还有一个可以突破阈值的周期数,超过该周期数后会进入警报状态。一旦触发该警报状态,就可以配置相应的操作。可用的操作包括向 SNS 主题发送通知、执行 EC2 操作、执行 AutoScaling 操作,或在 Systems Manager 中创建 OpsItem 或事件。
复合警报 使用你创建的多个警报状态,以便在警报触发时创建特定条件。
一旦告警触发,你可以让告警执行各种操作,如下所示:
-
停止、终止或重启一个 EC2 实例。
-
让自动伸缩组进行扩容或缩容。
-
向 AWS SNS 主题发送通知消息。

图 14.5 – CloudWatch 告警示例
在准备 DevOps 专业考试时,有一些关于 CloudWatch 告警的事实你应该知道。虽然专业考试不会直接考察这些事实,但它们可以融入到更大的场景中:
-
告警名称只能由 ASCII 字符组成。
-
每个区域、每个账户最多可以创建 5,000 个告警。
-
你可以将告警添加到 CloudWatch 仪表板中。
-
你可以通过使用
SetAlarmState设置来测试告警(无论是启用还是禁用告警)。 -
CloudWatch 服务保存告警历史记录 2 周。
接下来,我们将创建一个 CloudWatch 告警并创建一些事件来触发告警。为了接收告警通知,我们还需要创建一个 SNS 主题。然而,如果你已经有一个 SNS 主题并希望使用该现有主题,可以跳过这一步。只要确保如果跳过这一步,你已经订阅了该主题。
创建一个 CloudWatch 告警
你应该已经有一个 EC2 实例,它正在生成从我们上一个练习中建立的指标。我们将使用这个实例的指标来监控告警,并通过施加负载使告警被触发。
为了接收告警通知,我们需要一个 SNS 主题,供我们订阅电子邮件地址:
-
打开终端并输入以下命令来创建
topic:topic was created successfully, then it should return something like this:{
"TopicArn": "arn:aws:sns:us-east-2:470066103307:cwatch"
}
-
现在我们有了
topic,我们需要使用subscribe并填写我们的电子邮件地址:JSON statement telling you that the subscription is pending:{
"SubscriptionArn": "待确认"
}
-
现在,我们需要进入我们的电子邮件账户,找到 SNS 服务刚刚发送的电子邮件。然后,我们必须点击上面写有确认订阅的链接。
-
创建了 SNS 主题后,我们可以返回 AWS 管理控制台,导航到
CW_Agent并记下实例 ID。一旦记下了这个信息,去导航栏左上方的服务下拉菜单中选择 CloudWatch 服务。打开 CloudWatch 服务的新标签页,我们稍后需要回到这个实例来测试我们的告警。 -
一旦进入 CloudWatch 服务,从左侧菜单中找到告警菜单设置。点击该菜单项以展开并查看子菜单项。展开后,点击所有告警,这样你就能进入告警页面。
-
在告警页面,点击标有创建告警的橙色按钮来创建新的告警。这将弹出创建告警的提示。
-
点击选择指标按钮。这将弹出一个对话框,您可以选择指标。找到自定义命名空间,然后点击CWAgent。进入CWAgent命名空间后,选择标记为ImageId, InstanceId, InstanceType的分组,并点击该链接。
-
找到名为
mem_used_percent的指标。然而,在点击选择框之前,请确保InstanceId与您之前找到的实例 ID 匹配。如果一切匹配,则选中该指标左侧的复选框,以便在警报中使用此指标。当您选择此指标或任何其他指标时,顶部将显示一个图形,显示您所选指标的记录值。点击页面底部的橙色选择指标按钮继续:![图 14.6 - 在创建 CloudWatch 警报时选择要监控的单一指标]()
图 14.6 - 在创建 CloudWatch 警报时选择要监控的单一指标
-
向下滚动至
20。更改这些值后,点击橙色的下一步按钮。 -
现在,在通知屏幕上,使用以下选择。填充完所有部分后,向下滚动到页面底部并点击橙色的下一步按钮:
a. 警报状态触发器:在警报中。
b. 选择 SNS 主题:选择一个现有的 SNS 主题。
c. 发送通知到:选择您刚刚创建的 cwatch 通知主题。
-
接下来,在
chapter14处作为警报名称。点击橙色的下一步按钮。 -
最后,在预览并创建页面,向下滚动到页面底部,逐一检查页面上的各项值。如果一切看起来正常,请点击页面底部的橙色创建警报按钮。
-
现在我们已经创建了警报,接下来需要对其进行测试。我们可以通过使用 CLI 更改
SetAlarmState来进行测试。然而,我们将通过对 EC2 实例本身进行压力测试来测试警报。找到之前打开的包含实例 ID 的标签。选择该实例旁边的复选框,然后在 AWS 管理控制台的实例屏幕顶部,找到标有操作的下拉菜单。点击操作菜单以显示子菜单项。选择连接。 -
在连接屏幕上,使用会话管理器连接到实例。进入会话管理器标签页后,点击底部的橙色连接按钮,开始我们在 EC2 实例中的会话。
-
现在我们已经进入实例,接下来需要安装一个包来帮助我们对实例进行压力测试并触发警报。运行以下命令安装该包:
sudo apt-get install -y stress -
一旦安装了
stress包,我们可以使用以下选项来运行它,进行压力测试实例的内存:stress –vm 2 –vm-bytes 126M -
当实例的内存使用百分比超过 20%并持续 5 分钟后,您应该会收到一封电子邮件通知,通知将发送到您在 SNS 主题中订阅的电子邮件地址。
现在,我们已经看到 CloudWatch 服务如何收集和聚合日志,并通过发送警报帮助我们进行监控工作,接下来我们将介绍我们监控和调试工具包中的另一个工具:AWS X-Ray。
使用 X-Ray 添加应用程序跟踪
X-Ray 是用于监控现代 Web 应用程序的服务。现代应用程序本质上是面向服务的应用程序。这些应用程序可以是无服务器架构应用程序或运行在容器中的应用程序。在这些现代应用程序中,应用本身被拆分成多个部分。虽然这带来了许多优势,包括水平扩展的便捷性和充分利用云原生服务,但也会带来一些挑战。了解错误最终对您的服务(或业务)产生的影响变得更加复杂。
跟踪功能使您能够通过以下方式在现代应用程序中连接各个环节:
-
发现多个服务。
-
获取有关单个操作的洞察。
-
查看段内隔离的问题。
-
对特定问题进行根本原因分析。

图 14.7 – X-Ray 跟踪如何将各个部分拆分成段
跟踪功能使您能够快速查看并轻松检查特定 API 调用或特定用户发生了什么。
一个跟踪是一个全面的视图,它从客户的角度封装了从客户创建交易的端到端事务。
到此为止,X-Ray 会将跟踪分解成多个段。段是来自单个服务器的片段。
现在我们已经理解了跟踪,这是 X-Ray 中的一个主要概念,让我们来看一下 X-Ray 服务本身是如何工作的。
然后,跟踪被分解成不同的段。一个段提供了资源的名称、请求的具体信息以及正在执行的工作。段也可以显示在该段中发生的问题,如错误、故障和异常。
X-Ray 服务是如何工作的?
您首先将 X-Ray SDK 集成到您的应用程序中。可以针对不同的语言(如 Python、Java 和 Node.js)进行定制。接下来,一个实例上的守护进程开始收集数据。然后,守护进程将这些数据发送到 X-Ray 后端。在 X-Ray 后端,跟踪数据被记录。不同服务可能会在不同时间点提供数据,但 X-Ray 服务可以通过使用跟踪 ID将所有这些信息拼接在一起。一旦收集到跟踪数据,X-Ray 服务会创建一个名为服务地图的汇总视图。最后,X-Ray 提供了一套分析功能,允许您深入挖掘并回答三个重要问题。
另一个需要注意的事项是,X-Ray 服务是云无关的。这意味着你编写的代码不必仅在 AWS 云中运行。代码可以在其他地方运行,以利用 X-Ray 服务的跟踪功能,例如在开发者的笔记本电脑上或企业数据中心中。前提是运行环境能够连接回 AWS X-Ray 服务,并具有一组凭证以使其能够运行。
X-Ray 帮助你解答三个问题
X-Ray 服务帮助开发者解答三个特定问题:
-
我的应用程序运行得怎么样?
-
为什么我的应用程序表现成这样?
-
谁受到了这些问题的影响?
X-Ray 界面的图形化展示,表现为服务图,使你和你的开发团队能够看到应用程序用户在哪些地方消耗了资源。它还会给出不同资源的响应时间,让你看到是否某个特定资源是延迟或问题的根源。
现在我们了解了 X-Ray 如何帮助我们开发和排查在 AWS 云上运行的应用程序,让我们来看一下 X-Ray 服务如何与无服务器服务集成。
X-Ray 和无服务器服务
在与无服务器服务,特别是 Lambda 一起使用 X-Ray 时,X-Ray 服务提供了一些 CloudWatch 监控无法提供的独特优势。X-Ray 让你获取 AWS Lambda 冷启动的时间信息。
当 Lambda 服务首次收到请求执行一个函数时,它需要准备执行环境。这意味着它需要从存储代码的 S3 桶中获取代码,并分配运行时环境,包括内存和 CPU。经过最后的初始化步骤后,Lambda 就可以执行处理程序。
在 Lambda 函数上实施 X-Ray
在第十二章中,我们讲解了 AWS Lambda。这是 AWS 提供的函数即服务(Function-as-a-Service)。我们可以将自己构建的函数启用 X-Ray 服务,以查看来自 AWS X-Ray 的跟踪和段信息:
注意
如果你还没有完成第十二章中的创建 Lambda 函数练习,或者如果你已经从账户中删除了该函数,请返回并重新执行/重新部署该练习。我们将使用这个函数来继续进行 AWS X-Ray 练习。
-
登录到AWS 管理控制台并导航到Lambda服务。
-
一旦进入
my_word_count_python。点击该函数的名称以进入此函数。如果你没有创建此函数,或者在执行练习后删除了它,你有两个选项。你可以返回并重新创建此函数,或者你可以尝试按照你在帐户中创建的其他函数的步骤来实施 X-Ray 跟踪服务。 -
现在你已经进入Lambda服务,向下滚动页面,直到找到水平菜单栏,然后点击名为配置的菜单项:
![图 14.8 – Lambda 水平菜单中的配置高亮显示]()
图 14.8 – Lambda 水平菜单中的配置高亮显示
-
选择配置菜单项会在屏幕左侧弹出一个垂直菜单。找到名为监控和操作工具的选项并点击它。这会将监控和操作视图显示出来。在该视图的右上角,选择编辑。
-
在编辑监控工具页面,找到标有AWS X-Ray的部分。点击滑块按钮,为这个 Lambda 函数启用 X-Ray 跟踪。然后,在页面底部点击保存:
![图 14.9 – 将 AWS X-Ray 添加到我们的 Lambda 函数中]()
图 14.9 – 将 AWS X-Ray 添加到我们的 Lambda 函数中
-
点击保存将带你回到配置标题下的监控和操作工具页面。你应该会看到活动跟踪现在已经启用。启用跟踪后,让我们运行一个测试,看看 X-Ray 是如何工作的。从水平导航栏中,点击名为测试的菜单项。
-
如果需要创建另一个测试事件,你可以使用默认数据并将其保存为
XRtest。如果你仍然保留了上一个练习中的 Lambda 函数,那么你应该已经创建了名为Test1的测试事件。创建好测试事件后,点击测试事件部分右上角的橙色测试按钮:![图 14.10 – 测试事件部分右侧的橙色测试按钮]()
图 14.10 – 测试事件部分右侧的橙色测试按钮
-
一旦测试事件运行完毕,我们可以点击水平菜单中的监控菜单项,进入监控页面。默认情况下,该页面会显示指标部分。然而,我们将点击名为跟踪的项,以便查看生成的 X-Ray 跟踪信息。
-
在跟踪屏幕上,我们现在可以看到一个服务地图,它与函数的跟踪 ID 一起生成,相关的跟踪信息如下表所示:
![图 14.11 – 生成的 X-Ray 服务地图]()
图 14.11 – 生成的 X-Ray 服务地图
-
返回到测试部分,点击测试事件两到三次。当 Lambda 调用完成后,你可以返回到监控标签并再次查看追踪表格:

图 14.12 – 同一 Lambda 函数的追踪表格
如果你连续多次点击了测试事件,那么在表格中的响应时间列,你应该会看到一些函数的响应时间明显快于其他函数。这是因为这些函数不需要冷启动。
我们刚刚完成了一个练习,它将之前运行的 Lambda 函数与 X-Ray 追踪结合,帮助我们获取更多信息。我们可以看到调用的路径,从客户开始,以及函数首次响应所需时间的变化。
接下来,让我们总结一下本章关于 AWS CloudWatch 和 X-Ray 的内容。
总结
在本章中,我们探讨了在不同环境和应用程序中进行监控的重要性,尤其是 CloudWatch 服务。
在下一章中,我们将继续深入研究 CloudWatch 服务,重点关注该服务的监控和指标功能。我们还将学习如何使用 AWS EventHub 自动化响应 CloudWatch 服务。
复习问题
回答以下问题以测试你对本章的理解:
-
你被一家公司聘请,帮助 DevOps 团队。该团队目前需要帮助进行监控。公司希望使用所有原生的 AWS 服务,而不是第三方服务。目前有一个生产环境中的 RDS PostgreSQL 数据库需要密切监控,因为它是客户订单的主要数据存储。可以使用哪些服务来实时监控和告警,如果 IOPs 指标超过正常水平,并允许 DevOps 团队增加更多 IOPs?(选择两个)
a. Amazon CloudWatch
b. Amazon CloudTrail
c. Amazon Simple Notification Service
d. Amazon Route 53
-
你为一家公司开发了一个现代应用程序,该应用程序使用 AWS Lambda 函数,在有人将文件放入 S3 存储桶时被调用。公司希望更好地了解该应用程序,并要求你将 AWS X-Ray 集成到 Lambda 函数中,以便他们能看到追踪信息。为了确保所有未加 instrument 的服务调用你的 Lambda 函数时也能进行追踪,你应该如何操作?
a. 在 AWS Lambda 函数配置下,启用开始追踪。
b. 在 AWS Lambda 函数配置下,启用活动追踪。
c. 当 Lambda 函数由未加 instrument 的服务调用时,不支持追踪。
d. 当 Lambda 函数由未加 instrument 的服务调用时,不需要额外配置就能记录追踪。
-
你被安排加入一个使用主要基于无服务器架构的团队,该架构由 Lambda 函数组成。他们希望能够在软件开发生命周期(SDLC)的测试阶段分析这些函数的调用。以下哪两种工具可以帮助他们实现这一目标?
a. Amazon CloudTrail
b. Amazon CloudWatch
c. Amazon Inspector
d. Amazon X-Ray
审查答案
-
a, c
-
b
-
b, d
第十六章:CloudWatch 指标与 Amazon EventBridge
指标是 AWS CloudWatch 的核心内容之一。它们记录服务的性能,并可根据提供的数据触发警报和操作。虽然有大量现成的指标可用,但也可以创建自定义指标。这进一步扩展了 CloudWatch 的功能。
利用 Amazon EventBridge 捕获的指标,当它们达到某些阈值时,便是一项强大的能力。作为一名 DevOps 工程师,这是一个非常有力的工具,可以帮助你自动化系统,使其具备自愈能力,并能够根据客户生成的容量需求不断扩展和收缩。这些自动响应可以由本地 AWS 服务或第三方系统触发。这在日常监控和创建某些事件发生时的例程中尤其有用。
本章将涵盖以下主要内容:
-
更详细地了解 CloudWatch 指标
-
AWS 服务的 CloudWatch 基本指标
-
使用 CloudWatch 指标创建仪表板
-
Amazon EventBridge 概述
更详细地了解 CloudWatch 指标
在上一章中,我们了解了 CloudWatch 服务,并检查了它提供的一些功能。我们甚至在创建警报时讨论了指标的主题。
在应用程序和监控中,指标即数据。很多时候,这些是不断流动的大量数据。这些数据不仅从技术角度使用,也从业务角度使用,用来查看公司如何表现。
指标是 CloudWatch 的基础。当记录时,指标代表一组按时间排序的数据点,这些数据点随后会发布到 CloudWatch 服务中。
指标存在于单一区域。这意味着,如果你有一个多区域环境,那么不同资源的指标将被收集并存储在资源创建和运行的同一地区。尽管你不能删除指标,但它们会在 15 个月后自动过期。
命名空间是 CloudWatch 指标的容器。你将找到指标的命名空间与许多服务的 AWS 服务名称相同:

图 15.1 – CloudWatch 控制台中的命名空间
PutMetricData 命令与 CloudWatch 代理。
指标数据会在特定时间段内聚合成统计数据。这些聚合通过命名空间、指标名称、维度和度量数据点相关联。你可以通过五种方式来衡量统计数据:平均值、最小值、最大值、总和或样本数。当选择样本数时,CloudWatch 会计算数据点的数量。
CloudWatch 的一个优点是,即使资源没有运行,您仍然可以访问指标。您甚至可以访问已终止的资源的指标,例如已终止的 EC2 实例、已删除的 Elastic Load Balancers、Fargate 容器和已删除的 EBS 卷。
在 CloudWatch 中查看您的指标
您可以通过登录 AWS 管理控制台,进入CloudWatch服务,并从左侧菜单中选择Metrics来查看您的指标图表:

图 15.2 – CloudWatch 指标图表示例
在InstanceID、functionName、Invocations、Namespace等字段中,其中一个不起作用的是通过Amazon 资源名称(ARN)进行搜索。
使用 CloudWatch 指标流进行流式处理指标
正如我们之前所说,CloudWatch会保存您的指标数据 15 个月,然后删除这些数据。如果您希望将这些数据推送到像 S3 存储桶或数据湖这样的长期存储中,或者通过Amazon Kinesis Data Firehose推送数据,可以通过指标流实现。您还可以选择将您的指标数据通过指标流推送到第三方提供商。
CloudWatch 指标中的数据可以以 JSON 或 OpenTelemetry 格式推送到指标流。
现在我们已经了解了 CloudWatch 指标流是什么,接下来让我们看看为什么我们会使用指标流。
为什么要通过指标流将您的指标推送到第三方?
过去,专注于监控和仪表盘等服务的合作伙伴依赖于通过 CloudWatch 服务的 API 调用,将数据从您的账户导入他们的服务。随着账户的增长,这可能会增加您的额外费用。GetMetricData API 调用每 1,000 次请求收费 0.01 美元。指标流通过每 1,000 次请求仅收费 0.003 美元,大大降低了此成本。
现在我们已经了解了如何使用指标流存储或共享我们的指标,接下来让我们看看 CloudWatch 指标中有哪些不同类型的指标。
AWS 服务中的 CloudWatch 基本指标
CloudWatch 会自动免费监控一组基础指标,每 5 分钟更新一次。大多数 AWS 服务会自动将指标免费发送到 CloudWatch 指标中。这些包括 EC2、S3、EBS、Kinesis、Lambda 等基础服务。
EC2 服务的基本监控
当实例创建时,七个指标会以每 5 分钟一次的频率推送到 CloudWatch。你可以将这个频率更改为 1 分钟一次,额外收费。CloudWatch 还提供二进制状态检查,作为其免费套餐的一部分。使用此检查是查看实例是否正在运行的重要手段,但它并不是检查应用程序是否正常运行的好方法。状态检查可以作为早期预警,帮助识别如 AMI 问题、实例意外(或故意)终止,甚至可用区或区域故障等情况。
除了状态检查外,EC2 指标还分为三类标准类别:
-
CPU
-
磁盘 I/O
-
网络
CPU 指标包含 CPU 使用情况的指标数据。这是你可以用来触发 AutoScaling 事件的主要指标之一,帮助你判断实例是否开始接近其计算能力的上限。对于突发性能实例,例如 EC2 T 系列实例,你还会获得关于 CPUCreditUsage 和 CPUCreditBalance 的指标数据。
记住
对于突发性能 EC2 类型实例,你每小时会获得一定数量的 CPU 积分,这些积分可以累计,直到需要时使用。当实例处理需要比基准更多 CPU 的任务时,实例将使用其 CPU 积分余额。
几乎所有来自 AWS 的服务都与 CloudWatch 指标集成。当你构建和部署应用程序时,请考虑一些需要监控的最关键指标,以确保应用程序和环境的基本健康。这些可以包括以下内容:
-
EC2 实例的
CPUUtilization -
Lambda 函数的错误数量
-
Lambda 函数的持续时间
-
RDS 实例的
DatabaseConnections -
RDS 实例的
DiskQueueDepth -
S3 桶的
NumberOfObjects -
Elastic Load Balancer 的
ActiveConnectionCount -
Elastic Load Balancer 的
HealthyHostCount -
Elastic Load Balancer 的
TargetResponseTime
现在我们已经查看了 CloudWatch 为我们提供的一些主要指标以及常见服务,接下来让我们看看如何在 CloudWatch 中使用自定义指标。
在 CloudWatch 中使用自定义指标
AWS CloudWatch 服务不仅允许你查看和监控来自资源本身的指标数据,如 CPU、内存和网络使用情况。它还允许你创建自定义指标,这些指标可以与应用程序中的错误数量相关联,或直接与业务测量的关键绩效指标挂钩。
CloudWatch 中的高分辨率指标
在监控你的自定义指标时,有时 1 分钟的间隔不足以提供足够的详细信息。通过 put-metric-data API,无论是通过 CLI 还是从 SDKs,你都可以以每秒 1 次的间隔发布自定义指标。
如果你的应用程序可能会出现短时的高峰,而这些高峰的行为无法通过 CloudWatch 指标的默认 1 分钟间隔来捕获,那么启用高分辨率指标可以为你提供这种可见性。如果你需要实时监控,那么高分辨率指标同样可以满足这一需求。
在查看了我们可以使用的高分辨率指标后,让我们看看如何创建那些在我们自己场景中更加有用的自定义指标。
在 CloudWatch 中创建自定义指标
CloudWatch 指标允许你为对你重要的项创建指标和命名空间。你可以通过使用 AWS 为特定语言提供的 SDK,或使用 AWS CLI 和 put-metric-data 命令,将其集成到你的脚本中。
你可以为日志文件中的 ERRORS 实例等内容定义指标,或者跟踪像电商应用程序结账时购物车中商品数量等项目。
当你创建并发布自定义指标时,可以将其定义为标准分辨率,这样它将以 1 分钟为间隔进行度量,或者你也可以将其定义为高分辨率指标,这样它将以 1 秒为间隔进行度量。
现在,让我们使用 Lambda 函数来创建一些自定义指标。
发布自定义指标
自定义指标可以通过多个服务发布,包括 AWS Lambda、Elastic Beanstalk、Amazon EC2,甚至是像 ECS、EKS 或 Fargate 这样的容器服务。
对于我们的动手示例,我们将使用 Lambda 函数来创建自定义指标,然后将其发送到 AWS CloudWatch 服务。我们的示例场景包含一些示例代码,其中我们尝试跟踪某个特定营销活动的注册情况。通过这种方式,营销部门和高层管理团队几乎可以实时地知道这个特定营销活动的投入资金有多有效。我们将这些指标推送到名为 custom_metric 的 CloudWatch 指标中。
我们将在示例中使用的 Lambda 代码位于本书的 GitHub 仓库中,位于 Chapter-15 文件夹下,文件名为 cw_events.py。我们还包括了一个简化版的函数,它不包含 CloudWatch 事件的部分:
cw_events.py:
import boto3
import random
# Resources
cw = boto3.client('cloudwatch')
# The Lambda handler
def lambda_handler(event, context):
put_metric = custom_metric()
return put_metric
###################################
# Create CW Custom Metric
###################################
def custom_metric():
create_metric = cw.put_metric_data(
Namespace='custom_metric',
MetricData = [
{
'MetricName': 'Signups',
'Dimensions': [
{
'Name': 'EMAIL_CAMPAIGN',
'Value': 'cableTV_spot2'
},
],
'Unit': 'None',
'Value': random.randint(1,100)
},
],
)
return create_metric
创建自定义指标并将其发送到 AWS CloudWatch 服务的步骤如下:
-
登录到 Amazon Management Console 并导航到 Lambda 服务。
-
一旦进入 Lambda 服务,点击橙色的 Create function 按钮。
-
一旦你进入
Author from scratch,在custom_metric下 -
Python 3.8 -
权限:创建一个具有基本 Lambda 权限的新角色:

图 15.3 – 创建 Lambda 函数的基本信息
-
填写完所有这些选项后,按下橙色的 Create function 按钮。
-
一旦函数创建完成,进入
chapter-15目录中的lambda_function.py文件,替换lambda_function标签页中的内容。替换代码后,点击代码窗口顶部的部署按钮。这样可以确保未部署更改消息消失,并替换为绿色的已部署更改消息:![图 15.4 – 显示已部署更改的 Lambda 函数]()
图 15.4 – 显示已部署更改的 Lambda 函数
-
现在我们已经创建了函数,可以开始创建测试事件,这样我们既可以测试函数,又可以在 CloudWatch 指标中看到自定义指标。点击橙色的测试按钮来配置测试事件。无需特殊的测试数据,只需将事件名称设置为测试,然后点击对话框底部的橙色创建按钮。
-
在测试函数之前,我们需要再给函数添加一个权限——
PutMetricData的权限。在Lambda垂直菜单中,点击配置。进入配置设置后,点击左侧菜单中的权限菜单项。这将显示执行角色在主窗口中。点击执行角色标题右侧的编辑按钮。 -
这将带你到基本设置页面。页面底部,在现有角色的名称下方,应该有一个蓝色链接,允许你查看 custom_metric_role在IAM 控制台中的信息。点击此链接后,将会为 IAM 服务打开一个新标签页。
-
当你在
服务中的角色上时:选择 | CloudWatch -
操作:筛选 | PutMetricData:

图 15.5 – 从 IAM 向我们的 Lambda 角色添加内联策略
-
添加额外权限后,点击页面底部的蓝色审核策略按钮。
-
将策略命名为
PutMetricData,然后点击页面底部的蓝色创建策略按钮。 -
现在我们已经修改了 IAM 角色,使其具备了
PutMetricData权限,返回到包含 Lambda 函数的标签页。你应该仍然在基本设置页面上。点击屏幕底部的橙色保存按钮,这将带你回到主 Lambda 屏幕的配置菜单。点击水平菜单顶部的代码标签页。现在,按下橙色的测试按钮,将测试事件发送到我们的 Lambda 函数。 -
在顶部搜索栏中,转到
CloudWatch并右键点击它,以在新标签页中打开。 -
在自定义命名空间的左侧菜单中的
custom_metric:![图 15.6 – 我们在自定义命名空间中的自定义指标]()
图 15.6 – 我们在自定义命名空间中的自定义指标
-
点击 custom_metric 命名空间。此时,我们将看到我们的二级命名空间,即 EMAIL_CAMPAIGN。点击该值将跳转到指标数据页面。勾选 cableTV_spot2 旁边的框,查看图表上绘制的数据。由于我们在函数中使用了随机值,因此该数字会有所变化。
有了这些,我们已经创建了一个 Lambda 函数,它将创建并发布一个自定义指标到 CloudWatch 指标中。接下来,我们将看看如何将这个自定义指标与其他指标一起,纳入到 CloudWatch 仪表板中,为我们自己、我们的团队以及其他人提供快速查看环境状态的功能。
使用 CloudWatch 指标创建仪表板
在 CloudWatch 中查看单个指标可以提供许多有价值的细节。然而,有时,通过快速浏览一个单一的视图,将最相关的指标一并展示出来,会更加有用。CloudWatch 仪表板允许我们快速而轻松地创建这些视图——不仅展示我们账户中 Amazon 资源创建的指标,还包括自定义指标,以及文本和超链接,以便在紧急情况或其他有用的文档中参考运行手册。
CloudWatch 服务甚至为许多最常用的 AWS 服务(如 DynamoDB、EC2、Lambda、S3、EBS 等)提供了自动仪表板。这些预配置的仪表板都是互动式的,可以基于自定义的日期范围查看。
你甚至可以将你创建的仪表板与那些没有直接访问你 AWS 账户的人员共享。这可以通过几种方式实现。第一种方式是将仪表板投射到大屏幕上,这样一个用户团队,或者任何进入显示仪表板屏幕或投影的房间的人,都能查看仪表板上展示的指标和图表。
第二种方法是内建的功能,允许使用用户名和密码与指定的电子邮件地址共享仪表板。
分享仪表板访问权限的第二种方式对于当你试图为某个项目的相关方提供实时指标时非常有用。这个用户可能不太懂技术,但他需要正确的业务信息来帮助做出决策。在本章之前讨论的自定义指标,可以让业务相关方在不请求生成特定报告的情况下,随时查看特定的关键绩效指标(KPI)。
当你在 CloudWatch 仪表板中创建一个仪表板时,它将全球可用。这是因为仪表板不是区域特定的。
有了这些,我们已经了解了仪表板如何让我们作为 DevOps 工程师、开发团队,甚至是项目的相关方,快速查看我们的环境或项目的状态。接下来,让我们通过实际操作来创建一个仪表板。
创建一个基础仪表板来监控我们的资源
让我们使用之前创建的一些指标,并将它们集成到自定义仪表板中:
-
打开Amazon 管理控制台并进入CloudWatch服务。如果你失去会话,可能需要重新登录。同时,确保你在俄亥俄地区(或你用来创建资源的其他地区):
console.aws.amazon.com/cloudwatch/。 -
进入 CloudWatch 服务后,找到并点击左侧菜单顶部的仪表板菜单项。
-
这将带你进入自定义仪表板屏幕。我们将通过点击橙色的创建仪表板按钮开始创建仪表板的过程:
![图 15.7 – 创建仪表板按钮]()
图 15.7 – 创建仪表板按钮
-
按下
Chapter15。然后按橙色的创建仪表板按钮来关闭对话框并开始构建仪表板。 -
应该会弹出一个新的对话框,要求我们向仪表板添加小部件。我们将从
Explorer小部件开始:![图 15.8 – 向 CloudWatch 仪表板添加小部件]()
图 15.8 – 向 CloudWatch 仪表板添加小部件
-
通过点击数字小部件来开始你的仪表板。滚动到自定义命名空间并点击custom_metric命名空间。将周期从5分钟更改为1天,以便仪表板能保持数据。点击EMAIL_CAMPAIGN次级命名空间并勾选cableTV_spot2框。一旦选中该值,点击对话框底部的橙色框,标记为创建小部件:
![图 15.9 – 为数字小部件添加值]()
图 15.9 – 为数字小部件添加值
-
一旦我们的数字小部件被添加,点击橙色的添加小部件按钮,将另一个小部件添加到仪表板中。
-
选择
custom_metric搜索词,以便我们可以找到上一个练习中创建的 Lambda 函数的指标。滚动通过自定义命名空间,找到AWS 命名空间。你可以点击Lambda | 按资源或Lambda | 按函数,因为它们应该都包含相同的指标。找到调用次数指标并勾选函数名左侧的复选框。一旦勾选,点击橙色框,然后点击橙色的创建小部件按钮。 -
我们通过点击
custom_metric lambda函数来向仪表板添加另一个小部件。它应该被命名为/aws/lambda/custom_metric。使用复选框选择该日志组。一旦选择了日志组,点击橙色的添加到仪表板按钮。 -
你将回到仪表板页面,现在应该包含三个小部件。点击仪表板顶部的蓝色保存仪表板按钮。现在你有了一个可以查看和分享的工作仪表板:

图 15.10 – 我们创建的 Chapter15 仪表板
现在我们已经学习了如何将我们的度量指标整合到仪表板中,以便我们可以快速轻松地监控系统,并查看我们需要一眼看到的任何自定义度量指标,接下来我们来看一下如何使用 CloudWatch 通过Amazon EventBridge服务启动事件驱动架构。
Amazon EventBridge 概述
Amazon EventBridge是一个无服务器事件驱动总线,它使得从各种来源获取和处理数据变得容易。这些来源包括 AWS 服务、您的应用程序和第三方 SaaS 提供商。它消除了在服务之间编写点对点集成的复杂性。EventBridge 是 AWS 的托管服务,这意味着您不需要担心随着需求的波动而需要更多或更少的服务,EventBridge 服务会为您处理这些。

图 15.11 – 从事件到目标的 AWS EventBridge 流程
事件源几乎可以是任何 AWS 服务、自定义应用程序或 SaaS 应用程序。
对于 SaaS 应用程序,有一个特别支持的合作伙伴应用程序,称为事件源。此事件源为第三方 SaaS 提供商和您的 AWS 账户之间提供逻辑连接,无需预配任何跨账户 IAM 角色或凭证。
事件总线是EventBridge 服务的核心。默认事件总线用于处理 AWS 服务事件。事件总线可以为您的应用程序自定义创建。
一旦你设置了事件总线,你就可以创建规则。通过使用规则,你可以匹配事件总线检查过的事件元数据或有效负载中的值。规则随后决定哪些事件应该被路由到哪个目标:

图 15.12 – 一个示例事件及其触发的规则
一旦触发了规则,你可以将一个或多个目标与该规则关联。目标是各种 AWS 服务,如 Lambda 函数、Step Functions、Kinesis Streams 以及 ECS 或 Fargate 集群。
注意
CloudWatch Events 服务现在被称为 Amazon EventBridge。如果您之前使用过 CloudWatch 事件,那么该功能仍然可以通过 EventBridge 中的默认事件总线使用。
现在我们已经了解了 Amazon EventBridge 服务,接下来让我们看一下 EventBridge 服务上自动施加的一些限制。
EventBridge 服务限制
当你开始使用 EventBridge 构建事件驱动服务时,最好记住最初对 EventBridge 服务施加的服务限制。这可以帮助你在同时向事件总线发送过多事件的情况下,也能帮助你在构建应用程序时,因为你知道在一个地区默认允许多少个事件总线和规则:

表格 15.1 – AWS EventBridge 服务限制
注意
所有这些限制都是软限制。这意味着它们可以通过向 AWS 提交服务请求来提高。
现在我们已经了解了工作时的服务限制,让我们来看看如何使用 AWS EventBridge 构建事件驱动架构。
使用 EventBridge 构建事件驱动架构
现代云应用程序基于解耦服务。
事件驱动架构有三个关键组件:事件生产者、事件消费者和事件路由器。生产者是产生事件并将其发送到路由器的服务或触发器。路由器或事件总线会过滤特定的事件,并将特定的事件发送到事件消费者。
事件驱动架构的多重好处
当你使用解耦架构时,意味着每个组件执行特定的任务,你将获得多个好处:

图 15.13 – 一个服务使用 EventBridge 和自定义规则推送到多个目标
使用 EventBridge 捕获 AWS 服务事件
我们可以使用 EventBridge 服务通过规则和默认事件总线自动触发事件。让我们从捕获每当 EC2 实例状态变化时并将其发送到日志文件开始,这样我们就可以查看该事件:
-
登录到AWS 管理控制台,并导航到CloudWatch服务。从左侧菜单中找到并展开事件菜单。在事件子菜单中,点击规则链接。
-
一旦规则屏幕出现在主窗口中,点击蓝色的创建规则按钮:
![图 15.14 – EventBridge 规则页面,带有创建规则按钮]()
图 15.14 – EventBridge 规则页面,带有创建规则按钮
-
现在我们应该处于名为步骤 1:创建规则的界面。在事件源标题下,确保选择了事件模式旁边的单选按钮,这样我们就可以开始构建我们的模式了。
-
对于我们的事件模式,使用
EC2 服务。然后,在事件类型选择下拉菜单中,选择EC2 实例状态变化通知。 -
我们不想要来自 EC2 的所有事件;我们只想知道何时实例启动或终止。选择 特定状态,然后选择 已终止 和 待处理 状态作为规则的状态。你需要使用下拉菜单两次来填充这两个选择项。保留 任何实例 旁边的单选框:
![图 15.15 – EventBridge 规则的事件模式已填充]()
图 15.15 – EventBridge 规则的事件模式已填充
-
接下来,我们可以继续处理 步骤 1 的右侧,在那里你可以找到 Targets(目标)标题。点击 添加目标 按钮。
-
在第一个目标下,找到
EC2_STATE:![图 15.16 – 创建自定义日志组作为我们的 EventBridge 目标]()
图 15.16 – 创建自定义日志组作为我们的 EventBridge 目标
-
向下滚动到页面底部,点击蓝色按钮 配置详细信息。
-
对于规则的名称,使用
chapt15-ec2。你可以插入描述。如果你填好了名称和描述,点击蓝色的 创建规则 按钮。 -
我们的规则应该出现在
ec2实例上并触发规则。不要关闭浏览器窗口——我们稍后还要返回查看 CloudWatch 日志组。 -
打开终端窗口,使用
create-instance命令快速启动一个实例(如果你完成了 第十四章 的练习,CloudWatch 和 X-Ray 在 DevOps 中的角色,这些命令应该对你来说有些熟悉):# Capturing the AMI to a variable InstanceId so that you can quickly reference it when terminating your instance in the next step. -
大约 2 到 5 分钟后,我们将终止实例以创建另一个事件供规则使用:
aws ec2 terminate-instances \ --instance-ids {YOUR INSTANCE ID} \ --region us-east-2 -
现在,我们应该再等一两分钟,让实例完全终止。当它开始终止时,回到之前打开 Amazon 管理控制台 的浏览器。
-
在 Amazon 管理控制台 中,我们应该已经进入 CloudWatch 服务,因此我们只需要在 日志 下的 日志组 子菜单中找到它并点击。
-
现在,你应该能够找到我们快速创建的自定义日志组,名为
EC2_STATE。如果你所在区域有太多日志组,可以简单地搜索EC2_STATE,它应该会出现。点击日志组的名称,我们可以查看 EventBridge 为我们生成的内容。 -
现在,你应该在日志组中看到两条日志条目。一条对应于待处理事件,另一条对应于终止事件。
通过这一节,我们已经学习了如何利用在 AWS 账户中发生的事件以及 AWS EventBridge 服务来构建事件驱动架构。尽管我们在实践练习中只使用了一个简单的示例,但这可以扩展到执行诸如发送 SNS 通知并同时记录日志条目,甚至在这是一个关键基础设施的情况下创建新资源等操作。现在,让我们回顾一下本章中学到的所有内容。
总结
在本章中,我们深入探讨了 AWS CloudWatch 服务。我们关注了指标以及构成一个指标的内容。我们了解了 AWS 提供的不同类型的指标,从 Free Tier 的基本指标开始,然后是详细指标,最后学习了如何创建自定义指标。我们还学会了如何使用这些指标在 CloudWatch 中创建自定义仪表板,并发现这些仪表板不仅可以与拥有 IAM 访问权限的团队成员共享,还可以与我们 AWS 账户外的其他人共享。
我们还研究了 EventBridge,这是取代了 CloudWatch Events 的服务。我们学习了如何使用事件总线来处理 AWS 服务、定制应用事件,甚至是 SaaS 提供商,从而推动事件驱动架构的发展。
在下一章中,我们将研究来自不同 Amazon 服务的各种类型的日志。这包括 VPC 流日志、Elastic Load Balancer 日志、CloudTrail 日志,以及这些日志如何帮助我们排查应用程序或安全事件中的问题。
问题
-
你被一家企业聘用,帮助在 AWS 上开发一个电子商务应用程序。公司利益相关者希望了解通过该应用程序下单的订单数,并且希望以秒级粒度获取这一信息。为了获取这个信息,你需要使用 AWS CLI 创建一个自定义的 CloudWatch 指标。你知道默认情况下,自定义指标的粒度是 1 分钟。你如何让应用程序以子分钟间隔发送自定义指标?
a. 使用 AWS CLI
put-metric-data命令发布数据,并将StorageResolution选项设置为1秒,以将指标指定为高分辨率指标。b. 更新 CloudWatch 代理配置文件,然后添加
line high-resolution: true。c. 转到 Amazon 管理控制台中的 CloudWatch 服务的图表,并将分辨率设置为 1 秒的间隔。
d. 向 AWS CLI
put-metric-data命令添加flag –dimensions=1,以指定一个高分辨率指标。 -
你目前在一家中型电子商务公司工作,该公司使用 AWS Lambda 和 DynamoDB 构建了一个无服务器购物车系统。公司的一位高管要求你创建并分享一个仪表板,展示每个购物车的购买数量和每个购物车的弃购数量。董事会成员目前没有 IAM 账户。你如何以尽可能简单且成本效益高的方式向董事会成员提供实时数据访问权限?
a. 使用 Amazon Cognito 的社交登录。让 Cognito 承担一个具有访问特定仪表板权限的角色,以便董事会成员可以访问。
b. 为每个董事会成员创建 IAM 用户。创建一个 IAM 组,该组有权限访问 CloudWatch 仪表板,但设有条件,只显示他们需要查看的特定仪表板的 ARN。
c. 收集董事会成员的电子邮件。通过电子邮件访问功能,使用用户名和密码共享对 CloudWatch 仪表板的访问权限。
d. 收集董事会成员的电子邮件。为 CloudWatch 仪表板集成 SAML。允许董事会成员使用单点登录访问特定的仪表板。
审查答案
-
a
-
c
第十七章:生成的各种日志(VPC 流日志、负载均衡器日志、CloudTrail 日志)
日志是一条信息流,来自不同的源。来自负载均衡器的日志可以成为宝贵的数据源或故障排除的资源。了解如何启用这些资源对于设置或运行您的环境至关重要。在 AWS 环境中执行的任何操作,无论是通过 AWS 管理控制台、CLI 还是 SDK,都会通过底层 API 调用记录到 CloudTrail 中。作为一名 DevOps 工程师,了解是谁以及什么在对环境进行更改并能够检索这些数据,尤其是在请求时,是非常重要的。
在本章中,我们将讨论以下主要内容:
-
AWS CloudTrail 的强大功能
-
启用弹性负载均衡器日志
-
使用 VPC 流日志
-
清理资源
之前讨论的日志
到目前为止,我们主要讨论的是从应用程序本身生成的日志。还包括一些在之前使用 CloudWatch Logs 时 AWS 提供的日志,它们是这些日志的包装器;然而,这些大部分仍然是应用程序和 AWS 服务日志。
当我们想要了解用户如何与我们的环境进行交互时,无论是网络环境还是他们如何在我们的帐户内添加和删除资源时,我们将无法在应用程序日志中找到这些信息。相反,我们必须查看 AWS 中的其他日志。
了解哪些日志适用于哪个目的,还可以帮助我们保护环境的其他服务,例如GuardDuty。
注意
我们将在第二十二章中讨论 GuardDuty,了解的其他政策和标准服务。
现在我们已经看到了我们走过的路和未来的方向,让我们从第一组日志——CloudTrail 日志开始。
AWS CloudTrail 的强大功能
CloudTrail 可通过 AWS 账户或多个账户(使用 AWS 组织)启用治理、合规性、风险审计和操作审计功能。
在 AWS 中,每个操作都是通过 API 调用执行的。无论您是使用 AWS 管理控制台、Amazon CLI 还是任何可用的 SDK,都是如此。这些操作都通过 API 调用来执行,然后这些 API 操作如果已启用 CloudTrail 服务,则会被记录下来:

图 16.1 – 通过 CloudTrail 服务将操作流动到日志的过程
这些内容包括记录启动和停止 EC2 实例的调用、上传和删除 S3 对象、从 VPC 添加或删除安全组、在 DynamoDB 表中添加或删除索引等。 当您的帐户内发生活动时,CloudTrail 会捕捉并记录该活动作为 CloudTrail 事件。此 CloudTrail 事件包含以下详细信息:
-
执行请求的人
-
请求发出的日期和时间
-
请求的源 IP
-
请求是如何发出的
-
正在执行的操作
-
执行操作的区域
-
请求的响应
还需要注意的是,CloudTrail 日志不会实时推送到存储的 S3 存储桶中。相反,CloudTrail 服务每 5 分钟发布一次更新的日志文件,包含它收集到的一批事件。
在确保 CloudTrail 日志本身安全方面,默认情况下,服务会使用 S3 服务器端加密(SSE)对文件进行加密,并将其存储在 Amazon S3 中。你还可以选择使用 KMS 服务创建加密密钥,并使用该密钥对 CloudTrail 日志进行加密。
CloudTrail 服务提供了几个好处。第一个是它记录了用户和资源的活动。通过这些记录,你可以识别是谁在什么时间对 AWS 账户中的资源执行了什么操作。其次,由于事件日志会自动存储和记录,合规性报告变得更加易于管理。第三,你能够通过将 CloudTrail 事件发送到 CloudWatch Logs 来监控、警报和响应正在发生的事件。第四个也是我们在这里提到的最后一个好处是,通过使用类似 SQL 的语法,你可以利用 CloudWatch 服务搜索日志。这使你能够对 CloudTrail 产生的大量数据执行强大的查询。
现在我们了解了 CloudTrail 服务,我们将在我们的账户中设置 CloudTrail。
设置 CloudTrail
我们将设置 CloudTrail,然后再查看 CloudTrail 记录的日志。我们这样做是为了确保在执行本章其他练习时,CloudTrail 服务已经开启并记录了我们的操作。这还将确保在稍后进行 CloudTrail 练习时,我们有一个完整的记录集可以进行搜索。
亚马逊已经更新了默认创建 CloudTrail 路径的方式,使得所有区域在初始化时都被包含在内。在本节中,我们将创建一个特定于我们正在工作的区域的路径。这仍然是可能的,但仅在使用 AWS CLI 的情况下:
-
打开终端以便访问 AWS CLI。首先,我们需要创建一个 S3 存储桶,以便捕获并存储 CloudTrail 日志。使用以下示例命令,记住每个 S3 存储桶名称都是唯一的,你需要创建自己的 S3 存储桶:
aws s3 mb s3://devopsproandbeyond-trail --region us-east-2 -
为了让 CloudTrail 服务能够将日志放入 S3 桶,我们需要为我们的桶附加一个桶策略。将以下桶策略复制并粘贴到本地文件中(在你执行终端命令的地方),命名为
cloudtrail_s3.json。查找两处出现BucketName的地方,你需要将它们替换为你在上一步创建的桶的名称。该文件的副本可以从本书 GitHub 仓库的Chapter-16文件夹下载:{ "Version": "2012-10-17", "Statement": [ { "Sid": "AWSCloudTrailAclCheck20150319", "Effect": "Allow", "Principal": {"Service": "cloudtrail.amazonaws.com"}, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::BucketName" }, { "Sid": "AWSCloudTrailWrite20150319", "Effect": "Allow", "Principal": {"Service": "cloudtrail.amazonaws.com"}, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::BucketName/*", "Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}} } ] } -
创建策略文件后,你可以使用以下命令将其附加到你的桶上。确保更改桶名称,以便策略附加到你的桶:
aws s3api put-bucket-policy \ --bucket devopsproandbeyond-trail \ --policy file://cloudtrail_s3.json -
在附加了我们的 S3 桶后,我们可以创建单区域跟踪。使用以下命令创建你的跟踪,记得将命令中的 S3 桶名称替换为你在步骤 1中创建的桶名称。请注意,我们将跟踪命名为
sixteen。我们将在本章后面引用这个跟踪名称:aws cloudtrail create-trail \ --name sixteen \ --s3-bucket-name devopsproandbeyond-trail \ --region us-east-2
如果跟踪创建成功,你应该会看到返回的 JSON,类似以下内容:
{
"Name": "sixteen",
"S3BucketName": "devopsproandbeyond-trail",
"IncludeGlobalServiceEvents": true,
"IsMultiRegionTrail": false,
"TrailARN": "arn:aws:cloudtrail:us-east-2:470066103307:trail/sixteen",
"LogFileValidationEnabled": false,
"IsOrganizationTrail": false
}
-
现在是时候开始跟踪了。仅仅因为我们创建了跟踪并不意味着它会自动开始记录事件。使用以下命令启动跟踪,以便捕获该区域的所有 API 调用:
aws cloudtrail start-logging --name sixteen --region us-east-2 -
接下来,为了将日志流式传输到 CloudWatch 日志(以便我们以后可以搜索它们),我们需要登录到 AWS 管理控制台并快速编辑我们的跟踪。登录控制台后,导航到 CloudTrail 服务。当你进入 CloudTrail 仪表板时,你应该看到我们创建的名为sixteen的跟踪。点击该跟踪名称:
![图 16.2 – 仪表板上的第十六个 CloudTrail 跟踪]()
图 16.2 – 仪表板上的第十六个 CloudTrail 跟踪
-
当你进入第十六个 CloudTrail 时,你应该会看到一个名为CloudTrail 日志的部分。点击该部分右侧标记为编辑的按钮。
-
在
CloudTrailRole-sixteen上。然后,点击屏幕底部的橙色保存更改按钮。
现在,我们已经设置了 CloudTrail 服务来记录我们将来执行的 API 操作,接下来我们来看看弹性负载均衡器日志。
启用弹性负载均衡器日志
弹性负载均衡服务允许你捕获更多关于你环境的数据。这有助于故障排除,尤其是在延迟方面。弹性负载均衡器访问日志还能让你查看用户或服务从源地址到目标服务的路径。有时,这些信息不会出现在应用日志中,因为捕获到的源地址是弹性负载均衡器的地址。弹性负载均衡器访问日志包括以下信息:
-
客户端的 IP 地址
-
请求路径
-
请求接收的时间和日期
-
服务器响应(以数字格式显示)
我们在深入研究 Elastic Beanstalk 和 OpsWorks 等服务时,已经了解了负载均衡如何帮助在两个实例和服务之间分配负载。此时,我们还应该明白,弹性负载均衡可以用来附加多个实例,甚至是自动扩展组中的实例:

图 16.3 – 从弹性负载均衡器到 S3 存储桶的访问日志流
一旦你启用了弹性负载均衡器的访问日志记录,日志记录本身不会产生额外费用。然而,将日志存储在 S3 中会产生存储费用\。
设置弹性负载均衡器并启用日志记录
在本章的第一个实践示例中,我们将使用两个相互引用的 CloudFormation 模板来搭建一个 VPC;第二个模板将搭建一个弹性负载均衡器,并通过两个 EC2 实例提供一个简单的网站。子模板还将创建一个 S3 存储桶,用于捕获我们的访问日志。完成测试环境搭建后,我们需要进入 AWS 管理控制台并启用弹性负载均衡器的日志记录。启用日志记录后,我们可以尝试多次访问该网站。这样做应该会在我们的 S3 存储桶中留下记录,我们可以访问并分析这些记录。本练习中引用的模板位于本书 GitHub 仓库的 Chapter-16 目录下。在开始之前,请下载所有模板。我们开始吧:
-
登录到AWS 管理控制台,并导航到CloudFormation服务。
-
一旦进入CloudFormation页面,如果跳转到主 CloudFormation 服务页面,请点击橙色的创建堆栈按钮。否则,如果跳转到当前堆栈的列表页面,请点击主窗口右上角的创建堆栈按钮,并选择使用新资源(标准)选项:
![图 16.4 – 在 CloudFormation 中从堆栈列表页面的创建堆栈按钮]()
图 16.4 – 在 CloudFormation 中从堆栈列表页面的创建堆栈按钮
-
无论你是如何到达这里的,我们现在应该能够上传
vpc.yaml模板。然后,在对话框中点击打开按钮。一旦文件上传完成,你可以点击橙色的下一步按钮。 -
这将带你进入
Chapter16-VPC,这是为你的堆栈命名时需要使用的名称。这个名称很重要,因为这个堆栈将创建一些资源,后续堆栈将引用这些资源,并通过堆栈的名称进行引用。一旦输入了名称,点击页面底部的橙色下一步按钮。 -
在配置堆栈选项页面,向下滚动到底部并点击橙色的下一步按钮。
-
此时,我们将在
Chapter16-VPC堆栈中。向下滚动到页面底部,在Capabilities部分下的框中填写,确认此模板将创建一个 IAM 角色。完成后,点击橙色的Create stack按钮,以便初始化并创建我们的初始堆栈。 -
点击 CloudFormation 服务中的
Chapter16-VPC堆栈页面。堆栈创建完成后,进入Outputs部分。此时,你应该能看到 VPC 堆栈创建的六个输出,包括 VPCid、两个私有子网和两个公共子网:![图 16.5 – 初始堆栈创建的输出]()
图 16.5 – 初始堆栈创建的输出
-
创建好我们的 VPC 模板并显示输出后,我们可以继续下一个模板。下一个模板将设置负载均衡器,并配置两个运行 Apache Web 服务器的 EC2 实例。每个服务器都运行一个静态网页,但如果你看到的是不同的页面,就能知道自己是被定向到实例一还是实例二。
-
由于我们已经在CloudFormation页面的Outputs部分,我们可以直接前往右上角,点击白色的Create stack按钮。当下拉列表出现时,选择With new resources (standard)选项。
-
现在,返回
cross-stack-website.yaml模板上传它。上传模板后,点击页面底部的橙色Next按钮。 -
现在你应该处于
Chapter16-Elastic Load Balancer页面。在Stack name框中输入此值。 -
你还会看到一个参数框。这个框应该已经填上了
Chapter16-VPC。如果你之前的堆栈命名为Chapter16-VPC,你无需更改此值。如果你给堆栈取了其他名字,则需要在此输入该名称,因为这是驱动我们之前看到的所有输出的值。填写完值后,点击页面底部的橙色Next按钮:![图 16.6 – 指定堆栈详情页面中的堆栈名称和参数字段]()
图 16.6 – 指定堆栈详情页面中的堆栈名称和参数字段
-
此时,你将被带到Configure stack options页面。此页面无需配置任何内容,因此我们将向下滚动到页面底部,点击橙色的Next按钮。
-
最后,我们将进入Review stack页面。简要查看你为堆栈选择的选项。如果没有错误,点击页面底部的橙色Create stack按钮。
-
由于我们的堆栈正在创建两个 EC2 实例并安装软件和网页,同时还在创建经典负载均衡器,注册这些实例到该负载均衡器,并执行初步健康检查,因此需要几分钟的时间来完成创建。
-
一旦堆栈完成,点击输出菜单项,就像我们在前一个堆栈中所做的那样。这时,您会在这里找到一个密钥的 URL 和 Elastic Load Balancer 的公共 URL 值。右键点击该 URL 并在新标签页中打开。
-
现在,点击同一水平菜单中的资源菜单项,您在其中找到了输出。点击 Elastic Load Balancer 的物理 ID链接,您将直接进入 Elastic Load Balancer 的详细信息页面:
![图 16.7 – 在 CloudFormation 中显示的 ELB 资源列表]()
图 16.7 – 在 CloudFormation 中显示的 Elastic Load Balancer 资源列表
-
现在,向下滚动屏幕的下半部分,直到找到属性标题。在此标题下,您将找到访问日志部分。此处应该有一个值,当前设置为禁用。点击灰色的配置访问日志按钮。
-
当对话框出现时,您需要填写以下值:
-
勾选启用访问日志框。
-
将日志推送间隔更改为5 分钟。
-
为存储 Elastic Load Balancer 访问日志选择一个新的S3 桶名称。
-
勾选框以创建 S3 桶:
-

图 16.8 – 配置访问日志
填写完所有值后,点击蓝色的保存按钮。
-
现在,开启日志功能后,是时候回到之前打开的浏览器标签页,其中包含 Elastic Load Balancer 的 URL。多次刷新页面;如果两个服务器都已成功启动并通过 Elastic Load Balancer 的健康检查,您应该会看到服务器一和服务器二的混合显示在屏幕上。
-
一旦生成了一些流量,我们可以开始导航到为 Elastic Load Balancer 访问日志存储创建的 S3 桶。但是,请记住,日志每 5 分钟才会推送一次,因此您可能需要耐心等待日志的出现。
-
这时,是时候转到 S3 服务并找到您为存储 Elastic Load Balancer 访问日志而创建的桶的名称了。点击桶的名称。您应该会看到一个名为
AWSLogs的文件夹,然后是一个以帐户号码命名的子文件夹。在该帐户文件夹中,应该有名为elasticloadbalancing的进一步子文件夹,然后是按地区、年份、月份和日期命名的子文件夹。最后,您将看到日志文件。点击其中一个日志文件,下载并用 Textpad 或记事本打开它。
通过这个,我们已经了解了如何启用日志并查看来自我们的弹性负载均衡器的流量模式。然而,不要急着关闭这组 CloudFormation 模板。我们将在接下来的部分中使用这里创建的 VPC,来检查 VPC 流日志。但首先,让我们看一下弹性负载均衡器日志的用例。
弹性负载均衡器日志的用例
你可能会想,为什么你会对启用弹性负载均衡器日志感兴趣,而你可以从应用程序的日志文件中获取类似客户端地址的信息?让我们详细查看几个用例:
-
理解请求的延迟——响应请求需要多长时间。
-
监控访问请求——请求来自哪里,去往哪里。
-
衡量客户端与资源之间操作的效率——是否存在可以轻松检测到的瓶颈?
现在我们理解了何时使用弹性负载均衡器日志,让我们看看 VPC 流日志。
使用 VPC 流日志
流日志帮助您捕获有关虚拟私有云(VPC)网络接口进出 IP 流量的信息。一旦捕获到这些数据,它可以被写入 S3 存储桶或推送到 CloudWatch 日志组。
一旦创建了流日志组并开始记录日志,日志不会立即出现。日志可能需要最多 5 分钟才会出现在 S3 存储桶或日志组中:

图 16.9 – VPC 流日志在不同来源之间传输
可以为网络接口创建流日志。这些包括 VPC 本身的网络接口,甚至是其他包含网络接口的服务,如下所示:
-
弹性负载均衡器
-
亚马逊 RDS 数据库
-
亚马逊 ElastiCache 缓存
-
亚马逊 Redshift 数据库
-
亚马逊 WorkSpaces
-
传输网关
-
NAT 网关
现在我们了解了 VPC 流日志是什么以及它们可以附加到哪些内容,让我们先看看它们的限制,然后再设置之前创建的 VPC 上的流日志。
关于 VPC 流日志的限制
虽然 VPC 流日志允许您捕获大多数来自或前往VPC中不同网络接口的流量,但也有一些情况是无法捕获的。我们来快速了解这些情况。在这种情况下,如果在 DevOps 专业考试中或现实生活中出现其中一个场景,我们就知道流日志并不是最佳解决方案。例如,当 VPC 之间的对等连接未在同一帐户内进行对等时,无法为对等的 VPC 启用流日志。另一个需要注意的是,流日志并不会捕获所有的 IP 流量。有一些特定的流量是丢失的,特别是不会被流日志文件捕获的:
-
任何来自实例的流量,试图连接到亚马逊 DNS 服务器。
-
从 Windows 实例发送的用于 Amazon Windows 许可证注册的任何流量。
-
所有与
169.254.169.254之间的流量,用于元数据相关信息 -
所有与
169.254.169.123之间的流量,用于 Amazon Time Sync 服务 -
所有的 DHCP 流量
-
任何发送到 VPC 路由器并通过保留 IP 地址传输的流量
-
所有位于终端节点网络接口与网络负载均衡器接口之间的流量
启用 VPC 流日志
如我们之前在动手练习中提到的,我们将使用本次动手练习中创建的相同VPC来捕获 VPC 流日志。
创建流日志时,你需要指定以下项目:
-
你希望拥有的 AWS 资源
-
如果你希望捕获接受的流量、拒绝的流量或流日志中的所有流量
-
你希望数据发布到的地方(S3 桶或 CloudWatch 日志)
让我们开始吧:
-
从CloudWatch服务开始。在左侧菜单中找到日志,点击日志组。
-
在右上角,点击橙色的创建日志组按钮。
-
创建一个名为
FlowLogs的日志组。你可以更改保留设置,允许日志在 7 天后(1 周)过期。更新完这些设置后,滚动到页面底部并点击橙色的创建按钮。 -
返回到
Chapter16-VPC。点击这个堆栈名称查看该堆栈的详细信息。 -
然后,从堆栈的顶部水平菜单中点击资源菜单项。当资源表格出现时,向下滚动,直到找到 VPC 的条目(它可能靠近底部,因为它是我们最先创建的资源之一)。点击 VPC 的蓝色物理 ID链接,进入 VPC 界面。(在点击之前记下物理 ID 的最后 4 个字母数字字符;记住 VPC 的最后 4 个字母数字字符)。
-
一旦你进入你的 VPC页面,勾选VPC 名称右侧的框。勾选后,点击屏幕右上角的白色操作按钮。完成后,一个下拉菜单会出现。选择创建流日志菜单项。
-
此时,你将被带到
All -
1 分钟 -
发送到 CloudWatch 日志 -
FlowLogs -
VpcFlowLogRole -
填写完所有这些设置后,点击橙色的创建流日志按钮。
-
现在,回到你的 Elastic Load Balancer URL 并向已经加载在 EC2 实例上的网站发送一些流量。这样会生成 VPC 流日志。一旦生成了一些流量,回到名为
FlowLogs的 CloudWatch 日志组,查看它生成的记录。
我们刚刚学习了如何创建自定义的 CloudWatch 日志组并开启 VPC 流日志,以便捕获 VPC 中的流量。接下来,我们将看看在哪些使用场景下开启 VPC 流日志是有意义的。
VPC 流日志的使用场景
由于有如此多类型的日志可用,让我们来看一些使用 VPC 流日志的明确用例。
使用 VPC 流日志来监控远程登录
远程登录到你云基础设施上的实例应仅通过授权人员以及可信地址进行。你可以使用 VPC 流日志查看哪些用户和 IP 地址正在通过 远程桌面协议 (RDP) 或 安全外壳协议 (SSH) 等协议获取访问权限或尝试获取访问权限。
注意
你可以使用 虚拟网络连接 (VNC) 客户端连接到 AWS Mac 实例;然而,这种连接是不安全的。为了确保连接的安全性,你可以通过 SSH 隧道将连接封装起来,具体方法可以参考这里:aws.amazon.com/premiumsupport/knowledge-center/ec2-mac-instance-gui-access/。
使用 VPC 流日志检测威胁
如果你选择使用 VPC 流日志捕获所有事件,包括入口和出口,那么你可以检测到对环境的威胁,例如网络上的端口扫描、网络扫描、有人试图寻找弱点或进入点,或者数据被推送到未经授权的来源。
如果你发现你的系统受到某个事件的影响,那么你可以使用 VPC 流日志追踪攻击者通过网络的路径。
诊断和故障排除网络问题
在分层安全的情况下,有时你会遇到尝试弄清楚为什么无法访问某个实例或服务的情况,这可能会很麻烦。
了解你的网络流量
你可以使用 VPC 流日志来分析你的网络和 AWS 账户的用户行为,并生成可能发生的不安全行为的报告。这可能包括使用未保护的端口,或者允许来自全球的访问,而不是将访问限制在特定的 IP 地址上,并将全球访问限制为内容分发服务器(如 CloudFront)。
现在我们已经了解了 VPC 流日志的各种使用案例,我们将把注意力转向我们最初查看的日志——CloudTrail 日志。
回到我们的 CloudTrail 日志
现在,我们已经通过本章中执行的练习和多个 API 调用创建了一些资源,我们可以回到 CloudTrail 日志中,看看它们是如何被事件填充的。
搜索 CloudTrail 日志
由于我们目前已经执行了足够的操作来生成 CloudTrail 日志,现在我们将开始搜索日志,查看我们捕获到了什么内容:
-
返回到 CloudWatch 服务。从左侧菜单中找到 Logs,但这次点击名为 Log Insights 的子菜单。
-
从选择日志组的下拉菜单中,选择 CloudTrail 日志组。
-
将以下查询放入查询框中,然后按下橙色的 Run query 按钮:
filter eventSource="ec2.amazonaws.com" | stats count(*) as eventCount by eventName, awsRegion | sort eventCount desc -
你应该会看到类似以下的图形:
![图 16.10 – CloudWatch 日志洞察可视化图表]()
图 16.10 – CloudWatch Logs 洞察可视化图表
-
如果你愿意,可以尝试查看 CloudTrail 日志中你能发现的其他信息。
有了这些,我们已经学习了如何使用 CloudWatch Log Insights 查询 CloudTrail 日志。现在,在总结本章之前,让我们清理一下之前创建的资源。
清理资源
在本章中,我们创建了很多资源,如果不清理并保持运行,可能会导致你收到比预期更高的 AWS 账单。完成本章后,务必删除用于创建实例和 Elastic Load Balancer 的 CloudFormation 模板。
总结
在本章中,我们查看了三种不同的日志来源,这些日志可以为你的 AWS 账户提供信息,这些日志不是 CloudTrail 或应用程序日志。首先,我们学习了如何设置 CloudTrail 跟踪记录账户内发生的所有 API 调用。接下来,我们查看了 Elastic Load Balancer 访问日志,了解它们如何记录进入 Elastic Load Balancer 的 IP 地址、时间和响应。最后,我们查看了 VPC Flow Logs 如何捕获来自各种网络接口的网络流量。
在下一章中,我们将总结日志记录的讨论,介绍企业如何补充捕获日志的 AWS 服务。然后,我们将了解日志存储和高级搜索是如何处理的。
复习问题
-
你作为 DevOps 工程师在一家已经实施了多个 CI/CD 流水线的公司工作。一个流水线用于推送应用程序代码及其功能,另一个流水线用于更新账户的基础设施和安全设置。在应用程序的最后一轮安全组更新之后,公司某个远程办公室的所有用户无法再访问自动扩展组中的实例。这些用户仍然可以通过 Elastic Load Balancer 从 Web 协议访问应用程序。这些用户包含多个 IAM 用户组的成员,包括开发人员、权限用户,甚至是管理员。你可以去哪里寻找信息,试图找出问题发生的原因?
a. 收集被拒绝访问的 IAM 用户名。使用这些用户名搜索 CloudWatch 中的 IAM 日志组。
b. 确保已启用 VPC Flow Logs。搜索 VPC Flow Logs 中远程办公室的内部和外部 IP 地址。
c. 收集被拒绝访问的 IAM 用户名。转到 CloudTrail 服务,搜索用户名以查找拒绝访问的记录。
d. 启用应用程序的 Elastic Load Balancer 日志记录。检查 Elastic Load Balancer 日志,查看远程办公室的内部和外部 IP 地址。
-
你被引入到一家即将进行重要生产发布的公司,作为这次发布的一部分,他们正在实施一个新的治理模型,要求监控 AWS 账户上的所有活动。你如何快速有效地帮助公司实现这一目标?
a. 设置 Amazon Inspector 服务,持续检查账户上发生的所有活动。
b. 为所有 VPC 开启 VPC 流日志,确保捕获进出流量。
c. 设置 AWS CloudTrail 服务,监控并记录所有区域的活动。
d. 创建一个指定的 CloudWatch Logs 日志组,以便可以专门过滤创建或终止事件到该日志组。
审核答案
-
b
-
c
第十八章:高级和企业级日志记录场景
当我们准备结束关于日志部分的讨论时,我们将讨论如何实现企业级的日志系统。虽然 CloudWatch 可以搜索日志并呈现一些可视化内容,但我们将探索 AWS 提供的其他本地解决方案,这些解决方案更适合捕获、处理、存储并可视化不断流入的大量日志。
在本章中,我们将覆盖以下主要主题:
-
使用 QuickSight 可视化数据
-
将日志流式传输到 Amazon Elasticsearch
-
使用 Amazon Kinesis 处理日志
使用 QuickSight 可视化数据
尽管有多个第三方可视化工具可用于分析数据并创建日志的图形表示,但 Amazon 为其客户创建了一项本地服务,QuickSight。QuickSight 是为云端规模的 商业智能(BI)服务而开发的,易于使用,且能够从多个来源导入数据。
Amazon QuickSight 使用专有的 SPICE 引擎来计算和提供数据。SPICE 代表 超高速并行内存计算引擎。这项技术旨在实现企业级的极速性能。SPICE 引擎通过自动复制数据来实现这一点,允许成千上万的用户在极快的速度下对这些基础数据进行查询和分析。
Amazon QuickSight 的另一个关键特点是,你可以与 IAM 组织成员共享创建的仪表盘。它还可以通过电子邮件与没有 IAM 或联合账户的 AWS 组织成员共享访问权限。QuickSight 还提供适用于 iPhone 和 Android 的应用程序,方便访问:

图 17.1 – 日志流向 Athena 和 AWS QuickSight 创建可视化
在前一张图中,我们展示了 AWS 用户如何从他们所采取的行动中创建事件。
当你在 AWS 账户中设置 QuickSight 时,你会创建一个命名空间,这是一个逻辑容器,用于组织你的团队、客户以及其他你将邀请到 QuickSight 可视化中的人员。你可以创建多个命名空间,并且可以将用户查看的数据与该命名空间隔离。命名空间也可以跨多个区域。设置好命名空间后,从此不需要进一步的管理操作。
了解了 QuickSight 服务在为我们 Amazon 账户中的用户以及我们组织中的其他人创建可视化时带来的价值后,让我们来看一下 Athena 服务如何基于这些能力进行扩展,利用我们已经存储在 S3 存储桶中的文件。
使用 Amazon Athena 查询数据
AWS 创建了一项服务,允许你查询存储在 S3 存储桶中的数据。该服务是无服务器的,因此无需配置服务器,而且该服务仅对你运行的查询收费。
Presto 查询引擎支持 Amazon Athena。这是一个开源的 SQL 引擎,允许用户以低延迟查询大规模数据集。Presto 引擎还完全支持连接、数组和窗口函数。
Amazon Athena 的主要特点如下:
-
由于它是无服务器的,因此无需管理任何管理或基础设施。
-
它使用标准 SQL 来查询底层数据。
-
它具有极快的性能,无需调优。
-
它支持跨多个数据源进行联合查询。
-
它是安全的,允许你利用 IAM 和 S3 存储桶策略来控制数据访问。
-
它与 S3 作为数据源时具有高可用性。
现在我们已经了解了如何使用 Amazon QuickSight 结合 Amazon Athena 创建更强大的可视化,让我们看看一些 Amazon QuickSight 的应用场景。
Amazon QuickSight 的应用场景
下一节将探讨一些使用 Amazon QuickSight 与其他 AWS 服务结合的应用场景,以创建企业级系统,构建仪表盘和分析系统,用于监控日志和分析。
使用 QuickSight 可视化日志和使用分析,借助 Athena 和 Glue 的支持
亚马逊构建了一个交互式查询服务,允许你使用标准 SQL 语句查询数据,名为 Athena。除了使用标准 SQL 并且无需学习新的特殊语言之外,Athena 的另一个优点是它是无服务器的。这意味着无需配置服务器,且仅对你在系统上运行的查询和扫描的数据收费。
将机器学习洞察集成到你的仪表盘中的能力
Amazon QuickSight 扩展了仅仅以仪表盘格式展示数据的常规功能,通过添加自然语言功能和机器学习洞察,帮助你更全面地理解数据。这些功能帮助用户发现底层数据中隐藏的模式和趋势,而无需专业的技术专长或机器学习技能。
将用户仪表盘连接到你的数据仓库或数据湖
如果你的数据存储在数据仓库中,例如使用Amazon Redshift服务,那么你可以在 Amazon QuickSight 中创建连接,连接到你的 Redshift 集群。此 Redshift 集群会成为自动发现的数据集,并通过 SSL 自动保护 Redshift 集群和 QuickSight 之间的连接,无需额外配置。然后,你可以选择想要在 QuickSight 可视化中使用的表,或者创建自定义 SQL 语句将数据导入 SPICE 引擎中,以分析和可视化数据。
如果你将数据存储在数据湖中,尤其是使用 AWS 的 Lake Formation,那么数据就存储在 Amazon S3 存储桶中。接着,你可以使用 AWS Glue 来爬取数据并创建数据目录。一旦数据目录创建完成,你就可以使用 Amazon Athena 查询数据并创建表和数据库。这些表和数据库充当 S3 存储桶中数据架构的容器。Amazon QuickSight 然后可以连接到 Athena 数据库,创建数据的可视化,甚至进行进一步的 SQL 查询:

图 17.2 – 将 Amazon QuickSight 连接到 AWS 中的数据湖
现在我们已经讲解了一些企业在使用 Amazon QuickSight 时可能遇到的应用场景,接下来让我们通过一个动手练习来加深对该服务概念的理解。这样一来,如果在 DevOps 专业认证考试中遇到关于可视化的问题,我们就能有一个坚实的基础,知道何时选择 Amazon QuickSight 而非 CloudWatch 仪表板。
使用 Amazon QuickSight 创建仪表板
当你在 Amazon QuickSight 中创建数据仪表板时,你实际上是在发布一组交互式图表和图形,供用户探索。该仪表板使用的底层数据不仅展示了洞察,还为用户提供了进一步探索的工具,以防他们有此需求。
让我们一起走过在 Amazon QuickSight 中创建仪表板的过程。为了将数据导入临时数据库以便在 QuickSight 中连接,我们将需要借助 Amazon Athena 服务:
-
登录到 Amazon 管理控制台,在顶部搜索框中搜索
QuickSight。进入 QuickSight 页面后,验证你的 AWS 账户编号,然后按下蓝色按钮 注册 QuickSight。确保将默认的 企业版 更改为 标准版:![图 17.3 – 来自搜索菜单的 QuickSight 图标]()
图 17.3 – 来自搜索菜单的 QuickSight 图标
你也可以使用以下 URL:
aws.amazon.com/quicksight/pricing/。点击页面中间的 标准版 链接。进入 标准版 页面后,向下滚动到页面底部,点击大号黄色按钮 开始你的免费试用。你现在应该在标有 创建你的 QuickSight 账户 的页面上。保留第一个选项 使用 IAM 联邦身份 & QuickSight 管理用户 作为 身份验证方法。接下来,对于 QuickSight 区域,将区域更改为 美国东部(俄亥俄州):
![图 17.4 – 设置身份验证方法和区域以创建 QuickSight 账户]()
图 17.4 – 设置身份验证方法和区域以创建 QuickSight 账户
-
对于您的 QuickSight 账户名称,您需要选择一个独特的名称,并且可以记住。您还需要输入一个电子邮件地址。
-
现在,我们可以指定在当前设置中哪些数据将可供 QuickSight 使用。勾选以下项目旁边的框:
a. 启用在您的 Amazon Redshift、Amazon RDS 和 AWS IAM 服务中自动发现数据和用户。
b. 亚马逊 Redshift
c. 亚马逊 RDS
d. IAM
e. 亚马逊 Athena。
f. 亚马逊 S3(选择显示的桶 – chapter16-elb-logs):
![图 17.5 – 选择用于 QuickSight 的 S3 桶]()
图 17.5 – 选择用于 QuickSight 的 S3 桶
我们已经从之前的实践练习中添加了一个桶,该桶应该包含可供 Amazon QuickSight 查询的数据。
-
您现在将看到一个屏幕,上面有一个跳动的图形,AWS 正在为您创建 QuickSight 账户。账户创建完成后,您将看到一个蓝色按钮,上面写着 进入 Amazon QuickSight。点击此按钮继续。
-
点击按钮后,它将开始为您创建一些示例,并显示一个弹窗,欢迎您使用 QuickSight。点击弹窗中的蓝色 下一步 按钮来关闭它们,或点击右上角的 X。
-
我们需要从 S3 桶中的数据创建一个数据集。找到左侧垂直菜单中的数据集图标并点击它。进入数据集页面后,点击右上角的深蓝色 新建数据集 按钮。
-
如果您还没有选择
Chapter-17文件夹中的MOCK_DATA.csv文件,请选择它并将其上传至 QuickSight。点击 确认文件上传设置 弹窗中的蓝色 下一步 按钮。上传完成后,点击蓝色 可视化 按钮:![图 17.6 – 确认数据已正确上传至 QuickSight]()
图 17.6 – 确认数据已正确上传至 QuickSight
-
一旦数据加载完成,您将进入 Amazon QuickSight 的 可视化 部分。现在是时候从我们刚刚导入的数据中创建一个可视化了。我们需要首先选择一些字段来显示在图表上。
-
选择 填充地图 类型的图形,它位于右侧可视化类型列表的最后一个值。然后,在选择该可视化类型后,将
state_province值拖动到zip_postal_code值的 颜色 字段中。点击其他一些可视化类型,看看 QuickSight 如何改变数据的展示方式:

图 17.7 – Amazon QuickSight 中的填充地图可视化类型
重要提示
Amazon QuickSight 标准版的价格为每月 12 美元(按月支付)。发布时,有一个为期 30 天的免费试用期,适用于作者;但是,如果您已经使用过该服务,在通过本教程时将会被收费。
现在我们已经看到了如何使用 QuickSight 服务创建交互式仪表板和可视化,接下来我们来看看用于在企业级管理日志的下一个服务——Amazon Elasticsearch 服务。
使用托管 Elasticsearch 搜索和分组日志
许多人将 Elasticsearch 与 ELK 联系在一起;然而,它们之间存在差异。ELK 代表 Elasticsearch、Logstash 和 Kibana。在这种配置中,Elasticsearch 作为存储,Logstash 作为日志解析器,Kibana 作为系统的可视化前端,用户通过它与系统交互:

图 17.8 – ELK 堆栈与 Amazon 托管 Elasticsearch 服务的比较
使用 Amazon 的托管 Elasticsearch 服务时,默认情况下没有安装 Logstash;但是,还有其他选项可以将您生成的日志导入到 Elasticsearch 集群中。
托管 Elasticsearch 的使用场景
AWS 的托管 Elasticsearch 产品有多个使用场景。接下来我们来看看这些场景。
存储和搜索应用监控日志
您可以将存放在 AWS CloudWatch Logs 中的日志流式传输到 Amazon 托管 Elasticsearch 服务。一旦日志进入 Elasticsearch 集群,它们可以通过基于 Lucene 的 Elasticsearch 搜索引擎进行搜索。
安全信息和事件管理(SIEM)
将来自网络中多个事件和应用程序的日志存储在一个集中系统中,可以帮助您使用 Amazon 托管 Elasticsearch 服务的能力,几乎实时地检测和报警安全事件。
企业级搜索引擎
尽管 ELK 堆栈最常与收集和显示日志相关联,但 Elasticsearch 是一个强大的搜索引擎,基于 Lucene 库构建,允许进行近实时的搜索。您可以使用 RESTful API 连接到 Elasticsearch,将结果返回到应用程序,或者将新数据发送到搜索引擎存储。
监控您的基础设施
当您收集来自不同基础设施组件的日志时,无论它们位于云端还是本地,都可以使用 AWS 的托管 Elasticsearch 将它们集中收集到一个解决方案中。这有助于您从各个角度快速研究出现的问题,从而帮助减少您的 平均修复时间 (MTTR)。
请注意,Amazon 的 Elasticsearch 服务正在更名为 Amazon OpenSearch。
现在我们已经了解了 Elasticsearch 服务的使用场景,让我们通过一个实际操作的例子,看看如何将 CloudWatch 日志导入到 Elasticsearch 集群中。
将 CloudWatch Logs 中的日志流式传输到 Elasticsearch 服务
在使用托管 Elasticsearch 服务的实操练习中,我们将部署一个简单的 Lambda 函数来生成一些日志。然后,我们将启动一个单节点的 Elasticsearch 集群来接收这些日志。利用 Lambda 函数生成的日志,这些日志将进入 CloudWatch Logs 日志组。接着,我们会将该日志组订阅到刚刚创建的 Elasticsearch 集群。CloudFormation 脚本还包括一个 AWS 事件规则,每五分钟触发一次 Lambda 函数,以便定期将日志发送到我们的 CloudWatch 日志组。最后,我们将进入 Kibana 可视化界面,查看我们的日志。让我们开始吧:
-
我们首先需要从 GitHub 仓库中的
Chapter-17文件夹下载名为lambda_stack.yml的 CloudFormation 模板。 -
首先,登录到 AWS 管理控制台。在控制台内,导航至CloudFormation服务,以便我们可以快速启动 Lambda 函数。通过点击主服务页面中的橙色创建堆栈按钮,或者如果你已经在堆栈页面并且有之前创建的堆栈,点击右上角的白色创建堆栈按钮来创建带有新资源的堆栈。
-
下载自 GitHub 仓库
Chapter-17文件夹中的lambda_stack.yml文件后上传。上传文件后,点击屏幕底部的橙色下一步按钮。 -
现在,在文本框中的堆栈名称字段内输入
Logging-Lambda作为此 CloudFormation 堆栈的名称。输入后,点击屏幕底部的橙色下一步按钮:![图 17.9 – 输入 CloudFormation 堆栈名称]()
图 17.9 – 输入 CloudFormation 堆栈名称
-
在配置堆栈选项页面上无需操作。向下滚动到页面底部,点击橙色的下一步按钮。
-
在审核页面上,向下滚动到页面底部,勾选复选框,确认此模板需要创建一个 IAM 角色。完成后,可以点击橙色的创建堆栈按钮。
-
创建资源的过程应该需要 1 到 5 分钟;完成后,我们可以点击
LambdaLogGenerator。这将是我们实际的 Lambda 函数。点击此名称旁边的蓝色链接,它位于物理 ID列下。这将直接打开一个新窗口,显示我们的 Lambda 函数:![图 17.10 – 创建的 Lambda 函数的逻辑 ID 和物理 ID]()
图 17.10 – 创建的 Lambda 函数的逻辑 ID 和物理 ID
-
我们需要等待至少 5 分钟以便 Lambda 函数被调用,因此在此期间我们将创建 Elasticsearch 集群,以便在日志准备好时能够进行流式传输。在 AWS 管理控制台的顶部搜索框中,搜索
Elasticsearch。当你看到Elasticsearch 服务图标时,右键点击图标,在新标签页中打开该服务。 -
当你进入Amazon Elasticsearch 服务页面时,点击标记为创建新域的蓝色按钮。
-
对于部署类型,选择开发与测试,因为我们只需要一个可用区。在版本部分,选择最新版本。在撰写时,最新版本是 7.10。选择完毕后,点击屏幕底部的蓝色下一步按钮。
-
现在我们应该在
chapter-17域名设置页面。第二个设置将在T3.medium.elasticsearch实例下,因为我们只是进行短期测试,且不需要存储大量数据。做完这些更改后,滚动到页面底部并点击蓝色的下一步按钮。 -
在
devops中 -
Chapter17*
d. 在访问策略下,选择以下内容:
保持其他设置不变,然后点击页面底部的蓝色下一步按钮。点击标签页面上的蓝色下一步按钮,最后滚动到审查页面的底部,点击蓝色的确认按钮。
-
Elasticsearch 集群启动需要几分钟,这段时间我们可以回到 Lambda 函数的页面。返回我们浏览器窗口中的另一个标签页,在那里我们之前已经打开了 Lambda 函数。
-
一旦进入
Logging-Lambda-LambdaLogGenerator函数,点击横向菜单中的监控项。这不仅会让我们看到 Lambda 函数被调用的日志行,还会有一个白色按钮,位于横向菜单旁边,现标记为在 CloudWatch 中查看日志。点击该按钮将直接带你进入日志页面:![图 17.11 - 直接位于横向菜单下方的在 CloudWatch 中查看日志按钮]()
图 17.11 - 直接位于横向菜单下方的在 CloudWatch 中查看日志按钮
-
现在我们应该在 Lambda 函数的 CloudWatch 日志组中。日志流标题上方会有一个横向菜单。点击菜单项订阅过滤器。
-
一旦从下拉列表中选择我们刚刚创建的
chapter-17标题。选择Logging-Lambda并选择为日志 Lambda 函数创建的角色。选择log-test。最后,滚动到页面底部并点击橙色的开始流式传输按钮。 -
一旦点击开始流式传输按钮,一个 Lambda 函数将被创建。现在,我们的日志应该开始流入 Elasticsearch 集群中。
-
现在回到我们创建 Elasticsearch 集群的标签页,并点击
chapter-17作为链接域。点击devops)并输入在配置 Elasticsearch 集群时创建的密码。 -
我们现在在 Elasticsearch 集群的 Kibana 界面中。点击显示的文字 Explore on my own。当弹出 Select your tenant 对话框时,只需点击蓝色的 Confirm 按钮。
现在我们已经看过如何捕获日志并将其存储在托管的 Elasticsearch 集群中,接下来我们将探讨如何将 Amazon Kinesis 服务与 Elasticsearch 结合使用。
了解 Amazon Kinesis 服务
AWS 中有一个专门为实时处理流数据而创建的服务。这个服务就是 Amazon Kinesis。随着世界上越来越多的物品产生数据,越来越多的应用程序希望消费这些数据,必须有能够快速消费并对数据进行一些预处理的服务。Kinesis 服务还提供了一些冗余,以防主应用程序出现故障,通过其分片存储记录。默认情况下,记录可以在写入后 24 小时内访问。此设置也可以在配置中扩展,最多保存数据 7 天。发送到 Kinesis 的数据最大为 1 MB。
需要了解的 Amazon Kinesis 关键功能如下:
-
它允许实时摄取、处理和流式传输数据。
-
它是一个完全托管的服务,因此无需管理基础设施。
-
它与其他多个 AWS 服务集成,如 Amazon Redshift。
了解到该服务具备这些内建的优势,它自首次推出以来也经历了演变,以满足使用者的需求。尽管它在处理大量传入数据(如来自多个来源的日志)时非常有用,但这只是它众多用途中的一种。
Kinesis 服务来自 AWS,提供四个独立的功能:
-
Kinesis 视频流 – 该功能允许您轻松、安全地处理传入的视频数据,并支持分析、机器学习或其他处理。
-
Kinesis 数据流 – 该功能允许您将数据从应用程序流式传输到托管的 Kinesis 服务。
-
Kinesis 数据火 hose – 该功能为用户提供了一种简单的方法,将数据流捕获、转换并加载到 AWS 数据存储中,如 S3、ElasticSearch 和 Redshift。
-
Kinesis 数据分析 – 该功能允许用户使用 SQL 或 Apache Flink 轻松地实时处理数据流。
在某些场景中,您可能会同时使用多个功能。
测试小贴士
虽然在参加数据分析 – 专业认证考试时,你需要对 Amazon Kinesis 服务有更深入的了解,但在 DevOps 专业考试中,也有一些场景会考察你是否知道何时使用 Kinesis 服务是正确的解决方案(或错误的解决方案)。
现在我们对 Amazon Kinesis 服务有了基本的了解,让我们看看在企业场景中使用 Amazon Kinesis 服务来处理日志的合适时机。
使用 Amazon Kinesis 处理日志
Kinesis Firehose 允许我们添加一个自动调用 Amazon Lambda 函数的功能,该函数可以在将记录插入 Elasticsearch 集群之前对其进行转换。这与 ELK 堆栈中的 Logstash 实例处理传入日志并在发送到 Elasticsearch 实例之前进行转换的方式非常相似:

图 17.12 – Kinesis Firehose 同时将日志插入 S3 和 Elasticsearch 服务
图中有一个 S3 存储桶的原因之一是,Kinesis Firehose 可以在指定时间内重试任何失败的记录,以便在交付失败时重新发送到 Elasticsearch 服务。
什么因素可能导致失败?嗯,一个常见的原因是 Elasticsearch 集群的空间不足。如果你持续流式传输日志,但没有正确的方式来淘汰旧数据,或者没有向集群添加足够的节点,那么在某个时刻,集群将没有足够的空间,无法再接受任何新数据,或者在我们的案例中,无法接收新的日志。与其丢失这些信息或手动尝试将其插入集群,不如让 Kinesis 将错误的记录排入 S3 存储桶,然后在稍后重新尝试发送数据。
现在我们了解了如何使用 Amazon Kinesis 来增强日志记录设置,让我们来看看正确标记和分类日志的重要性。
使用标签和元数据正确分类日志
在对云资源和后续日志进行分类以便摄取时,标签可以帮助分类资源的来源,特别是在将所有日志推送到大型企业日志解决方案的情况下。
作为一个经验丰富的 DevOps 工程师,在 AWS 中创建资源时,你应该为从 CI/CD 管道中出来的资源添加多个标签,以便有效管理这些资源:

图 17.13 – 用于企业系统中的标签类别和键的示例
当我们在前面的示例中讨论使用 Lambda 函数和 Kinesis 处理时,我们可以查看元数据中包含的标签。
清理资源
在本章的实践过程中,我们在 AWS 账户中创建了许多资源。如果没有及时删除,像托管的 ElasticSearch 集群这样的资源可能会导致账单超出预期。每隔 5 分钟触发一次的 Lambda 函数可能会消耗您的免费套餐配额,因为每月大约有 43,800 分钟,因此此函数将被调用 8,760 次。只需删除不再使用的资源,并删除任何不再使用的 CloudFormation 堆栈,以确保您的 AWS 账单尽可能保持在最低水平。
此外,请记得取消您的 QuickSight 订阅,无论是免费试用还是单月订阅,以免因 QuickSight 服务而产生持续收费。
总结
本章中,我们讨论了如何实施企业级日志记录系统。我们还了解了 AWS 提供的其他本地解决方案,这些方案更适合捕获、处理、存储和可视化大量不断流入的日志数据。
在下一章中,我们将开始探讨如何确保我们的工作负载具有高度可用性,从 Auto Scaling 组及其生命周期开始。
复习问题
-
您的公司要求您创建一个可视化仪表盘,以图形化的方式展示日志,并且管理团队可以访问。管理团队不会通过 IAM 用户登录 AWS 账户,也没有 AWS 管理控制台访问权限。他们还希望从 AWS Redshift 数据库和通过 AWS Batch 过程创建并存储在 S3 桶中的 CSV 文件中进行数据增强。如何为管理团队创建一个易于访问、安全且动态的仪表盘?
a. 使用所有数据源创建一个 CloudWatch 仪表盘。收集管理团队的电子邮件地址,并发送仪表盘访问链接。
b. 通过 CloudWatch Logs 将所有数据流式传输到托管的 ElasticSearch 集群。创建一个 Kibana 仪表盘,展示所需的可视化内容。将 Kibana 仪表盘的链接与执行团队共享。
c. 使用 Kinesis Firehose 将 Redshift 中的数据流式传输到托管的 ElasticSearch 集群。创建一个 Kibana 仪表盘,展示所需的可视化内容。将 Kibana 仪表盘的链接与执行团队共享。
d. 使用 Amazon Athena 创建一个包含所有需要用于 QuickSight 仪表盘日志的临时表。将 CSV 文件导入 QuickSight 以进行可视化。将 Redshift 数据库作为数据源从 QuickSight 导入。收集管理团队的电子邮件地址,并发送仪表盘访问链接。
-
您最近加入了一家公司,该公司在 S3 存储桶中存储了多种不同的日志文件。这些日志来自各种来源,包括使用 S3 同步从本地服务器推送,应用程序负载均衡器日志,VPC 流日志等。公司希望您快速分析这些日志,并查明每个类别的日志有多老。您如何能够快速且经济有效地执行此任务?
a. 将包含日志的 S3 存储桶设置为 Amazon QuickSight 中的数据源。使用 SPICE 引擎分析日志。创建两个快速可视化,一个显示日志的年龄,另一个显示日志的类型。
b. 使用 S3 库存功能搜索 S3 存储桶中的文件。将报告导入 Excel,然后按年龄和日志类型对文件进行排序。
c. 创建一个 AWS Glue 作业目录,列出所有 S3 存储桶中的项目。使用 Amazon Athena 查询日志类型。创建一个查询来对日志类型进行分组。按日期降序排序,以便在每个组中首先显示最旧的日志。
d. 将所有日志导入托管的 Elasticsearch 集群。使用 Kibana 界面,运行一个关于日志类型的查询,然后按年龄对日志进行分组以获取日志数量的统计信息。
查看答案
-
D
-
B
第四部分:启用高可用工作负载、容错能力,并实施标准和政策
在任何环境中都会发生故障,但凭借 AWS 云的区域和全球能力,创建高度可用和容错的工作负载的障碍已经被消除。再加上按计划和实时强制执行标准和政策,你的 CI/CD 旅程将变得更加顺畅。
本书的这一部分包括以下章节:
-
第十八章,自动伸缩和生命周期钩子
-
第十九章,保护数据在传输和静止状态下的安全
-
第二十章,通过系统管理角色和 AWS Config 强制执行标准和合规性
-
第二十一章,使用 Amazon Inspector 检查你的环境
-
第二十二章,其他需要了解的政策和标准服务
第十九章:自动扩展与生命周期钩子
自动化的一个关键特性是利用自动扩展。虽然许多人仅在其基本功能上使用这个Amazon Web Services(AWS)服务,但受过教育的开发运维(DevOps)专业人员理解并利用自动扩展提供的一些更高级的功能。了解这些组件不仅有助于你通过认证考试,还能让你更有效地管理你的 AWS 环境。
在本章中,我们将介绍以下主要内容:
-
理解 AWS 自动扩展
-
使用自动扩展部署弹性计算云(EC2)实例
-
自动扩展生命周期
-
使用自动扩展生命周期钩子
理解 AWS 自动扩展
自动扩展是Amazon EC2 服务的一个子集,围绕自动配置和管理 EC2 实例展开,无需任何人工干预。自动扩展服务可用于在一个或多个可用区(AZs)内,始终保持固定数量的服务器。该服务还为你提供了弹性,可以在不需要持续监控系统的情况下,按需自动扩展,以应对客户或应用程序带来的需求激增。
它通过利用一个互补服务——Amazon CloudWatch 来实现这一点。CloudWatch 监控如中央处理单元(CPU)使用率等度量指标,并确保如果使用率超过 80%,即实例的可用 CPU 有 80% 被特定时间段(例如 5 分钟)占用,则会触发扩展事件。这有助于减轻该实例的负载,并且在新实例上线后,CPU 使用率应会降回 80% 以下。
自动扩展服务会定期对其自动扩展组(ASG)中的实例进行健康检查。健康检查之间的时间可以配置,但默认设置是 300 秒(5 分钟)。你还可以配置实例在被标记为不健康之前允许失败多少次健康检查。类似地,实例必须失败的健康检查次数与它必须通过的健康检查次数相同,才能将其作为健康实例添加到 ASG 中。
自动扩展在基础设施事件规划中也发挥着关键作用。如果你知道客户流量即将增加,例如市场部门购买了一个流行电视节目上的电视广告,或者有一场特别促销即将发生,那么你可以简单地增加 ASG 的期望容量和最大容量,以确保客户不仅有良好的体验,而且服务器也不会过载。
现在我们已经对自动扩展服务有了基本了解,接下来让我们看一下构成该服务的关键组成部分。
理解垂直和水平扩展的区别
在本章中,我们将讨论如何通过水平扩展来根据工作负载的需求调整实例的数量。这通常是一种更具成本效益的扩展方式,因为你可以根据工作负载的基准测试,知道你的工作负载实际需要多少内存和 CPU。这带来了许多好处,包括工作负载的可用性更高,因为有多个实例或容器同时运行应用程序。这避免了被垂直扩展的实例(或容器)成为单点故障(SPoF)。你也不受硬件限制。垂直扩展到一定程度时,你会遇到资源限制。尽管 AWS 中有一些实例拥有巨大的随机存取内存(RAM)和大量的 CPU,但这并不是正确构建和部署应用程序的方式。
水平扩展和垂直扩展的过程在下图中展示:

图 18.1 – 水平扩展与垂直扩展
现在我们已经了解了水平扩展和垂直扩展的区别,接下来让我们来看一下 AWS 自动扩展的关键组成部分。
自动扩展的关键组成部分
自动扩展的主要组成部分之一是 ASG(自动扩展组)。这个 ASG 是你的应用程序或服务的实例的逻辑组合。你需要为 ASG 设置三个主要变量:最小实例数、最大实例数和期望实例数。最小实例数告诉 ASG 在任何时刻,所有指定可用区(AZ)中可以运行的最少实例数。最大实例数告诉 ASG 在该区域内可以分配的最大实例数。这些最大值必须在服务限制范围内。最后,期望容量是指在没有计划动作或由扩展策略驱动的扩展事件的情况下,任何给定时刻运行的实例数量。
你可以在下图中看到 ASG 的示意图:

图 18.2 – ASG 可视化
自动扩展的另一个关键组成部分是启动模板。启动模板决定了 ASG 中的实例将以哪些属性启动。这些属性是通过启动模板提供的。在编写启动模板时,你可以确定例如实例大小、镜像标识符(ID)、虚拟私有云(VPC)ID 等项目。
如果你曾经使用过 ASG,那么你可能熟悉启动配置。启动配置与启动模板非常相似,但在某些方面,启动模板替代了启动配置。首先,启动配置是不可变的。每当你想要更改启动配置时,你需要克隆启动配置、进行更改,然后将其附加到 ASG 上。这与启动模板不同,启动模板支持版本控制。启动模板还支持最新的 EC2 功能,例如使用无限制的 T2 实例和弹性块存储(EBS)标签。
ASG 与弹性负载均衡(ELB)完全集成。无论你使用的是哪一种类型的 ELB,ASG 都能无缝集成。这意味着,如果一个 ASG 与负载均衡器关联,当实例被配置时,它会自动注册到负载均衡器中。相反,当实例被取消配置或终止时,负载均衡器会从实例中清空流量,并在终止实例之前将其从负载均衡器中注销。
注意
如果你有旧的启动配置,但希望利用最新的 EC2 技术,AWS 提供了一个文档页面,介绍如何将启动配置转换为启动模板。你可以在这里找到:docs.aws.amazon.com/autoscaling/ec2/userguide/copy-launch-config.html。
我们将要讨论的最后一个关键组件是扩展计划。扩展计划可以设置为使用预测扩展或动态扩展。如果你将扩展计划设置为使用预测扩展,ASG 将使用机器学习(ML)来分析工作负载的负载情况,特别是针对一周中的特定时间和天数,并生成预定的扩展操作,以确保你的应用程序具备满足这些需求的能力,具体如以下图示所示:

图 18.3 – 预测扩展如何在 Auto Scaling 中调度资源
动态扩展策略是你在使用动态扩展和扩展计划时配置的组件。
需要注意的是,即使你的扩展计算表明你应该超出你设置的最大实例数,这个最大值是一个硬性限制,扩展策略不会超越它。如果在扩展时达到最大实例数的上限,你可以提高最大实例数,或者你可能需要创建一个新的启动配置版本,以适应可能更好地处理应用程序流量的不同类型或系列的实例。
有一句老话形容自动扩展,叫做像火箭一样扩展,像羽毛一样缩减。这是因为从时间角度来看,扩展实例是昂贵的。如果你在扩展事件中启动一到三台实例,它们应该同时上线。引入三台实例将让你获得更多的容量,而不是一次扩展单个实例。如果这部分容量没有必要,那么你可以一次缩减一个实例,保持支出在合理范围内,通过自动扩展控制成本。
在规划 ASG 时,你需要考虑以下因素:
-
启动并配置将成为 ASG 一部分的服务器需要多长时间?
-
在监控工作负载性能时,哪些指标最适用?
-
你希望 ASG 跨多个可用区(AZ)部署吗?如果是的话,需要多少个?
-
自动扩展在你的应用程序中应该扮演什么角色?
在掌握了自动扩展的关键组件后,让我们来看看 AWS 自动扩展的主要使用案例。
了解不同类型的自动扩展
Amazon 的 EC2 自动扩展提供了多种选项,帮助你根据业务需求和预算目标扩展实例。
如果你想完全控制如何扩展实例,那么可以使用手动扩展。通过手动扩展,你可以根据工作负载的需求设置最小值、最大值和所需容量,ASG(自动伸缩组)会相应调整。
有时,流量到达工作负载的情况是相当可预测的。比如,客户在正常工作时间更为活跃,或者你可能有一些内部使用的业务工作负载,而这些工作负载的使用者都位于一个或两个特定的时区。这些情况下使用计划性扩展非常合适。使用计划性扩展时,ASG 会根据你设定的时间和日期自动进行扩展和缩减。
如果你希望在应用程序的服务需求高涨时,ASG 能够自动扩展,并在需求减少时缩回,这就是动态扩展的应用场景。动态扩展允许你选择一个对应用程序重要的特定指标,并设置一个百分比,一旦达到该百分比,与该指标关联的 CloudWatch 警报将被触发,从而启动一个或多个实例,将其添加到 ASG 中。同样,如果你之前响应特定指标扩展了容量,而该指标已经降到一个被低利用的水平,则扩展策略将检查应该开始终止的实例。根据你的配置,可能是最旧的实例、最新的实例,或者是最接近下一个计费周期的实例。
动态扩展还允许你使用步进扩展。这些步进调整可以根据指标警报触发的类型有所不同,这意味着如果流量突然激增,并且你的最大容量允许的情况下,你可以一次性扩展到多个实例。
将动态扩展的属性进一步扩展,就是预测性扩展。预测性扩展分析你的流量趋势,然后根据这些趋势增加或减少 ASG 中的 EC2 实例数量。预测性扩展是一个不错的选择,当你无法准确决定哪个指标最适合你的应用需求,或者你有需要较长时间初始化的应用时。对于那些看似周期性波动的工作负载,比如批量处理,预测性扩展也能发挥作用。预测性扩展分析可以分析这些工作负载,并决定何时引入更多容量。
我们刚刚看了不同的方式,ASG 可以如何被设置和调整,以应对工作负载流量的涌入。现在,让我们看看自动扩展的主要用例。
AWS 自动扩展的四个主要用例
自动扩展为客户解决了四个流行的用例,具体如下:
-
它自动化了服务器的配置。
-
它减少了分页的频率。
-
它使得使用竞价实例变得更加容易。
-
它允许你上下扩展云基础设施并节省成本。
现在我们已经了解了使用自动扩展的一些主要用例,接下来让我们通过创建自己的启动模板,来看看如何将 ASG 付诸实践。
使用自动扩展部署 EC2 实例
了解一个服务的最佳方式就是动手操作,看看它的表现,自动扩展服务也不例外。在这个动手练习中,我们将为我们的 ASG 创建一个启动模板。然后我们将创建一个 ASG。按照以下步骤进行:
-
使用你的管理员用户账户登录到Amazon 管理控制台。登录后,导航至 EC2 服务。在 EC2 服务中,找到并点击左侧菜单中的启动模板子菜单项,该项位于实例菜单标题下。
-
当你进入 EC2 的启动模板主屏幕时,点击主窗口中的橙色创建启动模板按钮。
-
我们现在应该处于标有
chapter18的屏幕上 -
版本 1 -
自动扩展指导—勾选框,如下图所示:

图 18.4 – 启动模板的第一部分已完成
-
接下来,向下滚动页面,查看下一个选择标准框。我们将使用以下值填写剩余的字段:
-
t2.micro。 -
密钥对(登录)—不要在启动模板中包含此项。
-
网络设置—VPC。
-
转到网络设置 | 安全组,并选择你的默认安全组。
-
-
一旦你填写了所有的值,我们可以点击橙色的创建启动模板按钮。此时你应该会看到成功创建了一个启动模板。
-
使用页面中间的链接,在从模板创建自动扩展组标题下,进入自动扩展部分,在此我们可以创建新的 ASG,如下图所示:
![图 18.5 – 创建自动扩展组部分,当你完成启动模板时]()
图 18.5 – 创建自动扩展组部分,当你完成启动模板时
-
你现在应该位于
eighteen。 -
在下一个框中,从下拉列表中选择
chapter18)。点击屏幕底部的橙色下一步按钮。 -
在配置设置屏幕上,保持所有默认选项,包括默认 VPC。我们在此练习中不使用任何现货实例或额外的 VPC。在网络框中,依次选择默认 VPC 中的三个子网,直到所有三个子网出现在选择下拉框下方。添加完所有子网后,点击页面底部的橙色下一步按钮,如下图所示:
![图 18.6 – 将默认 VPC 中的三个子网添加到 ASG]()
图 18.6 – 将默认 VPC 中的三个子网添加到 ASG
-
现在,将
300秒调整为30秒。做出此更改后,点击橙色下一步按钮。 -
在
1、1和3处。 -
向下滚动到
18 ASG 策略 -
平均网络输入(字节) -
5000
以下截图展示了这个过程:

图 18.7 – 我们的 ASG 的带度量的扩展策略
-
填写完伸缩策略的值后,向下滚动到页面底部,点击标有跳过审查的白色按钮。
-
在审查页面,向下滚动到页面底部,点击橙色的创建自动伸缩组按钮,来创建我们的 ASG。
-
一旦点击按钮,你应该会被带到EC2 | 自动伸缩组页面,在那里你会看到你的组的状态最初为更新容量,因为第一个实例正在上线。
-
如果你想查看你的实例扩展,那么你可以按照以下步骤操作。在
eighteen中。 -
在横向菜单栏中,点击
eighteenASG 策略。选中后,使用操作下拉菜单,选择编辑:![图 18.8 – 单个 ASG 的横向菜单栏,突出显示自动伸缩]()
图 18.8 – 单个 ASG 的横向菜单栏,突出显示自动伸缩
-
在
5000到100之间。一旦你更改了这个值,点击橙色的更新按钮。 -
返回主自动伸缩组页面并刷新,看到实例上线以满足即将到来的流量的需求。
现在我们已经了解了如何在实际环境中创建启动配置和 ASG,让我们继续深入理解自动伸缩生命周期,以及它如何不同于仅仅启动一个 EC2 实例。
自动伸缩生命周期
当你将EC2 实例放入 ASG 时,它会遵循一个普通 EC2 实例(你通过命令行或 AWS 管理控制台启动的实例)不遵循的特定路径。该实例首先由 ASG 启动。如果这是一个扩展事件的一部分,那么该实例有机会通过生命周期钩子执行特殊命令。生命周期钩子允许你在启动或终止作为 ASG 一部分的实例时添加自定义操作。一旦实例变为健康状态,它将处于服务中状态,并成为 ASG 的一部分。如果该实例未通过设定的健康检查次数,它可能会进入终止状态。如果当前运行的实例数不足以支持流量或指标数据,则可能会发生缩减事件。再次强调,就像扩展事件一样,这个缩减事件也允许我们使用生命周期钩子。
自动伸缩生命周期过程如下面的图示所示:

图 18.9 – 自动伸缩生命周期过程
现在我们已经理解了 ASG 的生命周期,让我们更深入地研究生命周期钩子以及何时最适合使用它们。
使用自动伸缩生命周期钩子
如我们刚才所见,Auto Scaling 生命周期中有两个状态,在实例进入这些状态时允许进行额外操作。这两个状态分别是Terminating:Wait状态,你可以让实例暂停最多 30 分钟,之后再进入Terminating:Proceed状态,最后进入Terminated状态。
生命周期钩子的使用场景
你可能想了解一些生命周期钩子的使用场景。让我们快速看一下几个例子。
第一个例子是使用启动状态来调用 Lambda 函数。一旦我们的实例通过待处理状态并进入Pending:Wait状态,我们就可以利用这个事件为我们的应用程序调用一个特定的 Lambda 函数。一个好的应用场景是,如果我们有 Windows 实例并且需要在每个实例启动时将其加入到特定的Active Directory(AD)域和名称服务器中。当实例进入初始生命周期钩子时,它可以运行一个脚本来获取其域名系统(DNS)名称并加入该域。
当我们开始终止一个实例的过程时,情况也是一样的。在终止实例时,有些情况下我们希望在允许实例进入终止状态之前,确保捕获到来自该一组应用程序的所有数据。
作为提醒,在生命周期钩子中使用复杂脚本可能会导致我们请求新实例上线并加入我们的 ASG 或终止之间的额外时间延迟,从而使我们在需要时能够获得更多的弹性。处于等待状态的实例仍然会占用与 ASG 的最大容量计算相当的实例容量。
清理资源
和我们其他的练习一样,建议你在完成本章后终止所有正在运行的实例并清理 ASG,以免在 AWS 账户中产生不必要的费用。
总结
在本章中,我们介绍了 Auto Scaling 以及它如何自动管理来自内部和外部客户的需求。我们了解了使用不同的扩展策略配置 ASG 的不同方式,甚至通过动手实践部署了一个 ASG。最后,我们探讨了 Auto Scaling 生命周期以及生命周期钩子如何帮助执行比简单扩展更复杂的任务。
在下一章,我们将开始几章的内容,重点讨论如何保护你的环境和管道,首先将讨论保护传输中和静态数据的安全。这将特别涵盖密钥管理服务(KMS)以及使用Amazon 证书管理器(ACM)来管理服务器端证书。
复习问题
-
你被引入了一家公司,该公司正在使用 ELB 和自动扩展运行一个业务关键型的工作负载。这个工作负载是一个二层应用程序,包括应用层和数据库层。目前,两个层都已经在
us-east-1区域的两个可用区(AZ)中部署。数据库需要以同步方式从应用程序进行复制。首席技术官(CTO)告诉你,即使单个可用区不可用,且自动扩展无法在剩余的可用区中启动新的实例,应用程序也必须保持完全可用。你该如何通过 AWS 特定的服务和架构来实现这一目标?-
在 ELB 中设置配置,以在三个可用区中进行部署,并将自动扩展设置为在峰值时每个区域处理 33%的负载。
-
在 ELB 中设置配置,以在三个可用区中进行部署,并将自动扩展设置为在峰值时每个区域处理 50%的负载。
-
在 ELB 中设置配置,以使用 Round Robin 算法在两个区域中进行部署,并将自动扩展设置为在峰值时每个区域处理 50%的负载。
-
在 ELB 中设置配置,以使用 Round Robin 算法在两个区域中进行部署,并将自动扩展设置为在峰值时每个区域处理 100%的负载。
-
-
你为一个在 EC2 实例上运行的应用程序创建了一个 DevOps 管道。客户通过附加到 ASG 的应用程序负载均衡器与此应用程序进行交互。自从发布了最新版本的应用程序和启动模板后,应用程序似乎在每天的每个小时都在多次扩展和收缩。你和你的团队应该采取哪些措施,以稳定 ASG,保持弹性,并优化成本?(选择两个答案)
-
修改应用程序的 ASG,使其使用计划扩展操作。
-
修改应用程序的 ASG 终止策略,使其优先终止最旧的实例。
-
修改应用程序的 ASG 冷却时间,使其变得更长。
-
修改与应用程序 ASG 组关联的 CloudWatch 警报,使其与缩减策略关联的警报周期更长。
-
-
你所在的公司有一个应用程序,包含通过 ASG 启动的 EC2 实例。你注意到当需求增加时,EC2 实例并未自动扩展。你应该如何检查并解决这个问题?
-
检查以确保 ASG 将实例分布到多个区域。
-
检查以确保 ASG 将实例分布到多个可用区。
-
检查以确保正在使用 ELB 健康检查。
-
检查以确保正在衡量正确的指标来触发扩展事件。
-
审查答案
-
b
-
c, d
-
d
第二十章:保护飞行中的数据和静态数据
当你和你的开发人员开始连接到你的系统时,安全性并非总是放在首位。尤其是当你认为加密密钥和证书握手可能会引起延迟时。无论如何,在今天的环境中,无论是传输中的数据还是静态数据,采用加密措施都是必须的。
有多种方法可以将加密技术融入你的环境。这可以从如何确保你与 AWS 之间传输的数据安全开始,然后是确保存储在亚马逊云上的数据安全,再到确保你为客户提供访问的数据的安全。
在本章中,我们将涵盖以下主要主题:
-
了解 KMS 密钥
-
向存储添加加密
-
向数据存储添加加密
-
使用 AWS 证书管理器保护传输中的数据
-
向 Amazon CloudFront 添加证书
数据加密简介
现在,推动加密数据的原因有很多。这个需求可能源于你的公司所在行业需要遵守的法规。也可能是公司内部的合规性治理规定要求数据必须加密。最终,也有可能是通过增加额外的保护层来采取主动的安全立场。无论推动加密的原因是什么,最终的目标都是为客户提供更安全的平台,并更好地保护数据:

图 19.1 – AWS 加密栈
最终,你和你组织的加密目标应该是通过最小化对数据的未经授权的物理和逻辑访问来简化。
在查看数据和加密时,有三个类别需要注意:
-
传输中的数据
-
静态数据
-
使用中的数据
如果按照亚马逊的建议进行操作,那么你应该在环境中尽可能多地进行加密。这包括在存储时对静态数据进行加密,并且在客户端和服务器之间传输数据时对传输中的数据进行加密。
在 AWS 中加密静态数据的选项
在本章中,我们将重点讨论来自 AWS 的两个服务:密钥管理服务和证书管理器。亚马逊生态系统中还有其他一些在数据加密过程中起作用的服务,我们希望简要提及它们,以防它们出现在测试中。
第一个是亚马逊虚拟私有云的一部分,第二个是AWS 虚拟私有网络(AWS VPN)。通过使用 AWS 的站点到站点 VPN 连接将你的数据中心与 VPC 连接,可以通过 IPSec 协议安全地传输数据。IPSec 协议组用于加密互联网传输。
您可以通过设置一个客户网关开始,这通常包括一个路由器,然后在 VPC 上创建 VPN 网关。VPN 的吞吐量限制为 1.25 千兆比特每秒。
现在我们了解了如何在 AWS 账户中加密静态数据的选项,让我们专注于使用 AWS 密钥管理服务(KMS)来保护我们静态数据。
理解 KMS 密钥
KMS 是 Amazon 提供的托管服务,使得生成和管理客户管理密钥(CMK)变得简单。CMK 是用于加密和控制存储在 AWS 上的数据访问的密钥。KMS 与许多其他服务(尤其是 IAM 服务)无缝集成,允许您控制谁有权访问这些密钥。
AWS 为 KMS 密钥创建密钥材料。作为客户,您不能提取、导出、查看或管理此密钥材料。您可以删除密钥,但不能删除密钥材料本身:

图 19.2 – AWS KMS 中的主密钥和数据密钥
在 KMS 中需要理解的一个关键概念是信封加密。当 AWS 加密您的数据时,您的数据是安全的,但您的密钥也需要保护。AWS 通过使用数据密钥加密数据,然后再用另一个密钥加密数据密钥来实现这一点。最顶层的明文密钥称为主密钥。
使用信封加密过程带来许多好处:
-
它保护数据密钥 – 这样,您可以将加密的数据密钥与加密的数据一起存储。
-
您可以使用多个密钥加密相同的数据 – KMS 允许您仅重新加密保护原始数据的数据密钥,而不是重新加密所有原始数据。
-
您可以结合多种算法的优点 – 对称密钥算法通常比公钥算法要小。但是,公钥算法允许继承的角色分离。使用信封加密可以让您同时使用这两种策略。
使用 AWS 托管的 CMK 密钥进行存储加密
每个提供加密的 AWS 服务都有自己的 AWS 托管 KMS 密钥。
AWS 托管的 CMK 和用户创建的 CMK 之间的一个关键区别是轮换计划。使用 AWS 托管密钥时,需要进行密钥轮换,并且每 1,095 天或每 3 年进行一次。
这两种不同类型的密钥的相似之处在于,AWS 托管密钥和 CMK 仅用于您的 AWS 账户。
使用 KMS 与 S3 保护静态存储的对象
KMS 与 S3 对象存储无缝集成。S3 拥有自己的服务托管密钥,允许您几乎不费任何力气地加密存储桶中的对象。还有以下安全控制可帮助将 KMS 与 S3 结合使用:
-
Amazon S3 具有自动加密所有新上传到存储桶中的对象的能力。这是通过 属性 部分中的一个存储桶设置来完成的,标记为 默认加密。一旦启用此设置,任何新上传到存储桶中的对象都会自动使用 Amazon 管理的 S3 密钥(默认情况下)或指定的客户管理的 S3 密钥进行加密。
-
如果你需要追溯性地加密 S3 存储桶中的项目,可以使用 S3 批处理功能。Amazon S3 具有在存储桶中的对象上执行批处理操作的能力。如果你的内部指导方针发生变化,或者审计发现某个用户(无论是内部用户还是外部用户)已经向存储桶中添加了未加密的项目,你可以使用 S3 批量操作来纠正这种情况。
-
如果你想检查某个 S3 存储桶中的项目是否已加密,可以运行 S3 清单报告。
现在我们已经了解了 KMS 如何与 Amazon S3 顺畅配合,特别是在使用 Amazon 管理密钥的情况下,我们将查看如何创建和管理自己的密钥,以及客户管理密钥和 Amazon 管理密钥之间的重要区别。
在 KMS 中创建和管理客户管理密钥
可能会有一些情况,某些用户或团队需要访问数据,而其他人则不应有权限访问。这是集成 CMK 与 IAM 策略来控制谁可以访问密钥的理想用例之一。
正如我们在本练习中所看到的,关键管理员和关键用户之间有职责分离。关键管理员是控制密钥访问的用户,包括旋转和删除密钥的能力。还有关键用户,这些是每天使用密钥的用户和服务角色。这些是你在创建和管理帐户中的密钥时必须理解的重要概念。可能有一些个人和团体需要管理密钥的能力,但不需要访问受密钥保护的数据。
在以下练习中,我们将使用 KMS 创建自己的客户管理密钥。在完成创建密钥之前,我们还将指定关键管理员和关键用户:
-
登录到 AWS 管理控制台并从顶部搜索菜单栏搜索
Key Management Service:![图 19.3 – 搜索菜单中的密钥管理服务图标]()
图 19.3 – 搜索菜单中的密钥管理服务图标
-
一旦进入 KMS,我们现在可以点击橙色的 创建密钥 按钮。
-
现在在 配置密钥 页面,选择 对称 密钥类型,然后点击页面底部的橙色 下一步 按钮。
-
这应该会将我们带到
chapter19作为 KMS 密钥别名。我们可以将example key作为 描述。向下滚动到页面底部,点击橙色的 下一步 按钮:![图 19.4 – 添加 KMS 密钥别名和描述]()
图 19.4 – 添加 KMS 密钥别名和描述
-
现在是选择密钥管理员的时候了。这是一个重要步骤,决定了谁可以控制密钥的访问权限以及谁可以删除密钥,但不包括可以使用密钥的人员和组。由于你很可能已经使用我们在开始时创建的
devops用户登录,因此选择该用户,如果你有其他管理员帐户并希望它能够访问密钥,请勾选该名字旁的框。一旦选择了管理员的名字,点击屏幕底部的橙色下一步按钮。 -
现在我们应该在
devops用户下,让我们把之前创建的开发者用户mariel也添加到授权用户列表中。选定后,点击屏幕底部的橙色下一步按钮。 -
在审查页面,向下滚动并点击橙色的完成按钮来创建密钥。
现在我们已经完成了创建 CMK 的过程,让我们看看如何使用这个密钥通过加密来确保我们的数据安全。
使用我们的自定义 KMS 密钥为数据存储添加加密
现在让我们来看看如何使用我们刚刚创建的 CMK 来加密我们之前创建的 S3 存储桶中的对象。在示例中,我们将使用在第四章中创建的存储桶,Amazon S3 Blob 存储:
-
登录到 AWS 管理控制台,进入
devopspro-beyond。找到它后,点击存储桶的名称以进入。 -
进入存储桶后,点击顶部水平菜单中的属性选项卡:
![图 19.5 – S3 水平菜单中的属性菜单项]()
图 19.5 – S3 水平菜单中的属性菜单项
-
现在显示的是 S3 存储桶的属性项目,向下滚动,直到找到默认加密标题。点击默认加密框右上角的白色编辑按钮以进入设置界面。
-
现在你应该在标记为编辑默认加密的页面上。在服务器端加密标签下,点击启用旁边的单选按钮。选择后,下面将出现一组新的选择项,供你选择加密密钥类型。选择AWS 密钥管理服务密钥(SSE-KMS)选项旁的单选按钮:
![图 19.6 – 在 S3 存储桶上启用 KMS 密钥]()
图 19.6 – 在 S3 存储桶上启用 KMS 密钥
-
一旦进入我们在前面的实操中创建的
chapter19。选择后,向下滚动到页面底部,点击橙色的保存更改按钮。 -
在设置好存储桶的对象加密后,点击横向菜单中的对象菜单项,返回到主存储桶页面。点击橙色的上传按钮,在上传页面上,点击白色的添加文件按钮。选择任意一个文件上传到你的存储桶。一旦文件排队准备上传,点击橙色的上传按钮。
-
当你的文件完全上传到 S3 存储桶时,你可以点击橙色的关闭按钮。这将把你带回到 S3 存储桶的对象页面。点击对象的名称,然后向下滚动到服务器端加密设置,查看你的对象是否已经使用 KMS 密钥进行了加密。
重要提示
如果你已经不再使用 KMS 密钥,你可能想要回去并安排删除它。KMS 密钥不会立即删除,至少需要七天才能删除。加密对象的密钥一旦被删除,将无法访问。
通过了解如何使用 KMS 保护静态数据,我们接下来将学习如何使用 AWS 证书管理器保护传输中的数据。
使用 AWS 证书管理器保护传输中的数据
当你的外部网站呈现传输层安全性(TLS)证书并使用安全的 HTTP 协议(HTTPS/443)时,客户会知道你正在以加密方式保护他们发送到你系统的数据:

图 19.7 – 从浏览器到客户端的 SSL/TLS 工作原理
当你或你的客户请求一个使用 SSL/TLS 证书保护的 HTTPS 网站时,以下步骤会发生:
-
服务器尝试通过安全的
443端口连接到网站。然后该网站服务器会进行身份验证。 -
服务器接着会发送其 SSL 证书的副本。
-
客户端会检查证书,看看它是否来自受信任的机构。如果信任该证书,它将向服务器发送确认消息。
-
服务器随后会发出一个数字签名的确认,开始 SSL 会话。
-
数据随后在客户端和服务器之间安全共享。
AWS 证书管理器(ACM)是一个可以帮助你快速且轻松地在 AWS 服务上创建、管理和部署 TLS 证书的服务器。ACM 也支持公共证书。ACM 处理私钥基础设施(PKI)中最难和最复杂的部分,包括创建证书、证书续期和颁发证书等任务。
ACM 可以快速且轻松地为外部面向的 AWS 资源(如以下内容)提供 TLS 证书:
-
弹性负载均衡
-
AWS Elastic Beanstalk
-
Amazon EC2 实例
-
Amazon API Gateway
-
Amazon CloudFront
ACM 创建的任何证书有效期为 13 个月(395 天)。但是,您不能下载您创建的 ACM 证书的私钥。一旦证书颁发,您就无法添加或删除该证书中的域名。如果需要新域名,您可以创建通配符证书(*.domain.com),或者需要创建新的证书。
当我们在以下段落中提到域名时,我们指的是已在注册商处注册并托管在 DNS 服务器或服务(如 Route 53)上的域名。许多情况下,这可以被认为是域名。当首次为某个域名申请 Amazon 证书时,ACM 必须验证您是否拥有或控制该域名。可以通过两种方式进行验证。第一种是通过电子邮件验证。ACM 会向 WHOIS 数据库中列出的三个电子邮件地址发送验证邮件,您需要在 72 小时内通过该邮件进行验证。第二种验证方式是通过 DNS 验证。ACM 为您的域名创建两个 CNAME 记录,并要求您将这些记录添加到您的 DNS 数据库中进行验证。一旦验证记录存在,服务就会知道您是该域名的所有者。
ACM 可以执行的两项功能
我们已经解释了安全证书的作用,主要是针对面向公众的网站。这些证书的颁发是 ACM 执行的关键角色之一。然而,这并不是它在您的 AWS 环境中唯一可以执行的角色。ACM 提供了两项独立的服务。第一项是为 Elastic Load Balancing、API Gateway 和 CloudFront 等服务以及其他面向前端的服务管理、配置和续订企业级 TLS 证书。第二项服务是作为私有证书颁发机构。这使您能够为您的应用程序和基础设施颁发安全和可信的私有证书,以支持您的工作负载和组织。
现在我们知道了 ACM 可以执行的功能,我们将通过一个实际操作,使用 ACM 创建并配置一个证书,然后在一个公开可用的 CloudFront 分发中使用该配置的证书。
将证书添加到 Amazon CloudFront
在充分理解 ACM 服务之后,我们将继续本章的最后一个实际操作。我们将从使用 ACM 创建一个 TLS 证书开始,然后创建一个非常简单的 CloudFront 分发,并使用我们的安全证书对其进行加密,以保护任何尝试连接到该分发的人。
如果您没有可用的域名,您可以使用 Amazon Route 53 服务轻松注册一个域名,以非常低的成本完成此练习。否则,您可以阅读以下练习步骤以了解过程:
-
登录到 AWS 管理控制台,搜索 ACM 服务。一旦它从下拉菜单中出现,点击图标进入主服务页面。为了让证书与 CloudFront 服务兼容,我们需要在
us-east-1区域创建它。如果你在其他区域创建证书,你将无法在本练习的第二部分中看到它。 -
在 ACM 主页面,找到标有提供证书的图标和标题。点击该标题下方的蓝色开始使用按钮。
-
在请求证书页面,由于我们没有可用的私有证书颁发机构,只有一个选项可供选择。保持此选项被选中,然后点击页面底部的蓝色请求证书按钮。
-
创建证书的第一步是向证书添加域名。除非你只希望证书用于单一子域(例如 www),否则可以使用星号作为通配符,覆盖你的整个域名。在文本框中以
*.devopsandbeyond.com的形式输入你的通配符域名,然后点击蓝色的下一步按钮:![图 19.8 – 将通配符域名添加到我们在 ACM 创建的证书中]()
图 19.8 – 将通配符域名添加到我们在 ACM 创建的证书中
-
下一步将是验证你是否真正拥有该域名。我们假设你通过 Route53 管理你的 DNS,并选择DNS 验证。保持DNS 验证选项被选中,然后点击蓝色的下一步按钮。
-
这将带你到添加标签页面。只需点击页面底部的蓝色审查按钮。当你进入审查页面后,确认你的域名输入无误后,按下蓝色的确认并请求按钮。
-
然后你需要将请求的 CNAME 添加到你的 DNS 文件中。获取该值并前往 Route53 服务。将该条目作为新的 CNAME 记录添加到你的域名 Route53 托管区。你可能需要等待几分钟,直到值传播完成,然后验证状态会变成绿色并显示为成功。一旦完成,你可以点击屏幕底部的蓝色继续按钮:
![图 19.9 – 在添加 DNS 条目后,验证状态显示为成功]()
图 19.9 – 在添加 DNS 条目后,验证状态显示为成功
现在我们的证书已创建完成,我们可以继续创建 CloudFront 分发。Amazon CloudFront 是 AWS 本地的内容分发网络(CDN)。CloudFront 允许你使用单一来源向全球的众多客户同时提供内容,相较于从单一位置(如服务器或自动扩展组)提供内容,其延迟更低。
-
现在,我们需要从 AWS 管理控制台顶部的搜索栏导航到 CloudFront 服务。进入服务主页后,点击橙色的创建 CloudFront 分发按钮,开始创建新的 CloudFront 分发。
-
页面标题现在应该命名为
devopspro-beyond;然而,你的存储桶将会有不同的名称。从下拉列表中选择你的源存储桶。源存储桶的名称将以.s3.us-east-2.amazonaws.com结尾。 -
在下一个文本框中,在源路径文本框中输入
/pages。 -
保持 CloudFront 创建的名称不变,继续进入S3 存储桶访问部分。选择是的,使用 OAI选项。此选项将允许我们保持存储桶私密,并要求用户通过 CloudFront 分发访问,而不是直接绕过 CDN 访问源中的资源。点击白色的创建一个新的 OAI按钮;你可以保留 CloudFront 提供的名称。然后点击橙色的创建按钮。
-
当对话窗口关闭时,在存储桶策略标题下,选择是的,更新存储桶策略选项。
-
向下滚动直到你看到
将 HTTP 重定向到 HTTPS选项被选中。 -
我们可以保持其他选项不变,直到进入设置部分。我们首先要做的事是优化成本,所以在价格类别下,我们要选择仅使用北美和欧洲。
-
现在,我们将安装来自 ACM 的自定义证书。在自定义 SSL 证书 – 可选标签下,使用下拉菜单选项找到你在练习第一部分创建的证书,位于ACM 证书标题下。
-
选择证书后,向下滚动至页面底部,点击橙色的创建分发按钮。
-
当 CloudFront 分发正在创建时,记下分发域名;这就是你如何在不添加 Route53 别名的情况下访问 CloudFront 的方式:
![图 19.10 – CloudFront 分发域名]()
<html> <head> <title> Chapter 19 - Protecting Data in Flight and at Rest </title> </head> <p> Protecting Transmission of data - <b> VPN </b> </p> <p> Protecting Data at Rest - <b> KMS </b> </p> <p> Protecting Data in Flight - <b> SSL / TLS certificates </b> </p> </html> -
返回到 S3。在那里,找到你指定为 CloudFront 分发源的存储桶。点击该存储桶的名称进入它。
-
进入存储桶后,我们需要点击白色的
pages,就像我们在 CloudFront 分发选项中所做的那样。在你命名文件夹后,点击橙色的创建文件夹按钮。 -
点击新创建的页面目录,然后点击我们在本节开始时创建的橙色
index.html文件。当索引页面准备好上传时,点击橙色的上传按钮。
我们刚刚了解了如何使用 ACM 创建并实现安全证书。现在,让我们回顾一下我们在本章学到的内容。
总结
在本章中,我们讨论了如何保护你在亚马逊账户中的数据,包括静态数据和传输中的数据。我们从账户级别开始,讨论了如何在数据传输到你的 VPC 时使用通过 IPSec 隧道的安全 VPN 连接进行加密。然后,我们探讨了 KMS 以及 Amazon 管理密钥和 CMK 之间的区别。最后,我们讨论了如何使用 ACM 保护传输中的数据。我们看到 ACM 如何简化了在多个 AWS 服务上创建和实施 SSL 和 TLS 证书的过程。
在下一章中,我们将探讨如何通过 AWS 提供的两个强大自动化工具——Systems Manager 和 Config,在你的组织中强制执行标准和合规性。
审查问题
-
公司所在的安全部门出台了新的合规性规定,要求所有加密密钥必须每 12 个月轮换一次,不得有例外。以下哪个选项不符合新规定?
a. 使用导入的密钥材料与 CMK
b. 使用 AWS 管理的密钥
c. 使用 AWS 客户管理的对称 CMK
d. 使用 AWS 客户管理的非对称 CMK
-
你被带入一家处理机密数据的公司。然而,他们在亚马逊管理控制台和使用 CLI 时都未加密地传输数据。你可以采取哪些步骤立即通过加密保护数据传输?
a. 在 KMS 中创建一组 CMK。使用信封加密,让每个用户在执行任何 CLI 命令之前加密每个交易。
b. 使用 ACM 创建证书以创建安全登录,并加密传输到亚马逊管理控制台的通信。
c. 在主 VPC 上创建客户网关和 VPN 网关。确保任何需要开发团队访问的其他 VPC 要么通过对等连接,要么通过过渡 VPC 连接器连接。
d. 要求所有用户为他们的账户添加多因素认证,以确保通过 CLI 和 AWS 管理控制台的安全通信。
审查答案
-
b
-
c
第二十一章:通过 Systems Manager 的角色和 AWS Config 执行标准和合规性
Systems Manager 是一个由多个单独功能组成的服务,这些功能被分为五个类别:运营管理、应用管理、变更管理、节点管理和共享资源。学习如何有效使用这个工具,可以让你作为一个 DevOps 专业人员变得更加高效,特别是在实现标准和检查一个或多个 AWS 环境或账户中的合规性时。随着组织对自动化和合规性要求的增加,拥有一个可以检查合规性、对不一致性发出警报并修复违规行为的工具,对于防止环境漂移至关重要。
在本章中,我们将讨论以下主要内容:
-
AWS Systems Manager 的各种功能
-
在 Systems Manager 中使用操作手册
-
AWS Config 基础知识
AWS Systems Manager 的各种功能
DevOps 是开发和运维两项职责的结合。AWS Systems Manager (SSM) 关注这些职责中的运维部分,为你提供了大量的工具,用于日常运营任务。这些工具涵盖了从创建预定义的操作手册,到在 Linux 或 Windows 实例上快速、轻松且重复地执行功能。Systems Manager 还可以为你提供一个接口,以便在一个统一的地方跟踪你的资源或资源组。
作为额外的好处,Systems Manager 不仅有助于管理 AWS 云中的实例,还可以通过在本地服务器上安装轻量级代理来管理这些服务器,并允许该代理与 AWS 账户进行通信。
Systems Manager 的关键特性和优势
Systems Manager 不仅仅是一个服务;它是一个供你使用的完整工具集。你可能不会使用它的所有功能,但了解它们可以帮助你快速解决问题:

图 20.1 – 组成 Systems Manager 的许多关键组件的概览
现在我们已经了解了一些 AWS Systems Manager 的功能,让我们深入探讨如何更有效地使用它来管理实例和节点。
使用 Systems Manager 进行节点管理
Systems Manager 为运维团队成员提供了许多功能,但有一类功能特别属于节点管理这一类别。
我们将查看 AWS Config 中一些专门为节点管理目的创建的特殊服务。
Fleet Manager
同时了解您控制的所有不同实例可能是一项令人生畏的任务。SSM Fleet Manager 为您提供了一个用户界面,让您查看所有在您控制下的实例。Fleet Manager 还允许您收集这些实例的数据,并传递回去,无需逐个进入服务器或实例。
清单
如果您需要查看本地服务器、云 EC2 实例或两者的状态,那么 Systems Manager 的清单功能对您非常有用。
混合激活
如果您有不在 AWS 云或本地的服务器,您可以使用 SSM 混合激活来管理这些设备,以及需要在单一管理控制台中管理的其他 EC2 实例。混合激活功能帮助您了解创建本地服务器激活所需的前提条件。包括创建 IAM 服务角色,确保操作系统兼容,并安装 Systems Manager 代理。
会话管理器
管理所有不同的 PEM 密钥,尤其是在开发人员自己创建密钥时,可能是一个繁重的任务。会话管理器通过允许授权用户使用基于 Web 的控制台执行命令,无需复制密钥,从而帮助减轻这一负担。您只需找到您需要远程创建会话的机器名称,然后立即启动会话。
本章稍后我们将通过一个练习来讲解如何使用会话管理器功能。
运行命令
通过 Systems Manager 的运行命令功能,您可以安全地更新您注册的管理实例的配置。命令文档是为执行运行命令而创建的。然后,使用实例 ID 或标签,针对指定的管理实例运行命令。
提示
您应始终在非生产或测试实例上测试您创建的运行命令。这样,您可以确保命令在执行之前会按预期执行,并且在生产流量到达服务器之前不会产生任何问题。
状态管理器
Systems Manager 的状态管理器允许您执行以下操作:
-
您可以配置网络设置。
-
您可以让您的实例加入 Windows 域。
-
它允许您在实例启动时使用引导脚本安装软件。
-
它允许您在整个生命周期内,在 Windows、Linux 甚至 macOS 管理的实例上运行脚本。
补丁管理器
如果您的环境中没有运行不可变基础设施,您应该有一个策略来保持您的实例系统补丁的最新状态。补丁管理器允许您在维护计划中添加这些系统补丁。
在 EC2 实例上运行远程命令
以前,如果你想在 EC2 实例上运行远程命令,必须创建一个 PEM 编码的密钥。SSM 会话管理器改变了这一切,它允许你通过浏览器使用具有正确权限的角色登录实例,而不是管理和轮换密钥。
注意
PEM代表隐私增强邮件,但这只是额外的知识,了解 PEM 的定义并不是考试的要求。
在接下来的练习中我们将看到这一点如何运作。在使用 Systems Manager 远程访问实例之前,我们需要设置一个 IAM 角色,该角色将允许 SSM 服务有权限访问任何具有该角色的实例。幸运的是,AWS 已经有一个托管的 IAM 策略,包含了我们完成此任务所需的所有权限;然而,我们仍然需要创建一个可以附加到 EC2 实例的角色。让我们开始吧:
-
打开浏览器,访问 Amazon Web 控制台,导航到 IAM 服务:
console.aws.amazon.com/iam/。 -
从左侧导航栏中选择角色,然后在出现的主框中按下蓝色的创建角色按钮。
-
在选择受信任实体类型页面,确保选择了AWS 服务。
![图 20.2 – 创建角色时选择 AWS 服务作为实体类型]()
图 20.2 – 创建角色时选择 AWS 服务作为实体类型
-
然后,从常见使用场景列表中,找到EC2并点击选择它。选择后,你可以点击页面右下角的蓝色下一步:权限按钮。
![图 20.3 – 在创建 IAM 角色时的常见使用场景]()
图 20.3 – 在创建 IAM 角色时的常见使用场景
-
现在你已经进入了附加权限策略页面,在屏幕中间的搜索框中,搜索名为 AmazonEC2RoleforSSM 的策略。策略出现在搜索结果中后,选择其旁边的框。一旦选择了该策略,你可以点击蓝色的下一步:标签按钮继续。
![图 20.4 – 向 IAM 角色添加托管权限策略]()
图 20.4 – 向 IAM 角色添加托管权限策略
-
在添加标签页面,由于我们不会为此角色添加标签,只需选择页面底部的下一步:审查按钮即可。
-
在
Remote2EC2SSM页面上,你可以根据需要更改角色描述,使其更符合该角色的功能。更新完成后,点击页面底部的蓝色创建角色按钮。太好了!你的角色现在应该已经创建完成。![图 20.5 – 添加角色名称和描述]()
图 20.5 – 添加角色名称和描述
创建好角色后,我们可以开始创建一个临时的 EC2 实例,用于测试 SSM 的功能。
-
在顶部菜单的左侧找到 Services 菜单项。点击 services 以弹出下拉菜单,显示所有 AWS 服务。点击 EC2,它应该靠近顶部,位于 Compute 标题下方,进入 EC2 服务页面。
![图 20.6 – EC2 服务页面]()
图 20.6 – EC2 服务页面
-
进入 EC2 页面后,在页面中间找到 Launch instance 部分。点击该部分中的橙色 Launch instance 按钮开始启动实例。当你点击该按钮时,会出现两个选项;选择标有 Launch instance 的选项。
![图 20.7 – 从主 EC2 页面启动 EC2 实例]()
图 20.7 – 从主 EC2 页面启动 EC2 实例
-
现在你应该会看到一个页面,可以选择要使用的 AMI。选择任何 2017.09 或更晚版本的 Amazon Linux 或 Amazon Linux 2,因为它已经预装了 AWS SSM 代理。点击蓝色的 Select 按钮选择镜像。
![图 20.8 – 在 AMI 选择页面上的 Amazon Linux 2]()
图 20.8 – 在 AMI 选择页面上的 Amazon Linux 2
-
我们的测试不需要太多计算能力,因此可以使用 t2.small 实例。点击灰色的 Next: Configure Instance Details 按钮,因为我们需要确保将角色附加到实例上。
-
一旦进入
Remote2EC2SSM,并选择该字段的值。完成后,点击灰色的 Next: Add Storage 按钮。![图 20.9 – 配置 EC2 实例时选择 Remote2EC2SSM 角色]()
图 20.9 – 配置 EC2 实例时选择 Remote2EC2SSM 角色
-
在
name字段中无需更改内容,使用RemoteTest作为值。确保将 N 大写,否则它不会正确设置实例名称的值,而只会设置标签和值对。设置好键值对后,可以点击页面底部的蓝色 Review and Launch 按钮。![图 20.10 – 使用标签设置实例名称]()
图 20.10 – 使用标签设置实例名称
-
在 Review Instance Launch 页面上,点击页面底部的蓝色 Launch 按钮。这时会弹出一个对话框,询问你想使用哪个密钥对。不过,我们将清除顶部下拉菜单中的值,使其显示 Proceed without a key pair。勾选框以确认你在没有密钥对的情况下继续,然后点击蓝色的 Launch instances 按钮来启动 EC2 实例。
![图 20.11 – 在没有密钥对的情况下启动我们的 EC2 实例]()
图 20.11 – 在没有密钥对的情况下启动我们的 EC2 实例
现在我们的实例已经开始启动,我们已经完成了本练习的所有前置条件。我们现在可以转到 AWS 控制台中的系统管理器服务,登录而无需密钥,并执行命令。
-
在 AWS 管理控制台顶部的搜索栏中,输入系统管理器,然后点击列表中出现的菜单项:
![图 20.12 – 从 AWS 管理控制台搜索时显示的系统管理器服务]()
图 20.12 – 从 AWS 管理控制台搜索时显示的系统管理器服务
-
一旦你进入系统管理器服务页面,找到左侧菜单中的节点管理标题。在此标题下,点击名为会话管理器的菜单项。
-
当主会话管理器页面出现时,点击主窗口右上方的橙色开始会话按钮。
-
现在我们已经进入了之前创建实例时的
Remote Test。点击实例名称旁边的单选按钮选择该实例,然后点击橙色的开始会话按钮,远程访问该实例,而无需使用 PEM 密钥。 -
一旦
ssm-user登录,新的标签页或浏览器窗口将会弹出。这是系统管理器会话管理器连接的用户。
你刚刚看到会话管理器如何从操作的角度使访问实例变得更加容易。你不再需要为实例创建和管理密钥。然而,让我们来讨论一些使用会话管理器时需要考虑的问题。
在系统管理器中使用运行手册
由于我们已经有一个托管实例正在运行,我们可以在 AWS 系统管理器中创建一个运行手册,看看如何轻松地在一个或一千个实例上执行命令,所有这些都只需通过单击鼠标即可远程完成。
在我们开始之前,我们将使用的clamav.json脚本文件将可以在本书 GitHub 仓库的Chapter-20文件夹中找到。由于文件不是特别长,我们将在本练习中也展示它。
本练习还建立在前一个练习的基础上,因此,如果你希望完成本练习但未进行过在 EC2 实例上运行远程命令的练习,你需要通过执行前一个练习中的第 1 到第 14 步来设置环境。让我们开始吧:
-
如果你之前已经退出了 AWS 管理控制台,请以管理员用户重新登录,并通过顶部搜索栏或左上角的服务下拉菜单导航到系统管理器服务。
-
我们需要创建一个文档供系统管理器运行。虽然 AWS 已经创建了几个预定义的运行文档,但我们将创建一个自定义文档。在系统管理器服务的左侧导航菜单中,在共享资源标题下,点击文档。
![图 20.13 – 系统管理器服务中的文档菜单项]()
图 20.13 – 系统管理器服务中的文档菜单项
-
现在我们在文档页面上,我们需要找到右上角的橙色创建文档按钮。当你点击它时,会出现两个选项。选择命令或会话选项。
![图 20.14 – 显示两个不同选项的创建文档按钮]()
图 20.14 – 显示两个不同选项的创建文档按钮
-
一旦
Linux_ClamAV_Installer被找到。 -
目标类型:保持此值为空。
-
文档:命令文档。

图 20.15 – 创建文档时的文档详情页面
-
在创建文档页面的底部是内容部分。这是我们加载要运行的脚本的地方。你可以直接从开始练习时下载的clamav.json脚本中剪切并粘贴脚本,或者手动输入脚本,如图所示。一旦脚本放入内容框中,点击橙色的创建文档按钮:
{ "description": "Install ClamAV on Amazon Linux, Run freshclam and clamscan", "schemaVersion": "2.2", "mainSteps": [ { "inputs": { "runCommand": [ "#!/bin/bash", "sudo amazon-linux-extras install -y epel", "sudo yum -y install clamav", "sudo touch /var/log/freshclam.log", "sudo chmod 600 /var/log/freshclam.log", "sudo freshclam ", "sudo clamscan -r /var --leave-temps" ] }, "name": "ALclamInstall", "action": "aws:runShellScript" } ] } -
按下创建文档按钮后,你将被带回主文档页面。在这里,你应该看到页面顶部的绿色横幅,确认你的文档已成功创建。如果你想快速而轻松地找到刚刚创建的文档,点击顶部菜单中的中间标签我拥有的。此时,你应该能看到你的文档。
![图 20.16 – 显示文档成功创建的通知]()
图 20.16 – 显示文档成功创建的通知
-
文档创建完成后,我们可以在左侧菜单选项中找到节点管理标题下的运行命令菜单项。点击运行命令以进入运行命令功能。
-
在运行命令功能屏幕上,点击主窗口右上角的橙色运行命令按钮以开始该过程。
-
为了让命令文档运行,我们将运行刚刚创建的文档。你可以通过在搜索框中输入
Linux来找到它。使用单选按钮选择文档的一个实例。由于我们只有一个文档版本,所以我们将保留默认版本(1)。![图 20.17 – 基于搜索词查找我们创建的文档]()
图 20.17 – 基于搜索词查找我们创建的文档
-
在目标部分,我们将手动选择我们的实例,因为我们在启动实例时使用的唯一标签是名称标签。当您点击手动选择实例时,如果看不到该实例,请输入实例的名称,即远程测试。选择实例名称旁边的选择框。
![图 20.18 – 选择要运行命令的目标实例]()
图 20.18 – 选择要运行命令的目标实例
-
对于
devopspro-beyond。一旦选择了您的存储桶,您可以点击页面底部的橙色运行按钮。 -
一旦启动运行命令,您应该会看到一个屏幕,显示您的实例和命令运行状态为进行中。
-
几分钟后,您应该会看到命令运行成功。
现在我们已经学习了如何在多个实例上运行远程命令,接下来我们来看看 AWS 系统管理器的一些使用案例。
系统管理器的使用案例
系统管理器可以以多种方式帮助您处理日常的运营管理任务。让我们来看一些系统管理器的实际使用案例。
您需要确保在 AWS 账户中运行的 EC2 实例保持最新的安全补丁。
如果您有合规性或安全性要求,要求所有发布的安全补丁必须在特定时间框架内安装,例如从发布日起的 7 天内,那么在没有自动化的情况下,这将是一项艰巨的任务。如果您没有使用不可变基础设施,并且需要维护需要更新的长期运行实例,尤其如此。
使用维护窗口服务时,该服务是 SSM 的一部分,您可以将维护窗口分配给一组资源,这些资源将在其主要任务计划之外运行,然后将其与补丁管理器服务结合使用,安装安全补丁。此组合适用于 Linux 和 Windows 操作系统,也适用于已安装 SSM 代理的本地服务器。
成功的关键之一是确保您的实例上有正确的标签,这样您就可以根据标签将资源分组。通过维护窗口,您可以在创建资源组时组合标签,仅针对您计划修补的特定类型的实例进行操作。
现在我们已经学习了如何使用 AWS 系统管理器管理我们的许多操作任务,并帮助保持资源的合规状态,接下来我们将学习 AWS Config 服务。通过 AWS Config,我们将学习如何不断记录环境的历史,直观地查看发生了哪些变化,甚至主动修复不符合我们为账户设置的规则的项目。
AWS Config 基础知识
在大多数情况下,AWS 账户中的资源以某种形式不断变化。实例在启动和停止,同时也在创建和销毁。安全设置不断变化,用户通过启用和禁用端口来允许正确的通信协议。
AWS Config 服务使您能够全面了解 AWS 账户中发生的事情。它还允许您查看事物如何随时间变化。
使用 AWS Config 服务,您将获得以下功能:
-
您可以评估 AWS 资源配置,查看它们是否符合账户的期望设置。
-
将当前配置设置保存为受支持资源的快照的功能。
-
您可以检索单个或多个受支持资源的历史配置。
-
您可以设置接收通知的功能,当资源被创建、删除或修改时,您将收到通知。
-
获取对资源之间关系的视图。
Config 提供的另一个价值是,您可以使用常见的预定义规则,甚至编写自己的规则来检查环境的合规性。
理解 AWS Config 的概念
在我们深入了解 AWS Config 服务之前,让我们先看一些将要讨论的关键术语和概念。
AWS 资源
您通过 AWS 管理控制台、CLI 或任何可用的 SDK 创建和管理的实体是AWS 资源。这些可以包括 EC2 实例、EBS 卷、DynamoDB 表、RDS 实例和安全组、S3 存储桶、SNS 主题等等。AWS Config 使用Amazon 资源名称(ARN)来标识每个唯一的资源。要查看完整的受支持资源列表,请访问docs.aws.amazon.com/config/latest/developerguide/resource-config-reference.html。
配置记录器
当您运行 AWS Config 服务时,配置记录器会保存并存储各种受支持 AWS 资源的值和更改作为配置项。然而,在它开始记录之前,必须先创建并启动配置记录器。
配置历史
当您想了解某个特定的受支持 AWS 资源发生了什么更改,以及这些更改发生的时间时,可以使用配置历史。配置历史是一个特定资源在配置记录器运行期间的所有数据(配置项)的累积。
配置快照
与名称所暗示的有所不同,配置快照不是时间点的配置项的图形化展示。相反,它是一个基于代码的记录,记录了在特定时间点如何使用您的受支持资源及其不同的设置。这些快照可以保存到指定的 S3 存储桶中,以便可以在未来或过去的配置快照之间进行检索或比较。
配置项
支持的 AWS 资源的即时视图被捕获为配置项。捕获的信息包括属性、元数据、当前配置、关系和相关事件。
现在我们已经了解了 AWS Config 使用的概念和组件,让我们深入了解一下 AWS Config 的工作原理。
理解 Config 的工作方式
启动服务后,AWS Config 开始扫描账户中支持的资源。随着发现这些资源,它为每个资源生成一个配置项。
当这些资源发生变化时,配置记录器会生成并记录一个新的配置项。

图 20.19 – 理解 AWS Config 的工作流程
如果您已启用规则以供 Config 服务评估,则 Config 服务将持续检查配置项是否符合规则的标准。如果某个项不符合规则的标准,则将触发与该规则关联的 Lambda,并执行相关操作。
例如,如果公司已启用强制要求所有 EBS 数据卷必须加密,无论是通过 CloudFormation、CLI、SDK 还是手动创建,那么可以创建一个简单的 AWS 规则,以便在发现违规卷后向包含电子邮件组列表的 SNS 主题发送通知。
可以创建一个更复杂的规则,不仅将通知推送到 SNS 主题,而且还可以使用相应 Lambda 函数中的 AWS SDK 来终止任何创建时加密的 EBS 卷。
当 AWS 编译您的配置项历史时,您可以查看 AWS 发现的资源清单,以及查看任何特定 AWS 资源的合规性历史。
如果您正在使用配置规则,那么资源在发生更改时可以进行持续检查。您也可以设置定期检查,例如每隔 12 或 24 小时进行一次。
现在我们对 AWS Config 的工作原理有了很好的理解,让我们通过下一个练习自己试一试,以便能够获得一些实践经验。
部署 AWS Config – 一个实际例子
为了了解 AWS Config 服务的工作原理,我们将部署一个配置记录器以及两个将检查我们账户的规则。一旦记录器已经部署并开启,我们可以过一段时间再回来查看其发现情况。
注意
因为我们正在使用 CloudFormation 模板来部署我们的 Config 记录器,所以一旦完成使用,我们可以轻松地将其关闭。如果您要从 AWS 管理控制台启动 Config 记录器,则在需要时关闭默认的 Config 记录器并将所有设置重置为零将会很具挑战性。
在开始之前,确保你已经从本书的 GitHub 仓库中下载了名为 configTemplate.yml 的 CloudFormation 模板,位于 Chapter-20 文件夹下:
-
打开浏览器并使用管理员用户登录到你的 AWS 账户。登录后,进入 CloudFormation 服务。
-
在右上角,点击创建堆栈按钮。点击后,选择使用新资源选项。
-
在
configTemplate.yml中选择以下选项。 -
使用这些选项后,点击橙色的下一步按钮。
-
你将看到关于
MaximumExecutionFrequency的所有参数:One_Hour
填写完这些参数后,点击橙色的下一步按钮。
-
在创建堆栈时点击初始的下一步按钮后,你将进入配置堆栈选项页面。只需点击页面右下角的橙色下一步按钮继续。
-
一旦进入审核页面,在页面底部,你需要勾选能力部分的框,确认堆栈可能会创建 IAM 资源。完成后,点击橙色的创建堆栈按钮,开始通过 CloudFormation 创建 Config 记录器和规则。
-
不到 5 分钟,资源应已创建完成,包括配置记录器、新的 S3 桶用于捕捉配置快照,以及一个专门用于 AWS Config 服务通知的 SNS 主题。
-
现在,在 AWS 管理控制台中间的搜索栏里搜索 Config 服务。当图标出现后,点击它进入该服务:
![图 20.20 – 从搜索结果中看到的 AWS Config 服务图标]()
图 20.20 – 从搜索结果中看到的 AWS Config 服务图标
-
从AWS Config仪表板开始,这是你进入该服务后看到的第一个屏幕,我们会立即看到我们的合规状态。在我们的 CloudFormation 模板中,我们自动启用了两条规则。这些规则在我的演示账户中已经显示符合合规要求。然而,如果你的根账户没有启用 MFA,那么它可能会显示你未遵守一个或多个 Config 规则。
![图 20.21 – AWS Config 仪表板上的合规状态]()
图 20.21 – AWS Config 仪表板上的合规状态
-
要查看我们当前在 AWS Config 中的规则,只需通过左侧菜单进入规则项。一旦点击此项,我们应该看到通过模板加载的两条规则的名称。
-
如果我们想查看 AWS Config 可以检查的我们账户中的资源,可以进入资源菜单项。加载完资源清单后,在资源类别的下拉菜单中,将选择项更改为AWS 资源。这将允许你查看 AWS 账户中 Config 可以跟踪的项目。
-
在任何这些资源上,点击蓝色的资源标识符按钮,将进入资源详情页面。如果你想查看资源随时间变化的时间线,请前往资源详情页面的右上角。这里,你会看到一个名为资源时间线的按钮。点击此按钮将打开时间线界面,显示资源随时间的变化。
我建议在你对账户中的不同资源进行一些更改时,可以将配置记录器保持开启一天左右。记得通过 CloudFormation 模板将配置记录器关闭;否则,你将承担 AWS Config 服务的费用。
现在我们已经学会了如何启动配置记录器并在 AWS 账户中启用一些规则,接下来让我们深入了解 AWS Config 提供的不同类型的规则。
配置规则结构
AWS Config 可以通过使用配置规则不断检查你的 AWS 资源是否符合合规要求。这些规则描述了你的资源应该如何构建的理想状态。
你可以使用配置规则来帮助确定你的环境和资源是否符合行业指南、内部最佳实践以及你需要执行的特定政策。
规则可以基于几种不同类型的触发器运行:
-
配置更改:当配置服务检测到资源发生变化时。
-
定期检查:配置服务按常规计划运行,例如每 3 小时或每 24 小时,检查资源是否发生变化。
托管规则与自定义规则
有许多 Amazon 已经设计好的预定义规则,可以用于许多常见的使用场景。这些规则可以检查资源,例如 EBS 卷是否已加密,或者某些端口是否已打开以允许流量通过。
这些托管规则可以通过额外的修复项进行自定义。
可以为任何需要检查和/或执行的资源或政策创建自定义规则。
通过使用托管规则和自定义规则,你可以自动地将你的组织保持在其期望的合规状态。
现在我们已经学习了如何使用 Config 和 SSM 来帮助保持我们的 AWS 账户合规,接下来让我们回顾一下本章所学的内容。
总结
在本章中,我们讨论了一些可以帮助简化 DevOps 角色中操作部分的工具。这包括 AWS Systems Manager,它本身提供了多种服务来帮助你完成任务。这些任务包括能够快速在远程实例上创建会话、创建可重复的流程、安装软件或从实例收集文件。我们还了解到,Systems Manager 可以与云中的计算实例以及本地服务器配合使用。
我们还研究了 AWS Config 服务。我们了解了它如何保留支持的 AWS 资源状态的时间线。我们还研究了 Config 规则的工作原理,以及它们如何用于标记不符合我们组织标准的资源。
在下一章中,我们将探讨使用 Amazon Inspector。这是一项帮助你主动发现账户中安全漏洞的服务。
问题
-
一家公司要求你配置 EC2 实例,以便它们可以通过 AWS Systems Manager 进行管理。该公司使用的是一种不同版本的 Linux 作为其基础的 Amazon Machine Image。哪些操作能确保一旦从该 AMI 启动实例,它能够在 Session Manager 控制台中找到?(选择两个答案)
-
将 Systems Manager Agent 安装为基础 AMI 的一部分。
-
创建一个名为
ssm-user的密钥对,并在启动实例时使用该密钥对。 -
确保实例所关联的任何安全组允许来自端口
22的流量。 -
为任何已启动的实例添加一个实例角色,该角色允许 Systems Manager 权限。
-
-
你正在为一家公司工作,该公司要求每周报告在两个区域内正在运行的 EC2 实例中使用的前五大操作系统。获取这些信息的最快且最具成本效益的方法是什么?
-
使用 Amazon Athena 收集关于所有运行实例的 CloudTrail 数据。创建一个 QuickSight 报告,显示每个区域前五大操作系统的图表和详细数据。将此报告分享给请求的相关人员。
-
确保所有实例具有允许 Systems Manager 服务访问的实例配置文件。使用 Systems Manager Inventory 创建一个报告,显示每个区域的前五大操作系统。
-
使用 EC2 实例控制台按操作系统对所有实例进行分组。从排序后的数据中创建报告。
-
创建一个 Lambda 函数,使用 CLI 调用所有 EC2 实例的操作系统类型。将此输出发送到 S3 存储桶,由相关人员下载。
-
-
一家电子商务公司的安全部门已执行一项新公司政策,规定任何 Web 流量不得通过不安全的 HTTP 或端口
80传输。任何之前允许通过端口80的流量,现在必须使用安全证书重定向到端口443。任何发现开放端口80的安全组将违反此新政策并立即暂停。定期监控是否有任何安全组允许流量进入端口80的最佳方法是什么?-
使用 Trusted Advisor 扫描已创建的非安全安全组。设置一个 SNS 主题,让 Trusted Advisor 可以发送通知。
-
向所有 VPC 添加一个网络 ACL 规则,阻止进入端口
80的流量。 -
使用 CloudTrail 日志来确定是否有任何安全组开放了端口
80。 -
在 AWS Config 中设置规则,检查是否有流量被允许通过端口
80访问任何安全组。如果发现安全组违反此规则,请向安全部门的 SNS 主题发送通知。
-
审查答案
-
a 和 d
-
b
-
d
第二十二章:使用 Amazon Inspector 检查您的环境
Amazon Inspector 允许您将安全测试作为开发和 信息技术(IT)运营的常规部分。随着 开发运营(DevOps)向 开发安全运营(DevSecOps)的转变,安全责任更多地由开发人员承担,使用像 Amazon Inspector 这样的工具可以帮助您采取更主动的安全态度来保护您和您组织的安全状况。
本章将涵盖以下主要内容:
-
了解 Amazon Inspector
-
手动和自动配置 Inspector 代理
了解 Amazon Inspector
Amazon Inspector 使您能够分析您的 Amazon Web Services(AWS)资源的行为,并帮助您识别潜在的安全问题。使用 Amazon Inspector,您可以基于 AWS 安全专家创建的数百条规则,针对您在 AWS 云中托管的所有或任何应用程序进行自动化评估。这些规则会寻找漏洞以及与最佳实践的偏差。执行评估后,Amazon Inspector 会提供一份详细的发现清单,并按严重性级别进行分类。该过程如图所示:

图 21.1 – Amazon Inspector 过程
在撰写本文时,Amazon Inspector 能执行的评估仅限于针对 Amazon 弹性计算云(EC2)实例的评估。
既然我们已经概述了 Amazon Inspector,接下来我们来看看如何开始使用 Amazon Inspector 服务。
开始使用 Amazon Inspector
要开始使用 Amazon Inspector,需要执行以下三个初始步骤:
-
在您希望 Inspector 扫描的 Amazon EC2 实例上安装 AWS Inspector 代理。
注意
为实例打上唯一标签是一个好主意和好做法,这样您可以将这些实例添加到特定的评估目标中进行评估运行。
-
创建评估目标,这是您希望 Inspector 检查的 AWS 资源的集合。
-
创建一个评估模板,作为您评估的蓝图。
-
在您的目标上运行评估。
-
审查您的发现并修复任何安全问题。
还有一些方法可以将其他 AWS 服务集成进来。您可以配置一个 简单通知服务(SNS)主题,当发布发现报告时,将通知发送到特定的电子邮件地址或分发组。您还可以设置 Lambda 函数,自动启动 Inspector 扫描,无论是定期使用 CloudWatch 事件,还是每当发生特定事件时,比如创建新的 Amazon Machine Image(AMI)。
我们刚刚了解了如何开始使用 Amazon Inspector,甚至对如何将一些其他 AWS 服务与 Inspector 评估结合使用进行了简要概述。接下来让我们看看 Amazon Inspector 的一些真实世界使用案例。
Amazon Inspector 的使用案例
公司们将 Amazon Inspector 作为独立服务使用,同时也将其集成到 DevOps 流水线中,以确保实例没有漏洞,特别是在生产环境中。
对于那些需要遵守健康信息可携带性与责任法案(HIPAA)准则或支付卡行业数据安全标准(PCI DSS)的公司,尤其是在受监管的行业中,扫描漏洞时,Amazon Inspector 的评估报告不仅提供了发现的漏洞列表,还可以通过对比过去的报告,显示修复的时间线。下图展示了 Inspector 如何在持续集成/持续部署(CI/CD)流水线中使用:

图 21.2 – Inspector 在 CI/CD 流水线中的应用
正如前面的图所示,Amazon Inspector 也可以作为漏洞评估添加到 CI/CD 流水线中,作为创建最终 AMI 之前的最后检查之一。这个最终 AMI 可以作为金镜像使用,或者作为应用程序的版本镜像。如果 Inspector 在这个流水线设置中发现问题,构建将失败,任何问题都需要修复后才能进入最终阶段,创建镜像。
现在我们了解了 Amazon Inspector 在现实世界中的应用,接下来我们看看如何安装 Amazon Inspector 代理,以便我们可以执行自己的评估。
手动和自动配置 Inspector 代理
run 命令功能可以自动将 Inspector 代理安装到我们希望 Inspector 服务检查漏洞的实例中。第三种方法是将一个简单的脚本集成到用户数据中,这样代理将在实例启动时被安装。这三种方法如以下图所示:

图 21.3 – 安装 Inspector 代理的三种方式
现在我们已经了解了如何安装代理,接下来我们将进行一个练习,通过启动一些实例并使用系统管理器安装代理。
实操使用 Amazon Inspector
在接下来的动手实践中,我们将同时启动两个实例,并为它们提供一个标签Inspector和一个值TRUE。由于我们将使用来自 Systems Manager 的run命令选项,因此我们需要一个身份与访问管理(IAM)角色,该角色允许访问我们的实例。好消息是我们之前在第十四章《CloudWatch 和 X-Ray 在 DevOps 中的作用》的练习中创建了这个角色。如果你没有完成这个练习,并且希望进行此操作,那么在开始这个练习之前,你需要回去创建这个角色。
我们将首先在我们的组中创建两个实例,其中一个将使用 Ubuntu 16.04 chapter 21 GitHub 存储库中的资源。再次安装 SSM 代理的脚本叫做agents.sh。
我们刚刚通过使用 Systems Manager run命令设置了 Amazon Inspector 代理,并进行了 Inspector 评估。接下来,我们将看到如何获取评估报告中的发现,如下所示:
-
打开终端,准备开始输入命令。确保在你正在使用的目录中,要么复制了你在第十四章《CloudWatch 和 X-Ray 在 DevOps 中的作用》中最初创建的
agents.sh脚本,要么从Chapter 21GitHub 文件夹下载了一个新的副本。我们将首先获取 AMIIMAGE参数:$IMAGE command echo. -
现在,使用当前存储在
IMAGE参数中的 AMI,我们可以开始创建第一个实例。使用以下命令创建实例:aws ec2 run-instances \ --image-id $IMAGE \ --instance-type t2.micro \ --iam-instance-profile 'Name=CW_SSM' \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=AmazonLinux},{Key=Inspector,Value=TRUE}]' \ --region us-east-2 -
现在,我们将获取 Ubuntu 实例的 AMI ID。这个命令与存储 Amazon Linux AMI 变量的命令很相似,但
names值不同。运行以下命令,以便我们将 Ubuntu AMI ID 存储在名为AMI的变量中,然后创建第二个实例:AMI='aws SSM get-parameters --names \ /aws/service/canonical/ubuntu/server/16.04/stable /current/amd64/hvm/ebs-gp2/ami-id \ --query 'Parameters[0].[Value]' --output text --region us-east-2' -
现在,就像我们创建第一个实例一样,我们将创建第二个实例。此命令中的两个值将发生变化——第一个值是
image-id值,第二个是name tag值。你还应该注意到,我们为这些实例添加了第二个Inspector标签,值为TRUE。使用下面显示的命令来创建第二个 Ubuntu 实例:aws ec2 run-instances \ --image-id $AMI \ --instance-type t2.micro \ --user-data file://agents.sh \ --iam-instance-profile 'Name=CW_SSM' \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=Ubuntu},{Key=Inspector,Value=TRUE}]' \ --region us-east-2 -
此时,两个实例应该都已启动并运行。我们现在可以切换到浏览器。登录到你创建实例的
Ohio区域。一旦进入Systems Manager服务,在左侧菜单的节点管理下,找到名为Run Command的子菜单选项并点击它。 -
现在,在主窗口中使用 AWS Systems Manager 的
run命令,点击橙色的run命令以安装 Inspector 代理。 -
我们现在应该在
Inspector页面,并按下回车键。这将打开名为AmazonInspector-ManageAWSAgent的run命令文档。请点击文档名称旁边的单选按钮,如下图所示:![图 21.4 – 安装 Inspector 代理的系统管理器运行文档]()
图 21.4 – 安装 Inspector 代理的系统管理器运行文档
-
一旦我们选择了文档,向下滚动页面,直到看到标题为
Inspector和TRUE,然后点击添加按钮,在我们的搜索中指定标签,如下图所示:![图 21.5 – 指定要通过我们的运行命令目标的实例标签]()
图 21.5 – 指定要通过我们的运行命令目标的实例标签
-
接下来,向下滚动到
系统管理器命令。如果你没有现成的 S3 桶,可以简单地取消勾选启用 S3 桶框,因为这一步是可选的。 -
向下滚动页面到底部,点击橙色的运行按钮。你将被带到命令状态页面,在那里你应该在目标和输出的状态部分看到进行中。大约一分钟后,你可以刷新命令状态页面,并应该看到两个实例的状态都显示为成功,如下图所示:
![图 21.6 – Inspector 代理成功安装在我们的实例上]()
图 21.6 – Inspector 代理成功安装在我们的实例上
-
安装好代理后,我们可以转到Amazon Inspector服务。在Amazon 管理控制台的顶部搜索框中,输入Inspector,然后点击出现的服务。当主Inspector页面出现时,点击蓝色的开始使用按钮。
-
你现在应该被带到一个页面,页面顶部有标题欢迎使用 Amazon Inspector。在评估设置下,取消勾选网络评估旁边的框,因为我们只想对我们的 EC2 实例进行评估。这将保留主机评估旁边的框被选中。页面底部,点击灰色按钮一次运行,而不是蓝色按钮。
-
当对话框弹出时,点击蓝色的确定按钮。
-
评估报告可能需要大约一个小时才能准备好。
我们现在已经了解了如何在不同操作系统上设置 Amazon Inspector 代理。接下来,在我们的评估运行后,我们将查看报告,并了解如何消化报告中的发现。
理解 Inspector 评估报告的发现
一旦 Amazon Inspector 完成评估,它将返回评估报告。报告中返回的任何发现将包含关于安全问题的详细描述,并附有如何修复该问题的建议。
你可以存储这些报告,并将其与团队成员共享,以便他们对报告中的问题进行修复。
总结
本章中,我们学习了 Amazon Inspector 及其如何扫描运行应用程序的实例,以查找漏洞。我们了解了三种安装 Inspector 代理的方式,甚至进行了动手操作,通过 Systems Manager 的 run 命令安装了 Inspector 代理。最后,我们讨论了 Amazon Inspector 返回的结果。
在下一章中,我们将介绍一些其他的策略和标准服务,这些服务对于认证考试以及实际应用都非常重要。包括 AWS GuardDuty 和 Macie 等服务,这些服务也可能出现在考试问题中。了解这些服务将有助于你在当前和未来的职位中取得成功。
复习问题
-
你被引入到一个公司,他们正在努力改善其安全性和合规性状况。安全和合规团队现在要求所有 EC2 实例必须使用批准的 AMI。作为一名 DevOps 工程师,你必须找到一种方法来实现一个流程,识别出任何从未经批准的 AMI 启动的 EC2 实例。哪个解决方案可以满足这些要求?
a. 使用 Trusted Advisor 检查来识别从未经批准的 AMI 启动的 EC2 实例。
b. 创建一个 AWS Config 规则,用于识别任何未经批准的 AMI,并向安全和合规的分发列表发送通知。
c. 使用 Systems Manager Inventory 创建一个自定义报告,列出所有使用未经批准的 AMI 的 EC2 实例。
d. 让 Amazon Inspector 扫描账户中的所有实例,并将未经批准的 AMI 发现结果与安全和合规团队成员共享。
-
你和你的团队正在生产环境中运行一个应用程序。该应用程序是使用 Elastic Beanstalk 构建和部署的,但运行在 EC2 实例上。你希望确保该应用程序没有任何漏洞;你应该实施哪个 AWS 服务来帮助实现这一目标?
a. AWS 可信顾问(Trusted Advisor)
b. AWS Web 应用程序防火墙(WAF)
c. AWS Shield
d. AWS Inspector
-
最近,公司进行了一次调查。在调查过程中发现,生产 AWS 账户的所有应用程序编程接口(API)调用都已关闭。还发现创建了一个新的管理员用户账户,并生成了一个访问密钥和一个密钥访问密钥。该密钥对多次用于创建超大 EC2 实例。你如何利用自动化检测和防止此类事件发生?
a. 使用 Amazon CloudTrail 创建一个新的 CloudTrail,监控禁用任何 CloudTrail 事件以及创建任何 API 密钥的操作,这些密钥属于 Amazon 管理的管理员策略。
b. 使用 Amazon Inspector 审查所有调用的 API。配置 Inspector 代理,以便在检测到 CloudTrail 的任何更改时使用 SNS 主题。如果触发规则,创建一个 Lambda 函数重新启用 CloudTrail。使用 IAM 权限边界防止启动任何超大型 EC2 实例。
c. 使用 AWS Config 创建一个配置规则,检测 CloudTrail 是否被禁用。如果触发规则,创建一个 Lambda 函数重新启用 CloudTrail。使用 IAM 权限边界防止启动任何超大型 EC2 实例。
d. 使用可信顾问 API 定期检查 CloudTrail 是否已被禁用。如果触发规则,创建一个 Lambda 函数重新启用 CloudTrail。使用 IAM 权限边界防止启动任何超大型 EC2 实例。
审查答案
-
b
-
d
-
c
第二十三章:其他需要了解的政策与标准服务
还有许多其他服务也被纳入到 DevOps 专业认证考试中,涉及政策和标准的领域。这些服务在 AWS 生态系统中扮演着特定的角色,了解它们的使用案例以及适用场景,有助于为特定组织解决问题。尽管这些服务都很重要,我们将在此简要回顾它们。
本章我们将涵盖以下主要内容:
-
使用 GuardDuty 检测威胁
-
了解如何使用 Amazon Macie 保护数据
-
了解服务器迁移服务
使用 Amazon GuardDuty 检测威胁
Amazon GuardDuty 为您提供了一种新型的威胁检测服务,专门为云环境而设计。GuardDuty 会持续监控来自一个或多个账户的源数据流,并不断分析这些源中被驱动到 GuardDuty 服务中的网络和账户活动。GuardDuty 服务利用威胁情报、行为模型和机器学习相结合,智能地检测您的环境中的威胁:

图 22.1 – 从启用到采取行动的 GuardDuty 流程
从上述图示中,我们可以看到,在您的账户中启用并运行 GuardDuty 只需要几个简单的步骤:
-
启用 GuardDuty 服务 – 激活 GuardDuty 服务后,系统将开始分析您账户中的多种日志类型:VPC 流日志、DNS 日志条目和 CloudTrail 事件。
-
持续分析传入的事件 – GuardDuty 服务不断查看来自各种数据源的数据,尝试检测您 AWS 环境中是否存在未经授权或意外的活动。这些数据源包括 AWS CloudTrail 事件日志、CloudTrail 管理事件、CloudTrail S3 数据事件、VPC 流日志和 DNS 日志。
-
智能检测账户中的威胁 – GuardDuty 使用多种机器学习算法来处理其收集的数据,然后持续分析这些数据。这些数据将被分类为 EC2 发现、S3 发现和 IAM 发现等不同类型的报告结果。
-
对呈现的威胁采取行动 – 一旦找到威胁,GuardDuty 会提供威胁所在位置的详细信息,以便您或团队成员采取措施。威胁可能存在于特定的 EC2 实例、S3 存储桶,或 IAM 用户或组中。
关于 GuardDuty 需要理解的关键信息
在准备 DevOps 专业认证考试时,尽管 GuardDuty 服务可能不是考试中的主要服务,但它可能出现在某个问题或答案中。在这些情况下,理解该服务及其功能是有帮助的。
GuardDuty 拥有多个检测类别,包括以下几类:
-
Reconnaissance – 显示潜在攻击者或异常的 API 活动或端口扫描,或多次失败的登录请求等活动。
-
Instance compromise – 包括加密货币挖矿、恶意软件活动,甚至是外部拒绝服务攻击等异常活动,这些活动都被 GuardDuty 服务归类到此类别。
-
Account compromise – 如果您的账户尝试关闭 CloudTrail 日志记录,则属于账户泄露类别。如果有来自全球各地的尝试登录,而这些登录地点不符合账户基线,也会被归为此类别。
-
S3 桶泄露 – 包括诸如凭证滥用、未经授权的 S3 桶访问(来自没有历史访问该桶的用户或 IP 地址),甚至是来自已知恶意 IP 地址的桶访问;所有这些信息通过 CloudTrail API 调用收集。
GuardDuty 允许您的安全团队和其他系统管理员使用 IAM 访问分析器,帮助他们识别您账户内可以从外部访问的资源。
在 GuardDuty 服务提供的发现操作中,有许多细节可以帮助您和/或您的安全团队解决该情况。以下是一些细节:
-
CreateThreatIntelSet – 授予创建 GuardDuty ThreatIntelSets 的权限。
-
CreateDetectory – 授予创建 GuardDuty 检测器的权限。
-
GetFindings – 允许 GuardDuty 检索发现的内容。
-
StartMonitoringMembers – 允许 GuardDuty 管理员监控成员账户。
作为一名 DevOps 专业人员,您也能够提升技能,理解安全集成和您可以轻松使用的安全工具。
接下来,让我们看看 Amazon GuardDuty 的一些使用案例。
Amazon GuardDuty 的使用案例
现在我们已经了解了 GuardDuty 服务的能力,接下来可以看看一些使用 GuardDuty 合理的潜在用例。
您怀疑内部员工或外部用户可能正在公司账户上进行加密货币挖矿。
Amazon GuardDuty 可以通知您,您组织中任何账户上的 EC2 实例是否已联系与比特币网络或其他加密货币相关活动的 IP 地址。同样,GuardDuty 也能检测实例是否尝试通过与加密货币活动相关的 DNS 名称来引导互联网流量。
重要提示
如果您或您的组织正在合法地挖掘加密货币或从事与此活动相关的合法业务,可以通过 GuardDuty 服务抑制这些特定规则,以避免收到不适用于您组织的警报。
您的 S3 存储桶中存储了各种数据,或者您正在使用 S3 作为数据湖的存储解决方案。
Amazon GuardDuty 有一类特别的 S3 保护,它会执行这些保护操作,一旦启用,它将监控您账户中的所有存储桶。在监控 S3 使用的访问模式时,您无需采取额外步骤,例如为任何或所有 S3 存储桶启用 S3 日志记录,因为 GuardDuty 通过使用 CloudTrail 监控在 API 层级发生在不同 S3 存储桶上的操作。
了解 Amazon GuardDuty 在现实世界中的应用是回答 DevOps 专业考试中关于该服务问题的关键。接下来,我们将看看 GuardDuty 服务如何与 AWS 上的另一个关键安全服务——Security Hub——相结合。
Amazon GuardDuty 与 AWS Security Hub 自然集成。
当尝试全面了解您 AWS 环境的安全状态时,AWS Security Hub 是一项可以为您提供该视图的服务。Security Hub 会收集您管理的不同账户中的数据,以及这些账户中运行的不同服务。AWS Security Hub 还支持来自合作伙伴的第三方集成,如 Cloud Custodian、Check Point、IBM 的 QRadar、CrowdStrike Falcon 等。合作伙伴集成的完整列表可以在这里找到:docs.aws.amazon.com/securityhub/latest/userguide/securityhub-partner-providers.html。
一旦启动,Security Hub 会开始获取、组织,甚至优先排序来自其他 AWS 安全服务(如 Amazon GuardDuty、Amazon Inspector 和 Amazon Macie)的发现。使用 Security Hub 还允许账户持有者优先处理针对账户发现的事项,以便首先处理最脆弱的项目。
需要注意的是,在 Security Hub 控制台上,事件的检测和整合只有在您启动 Security Hub 服务后才会发生。启动服务之前发生的任何事件不会被收集,因此这些事件不会生成发现记录。
通过启用 AWS Security Hub 控制台并结合 GuardDuty 服务,GuardDuty 的发现不仅会发送给安全团队,而且任何被授予使用 Security Hub 服务 IAM 权限的人都能看到。这有助于问题的可见性和责任的分配。
现在我们已经了解了 AWS Security Hub 和 Amazon Guard Duty 如何协同工作来帮助保护您的账户,接下来我们将讨论 Amazon Macie 服务如何持续工作以帮助保护您的数据。
了解如何使用 Amazon Macie 智能地保护数据
对于那些正在迁移到云端或在过去几年已经建立云端存在的组织来说,数据快速积累。我们在第十七章《高级与企业日志记录场景》中讨论了拥有良好的数据卫生系统的重要性,包括标签和元数据。尽管这是最佳解决方案,但并非总是可行。您创建、获取和积累的数据可能会涉及多个敏感度和分类级别。一旦超越公共级别,未经授权访问该数据可能会被视为安全泄露:

图 22.2 – 数据分类级别示例
并非每个组织都会花时间对存储在云中的信息进行分类和归类。这可能导致许多内外部漏洞。从内部角度看,允许内部用户访问他们不应接触的数据,可能使组织面临暴露风险,因为这些用户可能没有接受过适当的网络安全培训,或者无意中将恶意软件带入系统,进而使这些恶意软件能够访问更高分类级别的数据,甚至是因为内部用户有恶意意图。
Amazon Macie 是 AWS 提供的完全托管的数据隐私与安全服务,利用机器学习和模式匹配技术。这有助于 Macie 即使在没有任何标签的情况下,也能发现账户中的敏感数据。然后,它通过向您展示发现的列表来帮助保护这些数据。
还可以使用预定的模式,通过 Amazon EventBridge,使 Macie 将所有发现结果发送到 EventBridge,然后,利用事件驱动架构,EventBridge 中的规则可以触发 Lambda 函数,自动处理这些发现。
Amazon Macie 为您提供关于发现和保护账户中的数据的四个主要功能:
-
您可以提高数据的可见性和评估能力,因为 Macie 会执行以下操作:
a. 它将评估您账户中的 S3 存储桶清单。
b. 它将评估您账户中 S3 存储桶的策略。
完成后,它将提供一个总览,展示存储桶的总数量、对象的总数、对象的存储大小,并概述这些对象和存储桶的策略。启用 Macie 服务后,任何这些策略的变化都会及时通知您。
-
它允许您发现敏感数据。
-
您可以集中管理所有账户中的数据。
-
它具有基于发现结果添加自动化的能力。
一旦设置了 Amazon Macie,它允许你设置警报。这些警报会在 Macie 服务发现潜在安全问题时通知你。Macie 服务会发送两种不同级别的警报:基本警报和预测警报。基本警报是 Macie 在执行安全检查时生成的警报类型。预测警报是基于 Macie 服务为你的账户确定的基线,并根据账户中正常活动的偏差来发送的警报。
当 Amazon Macie 服务发送警报时,它会分配四个安全级别之一。
需要注意的是,Amazon Macie 是一个区域性服务。这意味着你需要为每个希望利用其扫描和保护能力的区域启用 Macie。
开始使用 Amazon Macie 相当简单。你只需进入 AWS 管理控制台,然后导航到 Amazon Macie 服务。
Amazon Macie 的使用案例
在继续研究 Amazon Macie 服务时,探索使用该服务的企业和公司不同的使用案例将帮助我们更好地理解 Macie 服务带来的价值。
评估组织的数据隐私和安全
如果你的组织目前不知道存储数据的分类级别,或者没有现有的数据分类基准,那么使用 Amazon Macie 服务可以查看指定账户中是否存储了任何敏感数据,并允许你采取适当的措施。
知道敏感数据何时被放入你的数据存储中
即使你已经在账户中建立了数据存储的基线,允许 Macie 服务持续监控账户中新存储的任何数据,也能在敏感数据被添加时提供警报。如果将 Macie 与安全中心服务结合使用,这尤其有用,因为它可以为创建的任何新警报添加优先级。
在回顾一些可能出现在 AWS DevOps 考试中的其他安全工具后,我们接下来将探讨另一项服务——服务器迁移服务(SMS)。
简要了解 AWS 提供的迁移工具
许多组织仍处于云迁移的初期阶段。然而,当他们查看当前数据中心即将到期的合同时,迫切需要加快退出速度。如今,许多公司运行工作负载的方式不再是裸金属服务器,而是虚拟化的服务器集群,使用 VMware 或 Microsoft Hyper-V 等流行的软件产品。
意识到需要帮助客户快速、轻松地迁移到云端,Amazon 创建了 SMS。
该服务帮助应对将当前工作负载迁移到云端时所面临的许多挑战。
将你的服务器通过 SMS 引入 AWS
SMS 帮助简化了将多个服务器迁移到 AWS 云的过程。
使用 SMS 可以帮助你实现以下目标:
-
它帮助简化了云迁移过程。
-
它允许你协调多服务器的迁移。
-
它最大限度地减少了迁移过程中的停机时间。
-
SMS 支持最常用的操作系统,包括 Windows 操作系统以及许多主要的 Linux 发行版。
-
它允许你逐步测试服务器迁移。
虽然最初是为 VMware 场景设计的,但现在 SMS 适用于 VMware vSphere、Microsoft Hyper-V 和 Microsoft Azure 迁移。这些迁移是通过无代理迁移来执行的。
现在我们已经理解了 AWS SMS,接下来我们来看看需要了解的关键特性,包括实践中的要点和考试中的要点。
将工作负载迁移到 AWS 有几种不同的选项。包括需要安装代理的 CloudEndure 产品;还有 Import/Export 服务,其中包括像 Snowball 服务这样的 Snow 家族实例;然而,这些服务更适合用于将大量数据迁移到 AWS 云中。
SMS 的主要使用场景是当你在 VMware、Microsoft Hyper-V 或 Azure 上有多个工作负载,并且无法安装代理或不想安装代理来执行迁移时。
什么时候应该使用 SMS?以下是使用 SMS 的最佳时机:
-
如果你需要迁移到 AWS,但需要执行无代理迁移
-
如果你需要一个符合HIPAA资格标准的迁移解决方案
-
如果你需要一个符合联邦风险与管理计划(FedRAMP)合规性的迁移解决方案
-
如果你需要能够自动启动迁移后的虚拟机
-
如果你希望在迁移过程中有选择使用Amazon 机器镜像(AMIs)或 CloudFormation 模板作为输出选项
现在我们已经理解了 SMS 的好处,并了解了哪些使用场景最适合它,接下来我们来看看需要记住的关于 SMS 的关键特性。
SMS 的关键特性
以下是关于 SMS 的一些关键特性:
-
SMS 允许你将 VMware、Microsoft Hyper-V 或 Microsoft Azure 虚拟机自动迁移到 AWS 云。
-
SMS 允许你逐步将虚拟机复制为 AMIs。
-
使用 SMS,你可以将一组服务器作为一个具有多个层和相互依赖的单一应用程序迁移,例如 Web 层、数据库层和应用程序层。
现在我们已经理解了关键特性,让我们看看如何迁移一个由多个层组成的应用程序。这包括数据库层、文件服务器层、Web 层和应用程序层。
使用 SMS 迁移多层应用程序
由于 SMS 是无代理的,因此需要下载并安装一个特殊的镜像(对于 VMware 的情况是 开放虚拟化设备 (OVA)),这个镜像被称为连接器。在环境中安装连接器后,你需要创建一个具有正确权限的 vCenter 用户,该用户可以在选定的虚拟机上创建和删除快照。
包含多个应用层的服务器可以作为单个 AMI 进行复制,或者它们可以被细分为更小的子组,创建多个 AMI。如果你确实将一个较大的应用程序细分,那么 SMS 可以创建相应的 CloudFormation 模板,以协调的方式启动这些 AMI:

图 22.3 – 一个 SMS 任务启动顺序的示例
理解 SMS 无法将所有内容迁移到 AWS 是非常重要的。这到底是什么意思呢?这意味着,虽然大部分工作负载可以复制到 AWS 并转换为 AMI,但你仍然需要为这些实例创建底层基础设施。
总结
本章中,我们讨论了可能出现在 DevOps 专业考试中的其他相关服务,重点是安全性和策略服务。这包括了解 Amazon GuardDuty 和 Amazon Macie 服务,以及它们如何与 AWS 组织在区域基础上合作,保护你的资产和账户免受寻找漏洞的恶意行为者的攻击。我们还考察了 SMS。了解这个服务很有用,因为随着公司加快从当前数据中心迁移到云的步伐,一旦工作负载进入云,更新这些工作负载的能力就开始依赖像你这样的 DevOps 专业人员。
在下一章中,我们将讨论 DevOps 专业认证考试的结构。我们将讨论可用的考试形式,并讲解考试大纲。我们还将给出一些学习和通过考试的建议。
复习问题
-
你被引入到一家希望开始为其构建实施 CI/CD 的公司。这家公司最近进行了安全态势分析评估,需要确保任何实施的解决方案都是安全的。如果在实施后发现任何漏洞,就需要有一个修复计划,并且必须采取措施解决漏洞。
-
在 AWS CodePipeline 中设置好管道构建后,你还可以采取哪些进一步的步骤来确保在构建过程中创建的 S3 存储桶没有底层访问权限?
a. 每 15 天,使用 Trusted Advisor 服务检查并查看 S3 存储桶是否存在格式错误的存储桶策略。如果 S3 存储桶出现在易受攻击访问列表中,则创建一个存储桶访问策略,仅允许 CodePipeline 服务账户访问该存储桶。
b. 为 S3 桶启用日志记录。为新创建的 S3 桶添加版本控制。在桶上创建一个 CloudWatch 警报,监控桶的访问量。如果桶的访问量超过 AWS CodePipeline 运行的构建作业数量,则触发警报。为对象添加 AWS Key Management Service(KMS)的对象级加密。
c. 为 S3 桶创建一个桶策略,只允许来自账户本身和运行管道的服务账户的访问。为对象添加 KMS 的对象级加密。
d. 为 S3 桶启用日志记录。启用 GuardDuty 服务。如果检测到问题,按照 GuardDuty 服务提供的修复步骤进行处理。为对象添加 KMS 的对象级加密。
-
你所在的公司刚开始允许合作伙伴公司访问发布在一些特定 S3 桶中的订阅数据。访问是通过跨账户访问提供的。由于这是一个新的服务,并且预计将成为公司依赖的新收入来源,如何确保只有通过订阅被授予访问权限的合作伙伴能够获取这些数据?你的解决方案应该易于维护,且工作量最小:
a. 为所有区域启用 CloudTrail。为桶创建 CloudWatch 警报,警报条件为访问量超过客户数量乘以 30。创建一个桶访问控制列表(ACL),阻止没有当前客户的国家范围。
b. 为所有区域启用 CloudTrail。启用 GuardDuty。将当前客户添加到访问白名单中。每周审查 GuardDuty 的发现,确保没有未经授权的访问权限。
c. 为 S3 桶启用日志记录。启用高级 Trusted Advisor 检查。每周审查 Trusted Advisor 的检查结果,确保没有未经授权的访问权限。
d. 为 S3 桶启用日志记录。启用高级 Trusted Advisor 检查。创建一个桶 ACL,阻止没有当前客户的国家范围。
-
你刚刚加入一家公司,该公司正在将大量工作负载从当前数据中心迁移到 AWS 云中。他们当前在数据中心的工作负载运行在 VMware vSphere 上。数据中心中的这些工作负载包括 Windows Server、Red Hat Linux 和 Ubuntu Server,需要迁移到 AWS。公司有 400 至 500 台服务器,并且有严格的截止日期,因此不希望在每个虚拟机上安装代理。公司还希望在迁移过程中能够逐步进行测试。哪种工具可以帮助你实现公司的所有目标?
a. 登录到 AWS 管理控制台并订购一个 Snowball,以便可以将工作负载安全地下载到 Snowball 硬件上。Snowball 运回 AWS 后,下载数据并从下载的数据创建 AMI。
b. 使用 AWS CloudEndure 来发现需要迁移到 AWS 云的实例。创建迁移任务以开始将实例复制到指定的 AWS 区域。
c. 登录 AWS 管理控制台并使用 SMS 启动任务。在本地服务器上创建目录。创建并配置你的迁移任务。跟踪并测试你的迁移。
d. 确保你已经在计划进行迁移的机器上安装了 AWS CLI。使用 VM 导入/导出服务将虚拟机推送到 Amazon S3 服务。根据上传的镜像创建 AMI。
审核答案
-
d
-
b
-
c
第五部分:考试技巧与窍门
在这一部分,我们将介绍考试的结构、六个评分领域、学习技巧和学习指南。
本书的这一部分包含以下章节:
-
第二十三章,DevOps 专业认证考试概述
-
第二十四章,模拟考试 1
第二十四章:DevOps 专业认证考试概述
希望到你阅读到本章时,你已经对我们到目前为止覆盖的大量内容有了扎实的理解,这些内容都可能出现在DevOps 专业认证考试中。一旦你准备好参加考试,你必须注册考试并会收到指定的考试时间。
本章将涵盖以下主要主题:
-
DOP-CO1 考试指南
-
考试的评分标准
-
理解不同的测试选项
-
考试准备的学习技巧
DOP-C01 考试指南
每个当前提供的 AWS 认证都会发布考试指南。这是通过考试的成功蓝图。它解释了考生在参加考试前应具备的期望经验和要求。它还列出了考试中将涵盖的主题(或领域)。如果你想查看当前的考试指南,可以通过以下网址访问:d1.awsstatic.com/training-and-certification/docs-devops-pro/AWS-Certified-DevOps-Engineer-Professional_Exam-Guide.pdf。
根据考试指南的考试要求
在参加 DevOps 专业认证考试之前,建议你有 2 年或更多使用 AWS 平台的经验,能够配置、操作和管理 AWS 环境。你还应具备自动化基础设施和使用基础设施即代码(最好使用 CloudFormation 模板)构建系统的经验。你需要精通管理现代操作系统,如 Windows 和 Linux。最后,建议你对现代开发与运维流程以及构成这些流程的方法论有扎实的理解。
AWS 还会说明哪些内容不在考试范围内。这一点很有帮助,因为认证团队会告诉你哪些内容不需要在学习中集中精力。以下主题不在考试范围内:
-
高级网络(高级路由算法、故障转移技术)
-
面向开发者的深度安全建议
-
数据库查询与性能优化
-
全栈应用程序代码开发
-
数据模式的规范化
现在我们已经了解了 AWS 对我们的期望,作为候选人,关于要求方面,让我们来看看考试是如何评分的。
考试评分标准
AWS 认证考试分为多个领域。虽然这些领域有不同的评分标准,但掌握所有领域非常重要,因为错过一两个问题可能意味着通过与失败之间的差距。考试中有两种类型的问题:
-
多项选择题:这些问题有一个正确答案。
-
多选题:这些问题有两个或更多正确答案。
对于多选题,不能给予部分分数。你必须选择所有正确的答案才能获得该题的分数。另外,未回答的问题将视为错误答案。这意味着你最好选择一个答案,而不是留下空白。

图 23.1 – DevOps 专业认证考试的六个领域
考试本身持续 180 分钟或 3 小时,共有 80 道题目。这意味着你每道题目大约有 2 分钟的时间来阅读、理解并作答。接下来我们将更详细地探讨六个领域:
-
领域 1:SDLC 自动化 – 22%:本部分的考试内容集中在 CI/CD 流水线、源代码管理、测试和工件存储/管理上。这些问题可以测试你如何设置和配置代码库,以及如何自动化多阶段的部署流水线。你还需要了解如何在代码库中处理更改或新提交,并将安全实践与 代码版本控制系统(CVS)结合。
在领域 1 中,你还需要接受测试,评估你在代码流程中添加和运行集成测试的能力。这包括根据测试结果决定流程是通过还是失败。一旦你的代码通过测试,你需要能够以安全的方式创建并存储工件。你还需要具备根据需求选择正确的交付策略的能力,例如根据业务需求选择蓝绿部署、金丝雀部署或 A/B 测试策略。
-
领域 2:配置管理与基础设施即代码 – 19%:在领域 2 中,你将被测试评估根据部署的需求和要求来确定不同服务的部署能力。你还需要了解如何使用生命周期钩子来优化实例的启动和关闭。此外,本领域还包括识别不同配置管理工具的优缺点,并展示如何自动化运行配置管理的能力。
-
flumd,或其他工具。你还需要了解如何管理日志存储,例如将日志从 CloudWatch 迁移到 S3,使用 S3 生命周期淘汰旧日志,甚至通过 S3 事件触发事件驱动的操作。本领域还包括创建自定义 CloudWatch 指标和日志订阅过滤器的过程。 -
领域 4:政策和标准自动化 – 10%:通过自动化手动流程来实现成本优化是领域 4 的主要主题之一。领域 4 的另一个主要主题是实施治理策略的能力。这包括使用自助服务产品(如服务目录)来执行合规性,并对组织的合规性进行报告的能力。
-
Route53服务用于在区域故障时将流量引导到另一个区域。 -
领域 6:高可用性、容错性和灾难恢复 – 16%:这个最后的领域将评估你是否需要将服务部署到多个区域或多个可用区。你还需要评估组织 RTO(恢复时间目标)和 RPO(恢复点目标)要求所需的正确服务。你还需要能够评估一个部署中的潜在故障点。
注意
考试中有 10 个问题不影响你的分数,你不会知道这些问题是哪些。这些问题用于收集性能指标,以便在未来的考试中使用。
获取通过分数
DevOps 专业认证考试是一个通过或不通过的考试。一旦你按下最终提交按钮,考试将会被评分,并且你会被通知是否通过或未通过。考试的评分标准为 1,000 分,你需要至少 750 分才能通过考试。具体分数是这样计算的:在 70 道有效问题中(记住,10 个问题不计入分数),你需要正确回答 53 个问题才能通过考试。这个评分系统并不是全部,因为有些领域比其他领域更重要。换句话说,你在整场考试中最多只能错 17 道题。
AWS 稍后会通过电子邮件向你发送一份详细报告,说明你在六个领域中的得分情况。这个报告也会在你的Certmetrics账户中的“历史考试”部分查看。
现在我们已经了解了通过考试所需的条件,接下来简要讨论一下如果你第一次尝试没有通过,应该怎么办。
如果你第一次考试没有通过
如果在提交考试后看到令人沮丧的“不通过”字样,不要担心,一切并未失去。每次考试之间有强制性的 14 天等待期,并且你需要支付相应费用才能重新参加考试。现在,考生参加考试的次数没有限制。
其中一个关键步骤是把一张纸放在身边,无论你是在考试地点参加现场考试,还是选择在线监考方式后,都要在考试结束后找到一张纸。写下你觉得自己准备不足的主题。这是一个立即记录自己在考试中感觉没有准备充分的主题的机会,趁记忆还新鲜。如果不采取这一立即行动,等你回过头来回想那些需要集中精力的领域时,可能会后悔没有及时记录下来。
在重新学习材料后,承诺在短时间内再次参加测试。这一点非常关键。虽然不必直接在强制性 14 天等待期后立即参加,但最好不要超过 60 天。你已经花时间和精力准备初次考试,现在你对实际的考试题目有了更清晰的了解。此时,你会收到来自 AWS 的成绩单,显示你在六个领域的得分,并指出你在测试过程中的优缺点。不要犯错,忽视那些你得分高于其他人的话题。认证考试包含大量题库,连续出现相同问题的情况较为罕见。
理解不同的测试选项
AWS 已经开始提供多种选择来参加考试。你不仅可以选择在考试中心进行考试,还可以选择在家里舒适的环境中,通过在线监考考试,无需外出。让我们来看一下这两种选择,因为每种方式都有其优缺点。
注册参加考试
当你觉得自己对考试中将呈现的材料有了扎实的理解时,是时候注册考试时间了。要注册,你需要访问aws.training网站,如果你已有账户,请登录,或者创建一个新账户。

图 23.2 – aws.training 欢迎界面,用于安排你的认证考试
一个好的做法是在你觉得自己准备好考试时,大约提前两周安排考试。使用这种方法可以让你清除周围的所有最终干扰,因为你知道自己有一个必须遵守的硬性截止日期。如果你一直等到完全有信心时再安排考试,可能会导致在安排时的犹豫。
注意
如果你是非英语母语者,你可以获得额外的 30 分钟考试时间。然而,在安排考试之前,你必须通过 AWS 培训网站上的 certmetrics.com 部分申请此特别安排。点击即将举行的考试顶部菜单项后,你可以在此处申请考试特别安排。

图 23.3 – 下拉菜单显示为英语非母语者添加 30 分钟考试时间的选项
如果你无法按预定日期参加考试,你可以提前最多 24 小时取消,且不受任何处罚。如果你没有在此提前窗口内取消考试而错过了考试日期,则需要 forfeiture 考试费用,但不会算作考试失败。
现在我们已经了解了考试的基本流程,让我们来看看在测试中心和使用在线监考在远程地点考试之间的一些区别。
在测试中心参加考试
测试中心允许考生在现场参加认证考试,这些中心由 PSI 或 Pearson VUE 运营。你可以在附近搜索本地测试中心,并查看可用的考试时段。有时,你需要提前一周或更长时间预约,因此,随着你准备好参加考试,开始查看你所在地区的可用时段,并了解需要提前多久预约考试。
在安排考试的日期和时间后,你需要在预定时间前几分钟到达测试中心,以便进行签到并入座。最好准备一份 AWS 发送的邮件打印件,邮件中会指定你的考试确认号码,或者将该邮件保存在你的智能手机中,以防万一在系统中找不到你的名字和考试信息。签到时,你需要提供两种身份证明,其中一种必须是政府颁发的身份证件,另一种可以是学校 ID 卡或信用卡等。
在进入考试区之前,你将被要求清空口袋,脱掉多余的外套、手机、帽子、太阳镜、钢笔或其他不允许带入测试室的物品。测试中心会为你提供一个储物柜和锁具,你可以将物品存放在里面,考试期间使用。考试中心还会提供铅笔和 2-3 张空白草稿纸。考试结束后,你需要将所有草稿纸归还。
通过在线监考方式参加考试
如果附近没有可供考试的 Pearson VUE 或 PSI 中心,或者你觉得在自己熟悉的环境中考试会更舒服,你可以选择通过在线监考方式使用你的电脑参加考试。
如果你选择这种方式,你需要在你的计算机上安装 OnVUE 软件,以便远程监考人员在你参加考试时能够监控你的系统。最好在考试开始前几天(至少几小时)进行安装,以确保你计划使用的计算机符合所有要求,并且 OnVUE 软件可以进行系统测试。
你将参加考试的空间不仅需要整洁,还需要干净。这意味着你必须移除考试区域内的所有笔记、纸张和其他物品。考试区域内也不允许有食物或吸烟,但 Pearson VUE 网站表示允许携带任何容器的饮料。如果你的桌面上有多显示器设置,那么在考试期间这些额外的显示器必须拔掉。同样,任何在考试区域内的额外计算机或智能设备也需要移除。
在你预定考试时间的前 30 分钟,你需要使用提供的链接拍摄你考试区域的照片,以验证该区域是一个干净的环境。你还需要发送一张政府颁发的身份证照片,以确保摄像头中的人就是你本人在参加考试。
一旦开始考试流程,你不能使用手机。这样做会导致你的考试被取消。此外,离开摄像头视野也会被视为违规。考试开始时,监考员会注意听你周围环境中的噪音变化。这包括大声朗读问题或低声嘟囔,试图更好地理解问题。如果他们发现你发出噪音,你将收到警告;多次警告可能导致你的考试被取消。
这些最后几点是在线考试和在考试中心考试之间的两个主要区别之一。另一个主要区别是,在在线考试中心,你会获得 2-3 张纸和一支铅笔,在考试过程中做笔记。这与必须使用鼠标或触控板操作的虚拟白板形成了鲜明对比。
还有一个通常不会被提到的选择,那就是在 AWS re:Invent 大会上参加认证考试。
在 re:Invent 上参加认证考试——一则警示故事
如果你有机会参加 re:Invent 大会,我建议你至少去一次,体验一下。当你到达现场时,会有比早期更强烈的动机,促使你认证并进入认证休息区。在这种环境下参加认证考试与其他任何地方都不同。会议室里摆满了电脑屏幕,旁边挤满了人,大家安静地盯着自己正在做的测试。当你专注于考试时,不禁会看到其他人一遍遍地站起来坐下。这会分散注意力,有时你会不禁想,他们是否在做和你一样的考试,如果是,他们怎么能这么快完成。
当你报名参加 re:Invent 大会的考试时,可能不会想到的是,现场有许多课外活动,尤其是在晚上,很多时候伴随着一两杯酒。这可能会让你分心,无法静下心来进行最后的复习准备。如果你把考试安排在早晨,这种情况可能会导致你感到没有足够的精力。
鉴于我们已经讨论了参加实际认证考试的不同选项,现在让我们集中讨论一些考试的学习技巧,以优化你的成功机会。
准备考试的学习技巧
虽然我们在本书中覆盖了大量的内容,但通过认证考试需要学习和自律。经过多次参加并通过或未通过 AWS 考试后,积累的一些小贴士可以传递给你,帮助你尽可能提高成功的机会。
关于考试需要注意的第一点是,它不仅是对 AWS 服务和知识的考察,更是对阅读和理解能力的考验。匆忙浏览问题和答案可能会错过关键信息,从而导致错失问题。尽管你每道题目只有大约两分半钟的时间来阅读、理解和回答,但每道题都必须仔细阅读,以确保抓住正确的细节和要素。我发现,练习阅读这种大篇幅的问题格式是成功的关键之一。专注于这种长格式考试尤其有帮助,特别是当你抬头看到计时器时,发现剩下的时间已经不多,而你还有几道题需要回答。
AWS 白皮书阅读推荐
许多考试中的问题都是基于 AWS 多年来编写的白皮书。我强烈建议阅读这些白皮书,以更好地理解本书中介绍的主题。部分内容应有助于加深对本章及其动手练习所用内容的理解。其他内容则会深入探讨考试中涉及的一些话题。还有一些问题将直接源自白皮书的背景:
-
基础设施即代码: https://d1.awsstatic.com/whitepapers/DevOps/infrastructure-as-code.pdf
-
AWS 上的 DevOps 入门: https://docs.aws.amazon.com/whitepapers/latest/introduction-devops-aws/introduction-devops-aws.pdf
-
在 AWS 上构建日志分析解决方案:
d1.awsstatic.com/Projects/P4113850/aws-projects_build-log-analytics-solution-on-aws.pdf -
AWS 上的蓝绿部署:
docs.aws.amazon.com/whitepapers/latest/blue-green-deployments/blue-green-deployments.pdf -
使用 AWS Lambda 的无服务器架构:
docs.aws.amazon.com/whitepapers/latest/serverless-architectures-lambda/serverless-architectures-lambda.pdf -
在 AWS 上运行容器化微服务:
d1.awsstatic.com/whitepapers/DevOps/running-containerized-microservices-on-aws.pdf -
在 AWS 上实践持续集成和持续交付: https://d1.awsstatic.com/whitepapers/DevOps/practicing-continuous-integration-continuous-delivery-on-AWS.pdf
-
AWS 大规模治理: https://d1.awsstatic.com/whitepapers/Security/AWS_Governance_at_Scale.pdf
-
基础设施事件准备: https://d1.awsstatic.com/whitepapers/aws-infrastructure-event-readiness.pdf
-
操作卓越支柱(AWS Well Architected Framework):
docs.aws.amazon.com/wellarchitected/latest/operational-excellence-pillar/wellarchitected-operational-excellence-pillar.pdf
虽然这看起来是大量额外的阅读内容,但需要再次强调的是,许多问题来源于白皮书。获得必要的知识并理解其背景,将帮助你在阅读考试中提出的复杂问题时更加得心应手。
最后的考试提示
这次考试本身很长,持续时间为 3 小时。特别是如果你在早上参加考试,我建议你不要喝太多咖啡。记住,如果你正在进行在线监考,你不能离开摄像头的视野。在开始考试之前,最好先去一趟厕所,这样你就可以全神贯注地参加考试。
不要在标记大量问题以待复查时过于怀疑自己。大多数情况下,你的初始选择将是最好的选择。我过去在参加认证考试时曾有过几次犹豫不决的经历,我标记了 5-7 个问题以待复查,并在至少四个问题上改变了最初的答案,结果考试成绩公布时,居然因为错了 1-2 个问题而没能通过。那些我在考试结束时更改的答案,是否错了呢?我不能明确回答,因为 AWS 不会提供这些类型的反馈,但我已经改变了自己使用复查按钮的方式。如果我对问题和/或答案感到难以理解,我会选择一个答案然后继续答下一个问题。
尽管在参加专业级别考试之前,已经取消了低级别助理测试的前提要求,但我并不建议你直接跳到专业级别的考试。参加 AWS SysOps 助理或开发者助理认证考试,曾经是参加 DevOps 专业考试的必要前提,可以帮助你为专业级考试做好充分的热身。即使是在我的再认证过程中,我通常会先参加低级别测试,以便在较为简单的格式下判断考试中新增加的服务和问题,然后在几周后再进行专业级别的再认证。

图 23.4 – 脑力回忆格式示例
我建议去考试中心参加考试。这样做的主要原因之一是你会获得实际的纸质考试证书。在考试前一天晚上,拿一张空白纸,练习写下有关主要主题的快速笔记,这些笔记可以帮助你回忆起一些要点,正如前面的图示所示。我通常会在考试前的晚上练习这个过程 3-5 次,这样当我坐在考试中心的计算机前,输入用户名和考试 ID 时,我可以在不到 5 分钟的时间内完成这一过程,然后按下开始按钮。我曾在我运营了 6 年的 AWS 技术交流小组里教授过这种技巧,很多成员曾互相挑战,在多个 AWS 认证的不同级别上取得成就。你不能将任何类型的备忘单带入考试中心。你只是在考前将信息快速从脑中记下来,写在提供的草稿纸上,考试结束后再将草稿纸交还给考试中心。你可以在考试过程中参考这些快速笔记;然而,由于它们是你自己制作的,这可以让你在专心阅读和理解题目时放松并深呼吸。
总结
成为一名认证的(甚至是重新认证的)AWS 专业人员是一项需要奉献、学习以及成功通过严格测试格式的任务。相信你的努力和学习一定会得到回报。AWS DevOps 专业认证是一项荣誉,它在大学和雇主中都得到了认可。
在下一章中,我们将为你提供一个模拟考试,既可以测试你的知识,也可以继续熟悉专业考试中的问答格式。
第二十五章:模拟考试 1
本节将提供类似测试的问题样例,帮助你熟悉如何在限定时间内阅读和回答问题。
在本章中,我们将讨论以下主要主题:
-
软件开发生命周期(SDLC)自动化
-
配置管理和基础设施即代码
-
监控与日志记录
-
政策和标准自动化
-
事件和事故响应
-
高可用性、容错性和灾难恢复
在开始回答以下问题之前,建议你使用某种计时器来跟踪每个问题的回答时间。所有问题都不是实际的 AWS 测试题目。然而,它们的格式是根据测试的形式制作的。这包括长场景类型的问题,以及非常相似的多项选择答案。细小的细节可能决定正确答案和错误答案之间的差异。
这些问题和答案都很长。许多答案中也包含相同的组件,这使得与一些关联测试不同,在这些测试中,你可以通过排除一些你知道错误的答案,然后从剩下的一两个答案中选择正确答案。
测试问题
-
你已经开发了一组 CloudFormation 模板,可以供你当前的公司用来部署其处理文件的中间件解决方案。这个应用部署在多个 EC2 按需实例上,并且在 CloudFormation 中有一个用户数据组件,负责从 S3 存储桶中下载多个脚本,包括一个初始化的 shell 脚本,用于帮助配置这些实例。存储脚本的 S3 存储桶已启用版本控制。公司中唯一已知的脚本副本位于该 S3 存储桶中。一名新实习生在尝试上传另一个静态资源到存储桶时,不小心删除了脚本。那么,恢复脚本并重新部署服务器的最快方式是什么?
a. 你需要重新创建脚本并使用相同的名称将其上传到 S3 存储桶。启用了文件版本控制后,你只能看到文件之间的差异,而无法恢复已删除的文件。
b. 你需要修改 CloudFormation 脚本,使其使用之前的脚本版本 ID,该版本已在 S3 存储桶中被删除。
c. 你需要进入 AWS 管理控制台,导航到存放部署脚本的 S3 存储桶,然后选择“列出版本”选项。你可以找到被删除的脚本并移除删除标记。
d. 你需要进入 AWS 管理控制台,导航到存储部署脚本的 S3 桶,然后选择“列出版本”选项。然后,你可以下载之前被删除的脚本的版本。在脚本下载后,你可以将其重新上传到桶中,并将其重命名为原始脚本名称,以便 EC2 实例可以从 CloudFormation 模板中找到它。
-
你是一个团队的一员,团队最近开发了一个 Spring Boot 应用程序,并准备将其部署到 AWS 云上。由于应用程序的流量波动较大,你已将应用程序配置为在 Auto Scaling 组中启动。确保应用程序正常运行非常重要,因此你创建了一个 Bash 脚本,脚本将在每个 EC2 实例上运行并定期检查应用程序的健康状况。如果实例不健康,则应标记该实例并用新的健康实例替换它。构建该 Bash 脚本以执行此任务的最佳方式是什么?
a. 构建脚本以在健康检查失败时重启实例。以 root 用户身份运行脚本。Auto Scaling 组检测到重启后,将终止该实例并创建一个新的实例替代它。
b. 构建脚本以使用 AWS CLI。让实例使用
autoscaling set-instance-health命令,告知 Auto Scaling 组该实例不健康。然后,Auto Scaling 组将终止该实例并创建一个新的实例替代它。c. 构建脚本以使用 AWS CLI。让实例使用
autoscaling put-notification-configuration命令通知 Auto Scaling 组该实例不健康。然后,Auto Scaling 组将终止该实例并创建一个新的实例替代它。d. 构建脚本以使用 AWS CLI。让实例使用
autoscaling enter-standby命令,告知 Auto Scaling 组该实例不健康。然后,Auto Scaling 组将终止该实例并创建一个新的实例替代它。 -
你被引入了一家公司,该公司最近为其在 AWS 上运行的基础设施资源建立了配置和标签标准。你被要求设计并构建一个近实时的仪表板,展示合规性状况,并强调任何违规情况。
a. 在 Amazon Inspector 中定义标签和资源要求。创建一个简单通知服务(SNS)主题,以便在发现异常时收到通知。让 Inspector 定期检查合规性要求,并在发现问题时将通知发送到 SNS 主题。使用 AWS Security Hub 快速可视化违规情况。
b. 创建一个自定义的 CloudWatch 指标来跟踪所有资源和标签标准。使用 CloudWatch 服务创建一个仪表板,以可视化跟踪任何不符合标签标准的资源。
c. 启用 AWS Config 服务,并使用配置记录器记录所有创建和删除的资源。将配置更改发送到 S3 存储桶。利用 Amazon QuickSight 将 S3 存储桶中的数据转换为可视化信息和仪表板进行分析,从而能够轻松发现不合规的资源。
D. 在 AWS Service Catalog 中定义多个资源配置。使用 Amazon CloudWatch 监控 Service Catalog 中的任何合规性违规。利用 CloudWatch 服务创建一个仪表板,以可视化方式跟踪不符合标签标准的资源。
-
你加入了一个应用程序团队,该团队正在将他们的 MySQL 数据库从本地迁移到 AWS 云。这个应用程序非常关键,因此它需要比单一的本地服务器更高的稳定性。该应用程序是读密集型的,具有 10:1 的读写比。成本是主要目标,但他们确实需要关注项目预算。目前团队中的成员都不具备 DBA 技能,大家都希望能更多地专注于应用程序开发。你会建议什么样的配置,以确保数据库在当前区域的可用区发生故障时能够继续运行?
a. 创建一个 MySQL RDS 实例。在设置实例时,选择 Multi-AZ 功能。数据导入完成后,创建一个只读副本,并编程让应用程序使用该只读副本进行大量读取操作。
b. 创建一个 MySQL RDS 实例。数据导入完成后,在另一个区域创建一个只读副本,并编程让应用程序使用该只读副本进行大量读取操作。
c. 创建一个 CloudFormation 模板,启动一个自动扩展组,并在启动模板中配置 MySQL 服务器,分别在不同区域的两个 EC2 实例上运行。配置使 MySQL 服务以主主(Master-Master)模式运行,以便在发生故障时,任何一台服务器都可以作为目标。
d. 创建一个 CloudFormation 模板,启动一个自动扩展组,并在启动模板中配置 MySQL 服务器,分别在不同区域的两个 EC2 实例上运行。模板中还将创建一个第三个较小的 EC2 实例作为 MySQL 代理,这样应用程序服务器可以指向该代理。代理会自动在当前主服务器和从服务器之间切换。
-
你之前在 AWS CodePipeline 中为你的团队的应用程序构建了一个 CI/CD 管道。当前管道包括代码签出、构建、测试、部署到开发环境以及部署到测试环境的自动化阶段。现在,你正在更新 CodePipeline,新增一个部署到生产环境的阶段,并在代码发布到生产环境之前,添加产品负责人的手动审批。在新阶段的初次测试中,产品负责人通知你,在使用他们的 IAM 用户登录 AWS 管理控制台并进入 CodePipeline 管道后,他们发现自己没有权限批准构建。你该如何解决这个问题?
a. 为部署到生产环境阶段创建一个新的 SNS 主题。将产品负责人添加到该主题。当 SNS 消息发送时,让产品负责人点击消息中的审批链接。
b. 从 AWS 管理控制台,进入指定的 CodePipeline,并将产品负责人的 IAM 用户添加为该管道的审批人。
c. 从 AWS 管理控制台,进入 IAM 服务。创建一个新组,命名为
CodePipeline Approvers。将AWSCodePipelineFullAccess托管 IAM 策略附加到该组。将产品负责人添加到该组。d. 从 AWS 管理控制台,进入 IAM 服务。创建一个新组,命名为
CodePipeline Approvers。将AWSCodePipelineApproverAccess托管 IAM 策略附加到该组。将产品负责人添加到该组。 -
一个组织已经将其开发人员的代码版本控制系统迁移到 AWS CodeCommit。开发团队在测试时创建并处理功能分支,准备好合并到主分支时创建拉取请求。该组织已设定规定,任何人不得直接提交到主分支。任何开发人员都会是 IAM 组 "developers" 的成员。这个组最近被修改,添加了
AWSCodeCommitPowerUser托管策略,现在该组的所有成员都能提交到组织 AWS CodeCommit 中任何仓库的主分支。为了防止这种情况并执行组织的规定,应该采取哪些措施?a. 创建一个附加的 IAM 策略,允许执行
codecommit:GitPush操作。为策略添加一个条件,指定资源声明中的 CodeCommit 仓库。b. 创建一个附加的 IAM 策略,拒绝执行
codecommit:GitPush操作。为策略添加一个条件,指定资源声明中的 CodeCommit 仓库。c. 修改 IAM 策略,移除
codecommit:GitPush操作。d. 修改 IAM 策略,添加一条拒绝规则,针对
codecommit:GitPush指定不允许推送的特定仓库。 -
你已经配置了 AWS CodeDeploy 来自动化部署到位于你 AWS 账户中的开发和测试环境中的 EC2 实例,以及一些仍在本地的 RHEL 服务器。已经配置了一个部署组,定义了所有包含在部署中的特定实例。有一个公告指出,部署组中的一个本地实例将进行硬件更新,预计将花费 2 周时间完成。在此期间,不应向这些实例推送新的部署。哪种方法最适合实施这个针对特定本地服务器的 2 周冻结期?
a. 创建一个新的部署组,标签仅供该用户使用。
b. 验证两个部署组使用的标签。使用 AWS CLI 删除将与
aws deployremove-tags-from-on-premises-instances命令一起服务的特定实例。c. 使用 AWS CLI 通过
deploy deregister命令取消注册本地实例的 CodeDeploy 部署。d. 使用 AWS CLI 卸载本地实例上的 CodeDeploy 代理,使用
deploy uninstall命令。 -
你团队中的一位 DevOps 工程师提交了以下
buildspec.yaml文件进行安全审查。安全审查未通过。你被指派帮助这位初级工程师审查该文件:图 24.1 – 安全审查文件
![图 24.1 – 安全审查文件]()
你会建议初级 DevOps 工程师做哪些更改,以便使
buildspec文件符合安全最佳实践(选择三个)?a. 为 CodeBuild 角色添加权限,以便在构建过程中执行必要的操作。移除文件中的访问密钥和秘密密钥。
b. 使用 KMS 加密环境变量,以便它们不会以明文形式出现在文件中。
c. 将所有环境变量写入文件。将文件存储在 S3 中,并在执行时将文件拉取下来,以便变量不会以明文形式出现在文件中。
d. 使用 AWS Secrets Manager 存储
DB_PASSWORD值。存储后从环境变量中删除 DB 值,然后在需要时检索。e. 在系统管理器中创建一个运行命令来执行这些命令。使用系统管理器代替直接从实例使用 SSH 和 SCP。
-
你被招募到一家公司,该公司正在扩展其在 AWS 云上的业务。他们希望通过 CloudFormation 构建他们的足迹。然而,他们希望在各种应用程序中使用通用组件和模式。许多基础组件,如基础设施和网络,在生成后不会经常修改。公司希望独立管理所有通用组件项,并允许其他应用堆栈在需要时重用这些组件。你如何实现这一目标?
a. 创建一个 CloudFormation 堆栈来容纳所有公共资源。其他 CloudFormation 堆栈可以通过 AWS 管理控制台导入这些资源来使用它们。
b. 创建一个 CloudFormation 堆栈来生成所有公共资源。导出输出值,以便其他 CloudFormation 堆栈可以使用
GetAttribute函数导入这些值。c. 构建一个 CloudFormation 堆栈来生成所有公共资源。导出输出值,以便其他 CloudFormation 堆栈可以使用
ImportValue函数导入这些值。d. 创建一个 CloudFormation 堆栈来生成所有公共资源。任何应用堆栈都可以作为此堆栈的嵌套堆栈来使用所有公共资源。
-
一家公司刚刚推出了一个新的预订服务,提供网站和移动应用。部分得益于市场团队的努力,该服务在客户中取得了巨大成功,吸引了越来越多的用户。首席技术官(CTO)已经实施了一项新的指令,在接下来的季度内尽可能提高应用程序效率,并对性能进行必要的调整。为了实现这一目标,开发团队需要监控应用程序的各个细节,以找出任何问题、错误和延迟的根本原因。他们可以如何使用 AWS 原生工具和服务来实现这一目标?
a. 配置 Amazon Inspector 以查看应用程序。定期阅读 Inspector 评估报告,查找任何延迟问题及错误。使用时间戳追踪 CloudWatch 日志中的日志。
b. 配置 Amazon Elasticsearch 订阅应用程序的 CloudWatch 日志组。使用 Kibana 绘制从用户点击到应用程序响应的延迟时间图表。创建自定义 Kibana 可视化以统计错误数量。
c. 在 Amazon CloudWatch 中配置自定义指标来跟踪延迟。创建一个 CloudWatch 仪表板来跟踪该指标。
d. 配置 AWS X-Ray SDK 以供应用程序使用。将数据片段发送至 X-Ray 进行处理。在 X-Ray 服务控制台中查看服务图和追踪信息。
-
你已经为公司设置了 AWS CodeCommit 作为代码版本控制服务。主要应用团队正在开发一个手机应用,并将源代码提交到 AWS 账户(账户 A)中的一个 CodeCommit 仓库(仓库 A)。公司刚刚收购了另一家公司,该公司有自己的 AWS 账户(账户 B),一些开发人员被指派协助开发该手机应用的新功能。为了使账户 B 中的开发人员能够访问账户 A 中的仓库 A,你应该采取哪些操作来配置跨账户访问(选择两个)?
a. 进入 AWS 管理控制台中的 AWS CodeCommit 服务(账户 A),将仓库 A 与账户 B 共享,以便账户 B 中的用户可以访问该仓库。
b. 进入 AWS 管理控制台中的 AWS CodeCommit 服务,在账户 A 中将账户 B 的 IAM 用户添加到存储库中作为用户。
c. 在 AWS 账户 A 中,进入 IAM 控制台,创建一个 IAM 策略,允许访问 CodeCommit 的存储库 A。然后创建一个可以被另一个账户假设的 IAM 角色,并附加此策略。允许账户 B 中的用户假设此角色。
d. 在 AWS 账户 B 中,进入 IAM 控制台,创建一个 IAM 策略,允许对 CodeCommit 服务的完全访问,并连接到存储库 A ARN 资源。将此新策略附加到所有需要访问 AWS 账户 A 中存储库 A 的用户。
e. 在 AWS 账户 B 中,创建一个 IAM 策略,允许使用安全令牌服务(STS)进行角色假设操作,以便可以假设跨账户角色。将此新策略附加到所有需要访问 AWS 账户 A 中存储库 A 的用户。
-
您所在的公司刚刚进行了审计。审计回馈的纠正措施包括需要保留和存储所有系统日志 6 年。开发和运维团队需要 30 到 60 天的日志用于故障排除。市场部门需要至少 6 个月的 web 流量日志用于分析。管理层希望确保您提出的解决方案不仅符合审计员的要求,而且具有成本效益。您如何满足管理层和审计员的需求?
a. 将日志存储到 EBS 卷中。创建每月的 EBS 快照,以便在 60 天后进行长期存储。
b. 将日志存储到 Amazon S3 Glacier 中。
c. 将日志存储到 Amazon CloudWatch Logs 服务中,并将日志组的保留策略设置为 6 年。
d. 将日志存储到 Amazon S3 存储桶中。创建一个存储桶策略,使日志在 60 天后转移到低频访问存储,然后在 1 年后转移到 Amazon Glacier。
-
您的公司在 AWS 上运行一个 .NET 应用程序,该应用程序依赖大约 50 台 Windows 服务器作为基础设施。公司有一项政策,要求开发、测试和生产环境中的所有服务器必须保持最新的安全补丁。这些 Windows 服务器都是从一个主 AMI 镜像构建的。负责实例修补的 DevOps 团队只有您和另外一名团队成员,因此创建一个自动化的方式来执行此过程至关重要;否则,您将不得不在周六早晨凌晨 1 点到 4 点之间的有限时间窗口内完成所有更新,此时客户流量极少。您如何使用原生的 AWS 服务来自动化这一过程?
a. 创建一个 Lambda 函数,能够在 PowerShell 中下载并运行更新。使用 CloudWatch Events 将 Lambda 调度为每周凌晨 1 点运行。
b. 使用 AWS Systems Manager Patch Manager 对 Windows 实例集群进行补丁管理。使用 Systems Manager 执行命令来安装更新。
c. 应用 AWS 系统管理器补丁管理器到 Windows 实例集群。使用系统管理器维护窗口安排每周凌晨 1 点运行更新。
d. 在 OpsWorks 中创建自定义 Chef 脚本,用于下载并安装 PowerShell 更新。在 OpsWorks 中创建一个任务,安排每周凌晨 1 点运行更新。
-
首席技术官最近找到了您,关心公司 AWS 账户的安全。他们希望您实施监控,防止可能的攻击侵害公司 AWS 资源。他们特别强调了监控端口扫描、暴力破解攻击或任何 SSH 攻击。如果检测到攻击,他们希望将其发布到公司的 Microsoft Teams 安全频道。您如何实现这一目标?
a. 设置 Amazon GuardDuty。如果检测到可疑活动,触发一个 Lambda 函数,将信息发布到 Microsoft Teams 渠道。
b. 创建一个 Lambda 函数,扫描 CloudTrail 日志中的可疑活动。如果发现可疑活动,将其发布到 Microsoft Teams 渠道。
c. 设置 Amazon Inspector。如果检测到可疑活动,触发一个 Lambda 函数,将信息发布到 Microsoft Teams 渠道。
d. 创建一个 Lambda 函数,扫描 VPC 流日志。如果发现可疑活动,将其发布到 Microsoft Teams 渠道。
-
首席执行官亲自访问了 DevOps 团队,并表示公司承诺为客户提供六个 9 的正常运行时间,否则公司将提供大量退款。这意味着您和您的团队每年只有 31.56% 的停机时间。主要的工作负载包括多个配置在 Auto Scaling 组中的 EC2 实例,这些实例通过应用负载均衡器运行。您如何配置工作负载,以确保即使在发生区域性故障的情况下,公司也能保持这一正常运行时间的承诺?
a. 在负载均衡器和实例前设置 Amazon CloudFront。CloudFront 将缓存工作负载,以防故障发生时为客户提供服务。
b. 设置一个 Route 53 地理接近度路由记录。确保 Auto Scaling 组配置为使用两个可用区。让 Route 53 路由记录指向应用负载均衡器。
c. 设置一个 Route 53 权重路由记录。确保 Auto Scaling 组配置为使用两个可用区。让 Route 53 路由记录指向应用负载均衡器。
d. 设置一个 Route 53 延迟路由记录。将您的工作负载 EC2 实例、Auto Scaling 组和负载均衡器部署在两个不同的区域。让 Route 53 路由记录指向应用负载均衡器。
-
你的公司想在 AWS 上实现 Apache Cassandra NoSQL 数据库。Cassandra 没有托管服务,因此你需要在 EC2 实例上构建它。你的团队希望你选择正确类型的 EBS 卷,以便为这个高性能的 NoSQL 数据库提供最佳性能。在为集群中的 EC2 实例构建时,你应该选择哪种类型的卷?
a. 在创建实例时使用 IO1 EBS 卷。
b. 在创建实例时使用标准 EBS 卷。
c. 在创建实例时使用 GPL EBS 卷。
d. 在创建实例时使用 GP2 EBS 卷。
-
你被引入一个组织,帮助创建一个新的 AWS CodePipeline 管道,以便团队可以实现持续集成。该管道需要拉取源代码,并让 AWS CodeBuild 运行一个测试阶段。测试包括从数据库中提取数据,这需要用户名和密码。你需要在测试阶段使用环境变量将这些信息传递进去。如何在 CodeBuild 阶段安全地配置这些变量?
a. 使用 CodeBuild 环境变量选项存储机密。在存储值时选择
Plaintext类型,并使用 KMS 密钥对值进行加密。b. 使用 CodeBuild 环境变量选项来存储机密。在存储值时选择
SecureString类型。c. 使用 AWS Secrets Manager 存储值。更新你的 CodeBuild 环境变量,并使用机密名称作为
Plaintext中的值。d. 使用 AWS Systems Manager Parameter Store 存储值。更新你的 CodeBuild 环境变量,并将参数名称作为
Parameter类型的值使用。 -
你被要求帮助一个使用 OpsWorks 的团队来增强他们堆栈的监控。这个团队在使用 Chef 开发自动化方面非常熟练,但似乎只了解在 AWS 上运行服务的基本知识。以下哪项不会帮助他们增强在 OpsWorks 中部署的应用程序的监控?
a. 利用 Amazon CloudWatch 指标并创建一个自定义指标来跟踪应用程序。
b. 使用 Amazon CloudTrail 确保只有授权的调用被发送到应用程序。
c. 使用 Amazon CloudWatch Logs 收集应用程序的日志。
d. 使用 AWS Config 收集应用程序的配置更改。
-
你被引入一个小型初创公司,该公司的营销网站仅包含静态内容。营销部门一直在抱怨加载时间过长,这影响了他们的搜索引擎排名。他们的预算有限,希望能最大程度地利用这些资金进行升级。该初创公司也在将所有数字资产迁移到新的 AWS 账户的过程中。他们还希望让网站尽可能快。以下哪项建议最能满足他们的需求?
a. 使用 EC2 服务器提供他们的网站服务。在前端添加 Amazon CloudFront 作为内容分发网络。
b. 将所有静态资源迁移到 S3。使用 EC2 Spot 实例提供网站服务。在前端添加 Amazon CloudFront 作为内容分发网络。
c. 将整个网站迁移到 S3。添加 Amazon CloudFront 作为内容分发网络。
d. 在 EC2 Spot 实例上提供他们的网站服务。添加 Amazon ElastiCache 进行内容缓存,以加快页面加载速度。
-
一个组织在 AWS 上运行一个成功的房间预订移动应用程序。他们使用 DynamoDB 存储所有交易记录和信用卡公司在预订确认后提供的确认码。他们选择 DynamoDB 是因为它能够快速自动扩展并处理任何需要的容量,而无需过多管理。这些交易记录对公司至关重要,必须确保不会因为任何服务器故障而丢失。该组织有一个政策,要求金融交易记录必须保存 3 年,以应对可能的客户争议。实现这一目标的最具成本效益和可靠性的方法是什么?
a. 使用 CloudWatch Logs 捕获来自 DynamoDB 的记录。将 CloudWatch Logs 中的保留期设置为 3 年。
b. 使用 DynamoDB Streams 将事务记录流式传输到 Lambda 函数。让 Lambda 函数将记录写入 S3 存储桶。使用生命周期策略将对象转移到 S3 Glacier 存储以节省成本。
c. 使用 DynamoDB 全球表将数据复制到辅助区域。创建一个 Lambda 函数,根据记录的创建日期减去 3 年来修剪记录,并且每晚运行一次。
d. 使用 DynamoDB Streams 将事务记录流式传输到 S3 存储桶。使用生命周期策略将对象转移到 S3 Glacier 存储以节省成本。
-
一家公司通过 AWS 组织设置了多个账户。他们刚刚开始实施事件驱动的自动化,并迈出了第一步,计划通过 SNS 从主账户中的 CloudWatch 事件总线向主题发送通知。他们该如何设置主账户并授予所有子账户访问权限,以便事件能够发送到主账户中的事件总线?
a. 创建一个 IAM 策略,允许发送 CloudWatch 事件。将该策略附加到主账户中的一个角色,该角色可以被组织中所有子账户假设。
b. 在每个子账户中创建一个 IAM 策略,允许发送 CloudWatch 事件,并指定主账户中事件总线的 ARN。将此策略附加到任何需要向主账户发送事件的基于服务的角色。
c. 在主账户中,进入 CloudWatch Events 控制台,然后选择你的事件总线。进入添加权限页面,选择通过输入组织 ID 来添加整个组织的权限。
d. 在主账户中,转到 CloudWatch Events 控制台,然后选择你的事件总线。转到添加权限,然后为每个需要权限将事件发送到事件总线的子账户添加 ID。
-
你正在与一个开发团队合作,团队试图跟踪他们构建并运行在一组 EC2 实例上的应用程序的性能。该团队特别关注他们的 Java 代码生成的任何错误信息,并希望如果在 5 分钟内发生超过 5 条错误信息,能够通知整个团队。以下哪个解决方案可以满足团队的要求?
a. 配置实例使所有 Java 日志写入 EC2 实例上的 syslog 中,使用用户数据脚本。使用 Kinesis Data Firehose 拉取实例的 syslog 数据并统计错误消息数量。为开发组创建一个 SNS 主题。如果在 5 分钟内有超过 5 条错误日志,使用 Kinesis 发送通知到该主题。
b. 配置实例将日志写入 Amazon CloudWatch Logs 中的一个日志组。使用 Amazon Elasticsearch 订阅该日志组。构建一个 Kibana 仪表盘,以便开发人员查看每分钟生成的错误日志数量。
c. 配置实例安装 AWS Systems Manager Agent。让代理将日志拉取到 Amazon EventBridge。为开发组创建一个 SNS 主题。创建一个 Lambda 函数,如果在 5 分钟内有超过 5 条错误日志,则将通知发送到 SNS 主题。
d. 配置实例安装统一的 CloudWatch 代理。创建一个自定义指标来统计 Java 日志中的错误数量。为开发组创建一个 SNS 主题。将日志和自定义指标推送到 Amazon CloudWatch。如果自定义指标在 5 分钟内达到大于 5 的值,创建一个 CloudWatch 警报,将通知发送到 SNS 主题。
-
你组织中的所有开发人员目前都可以通过登录 AWS 管理控制台并在实例状态设置下选择停止实例,来启动和停止开发账户中当前运行的任何 EC2 实例。一些团队抱怨他们的工作负载被其他开发人员误停止了错误的 EC2 实例。你如何实施安全措施,以便只有特定团队的成员能够使用原生 AWS 功能启动和停止自己的 EC2 实例?
a. 为公司中的每个开发团队创建一个策略,限制通过
${aws:Principal/Team}标签作为资源启动和停止实例。b. 向所有 EC2 实例添加一个
Team标签,通过比较个别开发者附加的${aws:Principal/Team}标签和实例上的ec2:ResourceTag/Team标签,限制访问权限,并查看它们是否匹配。c. 为所有 EC2 实例添加一个
Team标签。通过检查 EC2 实例是否匹配团队标签,来限制开发者策略中每个团队的访问权限。d. 在 IAM 开发者角色中,移除启动和停止实例的权限。为每个团队创建一个 CodePipeline 作业,允许他们查看、启动和停止他们开发团队的所有实例。
-
您有一个提取、转换和加载(ETL)应用程序,它将日志发送到 CloudWatch Logs。这些日志存储在一个 CloudWatch 日志组中,且格式为 JSON。以下是日志文件的示例:
{ "eventType": "Process", "eventObject": "File", "errorCode": "CorruptFile" } -
如何创建一个指标筛选器,以便查找所有错误代码为
"CorruptFile"的事件?a. 筛选模式:
{ $.errorCode = "CorruptFile" }b. 筛选模式:
{ $.errorCode == "CorruptFile" }c. 筛选模式
{ errorCode = "CorruptFile" }d. 筛选模式
{ errorCode == "CorruptFile" } -
您的公司要求您为其三个 AWS 账户创建一个可靠且持久的日志记录解决方案,以便跟踪对其 AWS 资源的更改。以下哪个选项可以帮助您成功实现这一目标?
a. 创建一个新的 CloudTrail,并使用现有的桶来存储日志。在创建轨迹时,选择全球服务选项。使用 IAM 角色对 S3 桶进行访问控制,并启用 S3 加密来保护桶的安全。
b. 创建三个新的 CloudTrail,并为它们使用一个新的桶来存储日志。一个轨迹用于 AWS 管理控制台,一个用于 SDK 命令,另一个用于 AWS CLI。对于任何删除操作使用多因素身份验证,并在桶上启用 S3 加密。
c. 创建一个新的 CloudTrail,并为其创建一个新桶来存储日志。在创建轨迹时,选择全球服务选项。对于任何删除操作使用多因素身份验证,并在桶上启用 S3 加密。
d. 创建三个新的 CloudTrail,并为它们分别使用三个新的桶来存储日志。一个轨迹用于 AWS 管理控制台,一个用于 SDK 命令,另一个用于 AWS CLI。使用 IAM 角色对 S3 桶进行访问控制,并启用 S3 加密来保护桶的安全。
-
您的公司使用 AWS Organizations 来创建和管理 AWS 账户。公司有多个账户,包括包含组织单元的子账户,这些子账户是通过 AWS Organizations 创建的。随着公司发展,现在需要为每个账户添加统一的角色。添加所有角色到整个组织的最有效方法是什么?
a. 在主账户中,使用 CloudFormation 部署一个模板来创建新的角色。使用 CloudFormation StackSets 在整个组织的子账户中复制这些更改。
b. 在组织的主账户中,创建一个服务控制策略(SCP),然后将角色添加到所有子账户中。
c. 在主账户中,使用 CloudFormation 部署一个模板来创建新的角色。使用 CloudFormation 更改集将这些更改复制到整个组织的子账户。
d. 在主账户中,创建一个在 Systems Manager 中运行的命令,以创建新的 IAM 角色。让 Systems Manager 在所有子账户上执行该命令以创建新角色。
-
你的 DevOps 团队成员找到你,因为他们注意到一个刚刚更新过的 Auto Scaling 组存在问题。应用程序没有达到稳定状态并提供流量,而是每小时多次进行扩展和缩减。使用 CloudFormation 的原生功能,你可以帮助团队调整哪些设置以稳定应用程序?
a. 检查当前 Auto Scaling 组的终止策略,并将值更改为首先终止最旧的实例,以便较新的实例保持在线。
b. 检查当前 Auto Scaling 组的终止策略,并将值更改为
ClosestToNextInstanceHour,以便实例变得更加稳定。c. 查找 Auto Scaling 启动模板的先前版本,并部署该版本以稳定应用程序。
d. 检查当前 Auto Scaling 组的健康检查宽限期,并扩展当前分配给实例的上线时间,以确保它们变得健康。
-
一家中型软件公司聘请你作为 DevOps 顾问,帮助建立他们的部署管道。他们希望能够快速将经过测试的代码推送到生产环境,但又不希望遇到任何可能导致客户停机的问题。你已经与应用团队合作,将他们的应用程序配置为运行在容器上并部署到 Amazon Elastic Container Service(ECS)。他们的 DNS 由第三方服务托管,DNS 更改需要一个变更工单。你会实施什么部署方法?
a. 在 ECS 服务设置中,在开始滚动更新服务之前,设置任务的
minimumHealthyPercent和maximumHealthyPercent值。b. 为你的更新创建一个 CodeDeploy 作业。使用蓝绿部署类型。将蓝绿部署的配置设置为全部同时(all-at-once)。
c. 为你的更新创建一个 CodeDeploy 作业。使用蓝绿部署类型。将蓝绿部署的配置设置为线性(linear)。
d. 为你的更新创建一个 CodeDeploy 作业。使用蓝绿部署类型。将蓝绿部署的配置设置为金丝雀(canary)。
-
你的团队最近进行了代码审计,并且在应用程序代码中发现了多个明文数据库用户名和密码。公司已将其标记为不可接受,并要求团队在 30 天内解决这个问题。根据公司指南,团队需要能够通过原生 AWS 服务安全地加密存储机密,并且该服务还需要能够每 60 天自动旋转机密。你和你的团队如何解决这个问题?
a. 移除之前在代码库中设置的数据库值。将环境变量添加到部署过程中。将用户名和密码作为相应的部署变量插入。
b. 移除之前在代码库中设置的数据库值。将用户名和值存储在 AWS Systems Manager 参数存储中。更新你的 IAM 角色,允许访问从参数存储中检索机密。
c. 移除之前在代码库中设置的数据库值。将用户名和密码存储在 AWS Secrets Manager 中。更新你的 IAM 角色,允许访问从 Secrets Manager 中检索机密。
d. 使用 KMS 加密数据库的用户名和密码值。用新加密的值替换代码中的旧值。
-
你的开发人员创建了一个 DynamoDB 表,并且似乎发现他们的性能在测试过程的 20-25 分钟后总是会变慢。从 AWS 管理控制台的基本监控中,他们可以看到请求正在被限制。你能做些什么帮助找出问题?
a. 增加表格的读取容量单元(RCUs),以使查询不再被限制。
b. 增加增强型 CloudWatch 监控,并在发生限制时触发警报。
c. 在表格上启用贡献者洞察(Contributor Insights),以便显示被限制最多的键。
d. 为表格添加自适应容量,以便将额外的 RCU 均匀分配到变热的分区上。
测试答案
-
c
由于桶启用了版本控制,移除删除标记会恢复对象,任何使用该脚本的当前或未来部署都能够找到它。
-
b
你可以使用 AWS CLI 和
autoscaling set-instance-health命令,并使用--health-status Unhealthy标志,将实例设为不健康状态,停用服务。更多信息可以在 AWS CLI 文档页面找到,链接如下:
docs.aws.amazon.com/cli/latest/reference/autoscaling/set-instance-health.html。 -
c
使用配置记录器,AWS Config 可以评估在帐户中创建的新资源。项目作为 JSON 快照记录到设置中声明的 S3 桶中。
-
a
RDS 使用 DNS 在多可用区(Multi-AZ)实现中切换到备用副本,以实现无缝过渡。
-
d
尽管
AWSCodePipeline_FullAccess策略可以提供批准访问权限,但它不遵循 AWS 最小权限原则。此策略会给予产品所有者超出其需要的权限。因此,AWSCodePipelineApproverAccess将补充他们缺少的访问权限。 -
b
你无法修改托管的 AWS 策略,因此这排除了 c 和 d 两个答案。你试图阻止用户直接推送到主分支的操作。
-
b
当一个本地实例标签不再使用,或者你想要将本地实例从依赖该标签的任何部署组中移除时,可以从本地实例中移除该标签。
-
a、d 和 e
将所有值写入 S3 文件并不能保证其完整性。使用角色并将数据库值存储在凭证存储中(如 Secrets Manager 或 Systems Manager Parameter Store)是一种更安全的做法。
-
c
Fn::ImportValue内建函数返回一个之前创建的堆栈中导出值的值。这用于创建跨堆栈引用。 -
d
Amazon Inspector 是一个安全服务,无法检测应用中的延迟。X-Ray 服务帮助开发人员识别性能问题和错误的根本原因。
-
c 和 e
为了访问另一个 AWS 账户中的资源,需要创建一个跨账户 IAM 角色,以便其他 AWS 账户可以假设该角色。同样,另一个账户的用户必须有一个附加的策略,允许他们假设该角色。
-
d
使用 Amazon S3 生命周期策略将允许你和你的团队同时快速访问当前日志,并根据审计员的要求将其存储在 Amazon Glacier 的低成本选项中。
-
c
使用 AWS Systems Manager,你可以结合使用 Patch Manager 和维护窗口,以 AWS 推荐的方式成功自动化此任务。
-
a
Amazon GuardDuty 可以检测 CTO 关注的所有不同类型的事件。添加一个 Lambda 函数,将其发布到公司的 Microsoft Teams 渠道,可以满足该要求。
-
d
只有通过部署到多个区域,才能确保你能防范区域性故障。使用基于延迟的记录在 Route 53 中,将在发生故障时自动指向响应最快的服务器集群。
-
a
io1 卷专为需要持续 IOPS 性能和 I/O 密集型数据库工作负载设计。
-
d
敏感值应存储在 Systems Manager Parameter Store 或 Secrets Manager 中。如果为 CodeBuild 使用 Secrets Manager,则应选择变量类型为 Secrets Manager,而不是
Plaintext。 -
d
Amazon Config 不是用于监控和度量的服务。
-
c
-
c
由于整个网站由静态内容构成,而 S3 是最经济且可靠的解决方案,因此这是最理想的选择。使用 S3 作为源并由 Amazon CloudFront 前端,将使得资产通过边缘位置更快速地传递给最终用户。
-
b
DynamoDB Streams 无法直接将数据流传输到 S3 作为源,因此 Lambda 函数需要首先
GetRecords,然后将其放入指定的 S3 存储桶,并设置生命周期策略。 -
c
CloudWatch 事件总线允许你在组织级别上添加权限。如果你的组织扩大,这也会有所帮助,因为你无需跟踪已添加到事件总线的账户,或在创建时记得将账户添加到事件总线权限中。
-
d
-
b
在 EC2 实例上使用标签可以作为区分不同团队之间 EC2 实例所有权的第一步。
ec2:ResourceTag是一个存在于 EC2 资源上的标签,可以在 IAM 策略中进行验证。 -
a
度量过滤器的语法为
{ $.errorCode = "CorruptFile" }。 -
c
使用全局选项会将所有记录的 API 操作发送到一个单一的 S3 存储桶。加入 MFA 将防止日志的任何未授权删除。
-
a
AWS CloudFormation StackSets 扩展了 CloudFormation 堆栈的功能,使你能够在多个账户和区域内通过一次操作创建、更新或删除堆栈。
-
d
尽管你可能通过代码版本控制系统回滚,但调整 Auto Scaling 组的当前健康检查将使你的实例上线并变得健康。
-
a
滚动式部署将是最优的部署方式,特别是在 DNS 托管在第三方提供商上的时候。
-
c
尽管根据新指南,系统管理器参数存储和 AWS Secrets Manager 都能安全地存储机密信息,但只有 Secrets Manager 会自动旋转数据库机密。
-
c
Amazon CloudWatch Contributor Insights 与 DynamoDB 集成,提供表格或全局二级索引中访问最多和限速的项目的信息。
问题分解
如果你对自己在特定领域的表现感兴趣,我们将如何将样本测试题目按测试领域分组,如下所示:
领域 1 – SDLC 自动化:
-
问题 6
-
问题 11
-
问题 17
-
问题 23
-
问题 26
-
问题 27
-
问题 28
领域 2 – 配置管理与基础设施即代码:
-
问题 5
-
问题 7
-
问题 9
-
问题 16
领域 3 – 监控与日志:
-
问题 10
-
问题 18
-
问题 21
-
问题 22
-
问题 24
-
问题 30
领域 4 – 策略与标准自动化:
-
问题 3
-
问题 8
-
问题 12
-
问题 13
领域 5 – 事件和事件响应:
-
问题 1
-
问题 2
-
问题 14
-
问题 19
领域 6 – 高可用性、容错与灾难恢复:
-
问题 4
-
问题 15
-
问题 20
-
问题 25
如果你在某些特定领域的问题回答不准确,那就回去重新阅读那些章节,参考第二十三章的结尾部分,DevOps 专业认证考试概述,里面有一篇 AWS 白皮书,可能会给你提供更多对该主题的深入理解,或者你也可以观看一些过去的 re:Invent 讲座或 AWS TechTalk 视频,以便更好地理解这个领域。
现在,让我们对整个认证之旅做一个最终总结。
总结
在本章中,你已经阅读了若干 DevOps 专业考试的样题,以便你能够练习到目前为止所学的所有内容,同时了解考试中的问题和答案格式。
希望到此时,你已经有足够的信心参加并通过 DevOps 专业认证考试。一旦通过,你将加入一小部分能够迅速被认可的专业人士,他们不仅在 DevOps 领域具有技能,还在 AWS 和云技术方面也具备卓越能力。









































































































































浙公网安备 33010602011771号