【不可变基础架构】是一条纪律:机器跑起来之后不再改它,要改就改镜像、重建一台——配套的做法叫【基础设施代码化】(IaC),把环境写成代码;这一套之所以要存在,是因为手改过的机器会慢慢变得各不相同,最后没人说得清线上到底是什么状态。
上一节(4-7)讲了声明式:你说想要什么,系统一直让它保持那样。这一节把同一个思路推到基础架构这一层:连机器本身也不再去【修】,而是【换】。
它是前面几节的自然结果——容器(4-6)本来就是一个【换掉比修好更便宜】的东西,而虚拟化(4-4)让【重建一台】只要几分钟。两件事凑齐,才让【不修只换】从一种理想变成一种可行的纪律。
一、要解决的问题:配置漂移
先看后果,再讲做法。
服务器跑起来之后,人总会去动它:打补丁、改配置、装个工具、临时调个参数排查故障。每一次动手,这台机器和【标准状态】就远了一点。 动了几十次、换过几拨人之后:
| 现象 | 后果 |
|---|---|
| 每台机器的配置都不一样 | 出问题的那台无法复现 |
| 说不清线上到底跑着什么版本 | 审计答不上来、合规过不了 |
| 大部分机器没打过某个补丁 | 漏洞长期存在,且没人知道范围 |
| 有机器已经没人用,还在计费 | 成本悄悄漏掉 |
这些现象有一个统一的名字:配置漂移。 它不来自任何一次错误的操作——每一次操作单独看都是合理的,漂移是它们叠加的结果。
二、两个做法,一个思路
教材把这两件事放在一起讲,因为它们是一套的:
| 做法 | 说的是什么 | 落地成什么 |
|---|---|---|
| 不可变基础架构 | 机器不做原地修改,要改就重建 | 一切都是镜像,改了镜像就重建 |
| 基础设施代码化(IaC) | 环境的定义写成代码,而不是操作记录 | 机器、网络、权限都用文件描述 |
为什么必须两个一起:
- 只说【不可变】,但没有【代码化】——你拿什么去重建?重建出来的还是不一样。
- 只说【代码化】,但保留【原地修改】——代码描述的状态和实际状态会分叉,代码就变成了一份过期的文档。
所以这套纪律的完整表述是:环境的定义放在代码里(版本管理,可评审、可回滚),每次变更都通过【改代码 → 出新版本 → 整体重建】来完成,而不是登录上去改。
三、它带来的三个变化
| 变化 | 具体表现 |
|---|---|
| 故障处理变了 | 不再【登录上去修】,而是【先换掉,再离线查这台坏的】 |
| 环境变得可复制 | 测试环境可以从同一份代码重建,和生产完全一致 |
| 变更变得可回滚 | 回滚 = 用上一个版本的代码重建,不依赖人的记忆 |
第一条是最反直觉也最有效的一条:机器出问题时的第一反应从【救它】变成【换掉它】。这样服务恢复的时间和故障原因完全解耦——不需要先搞清为什么坏,就能先恢复。原因慢慢查,业务先回来。
四、动手 Demo:漂移查出来有多少台
看到什么算成功:
==================================================================================================
【Demo 8】不可变基础架构:不修机器,换机器
==================================================================================================
可变做法:服务器跑起来之后,登录上去改配置、打补丁、装东西。
不可变做法:配置写进代码,产出镜像;要改就重出一版镜像、重建机器。
先看可变做法半年之后会发生什么(100 台服务器):
情况 台数 说明
----------------------------------------------------------------------------------------
与基线完全一致 41 台 一次都没手工动过
少打一个补丁 27 台 当时节点在维护,跳过了
配置文件被临时改过 18 台 为了排查故障改了没改回来
多装了一个测试包 9 台 试完忘了卸
已下线但仍在计费 5 台 没人记得它还在跑
----------------------------------------------------------------------------------------
100 台里只有 41 台是【标准状态】,其余 59 台各不相同。
这 59 台就是【配置漂移】,故障复现不了、审计答不上来的根源。
不可变做法把这件事变成:改代码 → 出新镜像 → 整套重建。
手工改机器这条路直接堵死(改了下一次重建就没了)。
基础设施代码化(IaC)的时间账:
手工建 50 台环境(含 IP、安全组、负载均衡):约 40 小时
写成代码后首次执行:约 20 分钟
以后每天重建一次(做测试用):每次 20 分钟,不需要人守着
带来一个额外好处:环境本身进了版本管理,能回滚、能评审。
读结果:
- 41 台这个数字要留意:它意味着接近六成的机器状态是未知的。这不是管理松散,这是可变做法的必然结果——只要允许登录修改,漂移就一定会发生,且速度比想象的快。
- 最后一段的时间账里,最值钱的不是【40 小时变 20 分钟】,而是最后那两行:环境可以每天重建。这件事让【做一次全量测试】的成本从【要排期】变成【顺手做】。
30 秒实验
找一台你能登录的服务器(或者打开云控制台的某一台实例详情页),做三件事:
- 看它的【创建时间】——已经运行了多久。
- 看有没有【从模板创建】或【从快照重建】的入口。
- 想一个问题:如果这台机器现在坏了,你要多久才能让一台一模一样的新机器跑起来?
做完这个你会得到一个很实际的判断:如果答案超过半小时,说明这台机器的状态只存在于它自己身上——那它就是【不可替代】的,而不可替代的机器,是运维最大的负担来源。
常见误区
-
错误:不可变的意思是机器永远不会变。——纠正:它是【不做原地修改】,不是【永不更新】。 变化的路径是【改代码 → 出新镜像 → 换成新机器】——变化一直在发生,而且比以前更频繁(因为变更成本低了)。所以【不可变】这个词说的是修改方式,不是禁止变化。把它理解成【不准动】就完全反了。
-
错误:基础设施代码化只是把操作写成脚本,本质一样。——纠正:区别在【描述目标状态】还是【描述操作步骤】。脚本是我告诉你【先装这个、再改那个、然后重启】——执行到一半出错,状态就卡在中间。代码化描述的是【我要 3 台这样的机器】,由工具负责把实际状态调整到符合描述,并且可以重复执行而不出错。这个差别跟 4-7 讲的声明式是同一件事。
-
错误:这套做法只适合大公司,我们几十台机器用不上。——纠正:越是人少的地方越需要。因为漂移的根源是【靠人的记忆维持一致性】,而人少意味着记忆更少、交接口更少、出错后更没时间查。几十台机器、两三个人的团队,恰恰是最容易出【没人知道线上是什么版本】的队伍。规模小只是意味着可以选更简单的工具,不是可以不守这条纪律。
-
错误:既然机器可以随时重建,那数据也可以。——纠正:这是最危险的一条误解。不可变的是计算节点的状态,而数据必须放在外面(对象存储、数据库、共享存储)——因为重建机器会把本地盘一起丢掉。所以这套做法有一个必须成立的前提:有状态的东西全部外置。做不到这一点就贸然推行不可变,等于定期删数据。
自测三问(点开对答案)
1. 为什么【配置漂移】的每一次成因单独看都是合理的? —— 因为**它们都是应对具体问题的正常操作**:这个补丁先跳过是因为当时在维护、配置改动是为了排查故障、装测试包是为了验证——**每一步都有当时充分的理由**。漂移的可怕之处正在这里:**它不是由错误决策造成的,而是由无数个正确决策的叠加造成的**。所以指望【让大家更小心一点】来解决它是无效的——**只能靠机制,也就是不让人有机会手工改。** 2. 为什么【换掉它,离线再查】能显著缩短故障恢复时间? —— 因为**它把恢复和诊断解耦了**。修复一条传统路径是【先查清原因 → 再修 → 再验证】,其中【查清原因】占的时间往往最长且不可控;而【换掉】这条路**不需要任何诊断结论**就能执行,恢复时间只取决于【重建要多久】——而重建时间是已知的、可控的。**所以这不是【更聪明的修复】,而是【绕开诊断这道关卡】。** 3. 为什么推行这套做法的前提是【有状态的东西全部外置】? —— 因为**重建会丢掉本机的一切**,包括数据。而数据是不能靠重建恢复的——**重建只能恢复【程序该有的样子】,恢复不了【发生过的事实】**。所以这套纪律在架构上的强制要求是:计算节点要变成【用完即弃】的,凡是需要留下来的(用户数据、日志、文件)都必须存在机器之外。**做不到这条,不可变基础架构就是一场灾难**;做到了,它才成立。- ☐ 下一节(4-9 开发与运用间的协调:DevOps)
相关笔记
- 实现多云计算的容器 —— 上一篇:声明式与持续纠偏
- 虚拟化技术为何如此方便 —— 重建一台只要几分钟,才有【换掉比修好便宜】
- 云服务的存储设备 —— 数据为什么要放在机器之外
- 云计算中需要长期支出的费用 —— 没人记得的机器怎么变成长期支出
- ☁️ 云计算 · 索引 —— 全课路线图