NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

写了 30 万行基础设施代码后,我们得出 5 个有用的经验

  • 2018-12-04
  • 本文字数:2560 字

    阅读完需:约 8 分钟

写了30万行基础设施代码后,我们得出5个有用的经验

在 Gruntwork,我们创建并维护着一个包含 30 万行基础设施代码的库,有数百家公司在他们的生产环境中使用这个库。在这篇文章中,我将分享我们在开发和维护这个库的实践过程中学到的非常重要的五课。

处于石器时代的 DevOps

虽然这个行业充斥着各种前沿的流行语——Kubernetes、微服务、服务网格、不可变基础设施、大数据、数据湖,等等——但实际情况是,当你在构建基础设施并陷入困境时,它们看起来一点都不前沿。


对我来说,DevOps 感觉更像这样:



构建生产级的基础设施其实很难,压力很大,而且非常耗时。


根据我们在与数百家不同公司合作时收集的经验数据,你大致可以估计你的下一个基础设施项目需要多长时间:


第 1 课:生产级基础设施检查清单

DevOps 项目总是比预期的要长,为什么会这样?


第一个原因是 Yak Shaving(给牦牛撸毛),那么什么是 Yak Shaving?看看这个场景你就明白了:


经理:你不是在开发用户登录功能吗?为什么现在在捣鼓一个我们根本用不到的数据库?

工程师:是啊,我是打算开发用户登录功能。然后我开始评估要用哪个库,我发现一个非常好的库,但它只支持 Postgres。于是我试着搭建一个 Postgres,看看值不值得这样做。但切换数据库会破坏索引,所以我现在在学习如何建立 Postgres 索引……这样才能把用户登录功能做出来,对吧?


第二个原因是构建生产级的基础设施涉及了太多的细节。绝大多数开发人员并不知道这些细节,因此,当你在估算项目时,你通常会忘记关键和耗时的细节。


为避免这个问题,每次你开始使用新的基础设施时,请检查以下清单:



并非每个基础设施都需要检查清单中的每个项目,但你应该有意识地记录你已实现的项目、决定跳过的项目以及相应的原因。

第 2 课:工具集

截至 2018 年,以下是我们在 Gruntwork 中用于构建和管理基础设施的主要工具:



Terraform:我们使用 Terraform 来配置所有的基础设施,包括网络、负载均衡器、数据库、用户、权限以及我们所有的服务器。


Packer:我们使用 Packer 来定义和构建在服务器上运行的虚拟机镜像。


Docker:我们的一些服务器组成了集群,上面运行着托管应用程序作的 Docker 容器。我们使用的主要 Docker 集群工具是 Kubernetes、ECS 和 Fargate。


现在,所有这些工具都很有用,但这不是重点。重点是,光是有这些工具还不够,你还需要改变团队的行为。


特别是,如果你的团队不信赖这些工具,或者你的团队没有足够的时间学习使用这些工具,那么即使是世界上最好的工具都无法为你的团队带来任何帮助。因此,关键的一点是,基础设施即代码是一项投资:需要前期预付成本,但如果你明智地进行投资,将获得长期的巨大好处。

第 3 课:大模块是有害的

基础设施即代码新手通常在单个文件或作为一个单元进行部署的一组文件中定义所有环境(dev、stage、prod 等)的所有基础设施。这是一种糟糕的做法。


以下是这种做法的一些缺点:


  1. 速度慢:如果你的所有基础设施都在同一个地方定义,那么运行任何命令都需要很长时间。我们已经看到公司的 terraform plan 需要 5-6 分钟才能运行完毕!

  2. 不安全:如果你的所有基础设施都是一起管理的,那么在更改内容时都需要可以访问所有内容的权限。这意味着几乎每个用户都必须是管理员。

  3. 风险:如果所有鸡蛋都在一个篮子里,那么任意一个错误都可能会破坏整个系统。你可能正在对 dev 中的前端应用程序进行微小更改,但由于输入错误或运行了错误的命令,可能把生产数据库给删掉了。

  4. 难以理解:在一个地方拥有的代码越多,人们理解它们的难度就越大。如果将它们捆绑在一起,你不理解的部分可能会影响到你。

  5. 难以测试:测试基础设施代码很难,测试大量基础设施代码几乎是不可能的。

  6. 难以评审:诸如 terraform plan 之类的命令的输出变得毫无用处,因为没有人想要查看数千行输出。代码评审也变得毫无用处。


你应该使用小型、独立、可重用、可组合的模块来构建代码。这不是什么有争议的新观点。你之前可能已经听过无数次了:


“一次做一件事,并把它做好”——Unix 哲学。


“函数的第一条规则是它们应该很小。函数的第二个规则是它们应该比小更小。”——《整洁代码之道》

第 4 课:没有自动化测试的基础设施代码太脆弱

如果你的基础设施代码没有经过自动化测试就很容易出问题。你只是不知道一些暗藏的问题。也就是说,测试基础设施代码很难。你没有“localhost”(例如,你无法在笔记本电脑上部署 AWS VPC),也没有“单元测试”(例如,你无法将“Terraform”代码与“外部”隔离开来,因为 Terraform 所做的事情就是与外界交互)。


