路线图

面试 · 概念解释型

星辉 2026-07-02 阅读 12 min 2,447 字 路线图
面试 · 概念解释型 封面

用自己的话讲清楚。考察对核心概念的深度理解,而非死记硬背定义。每题参考答案 300-500 字,需体现「为什么这样设计」「代价是什么」「实战中怎么落地」三个维度。


子类 1:DevOps 理念概念#

题目1:CALMS 模型是什么?为什么 L(Lean 精益)被很多团队忽视?它和 DORA 指标有什么关系?#

问题: CALMS 是 DevOps 的核心框架之一,请用自己的话解释 CALMS 五个字母的含义,重点说明为什么 Lean(精益)这一字母在落地时最容易被忽视,以及它和 DORA 四指标的关系。

参考答案:

CALMS = Culture(文化)+ Automation(自动化)+ Lean(精益)+ Measurement(度量)+ Sharing(共享)。Culture 强调打破开发与运维的部门墙,失败不甩锅;Automation 强调把可重复的流程工具化,从代码提交到部署全链路自动化;Lean 强调消除浪费、小批量流动、价值流持续优化;Measurement 强调用数据驱动决策,避免凭感觉治理;Sharing 强调知识、工具、教训跨团队流通。

Lean 最容易被忽视的原因是它不像 Automation 那样有具体工具可买、不像 Measurement 那样有指标可看,它是一种思维方式:识别价值流中的等待、返工、过度生产。常见表现是团队上了全套 CI/CD 工具,但 PR Review 等待 3 天、发版审批 5 个人签字、环境互斥排队——这些都是精益视角下的浪费,但不会被工具自动暴露。

和 DORA 的关系:DORA 四指标(Deployment Frequency 部署频率、Lead Time 变更交付时间、Change Failure Rate 变更失败率、MTTR 平均恢复时间)是 Measurement 层的具体度量,但也是 Lean 的体检表。(注:2021 年 DORA 增补第 5 指标 Reliability 可靠性——前四项测「交付快不快」,可靠性测「系统稳不稳」,防止团队只追速度牺牲稳定。)Lead Time 长 = 价值流有等待;Deployment Frequency 低 = 小批量流动没做到。所以 CALMS 是道(理念),DORA 是术(怎么度量有没有做到),两者配合才能闭环。实战中先把 DORA 指标亮到看板上,团队自然会回头去识别 Lean 浪费,比空讲「我们要精益」有效得多。

题目2:GitOps 的四条公理是什么?为什么说"CI 直接 kubectl apply"不是 GitOps?#

问题: GitOps 不是「把 yaml 存进 git」那么简单。请列出 OpenGitOps 工作组定义的四条公理,并解释为什么"Jenkins/GitLab Runner 拿着 kubeconfig 直接 apply"不符合 GitOps。

参考答案:

OpenGitOps 四条公理:① 声明式(Declarative)—— 系统期望状态全部以声明式配置描述;② 版本化且不可变(Versioned & Immutable)—— 所有状态在 Git 有版本,可追溯可回退;③ 自动拉取并持续收敛(Pulled Automatically & Continuously Reconciled)—— 控制器主动从 Git 拉取,持续对比实际状态与期望状态;④ 可审计且可自愈(Auditable & Self-healing)—— 任何漂移能被检测、按需收敛或告警。

判别 GitOps 的金标准只有一条:看谁持有 kubeconfig。如果是 Jenkins / GitLab Runner 持有集群 admin token 执行 kubectl apply,这是 CIOps 不是 GitOps。原因:① CI 持有集群凭据,攻击面大;② push 模式 apply 完就走,没人持续 reconcile,手动改了集群状态没人管;③ 多集群扩展时每个集群都要给 CI 配凭据、打通网络;④ 回滚要重新跑流水线而不是 git revert。

真正的 GitOps 是 pull 模式:控制器(ArgoCD/Flux)部署在集群内,主动拉 Git diff 收敛。好处是凭据不外泄(集群内拉 Git 只需 read-only)、漂移自动纠正(selfHeal)、回滚 = revert commit、多集群扩展只需在新集群装一次 controller。实战中很多人混用:CI 负责构建镜像 + 改 GitOps 仓库的 image tag,CD 由集群内 controller 收敛——CI 和 CD 的边界就是「谁持有 kubeconfig」。

题目3:IaC(Infrastructure as Code)的"声明式"和"命令式"有什么本质区别?为什么 Terraform 比 Shell 脚本更适合管理基础设施?#

问题: 很多团队用 Bash 脚本管理基础设施也算 IaC 吗?请解释声明式 IaC 和命令式脚本的本质区别,以及为什么 Terraform/HCL 比Shell 脚本更适合。

参考答案:

命令式脚本(Bash/Ansible 的某些用法)描述"怎么做":先执行 A,再执行 B,如果失败就重试。声明式 IaC(Terraform/OpenTofu/Pulumi)描述"要什么样":期望有 3 个子网、1 个 VPC、2 个 RDS 实例,由工具自己算出怎么从当前状态收敛到期望状态。

本质区别在四个维度:① 可重入性——声明式 IaC 跑 100 次结果一样(幂等),命令式脚本第二次跑可能因为资源已存在而报错;② 状态感知——Terraform 有 state 文件记录当前真实状态,diff 出来的是「需要做什么」,Shell 脚本每次都从头判断;③ 依赖管理——Terraform 自动构建资源依赖图,并行执行无依赖的操作,Shell 脚本要人工排顺序;④ Plan 预览——terraform plan 能在执行前展示「要创建什么、修改什么、删除什么」,Shell 脚本做不到。

为什么 Shell 不适合:① 复杂度高时脚本变成"意大利面",条件分支爆炸;② 没有状态,难以判断"这个资源是不是我管的";③ 错误处理弱,半完成状态难恢复;④ 无法 plan 预览,生产环境改一下就是赌命。但 Shell 不是完全没用——临时操作、应急止血、Terraform 不支持的边角场景仍是首选。Ansible 介于两者之间(声明式任务 + 命令式流程),适合配置管理但不适合基础设施编排。

题目4:DevSecOps 中的"安全左移"具体指什么?为什么"右移"也同样重要?#

问题: DevSecOps 强调安全左移(Shift Left),但也有人提出"安全右移"同样重要。请解释左移的含义、左移的具体做法,以及为什么不能只左移。

参考答案:

安全左移(Shift Left)指把安全检查前置到研发生命周期尽可能靠左的位置——IDE 实时提示、commit 钩子扫描、PR 阶段 SAST、依赖漏洞扫描、镜像构建后扫描。IBM 研究表明生产环境修复一个漏洞的成本是开发阶段的 30 倍以上,因为越晚发现需要回滚的代码越多、协调成本越高。左移在流水线各阶段的具体落地清单(pre-commit / PR / 构建 / 镜像 / 部署逐段做什么)见「子类4·题目1」,本题重点谈为什么不能只左移。

但只左移不够,右移(Shift Right)同样重要:① 左移扫不出业务逻辑漏洞(如越权访问、IDOR),需要在生产环境做 DAST 动态扫描和渗透测试;② 左移扫不出运行时威胁(如容器逃逸、异常进程),需要运行时安全(Falco/Tetragon);③ 左移扫不出配置漂移——上线时安全配置是对的,但运维手动改了,需要持续合规扫描(kube-bench 跑 CIS Benchmark);④ 供应链攻击可能绕过左移检查(如基础镜像被篡改),需要镜像签名验证(Cosign)+ Admission Webhook 拦截未签名镜像。

正确做法是"全程安全":左移拦截已知模式(便宜、早发现)+ 运行时检测未知威胁(兜底)+ 持续合规扫描(防漂移)+ 应急响应(被攻陷后快速止血)。三个阶段缺一不可,左移是降成本,右移是兜底,中间是持续保障。

