想象一座古老的书院。在印刷术诞生之前,书院里只有一本《论语》母本,管理员发现错字就直接拿笔涂改,几年下来母本上批注层叠、墨迹斑驳。更麻烦的是,学者们借去抄录,各自抄出不同版本——甲抄本保留了批注,乙抄本漏掉了修订,丙抄本甚至抄错了段落。读者拿到哪一本,全凭运气。这就是传统“可变服务器”的写照:每台机器上线后不断被 SSH 登录修改,打补丁、改配置、装软件,时间一长,每台机器都变成了独一无二的“手抄本”,环境之间谁也信不过谁。 印刷术出现后,书院彻底变了:文稿先被刻成一块铅字母版,母版一旦铸成便不再改动;要印书,就用母版批量刷印,每本一模一样;发现错字,不手改任何一本,而是重新刻版、重新印刷,旧书回收销毁。这个“刻版—印刷—回收—重刻”的循环,正是不可变服务器的灵魂:镜像如同母版,服务器如同印出的书,更新不是修改,而是整本替换。

岗位关联

掌握不可变服务器理念,你将懂得如何用“替换”代替“修改”来管理基础设施,大幅降低环境漂移风险,是成为云原生架构师、高级 DevOps 工程师的关键一步。

目录
  1. 可视化演示
  2. 核心理念:从手抄本到印刷术
  3. 镜像机制:刻好母版,一印定音
  4. 运维收益:千书一面,批量管理
  5. 挑战应对:书页之外,另设账簿
  6. 容器化结合:一版母版,印出无数卷
  7. 自动化部署:印刷流水线与发行策略
  8. 实战落地:书院清点与发行之道
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

对比可变服务器(原地修改致配置漂移)与不可变服务器(镜像替换保证纯净)的架构差异,展示构建→推送→部署→切换→清理五步流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

可变vs不可变服务器 可变:原地修改导致配置漂移和环境不一致 不可变:镜像替换保证环境纯净可回滚 不可变服务器是现代云原生架构的核心原则

核心理念:从手抄本到印刷术

书院的演变是理解不可变服务器最好的入口。手抄本时代,母本被反复涂改,抄本各自为政,管理员每天都要处理“甲乙两本哪本才对”的纠纷。对运维工程师来说,这种噩梦叫环境不一致——测试环境调好的配置,生产环境却怎么都复现不出来,因为每台机器都被不同的工程师改过,早已面目全非。

传统可变服务器正是如此:部署后,工程师通过 SSH 登录,打补丁、改配置、装软件,机器状态一天天偏离最初的设计。而不可变服务器提出一个相反的纪律:一台服务器一旦部署上线,就进入“只读”状态,任何人不得登录修改;需要变更时,用新镜像构建一台全新服务器,把流量切过去,旧服务器直接回收。

不可变服务器的生命周期只有四个动作:构建 → 发布 → 运行(只读) → 销毁。修复问题不能在运行中的实例上完成,必须回到构建阶段,产出新版本镜像,再走一遍发布流程。衡量一台服务器是否“跑偏”了,可以看它当前状态与基线状态的偏差:

印刷术的启示在于:修改这个动作,应该发生在构建时,而不是运行时。 母版刻错了就重刻,书页印坏了就重印,唯独不能在每一本书上分别补丁。不可变服务器把同样的纪律带进了基础设施。

Δ(S,S0)=∥S−S0∥\Delta(S, S_0) = \| S - S_0 \|
这是“漂移”的数学直觉——S 是当前状态,S₀ 是镜像定义的理想状态,偏差越大,环境越不可信;不可变服务器让这个偏差始终为零。
  1. 当前状态 S服务器此刻真实的状态,包括文件系统、软件版本、配置项。
    SS
  2. 基线状态 S₀镜像构建时固化的黄金状态,相当于母版定稿的内容。
    S0S_0
  3. 偏差范数\|·\| 表示度量两部分状态差异大小的一种方式,差异越多值越大。
    ∥⋅∥\|\cdot\|
  4. 漂移量 Δ可变服务器中这个值随时间增长且不可控,不可变服务器中恒为 0。
    Δ(S,S0)=0\Delta(S, S_0) = 0

