想象你是一家连锁餐饮集团的中央厨房负责人。过去,每家门店的厨师都按自己理解“现场发挥”——今天多放盐,明天少放糖,顾客抱怨口味不稳定。于是你决定改革:所有菜品在中央厨房统一制作,做成一盒盒标准化的“餐盒”,每盒贴上唯一的编号,封条一撕即知真假,谁也不能打开改菜。每天配送车按时把新餐盒送到门店,门店只负责加热、上桌。这套“中央厨房出餐”模式,就是不可变镜像CI/CD流水线在软件世界的翻版——每次代码提交,流水线自动“炒菜、装盒、贴标、配送、上桌”,全程标准化、可追溯、可回退。本文就当一次“中央厨房带班培训”,零基础也能看懂整套流程。

岗位关联

在 DevOps 和云原生时代,掌握不可变镜像流水线是发布工程师、平台工程师的必修课。它能让你把“上线像搬家”变成“上线像换菜谱”,显著提升发布效率与稳定性,是撑起现代基础设施的关键能力。

目录
  1. 可视化演示
  2. 流水线设计与阶段规划
  3. 镜像构建与不可变产出
  4. 版本管理与标签策略
  5. 自动化测试与质量门禁
  6. 安全扫描与镜像签名
  7. 蓝绿部署切换
  8. 金丝雀发布
  9. 回滚与失败处理
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示CI/CD流水线从代码提交到镜像构建、质量门禁、蓝绿部署与金丝雀发布的完整流程。

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

CI/CD流水线构建流程 青色流水线从代码提交到镜像构建、测试、安全扫描、推送,每阶段通过质量门禁后进入下一步 Code → Build → Test → Scan → Push 不可变镜像保证环境一致性

流水线设计与阶段规划

中央厨房改革的第一步,不是马上炒菜,而是先画一张“出餐流程图”:原材料入库→中央厨房烹饪→品控试吃→封装贴标→冷链配送→门店上桌。每一站都有明确的职责和验收标准。软件世界的 CI/CD 流水线也一样,第一步是设计阶段,把从代码提交到上线的过程拆成清晰的环节。

典型的不可变镜像流水线分为三大环节:构建(炒菜)、测试与质量门禁(品控试吃)、部署与发布(配送上桌)。每个环节内部还可以细分子步骤,比如构建阶段包括拉取依赖、编译代码、生成镜像;测试阶段包括单元测试、集成测试、性能基准。每个阶段的出口都要有“质量检查员”把关,不合格的餐盒不允许流到下一站,这就是出口条件。

1. 构建时间:从代码提交到生成可用镜像的总耗时。

构建=编译+打包镜像\displaystyle \text{构建}=\text{编译}+\text{打包镜像}

2. 测试/门禁时间:自动化测试与质量检查消耗的时间。

测试=单元测试+集成测试+门禁检查\displaystyle \text{测试}=\text{单元测试}+\text{集成测试}+\text{门禁检查}

3. 部署/发布准备时间:推送镜像到仓库、准备环境的耗时。

部署准备=镜像推送+环境预配置\displaystyle \text{部署准备}=\text{镜像推送}+\text{环境预配置}

把流水线设计成清晰的阶段,就像给中央厨房画好动线图。有了动线,工人才知道下一站去哪;有了流水线,开发者才知道代码下一步去哪。好的阶段规划是所有自动化流程的地基。

text1 行
\text{交付周期}=\text{构建时间}+\text{测试/门禁时间}+\text{部署/发布准备时间}

镜像构建与不可变产出

中央厨房改革的核心纪律是:每一餐都重新做,绝不在昨天的剩菜上加工。今天有优化就按新配方重新炒一锅,炒完装进新餐盒,贴上“新配方”的标签。昨天的餐盒原封不动留档。对应到软件世界,就是每次代码提交都触发一次全新的镜像构建,产出全新的镜像,而不是在旧镜像上打补丁。