题目5:平台工程(Platform Engineering)和 DevOps 是什么关系?什么是"黄金路径"?#

问题: 近年平台工程(Platform Engineering)成为热词,有人说它会替代 DevOps。请解释平台工程和 DevOps 的关系,以及"黄金路径(Golden Path)"这个概念的含义和价值。

参考答案:

平台工程不是替代 DevOps,是 DevOps 在规模扩大后的自然演进。DevOps 强调"开发也要懂运维",但实际执行中发现:① 30-100 人团队让每个开发都懂 K8s/ArgoCD/Prometheus 不现实;② 业务团队反复解决相同问题(怎么建流水线、怎么配监控、怎么发版);③ 平台团队被工单淹没。平台工程的解法是建一个内部开发者平台(IDP),把公共能力封装成自助服务,开发聚焦业务逻辑。

黄金路径(Golden Path)是平台工程的核心概念:平台团队为常见场景提供一条"默认推荐路径"——按这套模板做,CI/CD、监控、告警、日志、密钥、灰度全自动到位,开发只关心业务代码。例如"新建一个 Go HTTP 服务"的黄金路径:复制模板仓库 → 写 Dockerfile → 改业务代码 → push → 流水线自动构建 + 扫描 + 部署到 QA + 注入监控 + 注册到服务发现,全程零平台团队介入。

黄金路径的价值:① 降低认知负担——开发不需要做 100 个选择;② 标准化——80% 服务长一样,故障复盘和 review 标准变明确;③ 边际成本低——第 11 个服务接入和第 1 个一样快。但黄金路径不是强制——20% 特殊需求允许走自定义路径,但要明确标记为"长期例外"并承担额外维护成本。Spotify Backstage、Port、Humanitec 是 IDP 的代表工具,但黄金路径本身是一种治理思想,工具只是载体。

题目6:什么是"幂等性"?在 IaC 和 CI/CD 中为什么幂等性至关重要?#

问题: "幂等性(Idempotency)"是 DevOps 中频繁出现的概念。请解释幂等性的定义,以及在 IaC(Terraform/Ansible)和 CI/CD 流水线中为什么幂等性至关重要、如何保证。

参考答案:

幂等性指一个操作执行一次和执行多次产生的效果相同。数学定义:f(f(x)) = f(x)。在基础设施和部署场景中,幂等意味着"重复跑不会出错也不会产生副作用累积"。

IaC 中幂等性至关重要:① 网络抖动导致 Terraform apply 中途失败,重跑必须能从断点继续而不是从头重建;② Ansible playbook 跑第二次时,已存在的资源不应该报错"already exists";③ GitOps controller 每 3 分钟 reconcile 一次,每次 apply 都要安全。Terraform 通过 state 文件实现幂等——记录当前真实状态,diff 出需要变更的部分;Ansible 通过模块的"声明式语义"实现幂等——apt: name=nginx state=present 不管装没装过结果都一样;K8s 的 kubectl apply 是声明式的天然幂等,但 kubectl create 不是。

CI/CD 中幂等性的保证:① 镜像 tag 用 {commit}-{timestamp} 而不是 latest,同一 commit 多次构建得到同一 tag;② 数据库 migration 用 CREATE TABLE IF NOT EXISTS 而不是 CREATE TABLE;③ 部署脚本用 helm upgrade --install 而不是 helm install;④ Schema Check 注入必须幂等——重复跑不会加重复 stage。非幂等操作的典型坑:CI 失败重跑就报"资源已存在";GitOps controller 反复 sync 同一变更;数据库 migration 第二次执行报错导致流水线卡死。


子类 2:CI/CD 概念#

题目1:持续集成(CI)、持续交付(Continuous Delivery)、持续部署(Continuous Deployment)三个概念有什么区别?#

问题: CI、Continuous Delivery、Continuous Deployment 这三个概念经常被混淆。请明确区分三者,并说明在什么场景下应该选择 Continuous Delivery 而不是 Continuous Deployment。

参考答案:

三者的核心区别在"自动化到哪一步":

  • 持续集成(CI):开发人员频繁把代码合并到主干,每次合并自动跑构建 + 单测 + 扫描。目标是尽早发现集成问题。自动化到"代码可构建、可测试"。
  • 持续交付(Continuous Delivery, CD):在 CI 基础上,确保代码随时可发布到生产——每个通过 CI 的 commit 都是一个可发布的候选,但实际发布需要人工点击"发布"按钮。自动化到"一键可发布"。
  • 持续部署(Continuous Deployment, CD):在持续交付基础上,去掉人工审批——通过 CI 的 commit 自动部署到生产,无需人工干预。自动化到"无人值守发布"。

选择 Continuous Delivery 而非 Continuous Deployment 的场景:① 强合规行业(金融/医疗)要求发布有审批记录;② 核心链路变更需要业务方选择发布窗口(如电商大促期间冻结);③ 数据库 schema 变更需要人工评估向前兼容性;④ 团队对自动化测试覆盖率和金丝雀分析还不够信任。选择 Continuous Deployment 的前提:① 自动化测试覆盖率高(单测+集成+E2E);② 有完善的灰度发布和自动回滚机制;③ 监控告警能秒级发现部署引发的问题。

实战中很多团队是"混合模式":日常小改动走 Continuous Deployment(自动发布到 QA/PRE,prod 需要审批),大版本走 Continuous Delivery(人工审批 + 灰度)。DORA Elite 团队的特征是部署频率高(每天多次)+ 变更失败率低(<15%)+ MTTR 短(<1h),这通常需要接近 Continuous Deployment 的能力。

题目2:什么是"质量门禁(Quality Gate)"?如何设计一个不会成为开发负担的质量门禁?#

问题: 质量门禁(Quality Gate)是 CI/CD 中拦截低质量代码进入下游环节的机制。请解释质量门禁的设计原则,并说明如何避免它变成开发团队的负担。

参考答案:

质量门禁指在流水线某个阶段设置一组检查项,全部通过才允许进入下一阶段。常见检查:单测覆盖率 ≥ 80%、无新增 BLOCKER 漏洞、镜像无 HIGH/CRITICAL 漏洞、SonarQube Quality Gate 通过、Schema Check 通过。

设计原则:① 分层防御——不同阶段不同严格度。PR 阶段 warning 提醒不阻塞(让开发先看到问题),PRE 部署后 fail 强阻断(真的会出事才挡)。例如 Schema Check 双 Stage:pre 部署前 warning + post 部署后 fail;② 阻断条件要可执行——告诉开发"哪里错了、怎么修",而不是丢一个"扫描失败"。Trivy 报告要附 CVE 编号 + 修复版本号;③ 维护白名单——每个工具都有误报,建立白名单流程(安全团队 Review + 记录理由 + 到期时间);④ 渐进引入——第一周只跑不阻断收集基线,第二周对新增代码启用阻断,第三周逐步要求修复存量。直接把严格规则扔给团队只会制造对立;⑤ 指标可视化——把扫描结果推到 Grafana 仪表盘:每周新增漏洞数、修复平均时间、各严重级别趋势。数据可见才能驱动改进。

避免成为负担的关键:① 门禁要快——SAST 扫描超过 5 分钟开发就会跳过,用增量扫描(只扫改动的文件);② 误报要少——规则要持续调优,初始用宽松规则逐步收紧;③ 修复路径要清晰——附 Runbook 链接告诉开发"这个漏洞怎么修",而不是丢一个错误码。

题目3:什么是"制品晋级(Artifact Promotion)"?为什么禁止每个环境重新构建镜像?#