镜像机制:刻好母版,一印定音

印刷术的灵魂是那块铅字母版:工匠把文稿反刻在金属板上,一旦铸成,字形永恒;要改内容,只能重刻一块。母版可以反复刷印,每一本都一模一样。在不可变服务器里,承担母版角色的是镜像。

构建镜像时,我们把操作系统、运行时、依赖库和应用代码一次性打包成只读文件系统快照,再附上一份启动配置说明。这个快照就是“印出来的书页”的模板。镜像被推送到镜像仓库后,就视为不可变——没有人会去修改仓库里已经归档的母版。

镜像的“版次号”由内容决定,称为内容寻址。对镜像所有文件内容计算哈希,得到唯一的镜像 ID;任何字节发生变化,ID 就会面目全非。同一 ID 在任何机器上还原出的文件系统完全一致。

镜像仓库就是书院的母版库。每位工程师拉取同一镜像 ID,就像各分馆领到同一批印本,内容分毫不差。母版不动,就不可能有人“顺手”改出一本不同的书来。

ID(M)=SHA256(rootfs∥config)\text{ID}(\mathcal{M}) = \text{SHA256}(\text{rootfs} \parallel \text{config})
镜像 ID 是内容的指纹,内容变了指纹就变。这保证了“同一 ID = 同一母版 = 同一批书”。
  1. 镜像内容集 M整套镜像包含的所有文件和元数据。
    M\mathcal{M}
  2. 根文件系统 rootfs镜像里所有文件目录的集合,对应书页上的全部文字。
    rootfs\text{rootfs}
  3. 配置元数据 config进程启动参数、环境变量默认值等启动说明。
    config\text{config}
  4. 拼接符号 ∥把文件内容和配置说明首尾相连作为整体输入。
    rootfs∥config\text{rootfs} \parallel \text{config}
  5. 哈希函数 SHA256把任意长度内容压缩成固定长度的指纹,内容微变结果剧变。
    SHA256(⋅)\text{SHA256}(\cdot)

运维收益:千书一面,批量管理

印刷术让书院从“逐本管理”升级为“按批管理”。新增十本藏书,直接印十册,不必一本本誊抄校对;回收旧书,成批销毁;读者拿到的永远是内容一致的官方版本。不可变服务器给运维带来的是同样的质变。

首先是环境一致性:同一镜像 ID 部署一百台服务器,它们的行为高度一致,测试通过等于生产大概率通过。其次是消除配置漂移:没有登录修改的入口,漂移失去来源。然后是部署更快速:新服务器是“印”出来的,而不是“改”出来的。

部署耗时的对比尤其直观。可变部署依次执行 n 条变更命令,耗时是命令时间之和;不可变部署只需拉取镜像、启动服务:

千书一面,批量管理。书院不再雇人逐本涂改,运维不再逐台 SSH 打补丁。故障恢复也因此简单:坏一台扔一台、再印一台,而不是诊断“这台机器当年被谁改过什么”。

Timmutable=Tpull+Tstart≪∑i=1ntiT_{\text{immutable}} = T_{\text{pull}} + T_{\text{start}} \ll \sum_{i=1}^{n} t_i
当变更命令很多时,不可变部署节省的时间非常可观;而且每条变更命令都可能失败,命令越多风险越大。
  1. 拉取镜像时间 T_pull从镜像仓库下载新镜像的耗时。
    TpullT_{\text{pull}}
  2. 启动服务时间 T_start新实例从启动到通过健康检查的耗时。
    TstartT_{\text{start}}
  3. 逐条变更总时间 Σtᵢ可变部署中依次执行第 i 条变更命令 tᵢ 的累加。
    ∑i=1nti\sum_{i=1}^{n} t_i
  4. 远小于符号 ≪表示前者通常比后者小一个数量级以上。
    ≪\ll

