大卫·伊斯特曼回顾了“云原生”族谱——包括他在容器管理、编排和扩展方面的经验。
译自 From Cards to Clouds: A Family Tree of Developer Tools,作者 David Eastman。
随着 BASIC 60 岁生日 和 SQL 50 岁生日,我受到启发,回顾了软件开发的过去。然后,当我看到 Ian Miell 为演示文稿制作的图表(他是 Container Solutions 的合伙人)时,我立刻意识到它将成为一个很好的设备,可以用来记录一些历史。
并非所有工具都已放置在图表中——只有 Ian 认为取得了深思熟虑的进步的工具才被放置在图表中。例如,我非常熟悉的配置工具 Ansible 就缺失了。如今,许多处于职业生涯中期的开发者无疑会将 Kubernetes 视为“云原生”树中可识别的最终结果。但本文更关注之前发生的事情。所以让我们跳回去。
虽然 打孔卡 听起来真的很神秘,但它们在 20 世纪 80 年代被用于我们的学校。计算机研究课程中非常早期的学生使用一种称为 CESIL(学校教学语言计算机教育)的语言用打孔卡编写指令。这些指令被发送到大型机进行处理,结果以打印输出的形式返回。不用说,很少有孩子能运行任何东西。而且计算机仍然不受欢迎。
虽然像 Microsoft Windows 这样的图形用户界面 (GUI) 帮助在普通民众中普及了谁可以使用计算,但 shell 脚本 是程序员第一次看到一个进程如何可以通过一系列命令来控制的,*以及这如何成为程序代码本身的一个独立域。
第一个悄无声息的革命之一是停止以一系列命令来思考。从顺序编码到 声明式 形式的概念飞跃——并不是每个人都使用这个术语。只有当有足够的可用内存和系统空间来分离需要做什么和如何做这两个概念时,这才是可能的。SQL 是声明式语言的一个很好的例子,因为我们陈述了我们想要创建或看到的内容,但没有确切地提及如何或在哪里(甚至为什么)它应该发生。这开启了计算机成为计算工具的道路,但这两者仍然保持着微妙的独立性。它也略微违背了“程序员”作为机械输入代码行的工作者的想法,并预示着我们走向“开发者”时代。
在 90 年代初,当我第一次想使用 C 语言构建可执行程序时,我需要 Make。它既是一个声明式工具,也是最早的软件生产自动化工具之一。正如我们在 查看 Zig 时所回忆的那样,C 需要将源代码组合在一起,包括头文件,将语言编译成目标代码,然后将所需的库链接到一个可执行格式中。因此,有一系列事件需要完成,这些事件是从指令和目标文件类型中推断出来的。
从 make 观察图表,tar 文件是第一个组织尝试,用于制作可移植的文件集以进行部署。我第一次在 zip 文件中看到它,但它引入了相同概念——它用于使目标系统看起来像开发系统。这是对配置管理的早期探索。
源代码控制(或版本控制,在图表中 tar 的右侧)花了相当长的时间才变得相关。文件和存储很昂贵,而且程序很小。但随着规模和时间投入的增长,以及协作概念变得司空见惯,工具变得必不可少。CVS(并发版本控制系统)是第一个公认的客户端-服务器系统,用于跟踪代码存储库中的更改。我记得与我的团队讨论从 SVN 转移到 Git。Git 并不是一个简单的销售对象,因为它有添加、提交和推送代码这三个基本步骤,而之前的源代码控制系统只有两个步骤。Git 将你的本地机器视为一个有效的存储库。
使用脚本——或配方——适用于任何主要配置管理器(Ansible、Chef 或 Puppet),这意味着到 2000 年代,开发者必须充分了解管道。这使他们更接近生产过程的其他部分,例如质量保证 (QA),因为他们在管道中更靠后的位置进行测试。
Git 中重要的“分布式”部分并不是它不需要一个中心存储位置——大多数组织仍然使用 BitBucket 运行一个 GitLab 或 GitHub。这是因为“真实来源”可以合理地分布到分支中。可以系统地理解“主分支”和当前“发布分支”之间的差异。这是在协作时保持理智的主要技术。分支可以与环境(如暂存、测试和生产)相结合。
Java 是这一时期的主要语言,它使用 Maven 进行 依赖管理 以提取丢失的 工件。为了解决所有问题,它通常会提取感觉像是整个互联网的内容,以确保本地存储库拥有构建项目所需的一切。
Jenkins 是项目分支的成功结果,是持续集成/持续开发 (CI/CD) 成功关键。它自动执行从源代码管理中提取代码、构建代码,然后将其交付到环境(可能用于自动化测试)的过程。我记得有人创建了物理交通信号灯来显示我们的中央构建是否正常工作。周五晚上试图在交通信号灯为红色时下班是件糟糕的事情,并且让人们养成了在周末结束时不提交破坏性更改的习惯。
最后,我们迎来了云时代的曙光。当您实际上无法接触到自己的基础设施时,提前说明您想做什么就变得更加重要。我们现在处于 2010 年代。由于现在通常会向开发人员团队发放笔记本电脑,因此需要以某种方式将 Linux 体验捕获到 Windows 或(如果您幸运的话)Mac 上。我记得使用 Oracle 的 VirtualBox 等早期虚拟机 (VM)。如果我们尝试使用带有 GUI 的 Linux 操作系统,则 VM 必须处理棘手的部分,例如确保笔记本电脑的鼠标在 Ubuntu 等系统中正常工作。
隔离原则在 VM 中得到执行,并最终在 容器 中得到完善,容器不会尝试抽象出整个物理机。
Docker 一直是云采用的关键,因为它允许开发人员与容器通信,而无需过多担心容器所在的位置。然后,担心整体基础设施的责任可以转移到其他地方。现在,我们不再有一个项目,而是一个 镜像。
今天,我们处于图表底部,重点已转移到容器管理、编排、扩展和监控。
云为我们提供了新的机遇和许多不同的问题。亚马逊一家公司成功控制了云开发的思维方式——我们的工件或组件现在是 EC2 和 S3。开发人员已经了解了互联网的变幻莫测,从峰值容量到数据存储的地理位置和合法性。
现在,我们正在等待生成式 AI 的进一步影响。有人可能会认为“云原生”的概念不再那么流行,因为 GitOps 旗舰 Weaveworks 已不再活跃。
但该图表不一定与云、声明式编程甚至 DevOps 有关。我在不考虑这些术语的情况下使用过此处提到的大多数工具。当然,这是一段曲折的旅程,因为我们花更多时间研究如何尽可能少地处理更改结果。
这里的历史也与协作的价值以及对真实来源的持续搜索有关。然而,在未来一段时间内,开发人员仍会说出“但在我的机器上可以工作”这句话。