问题: 制品晋级(Artifact Promotion)是 CI/CD 的重要实践。请解释其含义,并说明为什么"每个环境各 build 一次"是反模式。

参考答案:

制品晋级指一个制品(镜像/包)在一次构建完成后,按环境顺序(qa → pre → prod)逐级"晋级"——同一份制品字节级一致地穿越所有环境,不重新构建。镜像 tag 用 {commit短hash}-{timestamp} 让 tag 可溯源,全环境复用同一镜像。

"每个环境各 build 一次"是反模式,原因:① 测的不等于发的——qa 环境测的是 commit-A 在 qa 构建机环境下的镜像,prod 发的是 commit-A 在 prod 构建机环境下的镜像,两者字节不一致。构建机环境差异(基础镜像版本、依赖锁文件、构建参数)可能引入未测的 bug;② 可追溯性差——同一个 commit 在不同环境有不同的镜像 tag,出问题难以快速定位"当时发的是哪个镜像";③ 资源浪费——重复构建浪费时间、存储、CI 资源;④ 供应链安全弱——每个环境构建都要有源码访问权限,攻击面大;晋级模式下 prod 环境只需拉镜像不需要源码。

正确做法:① CI 构建一次镜像,推到 registry;② QA/PRE/PROD 部署时只改 GitOps 仓库里的 image tag 字段,不重新构建;③ 跨云场景(AWS ECR + 阿里云 ACR)用 skopeo copy 把镜像从 ECR 同步到 ACR,不重新构建;④ 镜像签名在构建时一次性完成(Cosign sign),部署时只验证签名不重签。例外:CN 构建机访问不了 Docker Hub 时基础镜像要走国内 mirror,但应用镜像仍应一次构建双推。

题目4:Feature Flag(特性开关)是什么?它和灰度发布有什么区别与联系?#

问题: Feature Flag(特性开关)近年成为渐进式交付的核心工具。请解释其概念,并说明它和灰度发布的关系——是替代、补充还是重叠?

参考答案:

Feature Flag 是一种运行时控制代码路径的技术:把新功能包在 if feature_flag.is_enabled("new_checkout", user_id) 里,部署时代码已上线但开关默认关,需要时改开关(不重新部署)即可启用或关闭。

Feature Flag 和灰度发布的关系是"互补"而非"替代":① 灰度发布控制的是"流量比例"——5% 用户打到新版 Pod,95% 打到旧版 Pod,通过 Istio VirtualService 权重或 Argo Rollouts 实现;② Feature Flag 控制的是"代码路径"——同一份代码部署到所有 Pod,但每个用户请求时根据开关决定走新逻辑还是旧逻辑;③ 灰度的粒度是"流量比例"且需要部署多版本 Pod,Feature Flag 的粒度可以精确到"单个用户/单个属性"且只需一份代码。

Feature Flag 的杀手锏是"与部署解耦":① 紧急熔断——发现新功能有问题,关开关秒级生效,不需要回滚部署;② A/B 测试——按 user_id 哈希分桶,精确控制哪些用户走新逻辑;③ 业务控制——产品经理自己控制功能开关节奏,不需要开发参与部署;④ 长周期特性开发——主干上开发但开关默认关,不影响其他人。

实战中通常组合使用:① 部署阶段用金丝雀(Argo Rollouts)控制流量比例 + 金丝雀分析自动回滚;② 启用阶段用 Feature Flag 精确控制哪些用户看到新功能;③ 紧急熔断用 Feature Flag 秒级关闭。LaunchDarkly、Unleash、Flagsmith 是主流工具,小团队也可自建(基于 Redis/配置中心)。代价:① 代码复杂度上升(要维护两套逻辑);② 开关要清理(功能全量后删掉 if 分支);③ 测试覆盖要兼顾开关开/关两种情况。

题目5:CI/CD 流水线中的"触发器(Trigger)"有哪些类型?如何避免"同仓多流水线互相误触发"?#

问题: 流水线触发器看似简单,实际踩坑很多。请列举常见触发类型,并重点说明"同一代码仓库挂多条流水线"时如何避免误触发。

参考答案:

常见触发类型:① push 触发——推到指定分支自动跑,常用于主干 CI;② MR/PR 触发——提交合并请求时跑检查,常用于代码审查前的门禁;③ manual 手动触发——人工点击,常用于 prod 部署;④ schedule 定时触发——cron 表达式,常用于 nightly build、定时巡检;⑤ API 触发——外部系统调用 CI API,常用于上下游联动(如镜像构建完触发部署);⑥ webhook 触发——GitHub/Codeup webhook 推送事件。