挑战应对:书页之外,另设账簿

印刷术有个天然短板:书页印好了就不好再写字,可读者总想记笔记、贴书签。书院的解法很朴素——把笔记写到单独的笔记本上,书还是那本印刷书,笔记跟着人走,绝不污染公共版本。不可变服务器面对的挑战完全相同:状态往哪里放。

答案就是配置注入和数据外置。配置不属于镜像内容,而是在启动时通过环境变量、配置中心或挂载注入;数据更是要写入外部持久化存储,如数据库、对象存储、云盘。服务器本身是无状态的“印刷品”,随时可弃,但笔记本上的内容永存。

一台不可变服务器的运行时状态,可以拆成三个互不干扰的部分:

书印坏了换一本,笔记留在笔记本上不受影响;实例崩溃了换一台,数据在存储服务中安然无恙。把易变的东西请出书页,书才可能永远不朽——这就是不可变服务器应对“状态”难题的智慧。

state(server)=image∪cfginjected∪volumesexternal\text{state}(\text{server}) = \text{image} \cup \text{cfg}_{\text{injected}} \cup \text{volumes}_{\text{external}}
只读镜像 + 注入配置 + 外部数据卷,三者并集构成完整状态。这样既保持了不可变性,又让应用可以产生和读取数据。
  1. 服务器状态 state一台服务器运行时的全部事实,包括代码、配置、数据。
    state(server)\text{state}(\text{server})
  2. 只读镜像 image由母版固化的部分,永远不会被修改。
    image\text{image}
  3. 注入配置 cfg_injected启动时由外部传入的环境变量或配置项。
    cfginjected\text{cfg}_{\text{injected}}
  4. 外部数据卷 volumes_external挂载进来的持久化存储,指向外部服务。
    volumesexternal\text{volumes}_{\text{external}}
  5. 并集符号 ∪完整状态是三者组合,组合的方式清晰且可复现。
    ∪\cup

容器化结合:一版母版,印出无数卷

书院有了印刷术后,遇到热门典籍一天能印几百本,分发到各分馆,内容完全一致。母版只有一套,书却可以无限复制。容器正是这套逻辑在现代基础设施中的实现。

容器镜像是分层的只读文件系统,运行时容器只读使用镜像层;容器可以频繁创建和销毁,更新时直接换新容器,而不是钻进容器里改文件。Kubernetes 等编排系统把“替换”变成了第一操作:滚动更新、金丝雀发布,本质都是不同节奏的“换新版印刷品”。

一个镜像可以同时启动无数个容器,每个容器通过环境变量获得少量个性化配置。这种一对一多的关系,可用符号表达:

母版一遍遍印出相同的书卷,镜像一次次实例化为相同的容器。容器化不是“要不要用”的问题,而是“不可变理念最自然的降落点”。

∀c∈C: img(c)=M,cfg(c)=f(M,envc)\forall c \in \mathcal{C}: \ \text{img}(c) = \mathcal{M}, \quad \text{cfg}(c) = f(\mathcal{M}, \text{env}_c)
所有容器都基于同一个镜像 M,个性化只体现在 env_c 上。容器之间的差异被压缩到最小,漂移无从滋生。
  1. 容器集合 C某一次发布中运行的全部容器实例。
    C\mathcal{C}
  2. 任意容器 c遍历集合中的每一个具体容器。
    c∈Cc \in \mathcal{C}
  3. 容器所用镜像 img(c)每个容器都锚定到同一个镜像版本。
    img(c)=M\text{img}(c) = \mathcal{M}
  4. 配置函数 f容器配置由镜像基础配置和自身环境变量共同计算得出。
    f(M,envc)f(\mathcal{M}, \text{env}_c)