为什么要这样做?因为“不可变”意味着每一次构建的结果都精确对应一份源代码版本。Docker 镜像是一个只读的模板,它通过内容哈希(content hash)计算出一个唯一的标识——sha256:xxxx,就像餐盒上印着这盒菜的全部原料信息。内容不同,哈希就不同;哈希相同,内容必然一致。这就让镜像拥有了“指纹级”的身份认证。

有了不可变镜像,生产和部署就彻底解耦了。生产车间只管按配方产出标准餐盒,门店(运行环境)只负责拆盒使用。不会再出现“测试时好好的,上线就崩”的玄学——因为上线的餐盒和测试的是同一盒,哈希对得上,质量就对得上。

digest=SHA256(镜像内容层)\text{digest}=\text{SHA256}(\text{镜像内容层})
镜像ID是全部内容层哈希后的结果,等于给镜像内容做了一次身份证认证。
  1. 镜像内容层构建产生的文件系统变更集合。
    内容层={l1,l2,…,ln}\displaystyle \text{内容层}=\{l_1, l_2, \dots, l_n\}
  2. SHA256 哈希对全部内容做单向摘要计算。
    digest=SHA256(l1∥l2∥…∥ln)\displaystyle \text{digest}=\text{SHA256}(l_1 \Vert l_2 \Vert \dots \Vert l_n)
  3. 唯一身份只要内容不变,digest 就不变。
    内容一致  ⟺  digest一致\displaystyle \text{内容一致}\iff \text{digest一致}

版本管理与标签策略

餐盒要送到上百家门店,光有指纹还不够,还得有门店看得懂的编号。比如“川味宫保鸡丁·2024-06-14·批次A3”。软件世界也一样,镜像 digest 是给机器看的,人需要友好可读的标签(tag)来追溯版本。

标签策略的核心原则是:标签永不覆盖。每次发布都用新的标签,比如 myapp-v1.2.3-8f3a9c、myapp-v1.2.4-9c1e2b,而不是重复使用 latest 去覆盖旧镜像。因为一旦覆盖,历史版本就丢失了,回滚时找不到旧餐盒,就像门店想退回上周的口味却被告知“那批已销毁”。

好的标签策略让每个镜像都有“出生证明”。你可以随时说出线上跑的是哪个版本、对应哪次代码提交。就像中央厨房的每盒餐品都印着配方版本号,一旦出问题,精准召回那一批即可,不用把所有餐盒都倒掉。

tag=应用名−语义化版本−commit短哈希\text{tag}=\text{应用名}-\text{语义化版本}-\text{commit短哈希}
推荐格式为“应用名+版本号+Git提交短哈希”,既保留语义版本又精确定位源码。
  1. 应用名标识这个镜像属于哪个服务。
    app=前序名\displaystyle \text{app}=\text{前序名}
  2. 语义化版本主版本。次版本。修订号。
    version=Major.Minor.Patch\displaystyle \text{version}=\text{Major}.\text{Minor}.\text{Patch}
  3. commit 短哈希Git 提交的短哈希。
    hash=commit前7位\displaystyle \text{hash}=\text{commit}^{\text{前7位}}

自动化测试与质量门禁

中央厨房的品控部有铁面无私的试吃员——不对,AI 时代用自动化设备,每个餐盒都要经过自动化测试:称重、测温度、检测营养成分、扫描异物。软件世界的自动化测试就是这样的质检设备,在镜像构建完成后自动运行。

测试通过还不够,还要过质量门禁(quality gate):覆盖率是否达标?性能基准是否合格?安全隐患是否清零?这些门禁像品控表上的硬指标,任意一项红灯,餐盒就被拦截,不允许进入发布流程。门禁不是形式,而是自动化的“裁判”。

自动化测试和质量门禁把“人盯人”的发布变成机器值守。没有门禁时,代码好坏全凭老司机手感;有门禁后,菜好不好吃由数据说话。中央厨房的出品率因此稳定在99.9%,软件发布的信心也因此翻倍。