"同仓多流水线误触发"是高频坑。典型场景:一个仓库挂了 5 条流水线(构建、部署 US、部署 CN、Schema Check、E2E 测试),push 到 main 时全部触发,互相争抢构建机、重复部署。避免方法:① branchesFilter 双重隔离——每条流水线明确指定触发分支(如 main 只跑构建+部署,release/* 只跑发版),不能用通配 *;② triggerFilter.exclude 排除——除了正向匹配还要反向排除,如"部署流水线排除 feature/* 分支";③ 触发事件区分——push 触发构建,MR 触发检查,不要让 MR 也触发部署;④ path filter——只在改了特定路径时触发(如改了 k8s/ 才触发部署流水线);⑤ concurrency group——同一 PR 的多次 push 只跑最新一次(GitHub Actions 的 cancel-in-progress)。

云效 Flow 的特殊坑:① branchesFilter 必须是字符串不能嵌套对象;② cloneDepth 必须字符串 "0" 不能整数 0;③ triggerEvents 不支持 schedule,定时触发只能在 UI 配;④ branchesFilter 不支持 negative lookahead 正则,写了不报错但匹配为空;⑤ codeup OpenAPI CreateBranch 等同于 git push,会触发 push webhook——新建分支时要小心触发意外的流水线。

题目6:什么是 GitOps 的"漂移检测(Drift Detection)"和"自愈(Self-Healing)"?两者有什么区别?#

问题: GitOps 强调"声明式 + 持续收敛",其中漂移检测和自愈是核心能力。请解释这两个概念的区别,以及什么场景下应该开启自愈、什么场景下不应该。

参考答案:

漂移检测(Drift Detection)指 GitOps controller 持续比较 Git 期望状态(desired state)和集群实际状态(live state),发现不一致时标记为 OutOfSync。自愈(Self-Healing)是漂移检测的下一步——不仅发现不一致,还自动 apply Git 声明把集群状态拉回期望。

两者区别:漂移检测是"发现",自愈是"纠正"。可以只开漂移检测不开自愈——发现 OutOfSync 但只告警不自动改,让人决定是否纠正。

开启自愈的场景:① 生产环境的配置类资源(ConfigMap/Secret/Deployment spec)——有人手动 kubectl 改了应该自动拉回,否则下次部署会出问题;② 开发者误操作——kubectl scale deploy --replicas=10 改了副本数,HPA 接管后这个值应该被 selfHeal 拉回;③ 安全合规要求——禁止任何绕过 Git 的手动变更。

不开启自愈的场景:① HPA 管理的 replicas 字段——HPA 会动态调整副本数,selfHeal 会和 HPA 打架,永久 OutOfSync。解决方法是配 ignoreDifferences 忽略这个字段;② K8s 自动注入的字段——Istio sidecar 注入的 annotation、cert-manager 注入的证书,selfHeal 会反复尝试拉回;③ 调试阶段——开发手动改集群状态测试,selfHeal 会干扰;④ Resource limits 自动调整——VPA 改的资源字段要 ignoreDifferences。

实战配置:ArgoCD 的 syncPolicy.automated.selfHeal: true 开启自愈,ignoreDifferences 列出受 mutate 的字段(如 /spec/replicas for HPA、/metadata/annotations/kubectl.kubernetes.io/last-applied-configuration)。Flux 的 Kustomization 天然持续 reconcile(每 interval 秒全量 apply 一次),相当于默认自愈,通过 spec.patches 在 reconcile 前 strip 掉受影响字段。任何 selfHeal 配置都要先在测试环境跑 1-2 周观察是否有"震荡"(反复 sync 同一变更)。

题目7:语义化版本(SemVer)是什么?MAJOR.MINOR.PATCH 各在什么时候递增?^ 和 ~ 约束有什么区别?#

问题: 依赖声明里的 ^1.2.3、~1.2.3 到底锁了什么?语义化版本(Semantic Versioning)三段号各代表什么?它和镜像 tag、制品版本是什么关系?

参考答案:

语义化版本 SemVer 格式是 MAJOR.MINOR.PATCH(如 2.4.1),递增规则由「是否破坏兼容性」决定:① MAJOR(主版本)——做了不向后兼容的破坏性变更(删接口、改签名、改默认行为)时 +1,并把 MINOR/PATCH 归零;② MINOR(次版本)——新增向后兼容的功能时 +1,PATCH 归零;③ PATCH(修订号)——向后兼容的 bug 修复时 +1。附加标记:-alpha.1/-rc.2(预发布,优先级低于同号正式版)、+build.5(构建元数据,不参与版本比较)。核心契约是「看版本号就知道能不能安全升级」——PATCH/MINOR 升级应无痛,MAJOR 升级必须读 changelog。

^ 和 ~ 是 npm/Cargo 等包管理器的范围约束,控制「允许自动升到哪」:① ^1.2.3(caret 插入符)——允许升到不改变最左非零段的最新版,即 >=1.2.3 <2.0.0,能吃到 MINOR+PATCH 更新、锁住 MAJOR,是最常用约束(前提是依赖方遵守 SemVer);② ~1.2.3(tilde 波浪号)——只允许 PATCH 更新,即 >=1.2.3 <1.3.0,更保守。特例:^0.2.3 因为主版本是 0(不稳定期)只等价于 >=0.2.3 <0.3.0——0.x 把 MINOR 当破坏性变更看待。

和镜像 tag / 制品版本的关系:库/SDK 发布应遵 SemVer + Git tag,让下游用 ^/~ 判断兼容性;但容器镜像不能只用 SemVer 语义 tag(如 v1.2)做生产部署——v1.2 是可变指针会被覆盖,不可溯源、不可精确回滚。生产要用不可变 tag({commit}-{timestamp} 或直接锁 digest),SemVer tag 只作「人类可读别名」。两者不冲突:SemVer 回答「这次改动能不能兼容」,不可变 tag 回答「线上跑的到底是哪一份字节」。实战坑:把 latest 或浮动 v1 当生产 tag = 放弃了回滚与审计能力。

题目8:制品/镜像仓库怎么选型?Harbor、云厂商 Registry(ECR/ACR)、Nexus、Artifactory 各是什么定位?#

问题: 制品仓库不只是「存镜像的地方」。请区分 Harbor、云原生 Registry(ECR/ACR/GCR)、Nexus、Artifactory 的定位,并说明 Harbor 除了存镜像还提供哪些企业能力。

参考答案:

按「存什么 + 谁运维」分四类:① 云厂商托管 Registry(AWS ECR / 阿里云 ACR / GCR)——只管 OCI 镜像/Helm chart,全托管零运维,和云 IAM(IRSA/RAM)深度集成,跨区复制、生命周期清理开箱即用;缺点是锁定单云,跨云要 skopeo copy 同步;② Harbor(CNCF 毕业)——自建的企业级镜像仓库,重点在「镜像仓库 + 安全治理一体」;③ Nexus / Artifactory——通用制品仓库(「万能仓」),不止镜像,还管 Maven/npm/PyPI/NuGet/Go module/Debian 等几十种格式。Artifactory 是商业旗舰(功能最全、贵),Nexus 有免费 OSS 版(够用、格式支持略少)。

Harbor 相比「裸 Registry」多出的企业能力:① 漏洞扫描——内置 Trivy,push 后自动扫 CVE,可配「HIGH/CRITICAL 禁止 pull」门禁;② 镜像签名/内容信任——集成 Cosign/Notation 做签名与验签;③ RBAC + 多项目隔离——按 project 分权,对接 LDAP/OIDC;④ 复制(Replication)——跨 Harbor / 跨云 / 与 Docker Hub 的双向同步规则,解决 CN 拉不到境外镜像;⑤ 配额(Quota)与 GC——按 project 限存储、定期清 untagged/dangling 层;⑥ 代理缓存(Proxy Cache)——把 Harbor 当 Docker Hub 的 pull-through 缓存,减少外网拉取和被限流。

选型建议:① 单云、想零运维 → 直接用云 Registry(ECR/ACR)+ lifecycle policy 清镜像;② 只有容器镜像但要自建安全治理(扫描/签名/配额/跨云复制)→ Harbor;③ 多语言制品统一管理(Java/前端/Python 包 + 镜像)→ Nexus(省钱)或 Artifactory(要全功能与商业支持);④ 常见混合:业务镜像放云 ECR,Harbor 做跨云复制枢纽 + 代理缓存,语言包放 Nexus。关键纪律:无论用哪个都要配「生命周期清理 + 存储告警」,否则 registry 无限膨胀——和 Loki PVC 撑满是同一类「持久化资源不设上限」的坑。


子类 3:可观测性概念#

题目1:可观测性"三支柱"是什么?为什么说"三支柱 ≠ 可观测性"?#

问题: Metrics、Logs、Traces 被称为可观测性三支柱,但业界有人强调"三支柱不等于可观测性"。请解释三支柱各自的作用,并说明为什么光有三支柱还不够。

参考答案:

可观测性三支柱:① Metrics(指标)——时序数值数据,回答"出了什么问题"(CPU 高、错误率涨),低成本、易聚合、适合告警。代表工具 Prometheus;② Logs(日志)——离散事件记录,回答"为什么出问题"(堆栈、上下文),高成本、难聚合、适合排障。代表工具 Loki/ELK;③ Traces(链路)——请求跨服务的完整路径,回答"问题在哪一层"(A 调 B 调 C,B 慢了 500ms),中等成本、需埋点、适合复杂链路分析。代表工具 Tempo/Jaeger。

三支柱 ≠ 可观测性 的原因:① 孤岛问题——三套系统各管一摊,工程师排障时要在三个工具间跳转,要把 TraceID/日志时间戳/指标时间对齐,认知负担大;② 关联断裂——Metrics 发现错误率涨,但不知道是哪些请求;Logs 看到错误堆栈,但不知道影响多少用户;Traces 看到某次请求慢,但不知道是普遍现象还是个例;③ 字段不统一——同一个服务在 Metrics 里叫 backend,在 Logs 里叫 goalfymax-backend,在 Traces 里叫 service.backend,关联要靠人工映射;④ 缺少高维上下文——三支柱是"数据收集",可观测性是"能回答任意问题的能力"。如果系统出问题时你还要"加个日志重新发版才能定位",那就是有数据没可观测性。

真正的可观测性需要:① 统一 TraceID 贯穿三支柱——Metrics 加 exemplar 关联 Trace,Logs 加 trace_id 字段,Traces 加 attributes 关联 Metrics;② 结构化日志——不是文本日志而是 JSON,字段可查询可聚合;③ 高基数标签——OpenTelemetry 的 attributes 可以是 user_id/request_id 等高基数字段,不止 service_name;④ 主动探针——合成监控(synthetic probe)主动拨测,不依赖真实流量;⑤ 一键下钻——Grafana 里点一个指标能跳到相关日志和 Trace。

题目2:Prometheus 的"拉取模型(Pull Model)"和传统 Agent 的"推送模型(Push Model)"有什么本质区别?各有什么优劣?#

问题: Prometheus 采用拉取(Pull)模型,而 StatsD/Telegraf 等老牌工具采用推送(Push)模型。请分析两者本质区别和适用场景。

参考答案:

Pull 模型(Prometheus):Prometheus 主动按 scrape_interval(默认 15-30s)去目标 endpoint(/metrics)拉取指标。目标服务暴露 HTTP endpoint,Prometheus 来拉。Push 模型(StatsD/Telegraf):应用主动把指标推送到 Agent/聚合层,Agent 再推送到后端。

本质区别:① 谁主动——Pull 是监控方主动,Push 是被监控方主动;② 服务发现——Pull 需要知道目标列表(通过 ServiceDiscovery 动态发现),Push 不需要(目标自己找过来);③ 生命周期管理——Pull 拉不到说明目标挂了(健康检查),Push 不推送可能是目标挂了也可能是网络问题,难以区分;④ 批处理 vs 流式——Pull 是批量拉取(一次拉所有指标),Push 通常是单值推送(每个 metric 一次请求)。

Pull 优势:① 主动方控制采集频率,不会被应用推送洪水淹没;② 拉取失败 = 目标不健康,自带健康检查;③ 应用不需要知道监控后端地址,解耦;④ Prometheus 自带缓存,应用挂了仍能查询最近一次拉取的数据;⑤ 容易做联邦集群(一个 Prometheus 拉另一个)。

Pull 劣势:① 短时任务(CronJob/Lambda)来不及被拉就结束了,需要 Pushgateway 中转;② NAT 网络后目标不可达,需要 Agent 边车模式;③ 大规模场景下 Prometheus 拉取压力大,需要分片。

Push 优势:① 适合短时任务和 NAT 网络;② 应用控制推送频率,可以做事件驱动的高精度指标;③ 网络中断时 Agent 可本地缓存。

Push 劣势:① 应用要配置监控后端地址,耦合;② 推送洪水风险(应用 bug 导致疯狂推送);③ 难以区分"目标挂了"和"网络断了"。

Prometheus 选择 Pull 的核心理由是"主动方控制"——监控系统的负载由监控系统自己决定,不被应用绑架。这是 SRE 的核心原则之一。Push gateway 只在 CronJob 等短时任务场景使用,且要配 TTL 自动清理。

题目3:SLI、SLO、SLA 三者是什么关系?如何从 SLI 推导出 SLO?#

问题: SLI、SLO、SLA 是 SRE 的基础概念,但很多团队混淆使用。请解释三者的关系,并以"登录功能"为例说明如何从 SLI 推导出 SLO。

参考答案:

三者关系是"度量 → 目标 → 契约"的递进:① SLI(Service Level Indicator)——服务水平的指示器,是一个具体指标。如"登录成功率 = 成功登录次数 / 总登录次数";② SLO(Service Level Objective)——服务水平的目标,是 SLI 的目标值。如"登录成功率 30 天滚动 ≥ 99.5%";③ SLA(Service Level Agreement)——服务水平的协议,是对外承诺的契约,违反有赔偿。如"月可用性 < 99.0% 赔付 10% 月费"。

从 SLI 推导 SLO 的步骤:① 定义用户旅程——不是"CPU 使用率",而是"用户能成功登录"。这是 SRE 的核心思想:度量用户感受而非系统健康;② 选择 SLI——登录旅程的 SLI 是"成功率"(good events / total events)。具体公式:sum(rate(login_total{status="success"}[5m])) / sum(rate(login_total[5m]))。注意分母要包含所有请求(含超时、5xx、业务错误),分子只算成功;③ 定 SLO 目标值——参考历史数据 + 业务期望。如果历史成功率 99.8%,定 99.5% 留余量;如果业务要求"用户每月最多感知 1 次登录失败",30 天 × 86400 秒 × 0.5% = 12960 秒不可用,对应 SLO 99.5%;④ 定义错误预算——SLO 99.5% 意味着 30 天允许 (1-99.5%) × 30 × 24 = 3.6 小时不可用。这 3.6 小时就是"错误预算",可以用于发版风险控制;⑤ 多窗口烧速告警——不是等 SLO 破了才告警(太晚),而是按烧速告警(预算消耗 = 烧速 × 窗口 / 720h):1 小时烧 2% 预算(14.4×速率)= P0 叫醒;6 小时烧 5% 预算(6×速率)= P1 工单;3 天烧 10% 预算(1×速率)= 看板趋势不发告警。

关键原则:① SLO 不是越高越好——100% SLO 意味着零错误预算,无法发版无法创新。Google 推荐 99%-99.95% 区间;② SLI 要可度量可埋点——如果当前没有埋点,先做埋点改造再定 SLO;③ SLO 要业务方签字——SLO 决定了"还能坏多久",影响发布节奏,必须有业务方认可;④ 错误预算要有政策——预算耗尽要冻结发布,不能只是数字摆设。

题目4:Google SRE 的"四个黄金信号(Golden Signals)"是什么?和 RED/USE 方法有什么关系?#

问题: Google SRE Book 提出四个黄金信号,是监控告警的基础框架。请解释四个信号,并说明它们和 RED/USE 方法的区别与联系。

参考答案:

四个黄金信号:① Latency(延迟)——请求耗时,要区分成功和失败的延迟(失败请求可能很快返回,掩盖问题)。用 P50/P90/P99 而非平均值;② Traffic(流量)——请求速率,如 QPS、并发连接数、消息消费速率。确认服务真的在接收流量;③ Errors(错误率)——失败请求占比,包括 5xx、业务错误(如登录失败)、协议错误;④ Saturation(饱和度)——资源利用率,CPU/内存/磁盘/队列长度。要关注"是否接近上限"而非"当前用了多少"。

RED 方法(Tom Wilkie 提出):Rate(请求速率)+ Errors(错误率)+ Duration(延迟)。适合 RPC/HTTP 服务,是 Golden Signals 的简化版——把 Traffic 简化为 Rate,把 Latency 简化为 Duration,去掉 Saturation(因为 RPC 服务饱和度难直接度量,靠延迟和错误率间接反映)。

USE 方法(Brendan Gregg 提出):Utilization(使用率)+ Saturation(饱和度)+ Errors(错误)。适合基础设施资源(CPU/内存/磁盘/网络),关注资源层健康。

三者关系:① Golden Signals = RED + Saturation,覆盖服务和资源两层;② RED 适合应用层监控(每个服务暴露 /metrics),USE 适合资源层监控(每个节点暴露 node_exporter);③ 实战监控大盘通常按 RED 组织服务视图 + USE 组织资源视图,Golden Signals 是顶层框架指导告警设计。

金丝雀分析(Canary Analysis)就是基于 Golden Signals——对比 canary 和 baseline 的四个信号,如果 canary 的错误率更高或延迟更长就自动回滚。Argo Rollouts 的 AnalysisTemplate 就是用 PromQL 查这四个信号做自动决策。

题目5:什么是"告警疲劳(Alert Fatigue)"?如何系统性治理告警噪音?#

问题: 告警疲劳是 On-call 工程师的最大敌人。请解释告警疲劳的危害,并给出系统性治理告警噪音的方法论。

参考答案:

告警疲劳指 On-call 工程师长期收到大量低质量告警后,对告警脱敏——要么直接忽略,要么延迟处理,导致真正重要的告警被淹没。危害:① MTTR 上升——重要告警被延迟处理;② 工程师 burnout——频繁被打断导致离职;③ 信任崩塌——"狼来了"效应,团队不再相信告警系统。

系统性治理方法论:① 告警可操作原则——每条告警必须有 Runbook 链接,告诉值班人"怎么排查、怎么修复"。无法操作的告警先 Silence 不要让它发出来;② 告警分级——P0(业务核心链路不可用,电话叫醒)、P1(性能下降,钉钉 @值班人)、P2(单 Pod 异常,钉钉静默群只发不 @)。分级在告警规则的 labels.severity 里写死,Alertmanager 按 severity 路由到不同通道;③ 告警抑制(Inhibit)——集群级故障时抑制具体节点/Pod 告警。如 KubeAPIDown 时抑制该集群所有 Pod 告警;④ 告警去重和分组——同一 alertname + severity 的告警 group_wait 30s 后合并成一条发送,避免 100 个 Pod 同时挂发 100 条;⑤ 告警静默(Silence)规范化——上线日临时 silence 必须设过期时间(默认 8 小时),用负匹配 alertname!=Watchdog 排除心跳告警;⑥ 定期审计——周巡检脚本扫长期 silence(>7 天)、永久 silence、.+ 全匹配等高危配置;⑦ 告警 SLO 化——从"症状阈值"(CPU > 80%)转向"用户旅程 SLO"(登录成功率 < 99.5%),告警数稳定可处理;⑧ Watchdog 心跳——永远 firing 的告警,配独立 receiver 推 healthchecks.io,30 秒收不到心跳反向告警。这是"监控的监控",确保告警系统自己活着。

实战治理案例:某团队治理前 198 条规则散落 5 套系统,月均误报 120 次、长期 silence 23 条无 endsAt、失效规则 12 条 75 天没生效。治理后规则数不变但重复覆盖消除、误报归零、on-call 响应中位数从 18 分钟降到 6 分钟。关键是"先测绘再治理"——不测绘就治理 = 治理一个不存在的系统。

题目6:什么是"结构化日志(Structured Logging)"?为什么 JSON 日志比文本日志更适合云原生场景?#

问题: 传统应用日志多为文本格式(如 2026-07-01 10:00:00 ERROR login failed for user=alice),云原生场景强调结构化日志。请解释结构化日志的优势和落地方法。

参考答案:

结构化日志指日志以 JSON 等机器可解析格式输出,每条日志是一个键值对集合。例如:{"ts":"2026-07-01T10:00:00Z","level":"error","msg":"login failed","user":"alice","trace_id":"abc123","latency_ms":450}。

结构化日志的优势:① 可查询——Loki/ELK 可以按字段过滤聚合,{app="backend"} | json | level="error" | user="alice",文本日志只能全文搜索;② 可关联——trace_id 字段可以一键跳转到 Tempo/Jaeger 看链路,user_id 字段可以聚合看某用户的所有请求;③ 可告警——基于字段的 metric 可从日志提取(如 error 率 = rate(log_bytes_total{level="error"}[5m]) / rate(log_bytes_total[5m]));④ 可机器处理——日志解析、归因、告警都可以程序化,不依赖正则匹配易错的文本格式;⑤ 多语言一致——Go 的 zap、Python 的 structlog、Java 的 logback 都输出 JSON,跨语言格式统一。

落地方法:① 日志库选择——Go 用 zap/slog,Python 用 structlog,Java 用 logback + JSON encoder,Node.js 用 pino;② 必填字段——ts(ISO8601 时间戳)、level(debug/info/warn/error)、msg(人类可读消息)、service(服务名)、trace_id(链路 ID)、request_id(请求 ID);③ 业务字段——user_id、project_id、latency_ms、status_code 等,根据业务需要;④ 不要打印敏感信息——密码、token、PII 要脱敏(如 password: "***");⑤ stdout 输出——容器场景日志打到 stdout/stderr,由 Fluent Bit/Promtail 采集,不要写文件(文件会丢、要挂卷);⑥ 日志级别治理——生产环境默认 info 级,debug 要按需动态开启(如通过 Feature Flag)。

文本日志的"人类可读"优势在云原生场景失效——没人会去看单个日志行,都是用 LogQL/KQL 查询。结构化日志的"机器可解析"才是核心需求。


子类 4:安全概念#

题目1:什么是"安全左移(Shift Left Security)"?具体在 CI/CD 流水线中如何落地?#

问题: 安全左移是 DevSecOps 的核心理念。请解释其含义、为什么左移能降低成本,以及在 CI/CD 流水线的每个阶段应该落地哪些安全检查。

参考答案:

安全左移指把安全检查从生产环境前置到研发生命周期尽可能靠左的位置——IDE、commit 钩子、PR 阶段、构建阶段。核心理由:IBM 研究表明生产环境修复一个漏洞的成本是开发阶段的 30 倍以上,因为越晚发现需要回滚的代码越多、影响面越广、协调成本越高。

CI/CD 流水线各阶段落地:① 代码阶段(最左)——pre-commit 钩子挂 gitleaks(检测硬编码密钥)+ semgrep(检测常见漏洞模式)+ detect-private-key(检测私钥泄露)。在开发者本地就拦截,不进 CI;② PR 阶段——SAST 扫描(SonarQube 质量门禁 + Semgrep 自定义规则)+ 依赖扫描(Snyk/Trivy 检测 CVE)+ IaC 扫描(checkov/tfsec 检查 Terraform/K8s yaml 安全配置)。Quality Gate 不通过 PR 不能合并;③ 构建阶段——Runner 隔离(不同项目不同 Runner 防横向污染)+ 构建不出网(只允许白名单域名防恶意依赖)+ 不在 Runner 存长期 Secret(通过 Vault 动态注入);④ 镜像阶段——Trivy 镜像扫描(HIGH/CRITICAL 阻断发布)+ Cosign 镜像签名(记录 Provenance)+ 基础镜像用 Distroless/Alpine 减少攻击面;⑤ 部署阶段——Kyverno/OPA Admission Webhook 拦截未签名镜像 + NetworkPolicy 限制 Pod 间通信 + Pod Security Admission(restricted 级别)+ RBAC 最小权限;⑥ 运行时(右移兜底)——Falco/Tetragon 检测异常进程 + kube-bench 定期跑 CIS Benchmark + 持续合规扫描。

落地注意事项:渐进引入三周、维护误报白名单、门禁要快(<5min)、指标推 Grafana 可视化——这四条通用门禁原则详见「子类2·题目2 质量门禁」,此处不重复。安全扫描相比一般门禁的特殊点有二:① 误报治理更重——SAST/SCA 误报率天然高,白名单流程 + 理由记录 + 到期复审是刚需,否则开发很快学会"无脑跳过";② 门禁按阶段分严格度——pre-commit/PR 阶段用 warning 引导(让开发先看到问题),到镜像/部署阶段才 fail 强阻断,避免一上来就制造对立。

题目2:SAST、DAST、SCA 三种安全测试有什么区别?分别在什么阶段执行?#

问题: SAST、DAST、SCA 是 DevSecOps 的三种核心安全测试方法。请对比三者的原理、优缺点和适用阶段。

参考答案:

三者区别:① SAST(Static Application Security Testing)——静态分析源代码,不需要运行程序。能发现 SQL 注入、XSS、硬编码密钥、不安全加密等。优点是发现早(开发阶段)、定位精确(知道哪一行)、覆盖率高(能扫所有代码路径);缺点是无法发现运行时问题(配置错误、依赖漏洞)、误报较多、对动态语言(Python/JS)弱。代表工具 SonarQube、Semgrep、Checkmarx。执行阶段:PR 阶段、commit 钩子。

② DAST(Dynamic Application Security Testing)——动态扫描运行中的应用,模拟攻击者从外部探测漏洞。能发现 SQL 注入、XSS、CSRF、未授权访问、配置错误。优点是发现真实可利用漏洞(已验证)、覆盖运行时配置、不依赖源码;缺点是覆盖率低(只能扫到有路由的接口)、发现晚(需要部署到 Staging)、速度慢(扫描一个应用要几小时)。代表工具 OWASP ZAP、Burp Suite、Nuclei。执行阶段:Staging 部署后。

③ SCA(Software Composition Analysis)——分析开源依赖的已知漏洞。能发现 Log4Shell、Spring Shell 等 CVE。优点是覆盖率高(现代应用 70-90% 代码来自开源)、数据源明确(NVD CVE 数据库)、修复路径清晰(升级到某版本);缺点是无法发现业务逻辑漏洞、无法发现 0day、许可证合规问题(GPL 传染性)。代表工具 Snyk、Trivy、OWASP Dependency-Check。执行阶段:PR 阶段 + 镜像构建后。

三者互补:SAST 扫自己的代码、DAST 扫运行时行为、SCA 扫依赖。完整 DevSecOps 流水线:PR 阶段 SAST + SCA → 镜像构建后 Trivy 镜像扫描 → Staging 部署后 DAST → 生产运行时 Falco。任何一个都不能替代其他——SAST 扫不出 Log4Shell(依赖漏洞),SCA 扫不出业务逻辑越权(需要 DAST),DAST 扫不出硬编码密钥(需要 SAST)。

题目3:SBOM(软件物料清单)和 SLSA 框架是什么?它们如何解决供应链安全问题?#

问题: SolarWinds 事件后软件供应链安全备受关注。请解释 SBOM 和 SLSA 框架,并说明它们如何协同提升供应链安全。

参考答案:

SBOM(Software Bill of Materials)是软件的物料清单——记录一个软件包含的所有组件(直接依赖 + 间接依赖)、版本、来源、许可证。类似食品的配料表。格式标准:SPDX(Linux Foundation)、CycloneDX(OWASP)。生成工具:Syft(扫描镜像/源码生成 SBOM)、cosign attach sbom(把 SBOM 附加到 OCI 镜像)。SBOM 解决"我知道我用了什么"——Log4Shell 爆发时,有 SBOM 的团队 5 分钟就能查出哪些应用用了 log4j,没 SBOM 的团队要花几天排查。

SLSA(Supply-chain Levels for Software Artifacts)是 Google 发起、现由 OpenSSF 维护的供应链安全等级框架。SLSA 自 v1.0(2023 发布)历经 v1.1(2025)到 v1.2(2026 现行)演进,Build Track(构建轨道)始终只有 L1–L3:① L1——构建过程产出 provenance(来源证明)文档;② L2——由托管构建平台生成、且已签名的 provenance(构建脚本无法伪造);③ L3——构建环境隔离加固(临时、无共享状态、不受用户流水线代码影响)、provenance 不可伪造。旧版 v0.1 的 L4 已被移除,相关目标降级为"规划中的未来级别";而"两人审核(two-party review)"属于 Source Track(源码轨道),不在 Build Track。SLSA 解决"我能证明这个制品是怎么来的、没被篡改"。

两者协同:① SBOM 是"是什么"——制品包含哪些组件;② SLSA 是"怎么来的"——制品的构建过程是否可信、是否被篡改;③ Cosign 签名是"完整性"——制品和 SBOM、provenance 一起签名,部署时验证签名确保未被篡改。

落地流程:① 构建阶段——Syft 生成 SBOM(spdx-json 格式)+ Cosign 对镜像签名 + 记录 provenance(git commit、pipeline ID、构建时间);② 存储阶段——SBOM 和 provenance 作为 OCI artifact 附加到镜像存储在 registry;③ 部署阶段——Kyverno Admission Webhook 验证镜像签名 + 验证 SBOM 完整性 + 检查 SBOM 中的依赖是否有已知 CVE;④ 运行时——定期重新扫描 SBOM,发现新 CVE 时通知。

实战价值:① Log4Shell 爆发时,有 SBOM 的团队 5 分钟查影响面,没 SBOM 的要几天;② 镜像被篡改(registry 被攻陷)时,签名验证能拦截;③ 合规审计时能证明供应链可控。代价:构建时间增加 10-20%(SBOM 生成 + 签名),但相比供应链事故成本可忽略。

题目4:Cosign 镜像签名的"Keyless 签名"是什么原理?比传统密钥签名有什么优势?#

问题: Cosign 支持"Keyless 签名"(无密钥签名),这是 Sigstore 项目的特色能力。请解释 Keyless 签名的原理,以及它比传统密钥签名优势在哪。

参考答案:

传统 Cosign 签名:用 cosign generate-key-pair 生成密钥对(私钥 + 公钥),私钥存在 CI Secret Manager(如 Vault),CI 用私钥签名镜像,部署方用公钥验证。问题:① 私钥管理负担——私钥泄露 = 攻击者可以签恶意镜像;② 私钥轮换复杂——轮换后所有历史镜像的签名验证要兼容新公钥;③ 难以追溯签名者身份——私钥是匿名的,不知道是哪个 CI Job 在哪个 commit 签的;④ 跨组织验证难——A 公司的公钥怎么分发给 B 公司验证。

Keyless 签名原理(基于 Sigstore 的 Fulcio + Rekor + OIDC)一句话概括:CI Job 用 OIDC token 证明身份 → Fulcio 换发一张 10 分钟短期证书(绑定 repo/commit/workflow identity)→ 用短期证书私钥签名镜像 → 签名与证书记入 Rekor 透明日志 → 部署方按 identity 规则验证证书链与签名。完整数据流和逐步验证过程见「3-原理追问型·子类4·题目1」,本题重点谈它相比传统密钥签名的优势。

Keyless 优势:① 无长期私钥管理——私钥是短期的(10 分钟),用完即弃,不存在泄露风险;② 身份可追溯——签名证书里绑定 CI Job 的 identity(repo、commit、workflow),出问题能定位到具体构建;③ 自动轮换——证书短期过期,不需要人工轮换;④ 跨组织验证——只要信任 Fulcio 根 CA,任何组织都能验证对方签名,不需要预先交换公钥;⑤ 透明日志——所有签名记录在 Rekor,可审计可追溯,攻击者无法偷偷签恶意镜像而不被发现。

落地:GitHub Actions 配 id-token: write 权限 + cosign sign --keyless 即可。Kyverno 验证时配 attestors 为 Fulcio 证书 + identity 规则。代价:① 依赖 Fulcio/Rekor 服务可用性(Sigstore 公共服务可能被墙,可自部署);② 验证时要联网查 Rekor,离线场景不适用;③ 比传统签名慢几秒(要和 Fulcio 交互)。

题目5:什么是"零信任(Zero Trust)"?它和传统"城堡护城河"模型有什么本质区别?#

问题: 零信任是近年安全架构的热词。请解释零信任的核心理念,以及它和传统"城堡护城河"模型的本质区别。

参考答案:

零信任的核心理念:永不信任,始终验证(Never Trust, Always Verify)。不因请求来自内网就信任,每次访问都按身份在最小权限内授权,全程加密,全程审计。

传统"城堡护城河"模型:内网 = 可信区,进了内网就横着走。防火墙/VPN 是护城河,护城河内默认信任。问题:① 边界一破全失守——攻击者一旦突破 VPN/防火墙,内网横向移动无阻碍;② 内网默认全开——很多公司生产库对 0.0.0.0/0 全开、Nacos 公网可达、13 人 cluster-admin,这些都是"城堡"失守的典型;③ VPN 是单点——VPN 挂了全员断网;④ 难以收敛——任何要被访问的资源只能往公网开口,越开越多无法回收。

零信任的本质区别:① 取消内网默认信任——不因在内网就信任任何流量,每次访问都验证身份+授权;② 身份即边界——访问控制基于身份(人/服务)而非网络位置,mesh ACL/RBAC/Pod Identity 是实现手段;③ 最小权限——只授予完成任务所需的最小权限,精确到网段:端口;④ 全程加密——WireGuard mesh 或 mTLS,不依赖网络层加密;⑤ 公网零暴露——所有资源收敛到 VPC 内,公网仅留网关入口;⑥ 离职只回收身份——不涉及 IP/VPN 撤销,秒级生效。

零信任的五支柱(参考 NIST 800-207):① 身份(Identity)——SSO + MFA + 设备身份;② 设备(Device)——设备健康检查、合规扫描;③ 网络(Network)——微分段、SDP、mesh;④ 应用(Application)——API 网关、OAuth、按需授权;⑤ 数据(Data)——分类分级、加密、审计。

落地要点:五支柱——零信任接入(如自建 Headscale/WireGuard mesh 替代公网直连)+ 暴露收敛(公网面收敛到 VPC + 网关)+ 权限最小化(cluster-admin → view+pod-exec)+ 凭据治理(静态 AK/SK → Pod Identity)+ 数据保护(S3 Versioning)。整改纪律是「观察实际使用 → 起草最小权限 → 并行验证 → 切换 → 回收」,先摸真实流量再动手、不搞挂业务。完整整改案例(含具体审计数字、命令、成本对比)见「5-方案设计型·子类3·题目1」。

题目6:DevSecOps 中的"安全即代码(Security as Code)"是什么意思?为什么 OPA/Kyverno 比手动配置审计更有效?#

问题: "安全即代码(Security as Code)"是 DevSecOps 的核心实践之一。请解释其含义,并说明为什么用 OPA/Kyverno 策略引擎比手动配置审计更有效。

参考答案:

安全即代码指把安全规则(策略、配置、扫描规则)用代码描述、版本化管理、随代码一起 Review 和部署。OPA 策略、Kyverno Policy、Semgrep 规则、Terraform 的 Sentinel policy——都应该是 Git 仓库里的代码文件,而不是某个人脑子里的"经验"或 wiki 上的文档。

为什么比手动配置审计有效:① 可执行——策略代码在 Admission 阶段强制执行,违规直接拒绝创建资源,不依赖人工事后发现;② 可版本化——策略变更走 PR Review,谁改的、为什么改、影响范围都留痕;③ 可测试——策略代码可以写单测(opa test),确保规则按预期工作;④ 可审计——每次策略执行有日志,知道哪个资源被拦截、为什么;⑤ 可复用——同一套策略可以应用到多个集群、多个环境;⑥ 防漂移——手动审计是"时点检查",策略引擎是"持续执行",运维手动改配置立即被拉回。

OPA(Open Policy Agent)和 Kyverno 的区别:① OPA 用 Rego 语言写策略,灵活但学习曲线陡,适合复杂逻辑(如"允许 dev 团队部署到 dev 命名空间,但禁止 prod 命名空间");② Kyverno 用 K8s 原生 YAML 写策略,简单直观,适合 K8s 场景(如"所有 Pod 必须 runAsNonRoot")。

实战落地案例:① 镜像签名验证——Kyverno ClusterPolicy 强制 production 命名空间的 Pod 必须有 Cosign 签名,未签名的拒绝创建;② NetworkPolicy 强制——Kyverno 策略"每个 namespace 必须有 default-deny NetworkPolicy",新建 namespace 自动生成;③ 资源配额强制——OPA 策略"production 命名空间的 Pod 必须 requests.cpu ≥ 100m",防止资源饥饿;④ 镜像来源限制——OPA 策略"只允许从 ECR 拉镜像,禁止 docker.io",防止供应链攻击;⑤ RBAC 审计——OPA 策略"ClusterRole 不能有 *FullAccess 通配",防止权限过大。

策略即代码的代价:① 策略要持续维护——新场景要加新策略,旧策略要调优;② 策略误判会阻断业务——要配 dryrun 模式先观察一段时间再切 enforce;③ 策略性能——OPA/Kyverno 在 Admission 阶段执行,每次创建资源都要评估,大规模集群要关注延迟。但相比手动审计的"事后发现 + 难以执行",策略即代码是云原生安全的必经之路。


子类 5:云原生网络与服务网格概念#

题目1:什么是服务网格(Service Mesh)?数据面/控制面、mTLS、sidecar vs ambient 分别是什么?#

问题: 排查题里频繁出现 sidecar、VirtualService、DestinationRule,但它们都属于服务网格。请解释服务网格解决什么问题、数据面/控制面怎么分工、Istio 的 sidecar 模式和新的 ambient 模式有什么区别。

参考答案:

服务网格是一层「专门处理服务间通信(东西向流量)的基础设施」,把重试、超时、熔断、负载均衡、mTLS 加密、流量切分、遥测这些跨切面能力从业务代码里抽出来,下沉到网络层。核心动机:微服务一多,如果每个服务都用各自语言的库实现这些逻辑,版本不一、语言不一、难以统一治理;mesh 让这些能力对业务透明、集中配置。

数据面 vs 控制面:① 数据面(Data Plane)——真正代理每个请求的组件,Istio 里是 Envoy 代理,负责拦截 Pod 进出流量、执行路由/加密/限流、上报指标;② 控制面(Control Plane)——Istio 的 istiod,不碰业务流量,负责把用户写的高层配置(VirtualService/DestinationRule)翻译成 Envoy 能懂的 xDS 配置下发给所有数据面代理,并签发工作负载证书。一句话:控制面下发策略,数据面执行策略。

关键抽象(排查题常见):① VirtualService——定义「匹配什么请求、路由到哪」(按 header/权重/路径分流,金丝雀和 PR 隔离靠它);② DestinationRule——定义「到达目标后怎么处理」(subset 子集划分、负载均衡、连接池、熔断)。金丝雀里 VirtualService 按权重把 5% 打到 canary subset,subset 由 DestinationRule 用 Pod label(如 version=canary)定义;③ mTLS——mesh 自动给每个工作负载签发证书,服务间双向 TLS 加密 + 身份认证,无需改代码,是零信任「身份即边界」的落地手段。

sidecar vs ambient:① sidecar 模式(传统)——每个业务 Pod 注入一个 Envoy 容器,流量经 iptables 劫持到 sidecar;优点是隔离强、功能全,代价是每 Pod 多一个容器(内存/启动开销),且 sidecar 与业务容器有启动顺序竞争(排查题里「sidecar iptables setup 跟业务 connect MySQL 竞争导致 CrashLoop」就是这类坑);② ambient 模式(Istio 无 sidecar,2024 GA)——拆成两层:节点级 ztunnel(DaemonSet)处理 L4 + mTLS,按需的 waypoint 代理处理 L7;免去每 Pod sidecar,资源开销和运维摩擦更低,适合大规模,代价是较新、L7 能力要显式部署 waypoint。

代价与选型:mesh 不是免费的——多一跳代理(延迟 + 资源)、控制面本身要运维、排障链路变长(多了 Envoy 层)。小规模、服务少时用 K8s Service + 应用内库可能更简单;当需要统一 mTLS、精细流量治理(金丝雀/PR 隔离)、跨语言一致的可观测性时,mesh 才划算。Istio 走「功能最全」路线(Envoy、生态大),Linkerd 走「轻量专注」路线(Rust 微代理、更简单)——两者详细对比见「2-对比辨析型·子类6」。