自动化部署:印刷流水线与发行策略

印刷术成熟后,书院建立了流水线:排版、校对、印刷、装订、发行,每一关都有检验,不合格不进入下一环。发行时也不会一次性把新书丢满全城,而是先让少数读者试读,确认无误再批量分发。不可变服务器的发布,同样依赖自动化部署这条流水线。

从代码提交到上线,一切都通过部署流水线完成:构建镜像 → 跑自动化测试 → 推送到仓库 → 触发发布。其中最关键的是健康检查——新实例必须通过探针确认可用,才允许继续替换下一批。基础设施即代码则保证整个环境定义是评审过的、可版本化的。

新版本流量的放大通常不是一步到位,而是渐进式的灰度策略。金丝雀发布中,新版本接收流量的权重随时间平滑增加,常可用这样的曲线描述:

流水线把关 + 渐进发行,让“换一个印刷版”变得可预测、可中止、可退回。书院不会砸掉旧版库存才印刷新版,滚动部署也永远保留旧镜像作为后路。

w(t)=11+e−k(t−t0)w(t) = \frac{1}{1 + e^{-k(t - t_0)}}
这是一个 S 形曲线:起初只有少量流量试探,然后加速放量,最后收敛在全量。如果中途告警,随时把权重打回零,切回旧版。
  1. 流量权重 w(t)新版本在任意时刻接到的流量比例,取值 0 到 1。
    w(t)w(t)
  2. 自然常数 e约等于 2.718,用于构造平滑变化的曲线。
    ee
  3. 放量速度 kk 越大,从少量到全量切换得越快。
    kk
  4. 放量中点 t₀权重变化最剧烈的时间点,通常对应 50% 流量。
    t0t_0
  5. 指数项 e^-k(t-t₀)随时间增大而衰减到 0,推动权重逼近 1。
    e−k(t−t0)e^{-k(t - t_0)}

实战落地:书院清点与发行之道

书院的经营不仅靠刻板印刷,还要清点库存、登记发行、定期修订。印刷术只是手段,真正让书院井然有序的,是从“定稿—印刷—发行—回收—修订”的完整闭环。不可变服务器的实战落地,同样要靠配套的工程习惯。

团队需要立下铁律:禁止 SSH 登录线上修改任何文件,所有变更必须通过流水线。与此同时,监控告警要盯住版本切换期间的错误率与延迟,版本管理要保留每个历史镜像,形成可回退的“母版库”。

回滚是实战中最响亮的收益。旧镜像静静躺在仓库里,回滚不是反向执行一堆变更命令,而是把流量切回旧镜像:

从母版刻制到库存清点,印刷术改变的是书院的工作方式。不可变服务器也一样——技术工具只是表象,把“不修改、只替换”刻进团队习惯,才是一切的归宿。

r(t)=Nnew(t)Ntotal,Trollback=O(1)r(t) = \frac{N_{\text{new}}(t)}{N_{\text{total}}}, \quad T_{\text{rollback}} = O(1)
新版本覆盖率 r(t) 描述替换进度;一旦告警,回滚时间与实例数量无关,几乎瞬间完成。
  1. 新版本实例数 N_new某个时刻运行新镜像的实例数量。
    Nnew(t)N_{\text{new}}(t)
  2. 实例总数 N_total整个服务集群的实例总量。
    NtotalN_{\text{total}}
  3. 覆盖率 r(t)新版本在当前集群中的占比,从 0 增长到 1。
    r(t)=Nnew(t)Ntotalr(t) = \frac{N_{\text{new}}(t)}{N_{\text{total}}}
  4. 回滚时间 T_rollback从发现问题到流量全部切回旧版的时间。
    Trollback=O(1)T_{\text{rollback}} = O(1)

AI 应用场景

云原生平台发布工程师的滚动发布

阶段:模型/应用服务的生产部署与版本迭代

解决的问题:传统发布需要登录每台服务器执行变更脚本,环境差异导致发布失败频繁。通过不可变服务器 + 容器编排,新版本镜像在流水线中构建并验证,滚动替换旧实例,健康检查失败自动回滚,发布过程可预测、可审计。

具体案例:某互联网公司每天发布 20 次 Web 服务,工程师将应用打包为不可变镜像,配合 Kubernetes 滚动更新与金丝雀策略。发布后若错误率上升,系统自动切回旧镜像,发布时长从 40 分钟缩短到 3 分钟,环境不一致导致的故障下降 80%。

MLOps 模型服务的版本固化

阶段:机器学习模型上线与在线推理服务管理

解决的问题:模型更新频繁,版本混乱且难以回退。将模型、依赖库和推理代码一起固化为不可变镜像后,每次上线都是新镜像实例的替换,灰度验证模型效果后再全量,A/B 测试也变成简单的流量切换。

具体案例:某推荐系统团队把特征工程代码和模型权重打包进镜像,通过不可变部署管理每日模型更新。某一版模型指标异常时,工程师一条命令切回上一镜像版本,线上服务从发现异常到恢复不到 90 秒,避免了重新训练和紧急补丁的混乱。

安全合规环境的审计保障

阶段:金融/政务场景的合规审计与安全取证

解决的问题:审计要求“线上环境可证明未被篡改”,可变服务器很难自证清白。不可变服务器将所有变更固化为镜像版本记录,审计人员可以通过镜像 ID 追溯每一个环境的确切内容,无需信任运行实例的自述。

具体案例:某金融机构将核心交易系统的服务器全部改为不可变模式,任何变更都留下“镜像版本号 + 流水线记录”。合规检查时,审计方直接核对部署记录与镜像哈希链,原本两周的环境盘点缩短为一天,且证据链完整性显著提升。

Python 演示

python55 行
# -*- coding: utf-8 -*-"""Immutable server rolling deployment simulator."""import randomimport time  class Server:    """One immutable server instance, version never changes after born."""     def __init__(self, sid, version):        self.sid = sid        self.version = version     def __repr__(self):        return "S{}({})".format(self.sid, self.version)  class RollingDeployer:    """Rolling deployer: replace old instances with new image ones."""     def __init__(self, total, batch_size):        self.total = total        self.batch_size = batch_size        self.servers = [Server(i, "v1") for i in range(total)]     def health_check(self, server):        """Health check: 5 percent chance to fail."""        return random.random() > 0.05     def deploy(self, new_version):        print("Start rolling deploy -> %s" % new_version)        old_servers = list(self.servers)        new_servers = []        for i in range(0, self.total, self.batch_size):            for j in range(i, min(i + self.batch_size, self.total)):                repl = Server(old_servers[j].sid, new_version)                if not self.health_check(repl):                    print("  Instance %s failed, rollback now" % repl)                    self.servers = old_servers                    print("Rollback done, keep v1 image pool")                    return False                new_servers.append(repl)            self.servers = old_servers[:]            for k in range(len(new_servers)):                self.servers[k] = new_servers[k]            print("  Progress: %d/%d replaced" % (len(new_servers), self.total))            time.sleep(0.2)        print("Deploy done: %s" % self.servers)        return True  if __name__ == "__main__":    deployer = RollingDeployer(6, 2)    print("Initial: %s" % deployer.servers)    deployer.deploy("v2")
目的:模拟不可变服务器的滚动部署——按批用新镜像实例替换旧实例,健康检查失败时立即回滚到旧镜像池。
  1. class Server:一台不可变实例,创建后版本永不改变,对应“印出的书页”。
  2. self.servers = [Server(i, "v1") for i in range(total)]初始集群全部运行旧版本 v1。
  3. def health_check(self, server):模拟新实例的探针检查,5% 概率失败。
  4. repl = Server(old_servers[j].sid, new_version)按新镜像创建替换实例,而不是修改旧实例。
  5. if not self.health_check(repl):新实例不健康就触发回滚,保留旧镜像池。
  6. self.servers = old_servers[:]回滚就是整体换回旧实例列表,体现 O(1) 级切换。
  7. for k in range(len(new_servers)):只替换已通过健康检查的槽位,实现滚动脉冲。

常见误区

误区“我用了 Docker 和 Kubernetes,容器每天重启,所以我已经是不可变服务器了。”

正解容器是不可变理念最常见的载体,但理念的核心是“运行时不修改、更新用替换”。传统虚拟机配合预置镜像和自动化替换同样可以不可变;反过来,如果团队频繁 docker exec 进容器改文件,即使全容器化也不算不可变。判断标准永远看更新方式:是修改还是替换。

为何常见:容器化与“替换式发布”几乎同时流行,工具带来的直观印象让人把手段当成了本质。

误区“服务器只读,那数据库写入、日志落盘、用户上传文件岂不是都不行?”

正解不可变指的是“镜像层/系统盘”不修改,而不是应用不能产出数据。数据库数据应写入外部存储服务,日志应发送到日志中心,临时文件可写入实例的临时盘但丢得起。数据不属于服务器,属于持久化服务——就像笔记写在本子上,而不是书页上。

为何常见:把“不可变”误解为“绝对静态”,忽略了服务器作为计算执行者的本来职责。

误区“镜像要一成不变,那不同环境就得分别做镜像,每个环境一个模板。”

正解恰恰相反,配置应当通过环境变量或配置中心在启动时注入,镜像保持单一可复用版本。开发、测试、生产使用同一个镜像 ID,只是注入的配置不同,这样才真正保证了环境一致性——同一本书,不同读者自己的笔记。

为何常见:混淆了“镜像不可变”与“一切输入都来自镜像”,没有理解运行时注入机制。

误区“出了故障要回滚,还不是需要重新构建旧环境?那和可变服务器的反向操作一样慢。”

正解旧镜像始终保存在镜像仓库中,回滚只是把流量或调度切回旧镜像,新的实例替换由编排系统几乎瞬时完成,T_rollback = O(1)。真正慢的是可变服务器的“反向执行变更命令”,因为要猜测哪条命令该被撤回。

为何常见:把回滚想象成手工重装系统,没有意识到“保留母版”带来的即取即用优势。

误区“我买了云厂商的托管主机,挂了会自动重建,所以我已经是不可变了。”

正解实例自动重建是云平台的基础能力,不等于你的团队遵循不可变实践。如果日常操作仍是 SSH 登录改配置、在运行实例上装包,那么基础资源再“弹性”,你仍然活在可变服务器时代。不可变是团队的操作纪律,不是云厂商的营销功能。

为何常见:把平台底座的能力错当为自身架构实践,忽略了流程层面的判断标准。

面试题

Q1. 不可变服务器的核心运行原则是什么?

单选题 · easy

  • A.部署后只读,更新时整机替换← 正确答案
  • B.部署后定期打补丁修复问题
  • C.部署后允许手工修改配置项
  • D.部署后不定期安装软件补丁

答案:A。用印刷术比喻:书印好后不手改,要改就重印整本替换。A 准确描述了不可变原则;B、C、D 都是可变服务器时代的操作方式。

Q2. 用“印刷术”类比不可变服务器,铅字母版对应什么?

单选题 · easy

  • A.运行中的服务器实例
  • B.不可修改的服务器镜像← 正确答案
  • C.外部持久化数据存储
  • D.配置中心的配置项

答案:B。母版是批量印刷的源头,对应固化了系统内容、内容不可修改的服务器镜像。实例是印出来的书,数据卷是笔记本,配置中心是分发规则。

Q3. 以下哪一项属于不可变服务器带来的直接收益?

