原标题:作为一名Java工程师,我在DevOps团队都经历了什么
作者 | Milan Milosevic
译者 | 无明
我是一名 Java 工程师。每当听到其他 DevOps 工程师讲述他们遇到的麻烦事我就感到莫名的开心。直到两年前,我开始参与代码的部署。一年前,我开始部署别人的代码。
我又参加了一场 DevOps 匿名会议。实际上我并不是 DevOps 工程师,而是一名 Java 工程师。每当听到其他 DevOps 工程师讲述他们遇到的麻烦事我就感到莫名的开心。他们都很喜欢我,因为他们以为我也会在半夜里收到监控系统发出的警报。然而并没有。
轮到 Bob 了(这个胸部很大的男人,我觉得可能是荷尔蒙分泌过多导致的):“我从一开始就提倡自动化,但没有人听。每个人都在用临时方案解决手头的问题。没有人会把事情记录下来。直到有一天我们不得不为其他客户复制整个环境,花了三个月时间从头把所有事情又做了一遍”。Bob 说着,眼睛里噙着泪水(可能又是荷尔蒙的关系)。
我很享受这些会议,参加这些会议就像在度假。然而好景不长。两年前,我开始参与代码的部署。一年前,我开始部署别人的代码。因此,参加 DevOps 匿名会议不再是找乐子了,我也成为他们当中的一员。下面是我的故事。
SysAdmin 在云端基础设施上做出变更
轮到我了
“我是 Milan,我想分享最近的一次项目经历。我们的想法是从一开始就对所有的基础设施创建操作进行自动化。我们的架构非常简单:一个运行 MongoDB 副本集的 AWS 主区域,CI 使用了 CodePipeline,监控和警报使用了 CloudWatch(以及几个较小的支持组件和服务),以及三个部署了 ECS 服务的副区域,其中 ECS 实例上运行着容器化的 NodeJS 应用程序。所有区域的应用程序服务之间通过 RabbitMQ 相互通信(运行在单独的容器中)。很简单,对吧?”——这是我第一次在 DevOps 匿名会上分享我的故事。
“我们估计要六到七周才能完成这些工作……看起来很糟糕。下面是我们从这个过程中学到的经验教训。”
即使简单且文档齐全的 AWS 服务也需要很长时间才能实现自动化
我先介绍一下我们使用的工具。
CloudFormation 是一种 AWS 原生语言,用于描述需要创建的资源。我们一直认为它能够支持我们需要的大部分服务和配置选项。不过,因为我们使用 Ansible 来配置数据库组件,所以决定在 Ansible 包装器中使用 CloudFormation。事实证明这是正确的组合,特别是当我们因为某些原因需要通过 CloudFormation 进行跨区域 VPC 连接而遇到麻烦时。不管怎样,它可以与 Ansible 的 ec2_vpc_peer 模块一起使用。
基本上,我们使用了 CloudFormation 和 Ansible。那么为什么从一开始就自动化所有东西会这么费时?
在 AWS 中创建 VPC 和 EC2 资源需要花费大量的时间。在 AWS 中创建 VPC、堡垒服务器以及所需的 EC2 实例需要 5 到 10 分钟,而要删除它们差不多也需要这么多时间。因此,在开发过程中做出变更和测试变更通常需要先删除再重新创建这些资源,这个过程需要 10 到 20 分钟。如果我一不小心指定了错误的引用,导致创建失败(有时在 10 分钟后才发现)并进行回滚,这又需要额外的时间。总而言之,这个过程可能非常耗时。
当你通过 Web 控制台创建 AWS 资源时,AWS 通常会在后台创建依赖资源。例如,如果要创建 ECS 服务,AWS 将自动为你创建和配置负载均衡器。而当你通过 CloudFormation 创建 ECS 时,必须自己创建并正确配置所有资源(例如负载均衡器)。这不是在造火箭,但仍然需要时间来阅读相关文档,然后试着找到正确的配置,并与其余部分集成在一起,然后开始测试并重复这个过程。
先让它跑起来,然后对它进行自动化
你可能已经知道 Spotify 是如何构建产品的:
事后看来,同样的原则适用于构建和自动化云基础设施(甚至是与业务相关的所有东西)。我们应该从一开始就专注于提供价值。首先,我们通过手动点击 AWS Web 控制台来构建基础设施。这样就可以在一开始就为客户提供真实的价值。然后,我们每一次自动创建一个组件。当然,通过一半脚本和一半手动操作构建起来的基础设施,在维护时需要一定的开销。你必须手动编辑脚本,并插入在 UI 上创建的资源 ID。它并不像看起来的那么简单。但我认为,为了尽早将产品 / 功能推向市场,这样做是值得的。
为调试而进行的优化
因为试验云资源需要花费大量的时间(创建、更改、回滚都需要时间),所以应该要对 Ansible/CloudFormation 脚本进行优化,以便进行更好的调试和试验。如果你正在尝试使用一个资源并且不需要运行其他部分,那么就可以把不需要的部分注释掉。我知道,这可能是一个令人惊讶的发现!但有好几次,我是这么想的:“让我试一下 MongoDB 实例的其他参数。我有把握不会出问题,最后还可以让它恢复原样”。然后我启用了所有资源,避免把时间浪费在注释不必要的资源上。然而,4 小时后,我仍在修改和实验,并等待创建、更新、删除整套东西。
对于 Ansible 来说也是如此。如果我正在试验一个之前没有用过的模块,我应该注释掉脚本的其余部分。即使通常不会对未发生变更的任务产生任何影响,Ansible 也会运行它们,我不得不等待良久才能看到需要测试的那部分代码被执行。我一直在想:“这次可能会成功,我不想花时间去注释脚本”。但实际上在第一次尝试时从未成功过(除非注释掉一些代码,在确认没有问题后再取消掉注释)。
grep 是你最好的朋友
DevOps 生态系统中的工具不像 Java 世界中的重量级 IDE(如 Eclipse 或 IntelliJ)那么高级。
但从事 DevOps 工作意味着我们需要经常使用 Unix 命令行。因此,使用命令行程序应该成为我们工作流程的一部分。grep 永远是你最好的朋友,因为它是最快、最灵活的搜索工具,例如,找出一个 Ansible 变量是在哪里使用或定义的。一旦你学会了 grep,就永远不会忘记它。grep 是在半个世纪前出现的,现在依然活力焕发。但你能这么说 Eclipse、IntelliJ、Atom、Sublime 或其他 IDE 和文本编辑器吗?不一定。花点时间学习 grep 的一些参数和用法肯定是值得的。
想知道“satelite_regions”这个变量在哪里使用和定义的?
grep -r satellite_regions
结果:
./infra.yml: regions: "{{ [ master_region ] + satellite_regions }}"./infra.yml: with_items: "{{ satellite_regions + [master_region] }}"./infra.yml: with_items: "{{ satellite_regions }}"./inventory/aws-dev/group_vars/all/vars/all.yml:satellite_regions: ['sa-east-1']./inventory/aws-production/group_vars/all/vars/all.yml:satellite_regions: ['ap-southeast-1', 'ap-southeast-2', 'sa-east-1']./inventory/aws-sandbox/group_vars/all/vars/all.yml:satellite_regions: ['sa-east-1']./inventory/aws-staging/group_vars/all/vars/all.yml:satellite_regions: ['sa-east-1']
这是一个非常可爱的 grep 用例插图,这要感谢 Julia Evans(https://jvns.ca):
由于几乎一直都在使用命令行,你可以开始使用 Vim 了,并拥抱这个最好的文本编辑器……
硬编码很好,DRY 的意思是 Do Repeat Yourself
想象一下这种非常常见的情况:我们需要创建几个(或几十个)几乎相同的 EC2 实例。它们可能只有几个参数是不一样的。在 Java(或其他高级编程语言)中,可能可以通过创建带有输入参数的方法来解决这个问题。所以,我总是倾向于使用 CloudFormation/Ansible 来实现这种“通用”方法。可惜的是,这种方法不能用在这里,因为 CloudFormation 不是图灵完备的语言(它没有循环的概念)。
因此,我们必须重复自己。这也适用于硬编码。我们想让一切都尽可能通用,但这样做通常会给自己带来苦果。到最后,或许我的 CF/Ansible 脚本都不需要动态创建 SSL 证书。那么为什么我还要自动创建它?我真的需要数千个证书吗?如果我只需要其中几个并且可以重复使用它们,我完全可以手动创建它们,并在脚本中硬编码 ARN 引用,这样可以节省大量的时间。
结论——自动化基础设施值得吗?
简单地说:值得,但必须要做得漂亮。
具体点说:当我们对基础架构进行自动化,将获得维护和运行代码的所有优点(和缺点)。
易于执行
系统性地修复错误
更少的文档
人们可以在项目间互换
更容易试验(这可能是最强的一点)
但我们必须确保能够尽快交付业务价值。从一开始就自动化所有东西可能会大大减慢我们的速度(甚至可能对我们造成阻碍)。因此,拥有完全自动化的基础设施是终极目标,而不是在一开始就要这样。我们必须意识到,在自动化和交付价值之间做出妥协是有必要的,如下图所示(从商学院学来的):
成功三角模型(Barker,Jack,2015)
对于我来说,使用一个命令就可以创建出所有东西,这种感觉太好了。想一想,就在几年前,通过一个命令来启动复杂的分布式基础设施是不可想象的,更何况数据库和应用程序服务器跨越了 3 个(甚至更多的)大洲,所有内容都要求具备高可用性和容错性。如果某个区域出现中断,请求将自动被重新路由到另一个 AWS 区域。
一切看起来都很美好…有了这个神奇般的技术,用户就可以看到我们的喵星人视频啦。
原文链接:
https://www.smartcat.io/blog/2018/devops-anonymous-lessons-learned-from-building-cloud-infrastructure-from-scratch返回搜狐,查看更多
责任编辑: