DevOps 面试题精选(一):CI/CD 与容器化
CI/CD 与容器化是 DevOps 岗面试的重灾区:概念人人会背,但一问"构建为什么慢""镜像为什么不能每环境重打"就露馅。本文精选 13 道高频题,每道先给结论再拆要点,适合面试前系统过一遍,也可直接当题库用。
本文题目一览
- 流水线如何划分阶段?设计原则是什么?
- CI 构建越来越慢,从哪些地方提速?
- Docker 镜像的分层机制是什么?瘦身为什么先看层?
- 为什么制品晋升不能每个环境重新构建?
- Docker 有哪些网络模型?容器间如何通信?
- 数据卷、绑定挂载、tmpfs 有何区别?
- 镜像仓库要做哪些治理?漏洞扫描门禁怎么落地?
- 蓝绿与金丝雀发布如何实现、如何回滚?
- GitFlow 与主干开发怎么选?
- 配置与密钥如何管理?
- Jenkins 与 GitLab CI 怎么取舍?
- 质量门禁怎么设才不被绕过?
- 流水线不稳定(flaky)怎么治理?
1. 流水线如何划分阶段?设计原则是什么?
结论:流水线是把交付拆成一系列可验证的关卡,典型顺序为 拉代码 → 构建 → 单测 → 静态扫描 → 打镜像 → 推仓库 → 部署测试 → 冒烟测试 → 人工审批 → 上生产。原则就三条:快速失败、反馈前置、制品唯一。
- 快速失败:编译、单测等秒级检查放最前面,越贵的检查越靠后,错了尽早变红;
- 能并行不串行:无依赖任务用 DAG 并行,不要写成一条直线;
- 制品唯一:构建只产出一份制品,后续阶段只搬运验证;流水线定义即代码,进仓库管理。
2. CI 构建越来越慢,从哪些地方提速?
结论:先看日志的时间分布再动手,八成时间通常花在依赖下载与镜像构建上,对应手段是依赖缓存、层缓存、远程缓存,最后才是加机器。
- 依赖缓存:Maven/npm 本地仓库按锁文件哈希做 key 缓存,免去每次全量拉取;
- 层缓存:Dockerfile 先拷依赖描述再拷源码,并用 BuildKit 的
--cache-from拉取仓库缓存跨机复用; - 拆分并行:单测按模块并行、独立服务拆流水线,避免改一行触发全仓构建。
# GitLab CI 缓存与 DAG 片段
stages: [build, test]
build-job:
stage: build
cache:
key:
files: [pom.xml]
paths: [.m2/repository]
script: mvn -DskipTests package
test-job:
stage: test
needs: [build-job]
script: mvn test
3. Docker 镜像的分层机制是什么?瘦身为什么先看层?
结论:镜像由只读层叠加而成,每条 Dockerfile 指令生成一层,运行时用联合文件系统合并呈现;层是共享与缓存的基本单位,体积问题本质是层内容问题。
- 删除不等于瘦身:后续层里
rm只是打白障标记,下层数据还在;清理必须与写入在同一条 RUN 内完成; - 先量化:用
docker history和 dive 看每层大小,大头通常是工具链、包缓存、误拷的 .git; - 顺序影响缓存:稳定的层放前面、常变的源码放后面,一层失效只波及其后的层。
4. 为什么制品晋升不能每个环境重新构建?
结论:重构建意味着测试验证过的东西和生产跑的不是同一个二进制,测试结论直接失效;晋升制保证"测什么就发什么",问题只剩环境差异。
- 构建不可复现:依赖漂移、基础镜像更新都会让两次产物不一致;
- 用 digest 流转:tag 可被覆盖,sha256 digest 才是内容寻址的唯一标识;
- 差异外置:配置、密钥、规格在部署时注入,镜像不感知环境,验证通过后只做复制或改标签。
5. Docker 有哪些网络模型?容器间如何通信?
结论:每个容器有独立网络命名空间,默认 bridge 模式下经虚拟网桥与 veth 对互通、出网走 NAT;跨主机则用 overlay 或云上的 CNI。
- bridge:默认模式,端口靠
-p映射;自定义 bridge 自带 DNS,可用容器名互访; - host:共享宿主机网络栈,性能好但端口易冲突、无隔离,生产慎用;
- none / container:无网络,或与另一容器共享命名空间——K8s Pod 的多容器正是这个原理。
6. 数据卷、绑定挂载、tmpfs 有何区别?
结论:容器可写层不适合存数据(随容器销毁而丢失),持久数据放命名卷,配置与调试用绑定挂载,敏感临时数据用 tmpfs。
- 命名卷:由 Docker 管理生命周期,备份与共享统一,是数据库数据目录的首选;
- 绑定挂载:直映射宿主机路径,所见即所得,但与单机目录结构绑死,迁移和权限问题多;
- 原则:能把状态外置到外部数据库或对象存储就不本地落盘,这是横向扩容的前提。
7. 镜像仓库要做哪些治理?漏洞扫描门禁怎么落地?
结论:仓库治理管三件事——谁能推、存多久、什么质量能进生产;漏洞扫描要做成流水线门禁而不是事后报告,否则扫了也白扫。
- 分层管理:开发仓库可自由推送,生产仓库只接收晋升镜像、禁止直推;
- 保留策略:按数量与时间自动清理旧 tag,已上线版本打不可变标记防误删;
- 扫描与签名:Trivy 等在 CI 扫描,Critical 漏洞阻断晋升;Cosign 签名、部署侧验签,防 tag 被替换。
8. 蓝绿与金丝雀发布如何实现、如何回滚?
结论:蓝绿是两套完整环境一次切换,回滚就是切回去,简单但资源翻倍;金丝雀按比例逐步放量,回滚是权重归零,粒度细但依赖流量治理。
- 蓝绿:新版部署到绿环境,自检通过后由负载均衡或 Service 一次切走全部流量,蓝环境待命;
- 金丝雀:借助 Ingress、Service Mesh 或 Argo Rollouts 按 5% → 20% → 50% 放量,每阶段看错误率与延迟;
- 共同前提:数据库变更必须向前兼容(先加列不删列),否则哪种策略都回滚不了数据。
9. GitFlow 与主干开发怎么选?
结论:看发布节奏——要长期维护多个已发布版本、按月发版的交付制软件适合 GitFlow;持续交付、每天多次上线的服务适合主干开发,分支活不过两天。
- GitFlow 的代价:分支众多、合并冲突与发版等待成本高,与 CI 小步快跑天然冲突;
- 主干开发的前提:强 CI 门禁、特性开关兜底未完成功能、评审节奏跟得上;
- 折中形态:GitHub Flow(主干 + 短命分支 + PR)是多数团队的实际上限。
10. 配置与密钥如何管理?
结论:普通配置与密钥分开管:配置随环境注入,密钥绝不进仓库和镜像,运行时从密钥系统按需拉取并能轮换。
- 环境变量:简单、符合十二要素,但明文可见、改动要重启,只适合非敏感配置;
- Vault:集中存储、动态短期凭证、审计齐全,适合合规要求高的环境,代价是多运维一套高可用组件;
- Sealed Secrets / SOPS:加密后的 Secret 存进 Git、私钥只在集群内,契合 GitOps;CI 侧密钥要用平台掩码变量,日志禁止回显。
11. Jenkins 与 GitLab CI 怎么取舍?
结论:存量插件资产多、流程高度定制、要对接老系统选 Jenkins;代码本就在 GitLab、追求开箱即用选 GitLab CI。选型问的是团队约束,不是工具优劣。
- Jenkins:插件生态无敌、共享库能沉淀复杂流程;代价是插件兼容与控制器升级全靠自己;
- GitLab CI:YAML 即配置、与仓库权限一体、Runner 弹性简单;深度定制和跨仓编排弱一些;
- 共同治理点:流水线定义进仓库、执行节点无状态可弹性、凭据集中托管,与选哪家无关。
12. 质量门禁怎么设才不被绕过?
结论:门禁贵在"少而硬":只卡不能进生产的红线(编译失败、单测失败、Critical 漏洞、核心模块覆盖率下限),其余指标做告警与趋势;且结果必须与合并、发布权限绑定。
- 覆盖率看增量:卡全量会逼出无意义测试,应卡新增代码覆盖率与核心模块下限;
- SAST 分级:高危注入类阻断发布,低危进技术债清单限期治理;
- 防绕过:分支保护把门禁设为合并前置条件,紧急发布走留痕的审计通道而不是后门,并定期复盘人工放行记录。
13. 流水线不稳定(flaky)怎么治理?
结论:把流水线当生产系统运维:先分清平台、代码还是用例的问题,flaky 用例要隔离和量化,不能靠"重跑直到绿"掩盖。
- 分层定位:同时段多条流水线一起红,先查 Runner 与网络等平台层;单条红才往代码与用例查;
- flaky 治理:统计用例历史通过率,不稳定的打标移出主干门禁、限期修复,禁止无限期躺隔离区;
- 可观测:运行时长、排队时长、失败原因分类要上看板,构建变慢是渐进的,没数据就发现不了。
面试官视角
这组题考的不是背诵,而是候选人有没有真正"养过"一条流水线。区分度最高的几道:制品晋升(讲得清 digest 与"测什么发什么"的,一定踩过重构建的坑)、镜像分层(知道删除不瘦身、清理要同层,说明真动手优化过)、质量门禁(能说出"少而硬、看增量、防绕过"的,是被门禁与业务双方夹击过的)。加分回答的共同特征:先给原则,再落到自己环境的具体参数,并主动说出方案的代价,如蓝绿的资源成本、主干开发对 CI 强度的依赖。只报工具名、把 Jenkins 与 GitLab CI 答成参数对比表的,通常停留在使用者层面。