单选题 · easy

  • A.消除环境之间配置漂移← 正确答案
  • B.允许运维直接修改代码
  • C.减少服务器资源占用率
  • D.避免创建新版本镜像

答案:A。不可变服务器关闭了运行期修改入口,环境状态由镜像锁定,配置漂移失去来源。B、D 违背不可变原则,C 与不可变性无直接关系。

Q4. 镜像内容发生任何细微变化后,镜像 ID 通常如何变化?

单选题 · mid

  • A.保持不变便于版本复用
  • B.由构建时间戳顺序递增
  • C.随内容哈希变化而改变← 正确答案
  • D.由注册仓库随机分配

答案:C。镜像采用内容寻址,ID 是对镜像内容计算哈希得到的指纹;内容一变,指纹就变。这保证了同一 ID 一定对应完全相同的母版内容。

Q5. 不可变架构中,运行期配置应该主要放在哪里?

单选题 · mid

  • A.写入镜像内基础配置层
  • B.启动时注入的环境变量← 正确答案
  • C.部署后手工修改配置文件
  • D.写入本地临时缓存文件

答案:B。配置是“读者的笔记本”,应通过环境变量或配置中心在启动时注入。写进镜像会破坏镜像复用性,手工改配置会引入漂移,本地缓存没有持久性保障。

Q6. 滚动部署中发现新实例健康检查失败,正确操作是什么?

单选题 · hard

  • A.强制继续替换全部剩余实例
  • B.暂停部署并回滚到旧版本← 正确答案
  • C.忽略失败实例继续灰度放量
  • D.登录失败实例手工修复镜像

答案:B。健康检查是流水线的质检关卡,失败说明新“印本”有问题,应立即切回旧镜像池,而不是强行推进。登录修复更是完全违背不可变原则。

Q7. 金丝雀发布中流量权重逐渐放大的过程,最接近哪种数学曲线?

单选题 · hard

  • A.常数函数保持权重不变
  • B.阶跃函数瞬间全量切换
  • C.sigmoid 函数平滑过渡← 正确答案
  • D.对数函数反向缩小权重

答案:C。金丝雀发布初期少量试探、中期加速、末期收敛,正是 sigmoid 的 S 形过渡。常数函数不推进,阶跃函数等于蓝绿切换,对数函数方向相反。

Q8. 不可变服务器通常通过哪些方式实现更新?(多选)

多选题 · mid

  • A.构建新版本镜像并发布← 正确答案
  • B.替换运行中的服务器实例← 正确答案
  • C.远程登录修改系统配置
  • D.通过编排滚动或灰度替换← 正确答案

答案:ABD。不可变更新 = 新镜像 + 新实例 + 编排替换,三者构成“重新印刷发行”的闭环。C 是典型的可变操作,是这套体系明确禁止的行为。

Q9. 不可变服务器中,下列哪些状态应放到实例之外?(多选)

多选题 · mid

  • A.数据库持久化数据文件← 正确答案
  • B.应用运行时的日志输出← 正确答案
  • C.用户上传的图片文件← 正确答案
  • D.镜像内置的应用代码

答案:ABC。数据、日志、用户文件都是“读者的笔记”,应外置到存储与日志中心,让实例保持可弃状态。应用代码本就在镜像中,不属于外置对象。注意 C 中的图片文件属于持久化数据,故选。

Q10. 团队声称“已在用不可变服务器”,以下哪种现象说明他们并未真正落实?

单选题 · extreme

  • A.通过 SSH 登录临时修改 nginx 配置← 正确答案
  • B.出现问题直接回滚到旧镜像版本
  • C.所有环境使用同一镜像 ID 部署
  • D.发布流程全部经镜像流水线完成

答案:A。SSH 登录改配置正是不可变服务器明令禁止的“手抄本式涂改”。B、C、D 都是规范实践:回滚保底、镜像统一、流程自动化。识别“伪不可变”要从操作习惯判断,而不是看工具。