门禁通过条件=测试通过⏟功能正常  ∩  覆盖率≥80%⏟测够范围  ∩  性能达标⏟跑得够快\text{门禁通过条件}=\underbrace{\text{测试通过}}_{\text{功能正常}}\;\cap\;\underbrace{\text{覆盖率}\ge 80\%}_{\text{测够范围}}\;\cap\;\underbrace{\text{性能达标}}_{\text{跑得够快}}
质量门禁的本质是一组必须同时满足的硬性条件,保证出厂的餐盒既好吃又安全。
  1. 测试通过单元/集成/端到端测试全部绿。
    Test=Unit∩Integ∩E2E\displaystyle \text{Test}=\text{Unit}\cap\text{Integ}\cap\text{E2E}
  2. 覆盖率被测试代码行数占比。
    Coverage=覆盖行数总行数≥80%\displaystyle \text{Coverage}=\frac{\text{覆盖行数}}{\text{总行数}}\ge 80\%
  3. 性能达标P99 延迟低于阈值。
    P99<threshold\displaystyle \text{P99}<\text{threshold}

安全扫描与镜像签名

餐盒封条是中央厨房的信任基础。软件世界对应两道防线:安全扫描(漏洞检测)和镜像签名(防篡改封条)。

安全扫描器拿着已知漏洞数据库(如 CVE 库)逐一比对镜像内的软件包版本,就像安检员扫描行李里的违禁品。一旦发现高危漏洞,扫描结果是 FAIL,镜像被拦下。镜像签名则用私钥对镜像 digest 进行签名,部署时验证签名,确保这个镜像确实来自可信构建系统,而不是被中途调包的“毒品餐盒”。

安全扫描和签名让每个镜像都“验明正身”。中央厨房的餐盒有封条,门店收货先验封条再上架;集群部署前先验证签名,防止从不可信仓库拉取镜像。这套信任链是云原生安全的地基。

验证成功  ⟺  Verifypubkey(Signprivkey(digest))=true\text{验证成功}\iff \text{Verify}_{\text{pubkey}}(\text{Sign}_{\text{privkey}}(\text{digest}))=\text{true}
私钥签名、公钥验证,保证镜像来源可信且未被篡改,相当于餐盒封条工艺。
  1. 签名用私钥对 digest 加密签名。
    σ=Signprivkey(digest)\displaystyle \sigma=\text{Sign}_{\text{privkey}}(\text{digest})
  2. 验证用公钥检查签名一致性。
    Verifypubkey(σ)=digest?\displaystyle \text{Verify}_{\text{pubkey}}(\sigma)=\text{digest}?
  3. 信任链只有验证通过才准部署。
    信任  ⟺  验证通过=true\displaystyle \text{信任}\iff \text{验证通过}=\text{true}

蓝绿部署切换

现在到了发布环节。传统的滚动更新像“一家家门店慢慢换菜谱”,新旧口味混杂,顾客体验不一致,一旦新菜有问题,要一家家改回来,速度慢。中央厨房的答案是蓝绿部署:同时开两家店——蓝店卖旧餐盒,绿店卖新餐盒。两套环境同时存在,各自完整、独立。

发布时,不做任何“改造”,只是在路由层轻轻拨一下开关:把入口流量从蓝店切到绿店。顾客感觉不到任何中断,因为两店都在营业。如果绿店出问题,再拨一下开关切回蓝店,回滚瞬间完成。

蓝绿部署把发布从“动手术”变成“切开关”。不需要停机、不需要渐进修改,只需要路由器拨一下。同时,蓝环境作为“保温柜”一直保留,直到确认新版本稳定后才回收,留足了后悔药。

切换:  Router={Blue旧版本Green新版本\text{切换}:\;\text{Router}=\begin{cases}\text{Blue} & \text{旧版本}\\\text{Green} & \text{新版本}\end{cases}
蓝绿部署的本质是在路由层做流量切换,应用本身零改动,因此切换和回退都极快。
  1. 路由指向路由器决定流量去蓝还是绿。
    流量目的地=路由规则\displaystyle \text{流量目的地}=\text{路由规则}
  2. 切换动作只改一个路由配置。
    Blue→Green\displaystyle \text{Blue}\rightarrow\text{Green}
  3. 回退动作反向改回配置。
    Green→Blue\displaystyle \text{Green}\rightarrow\text{Blue}

金丝雀发布

蓝绿是“一刀切”:要么全旧、要么全新。但有些时候,我们不放心直接把所有流量切到新版本,比如这次新菜加了新调料,想先在少数门店试水。这就是金丝雀发布——让新版本先服务一小部分流量,观察无异常后再逐步放量。

设想流量共 100 份,金丝雀先给新版本 5 份,观察指标(错误率、延迟)正常,再放大到 20% → 50% → 100%。整个过程由自动化指标驱动,监控系统是“试吃员”,指标异常会自动暂停甚至回滚放量。

金丝雀发布是渐进式发布的风险控制手段。如果说蓝绿是“换开关”,金丝雀就是“慢慢拧水龙头”——水流大小由指标说了算,手感不好随时拧回去。它特别适合新功能有不确定性或重大架构变更的场景。

金丝雀流量比例  r=新版本份数总份数={120, 15, 12, 1}\text{金丝雀流量比例}\;r=\frac{\text{新版本份数}}{\text{总份数}}=\left\{\frac{1}{20},\,\frac{1}{5},\,\frac{1}{2},\,1\right\}
金丝雀发布按预设梯度逐步放量,每一步都以观测指标为准,异常即暂停。
  1. 初始小流量5% 流量先试新。
    r1=120\displaystyle r_1=\frac{1}{20}
  2. 逐步放量20%、50%、100%。
    r2=15,  r3=12,  r4=1\displaystyle r_2=\frac{1}{5},\;r_3=\frac{1}{2},\;r_4=1
  3. 指标驱动每步验证后再放量。
    ri+1=f(errori,latencyi)\displaystyle r_{i+1}=f(\text{error}_i,\text{latency}_i)

回滚与失败处理

最后聊最关键的保命技能:回滚。在不可变镜像流水线里,回滚不是“修复”而是切换——切回上一个已验证的好版本。就像新菜不好吃,中央厨房不会尝试在原盒里改佐料,而是直接把配送单改回上周的经典款。

回滚的速度取决于两个因素:旧版本的镜像是否完好可用、切换路由是否够快。因为镜像不可变,旧版本永远躺在仓库里,随时可以重新拉起;因为蓝绿和金丝雀的架构,切换只需要改路由或调整流量比例。整个过程以观测指标(错误率、延迟、饱和度)为触发信号。

回滚能力是发布安全的最后防线。不可变镜像流水线最大的温柔,就是“永远留好退路”。每一份旧餐盒都完好封存在仓库,每一个切换开关都随时可用。正因为回滚快,发布才敢快;正因为不可变,回滚才可靠——这是一切自动化发布自信的源头。

MTTR回滚=检测到异常+切换路由+确认恢复\text{MTTR}_{\text{回滚}}=\text{检测到异常}+\text{切换路由}+\text{确认恢复}
回滚的恢复时间 = 发现问题的速度 + 切换的速度 + 验证的时间。不可变镜像让后两项几乎为0。
  1. 检测异常监控指标触发告警。
    Alert  ⟺  error_rate>θ1  或  latency>θ2\displaystyle \text{Alert}\iff \text{error\_rate}>\theta_1\;\text{或}\;\text{latency}>\theta_2
  2. 切换路由拨回上一版本。
    Route:vnew→vprev\displaystyle \text{Route}: v_{new}\rightarrow v_{prev}
  3. 确认恢复指标回归正常。
    Recovered  ⟺  error_rate≤θ1\displaystyle \text{Recovered}\iff \text{error\_rate}\le\theta_1

AI 应用场景

Kubernetes 蓝绿部署实现零宕机发布

阶段:部署与发布

解决的问题:传统停止旧服务再启动新服务会导致分钟级停机,在业务高峰期是不可接受的。利用不可变镜像 + Kubernetes Deployment 双副本集合,实现蓝绿两套环境并存,路由切换秒级生效,发布过程零感知。

具体案例:某电商平台在大促前更新订单服务,使用 kubectl 将新版本镜像部署为绿色 Deployment,待就绪探针通过后,将 Service 的 selector 从蓝色切到绿色,流量瞬间切换到新版本。验证无异常后回收蓝色环境,整个发布过程用户无感知。

金丝雀发布保护大模型推理服务

阶段:模型服务的灰度上线

解决的问题:大模型版本升级(如推荐模型参数更新)如果直接全量替换,一旦新模型效果不佳或推理延迟上升,将影响大量用户。用金丝雀发布先给 5% 流量使用新模型镜像,指标稳定后逐步放量。

具体案例:某推荐系统团队更新模型镜像,通过流量管理将 5% 请求路由到新模型容器,实时监控 CTR(点击率)与 P99 延迟,连续 30 分钟无异常后放量到 20% → 50% → 100%。发现指标异常时自动切回旧版本,将影响面控制在最小范围。

Python 演示

python49 行
import hashlibimport random  class ImmutablePipeline:    def __init__(self):        self.build_count = 0        self.images = {}        self.ready_list = []     def build_image(self, code_version):        self.build_count += 1        content = "app-v{}".format(code_version)        digest = hashlib.sha256(content.encode()).hexdigest()[:16]        tag = "myapp-{}-{}".format(code_version, digest[:7])        self.images[tag] = digest        return tag     def run_test(self, tag):        return random.random() < 0.95     def quality_gate(self, tag, coverage):        return self.run_test(tag) and coverage >= 80     def canary_deploy(self, tag, steps=(5, 20, 50, 100)):        for ratio in steps:            healthy = random.random() < 0.9            print("  canary {}% -> {}".format(ratio, "ok" if healthy else "rollback"))            if not healthy:                return False        return True     def release(self, tag, coverage):        if tag not in self.images:            raise ValueError("tag not found")        if not self.quality_gate(tag, coverage):            raise RuntimeError("quality gate failed")        print("deploy {} (blue/green switch)".format(tag))        if self.canary_deploy(tag):            self.ready_list.append(tag)            print("release success: {}".format(tag))        else:            print("rollback to previous: {}".format(self.ready_list[-1]))  if __name__ == "__main__":    pipe = ImmutablePipeline()    new_tag = pipe.build_image("1.4.0")    pipe.release(new_tag, coverage=92)
目的:演示不可变镜像流水线的核心流程——构建、测试门禁、金丝雀发布与回滚。
  1. digest = hashlib.sha256(content.encode()).hexdigest()[:16]用 SHA-256 为镜像内容生成指纹,内容变则指纹变。
  2. tag = "myapp-{}-{}".format(code_version, digest[:7])标签 = 应用名 + 版本号 + 哈希前缀,实现标签永不覆盖。
  3. self.quality_gate(tag, coverage)质量门禁:测试通过且覆盖率达标才放行。
  4. self.canary_deploy(tag, steps=(5, 20, 50, 100))金丝雀发布按 5%→20%→50%→100% 渐进放量。
  5. if not healthy: return False任一阶段指标异常立即触发回滚。
  6. self.ready_list[-1]回滚时直接切回上一个已验证的版本,而不是修复当前版本。

常见误区

误区不可变镜像是不是以后代码改了也没法更新?那怎么迭代?

正解不可变不是“不能发布新版本”,而是“已发布的旧镜像不允许篡改”。每次迭代都构建一个全新镜像,用新标签发布新版本,旧镜像保持原样留存。就像新菜上市不改变旧菜谱,而是直接出新品。

为何常见:把“不可变”误解为“不能用”,其实“不可变”指的是历史记录不可更改,与更新迭代完全兼容。

误区蓝绿部署不就是一个个重启实例吗?跟滚动更新差不多。

正解蓝绿部署是两套完整环境并存、路由切换,实例数量不变,切换瞬间完成;滚动更新是逐步替换实例,新旧版本在一段时间内共存。蓝绿的回退更快(切路由即可),滚动更新的回退需要再次逐台替换。

为何常见:二者都涉及新旧版本,但机制完全不同。混淆它们会导致设计发布方案时选错架构。

误区出了 bug 赶紧写一个补丁包,直接更新线上实例修复。

正解在不可变流水线里,回滚 = 切换到上一个已知良好的镜像版本,而不是修改当前镜像。修复是下个版本的事,当前线上只需要快速恢复服务。类似于餐盒坏了不会在盒子里炒菜,而是退回上一批完好餐盒。

为何常见:传统运维的习惯是“就地修复”,而不可变哲学是“快速切换”。不理解这一点,就无法体会不可变带来的恢复速度优势。

误区为了赶版本,质量门禁先跳过,安全扫描发现漏洞也先放着,反正线上不一定被触发。

正解质量门禁和安全扫描是流水线的自动闸门,跳过它们等于放弃最后一道防线。高危漏洞不修复直接上线,等同带病上岗,事故概率大增。正确做法是让漏洞阻断发布,推动修复后再走流水线。

为何常见:短期进度压力下,人容易“图快”而忽略安全。但自动化门禁的价值就在不受情绪影响地守住底线。

误区每次都打 `latest` 标签,简单方便,反正只需要最新的。

正解latest 标签被覆盖后,一旦新版本出问题,你无法快速找到上一个可用镜像,回滚就会很困难。不可变标签策略要求每次构建都使用唯一标签,让每个镜像都可追溯、可回滚。

为何常见:追求方便是人类本能,但在生产环境中,可追溯性和可回滚性比“少打字”重要得多,好习惯一开始就值得养成。

面试题

Q1. 不可变镜像的核心特征是什么?

单选题 · easy

  • A.镜像内容可以随时修改和推送更新
  • B.镜像一旦构建,内容不再被篡改,发布新版时构建全新镜像← 正确答案
  • C.镜像只在开发环境不可变,生产环境可以随意改
  • D.镜像内容完全固定,不允许再新增功能迭代

答案:B。不可变镜像的关键是“构建后内容不改变”,迭代通过构建新镜像实现而非修改旧镜像。A 描述的是可变镜像,C 与不可变性矛盾,D 混淆了“不可变”与“不能迭代”。

Q2. 镜像的 digest(摘要)由什么计算得到?

单选题 · easy

  • A.镜像的名称和标签拼接后哈希
  • B.镜像全部内容层的内容哈希计算得出← 正确答案
  • C.镜像构建时的系统时间戳哈希
  • D.镜像仓库地址哈希

答案:B。digest 是对镜像内容层做 SHA-256 等哈希运算的结果,是内容的指纹。名称、标签、时间、仓库都只是外部元数据,不影响 digest,内容相同则 digest 必然相同。

Q3. 以下哪个标签策略最符合不可变镜像最佳实践?

单选题 · mid

  • A.每次构建都覆盖 latest 标签
  • B.使用 v1.0.0、v1.0.1 等唯一标签并永不覆盖← 正确答案
  • C.用日期作为唯一标签,版本号仅写在备注里
  • D.标签随意命名,只要人记得住

答案:B。唯一标签且不覆盖是核心原则,便于追溯与回滚。覆盖 latest 会丢失历史,只用日期不便于语义化定位,随意命名违背可追溯性原则。选项 B 最符合不可变与可追溯要求。

Q4. 蓝绿部署中“切换”操作的本质是什么?

单选题 · mid

  • A.将旧环境实例逐一关停再启动新环境
  • B.在路由/负载均衡层将流量从一套环境切到另一套环境← 正确答案
  • C.修改镜像内容让新环境兼容旧环境
  • D.同时向两套环境发送全部流量

答案:B。蓝绿部署本质是两套完整环境并行,切换只发生在路由层。A 是滚动更新的思路,C 违反了不可变性,D 描述的是双活而非蓝绿切换。

Q5. 金丝雀发布的主要目的是什么?

单选题 · mid

  • A.用最少资源同时运行所有版本
  • B.让新版本先接收少量流量,验证指标稳定后再逐步放量← 正确答案
  • C.在镜像构建前用金丝雀测试代码质量
  • D.一次性将所有流量切换到新版本

答案:B。金丝雀发布的核心是风险控制——小流量验证、渐进放量、异常即回。A 描述的负载多版本混跑不是金丝雀;C 属于测试范畴;D 是全量发布的思路。

Q6. 不可变镜像流水线的质量门禁可以包含哪些检查项?

多选题 · mid

  • A.自动化测试是否通过← 正确答案
  • B.代码覆盖率是否达到阈值← 正确答案
  • C.容器镜像的高危漏洞扫描是否清零← 正确答案
  • D.发布负责人当天心情是否好

答案:ABC。质量门禁必须全部机器自动执行、可量化、可重复。A、B、C 都是标准自动化门禁项,D 是主观因素,无法自动化和复制,也不应成为门禁。

Q7. 在蓝绿部署中,为什么旧版本环境应保留到确认新版本稳定后再回收?

单选题 · hard

  • A.为了节省云资源费用而按量计费
  • B.为了提供秒级回滚能力,随时切回旧版本← 正确答案
  • C.为了双环境分担流量压力
  • D.为了给新版本做灰度测试

答案:B。保留旧环境的意义在于回滚的“后悔药”。只要旧环境还在,发现新版本异常即可立即切回。A 的云费用反而增加,C 不是蓝绿的核心目的,D 的灰度是金丝雀的职能。

Q8. 以下哪些做法有助于提升回滚速度?

多选题 · hard

  • A.每次发布前确认旧镜像仍保存在仓库中← 正确答案
  • B.部署架构预留路由切换能力(蓝绿或金丝雀)← 正确答案
  • C.将回滚流程编写为自动化脚本并定期演练← 正确答案
  • D.发现问题后手动登录服务器改代码重新编译

答案:ABC。A 保证有旧版本可回,B 保证切换通道,C 保证回滚流程可靠,三者共同决定回滚速度。D 是“就地修复”思路,与不可变理念相悖,速度慢且风险高。

Q9. 镜像签名的主要作用是什么?

单选题 · easy

  • A.让镜像体积可变,签名时自动压缩
  • B.保证镜像来源可信且内容未被篡改← 正确答案
  • C.让镜像运行速度变快
  • D.标记镜像由哪个开发者构建

答案:B。签名用私钥对 digest 加密,部署时用公钥验证,确保镜像是可信构建系统产出且没被篡改。A、C 与签名无关,D 是标签或元数据的功能。

Q10. 金丝雀发布过程中,当监控指标出现异常时正确做法是什么?

单选题 · mid

  • A.立即将所有流量切到新版本,让问题迅速暴露
  • B.暂停放量并回滚到上一稳定版本,待修复后再发布← 正确答案
  • C.继续按原计划放量,观察指标是否自行恢复
  • D.只回滚出问题的实例,其他服务不受影响

答案:B。金丝雀发布的纪律是“指标异常即暂停或回滚”,这正是它控制风险的价值所在。A 反其道而行,C 是碰运气,D 忽略了异常指标的全局性,正确做法就是 B。