因此,要正确测试你的基础设施代码,通常需要将代码部署到真实环境,运行真实的基础设施,验证它们做它们该做的事情(对于这种测试方式,请参考 Terratest,一个开源库,包括用于测试 Terraform、Packer 和 Docker 代码的工具)。因此,对于基础设施测试,你必须重新定义一些术语:



  • 单元测试是指部署和测试来自一种基础设施的一个或少量密切相关的模块(例如,测试单个数据库模块)。

  • 集成测试是指部署和测试来自不同类型的基础设施的多个模块,以验证它们是否能够正常协同工作(例如,测试 Web 服务模块和数据库模块)。

  • 端到端测试是指部署并测试整个架构。


这张图是一个金字塔,我们有很多单元测试、较少数量的集成测试和极少数的端到端测试。为什么?这是由每种类型的测试所需要的时间来决定的:



基础设施测试的周期时间很慢,特别是金字塔越往上就越慢,所以你会想尽可能多地在金字塔底层捕捉到错误。这意味着你应该:


  1. 构建小巧、简单的独立模块,并为它们编写大量单元测试。

  2. 将这些小型、简单、经过实战检验的构建块组合在一起,创建更复杂的基础设施,并进行少量的集成和端到端测试。

第 5 课:发布过程

现在让我们把这一切都放在一起。以下是你从现在开始应该采用的构建和管理基础设施的方法:


  • 对照生产级基础设施检查清单,确保你正在构建正确的东西。

  • 使用 Terraform、Packer 和 Docker 等工具将你的基础设施定义为代码。确保你的团队有时间掌握这些工具。

  • 使用小型、独立、可组合的模块构建代码(或使用基础设施中的现成模块作为代码库)。

  • 使用 Terratest 为你的模块编写自动化测试。

  • 提交拉取请求,让别人来评审你的代码。

  • 发布新版本代码。

  • 将你的代码从一个环境推到另一个环境。



英文原文:https://blog.gruntwork.io/5-lessons-learned-from-writing-over-300-000-lines-of-infrastructure-code-36ba7fadeac1


2018-12-04 14:403583
用户头像

发布了 731 篇内容, 共 433.9 次阅读, 收获喜欢 1997 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

书单推荐|书籍是人类的良师益友

图灵教育

书单 教师节

为什么大家偏爱怪异盒模型border-box?

茶无味的一天

CSS 前端 HTML5, CSS3

【C语言难点突破】指针的常见易错点

Geek_65222d

10月月更

Qt|使用QuaZip压缩包中文乱码问题解决

中国好公民st

c++ qt 10月月更

你的方案逻辑自洽吗?

老张

测试方案 思维逻辑

书单推荐|书籍是人类的良师益友

图灵社区

书单 教师节

【牛客刷题-算法】NC141 判断是否为回文字符串

清风莫追

数据结构 算法 刷题笔记 10月月更

【牛客刷题-算法】NC151 最大公约数

清风莫追

数据结构 算法 最大公约数 10月月更

clickhouse准实时数仓能力探索

水滴

实时数仓 OLAP 数仓 10月月更 clickhosue

浅谈中小企业如何正确选择网络营销模式

石头IT视角

Vue项目处理错误上报如此简单

茶无味的一天

Vue 异常捕获

【Nacos源码之配置管理 四】DumpService如何将配置文件全部Dump到磁盘中

石臻臻的杂货铺

nacos 10月月更

在Chrome浏览器中最快速实现拾色器(颜色吸管)

茶无味的一天

前端 谷歌浏览器

Android Coder带你了解反射

子不语Any

后端 java; 10月月更

GitHub上的宝藏级SpringBoot核心文档,拿走不谢!

Geek_0c76c3

Java 数据库 开源 程序员 开发

开发者有话说|在刷怪升级的成长路上,技术人应该掌握的三个大招

迷彩

个人成长 10月月更 学会学习 学会提问 学会思考

【结构体内功修炼】结构体实现位段(二)

Albert Edison

C语言 结构体 10月月更 位段

【一Go到底】第六天---值类型、引用类型、标识符

指剑

Go golang 10月月更

【愚公系列】2022年10月 Go教学课程 020-Go容器之数组

愚公搬代码

10月月更

pgsql数据库自动备份

衝鋒壹号

10月月更

二本Java菜鸟9面字节遭虐,苦修数月深造这份 Java面试宝典,终进阿里

程序知音

Java java面试 程序员面试 后端技术 Java面试八股文

阿里P8面试官总结的《2022最新java面试题》,搞定90%以上的技术面

程序知音

Java 程序员面试 后端技术 Java面试题 Java面试八股文

【牛客刷题-算法】加精 _ 合并两个有序的链表 - 从思路设计、bug排除到最终实现的全过程

清风莫追

算法 链表 算法数据结构 10月月更

Python 3.12 目标:还可以更快!

Python猫

Python

极客时间架构训练营模块二作业

李晨

架构

Redis--Redis事务及错误处理方式

Java学术趴

10月月更

Redis--Redis持久化方式

Java学术趴

10月月更

【Go实现】实践GoF的23种设计模式:访问者模式

元闰子

Go 设计模式 访问者模式

【Nacos源码之配置管理 三】TaskManager 任务管理的使用

石臻臻的杂货铺

nacos 10月月更

踩上元宇宙的风口后,消费级AR眼镜真的复兴了吗?

脑极体

2022-10-06:以下go语言代码输出什么?A:[1 2 3] [1 2 3] ;B:[1 2 3] [3 4 5]; C:[1 2 3] [3 4 5 6 7 8 9];D:[1 2 3] [3

福大大架构师每日一题

golang 福大大 选择题

写了30万行基础设施代码后,我们得出5个有用的经验_架构_Yevgeniy Brikman_InfoQ精选文章