为什么不可变的基础设施
假设我们有一个应用程序。为了生成可交付成果,我们需要从源代码构建它。这包括编译源代码,处理和复制资源,以及可能的更多步骤。
最简单的形式是这个过程如下所示:
生成的应用程序可交付物(通常是基于JVM的应用程序的.jar或.war文件)
- 一个单一的不可变单位
- 构建一次并存储在工件存储库中
- 每次更改后都会通过持续集成系统进行再生
软件堆栈
当然,应用程序不会直接在裸机上运行。无论是在笔记本电脑上还是在服务器上,它都需要一堆软件来执行。
典型的服务器应用程序需要应用程序服务器(嵌入在应用程序中或不嵌入应用程序中)和语言运行时(如JVM)。语言运行时本身使用各种库,并在驱动硬件的操作系统内核之上运行。
多台机器和环境
除最简单的项目外,应用程序需要运行几台机器,并将其组织在多个环境中。 应用程序逐渐从环境升级到环境。 这确保了在生产中运行的是在测试中进行的测试。为了达到这个目的,将相同的应用程序从工件存储库中提取出来并部署到不同的机器上:
这避免了在每个环境中构建独立工件的经典错误,并有效地避免了在所有机器上运行可能不同的东西的风险。
然而,当我们看看我们堆栈的其余层时,这正是发生的事情!
系统管理员的工作是确保这些机器尽可能相同,但每个都是单独构建的。所有更改,补丁和升级都需要在所有机器上执行。这项任务的复杂性和众多移动部件使得这难以可靠实现。即使使用自动化配置工具和配方,一些小细节也很容易通过裂缝!
那么可能会出现什么问题呢?
这里只是问题的简短列表,其中大部分可能已经遇到:
- 一些额外的软件丢失
- 资源(目录,...)已经以错误的名称创建
- 安装了某些软件的错误版本(通常是带有错误的旧版本)
- 权限设置不正确
- 一个关键资源(端口,...)被占用
如果这些都是风险,那么我们为什么不 通过应用相同的原则来构建它们,而使我们的系统与我们的应用程序保持相同的标准?
当我们需要的是一群克隆人时,为什么我们仍然在建造艺术品和雪花服务器?
不可变基础设施
这是不可变基础设施进入的地方。
整个机器现在不是只装配应用程序,而是作为一个单一的不可变单元打包。它包含整个软件堆栈,并在每次更改后由持续集成服务器重新生成:
无需担心在所有层上更新许多移动部件,整个机器图像现在都从环境升级到环境。有效地最终确保我们在生产中运行的是我们在测试中测试的结果。