DevOps 工程师
DevOps 工程师处理的,是从一次合并的提交到变更安全运行在生产环境之间的这段距离——承载它的流水线、限制一次糟糕发布能造成多大破坏的部署策略,以及告诉你它是否奏效的信号。这一学科既关乎团队运行哪些工具,也同样关乎团队如何组织责任。本指南说明这个角色具体包含哪些工作、哪些交付问题足以说明它的必要性,以及如何分辨一位设计交付系统的工程师和一位只运维过交付系统的工程师。
DevOps 工程师做什么?
DevOps 工程师构建并维护那套把软件从开发者的一次提交送进生产系统的自动化,以及在此之后告诉团队发生了什么的反馈。工作范围包括:持续集成,构建与发布自动化,以代码形式表达的基础设施,用于限制一次糟糕变更影响范围的部署策略,监控与告警,以及参与事故响应。这一学科的目的,是让发布变得小、频繁、可撤回且平淡无奇——这改变的不只是团队运行什么,还有团队如何工作。
这个名称本身带来了麻烦,因为 DevOps 最初是一场关于组织结构的争论,而不是一个职位名称。它的主张是:把写软件的人和运行软件的人分开,会产生可以预见的失效——交接中丢失上下文、激励方向彼此相反、发布过程变成一场谈判。按这个头衔招人并不能了结那场争论。当它真的奏效时,它带来的是让团队里有一个人,其研究对象就是变更的流动本身。
大部分价值来自缩小发布的体量、提高发布的频率。一次大规模发布积累的风险无法归因——出了问题,几十项变更都是嫌疑对象。一个几分钟就能上线、也能在几分钟内撤回的小改动,失效面很窄;而能不能撤回,会改变一个团队愿意尝试什么。部署策略、自动化验证和一条演练过的回滚路径,正是这种做法收回成本的机制,而不是叠加在上面的便利设施。
这个角色的另一半从部署之后开始。总得有人决定测量什么、什么值得在半夜把人叫醒,以及当那条告警在凌晨三点响起时会发生什么。不断触发的告警,会训练人们忽略它;从不触发的告警,通常意味着没有在看任何重要的东西。守住这个平衡是不体面且持续的工作,很少出现在职位描述里,却能可靠地把一位有经验的工程师和一位有能力的新手区分开。
团队在什么时候需要这项能力
交付自动化通常是由最需要它的那个人,在功能开发的间隙里搭起来的。以下这些迹象,说明这样一路累积下来的安排已经撑不住了。
发布变成了一场活动
部署被安排在固定的时间窗口里进行,照着一份手工步骤文档执行,还需要有人在场以防出问题。代价并不是那个晚上。所有事情都排在下一个窗口后面,于是批次越攒越大,每次发布携带的不可归因风险都比上一次更多。
各套环境之间已经不再相像
生产环境累积了大量手工做出、从未记录的改动,预发环境(staging)是凭记忆配置出来的,“在预发环境上没问题”这句话已经不再让人安心。此时复现一个生产问题所花的时间超过修复它,这会悄悄让每个缺陷的成本翻倍。
客户比监控更早发现故障
团队是从客服工单里得知系统出了故障的。要么这些信号根本不存在,要么信号存在、却没有人再相信它们——因为告警渠道嘈杂得够久,已经被静音了。这两种情况从外面看一模一样,需要的却是不同的处置。
流水线本身成了约束
持续集成耗时长到工程师宁愿把工作攒起来也不愿等待,而且其中一部分失败并非真实问题,只是不稳定的用例。一套人们会反复重跑直到通过的测试,已经不再起到关卡的作用:它消耗时间,却不提供任何保证。
人工关卡增加的速度,快过有人去撤销它们
每次事故都添上一道审批、一份检查单或一个签字,事后又没有任何一项被移除。这套流程消耗真实的工时,提供的保证却大体上是仪式性的,因为签字的人并没有能力对他们批准的东西做出实质判断。
可部署服务的数量,超出了部署它们的方式所能承受的范围
一套适用于单个应用的安排,放到十五个应用上就变得难以管理,而且每条流水线都由不同的人以略有差异的方式写成。新增一个服务的边际成本不断上升,直到即便拆分才是更好的设计,团队也不愿再新建服务。
核心能力
持续集成
让共享分支始终处于随时可以发布的状态:每一次变更都能得到快速反馈,测试套件因为确定性而值得信任,构建时间短到人们愿意一天集成好几次,而不是攒下整整一周的分叉。
发布与部署自动化
可重复的无人值守部署,并有一条定义清楚的退路。滚动发布、蓝绿发布与金丝雀发布,借助功能开关做渐进放量,变更上线之后的自动化验证,以及一套演练过而不是假设可行的回滚。
基础设施即代码
把服务器、网络、集群及其配置表达为纳入版本控制的定义,使变更可评审、可追溯到人。这门功夫的重点不在工具,而在于当一次不留记录的手工改动明明更快时,仍然选择不那么做。
制品晋级与环境一致性
每个可发布的提交只构建一次,并把同一个制品逐环境向前晋级,所有确实应当不同的部分都在运行时提供。为下一个环境重新构建会产生另一个制品,这意味着此前验证过的是另一个东西。
监控与告警
决定测量什么,把阈值设在用户可感知的影响上而不是资源使用率上,并让告警集合小到每一次呼叫都值得响应。on-call 的设计——轮值、升级、交接——属于这项工作本身,而不是它的后续。
可靠性目标与错误预算
把可靠性表述为一个明确的目标而不是一种期望,并用剩余的预算来决定下一次变更应该是新功能还是修复。它把一场关于该不该谨慎的争论,换成一个工程和产品都能读懂的数字。
交付路径上的密钥
不让凭据出现在代码仓库、镜像和构建日志里;给流水线签发短期、权限范围收窄的凭据,而不是长期有效的密钥;并让轮换成为例行操作,而不是等到事故当中才头一回尝试的动作。
构建与供应链完整性
锁定依赖版本,记录构建了什么、来自哪次提交的溯源信息,镜像扫描,以及在威胁模型确有需要时做签名。一条持有广泛权限的流水线,是组织内最有价值的攻击目标之一,也往往是防护最薄弱的。
事故响应与复盘
以明确的角色分工和一条清晰的沟通路径处置事故,随后开一次不追责的复盘,产出具体的、指定了负责人的改动。一次以“大家应该更小心”作结的复盘,记录下来的是一个愿望,而不是找到了原因。
技术生态
以下列出 DevOps 工程领域常见的技术。这描述的是该学科在业界的一般实践,而不是对任何特定工程师技术栈的说明。流水线设计、部署策略和告警判断力在这些工具之间的可迁移程度,远高于工具名称给人的印象。
持续集成与持续交付
- GitHub Actions
- GitLab CI
- Jenkins
- CircleCI
- Argo CD
- Flux
容器与编排
- Docker
- Kubernetes
- Helm
- Podman
- containerd
基础设施与配置管理
- Terraform
- Pulumi
- Ansible
- Packer
- Kustomize
监控与告警
- Prometheus
- Grafana
- Alertmanager
- Datadog
- PagerDuty
日志与链路追踪
- OpenTelemetry
- Loki
- Elastic Stack
- Jaeger
- Sentry
密钥与供应链
- HashiCorp Vault
- SOPS
- Sigstore
- Trivy
- Dependabot
脚本与自动化
- Bash
- Python
- Go
- Make
- jq
How this role works with your team
Engineers work inside your team, on your priorities, to your standards. You direct the work; Talent.ID carries the employment. The division below is the whole arrangement.
You keep
- 产品
- 业务优先级
- 路线图
- 架构
- 冲刺优先级
- 工程标准
- 日常技术协作
Talent.ID handles
- 雇佣关系
- 薪资发放
- 员工福利
- 人才管理
- 持续的员工关系
招聘时应该关注什么
同一个职位名称覆盖着差别很大的工作,因此首先要弄清楚候选人一直在做的究竟是哪一种。有人设计过交付系统,有人运维的是别人设计的系统,也有人只是填表申请虚拟机。以下这些方面能把他们区分开。
流水线设计,而不是流水线配置
在已有的工作流文件里加一个步骤,谁都会。更难的本事是判断哪些东西根本就该放进流水线、什么应该让构建失败、什么只需要给出提示,以及某道关卡提供的究竟是保证还是延迟。
- 能说清楚为什么某项检查会拦住合并,而另一项只做汇报
- 把构建时长本身当作一项需要正视的约束,因为它直接影响开发者的行为
- 曾经移除过一个代价高于其拦截收益的阶段
- 了解流水线自身的失效模式,以及这些失效如何被暴露出来
部署与回滚策略
最有信息量的信号,是回滚究竟是一项演练过的能力,还是一种指望。问他们当一次部署把情况弄得更糟时会发生什么,注意回答是从恢复服务开始,还是从定位原因开始——这个先后顺序透露的信息很多。
- 先恢复服务,再做排查
- 能描述一次无法回滚的变更,以及当时是怎么处理的
- 理解数据库迁移为什么会让可逆性变复杂
- 用过渐进放量来控制先由谁看到某个变更
基础设施即代码的自律
有意思的问题不是他们是否使用声明式工具,而是当故障期间最快的修法就是手工改一下时,他们会怎么做。所有人最终都会做出那样的改动;区别在于它是在同一周内被回填对齐,还是一年之后由别人发现。
- 对配置漂移的检测与回收有明确的主张
- 把状态和模块组织成让一次失误影响范围有限的样子
- 能讲出一次在 plan 阶段就被拦下、尚未执行的破坏性变更
告警质量与 on-call 的真实情况
问他们在一个典型的月份里被呼叫过多少次,其中有多大比例真正需要处理。真正背过 on-call 的候选人回答得很具体,而且通常对自己删掉过哪些告警有看法;没背过的会转而讲看板。
- 基于用户能察觉到的症状告警,而不是基于资源阈值
- 为降低噪音删除或合并过告警,并且说得出是哪些
- 能区分需要呼叫的、应该开工单的,以及只该出现在看板上的
- 把反复出现的低价值告警当作一个需要从源头修掉的缺陷
事故处置及其后续
问一次他们亲身参与过的事故,而不是他们读到过的。有价值的部分在事后:写下了什么,谁来负责后续项,以及在紧迫感过去之后,这些事情是被完成了,还是被悄悄放下了。
- 无需提示就能把触发因素和背后的原因分开
- 描述的复盘把改动指派给系统,而不是把责任指派给人
- 说得出某个从未被落实的后续项,以及为什么
交付路径上的安全
交付自动化是一个高权限系统:它通常可以把任何东西部署到任何地方,还往往持有所有环境的凭据。问他们如何限定一条流水线可以做什么,以及一份泄露的凭据会如何被发现和吊销。
- 更倾向使用短期的联合身份凭据,而不是存放长期有效的密钥
- 按环境分别限定权限,而不是授予一个宽泛的角色
- 对轮换一个正在被使用的密钥有可操作的答案
他们如何与工程团队的其他人协作
这门学科在变成一个需求受理台之后,会以可以预见的方式失效。问他们当同一个请求第三次到来时会怎么做。答案能把一位高效清空队列的工程师,和一位消除队列存在理由的工程师区分开,而只有后者能随规模扩展。
- 把重复出现的请求变成团队不必来问就能自己完成的事
- 写的文档开发者真的会用,而且他们确认过这一点
- 避免成为唯一理解部署路径的那个人
值得一问的面试问题
以下问题呈现的是候选人如何推理风险与流动,而不是他们能报出哪些工具名称。请在您自己已有的面试流程中使用;评估与决定完全属于您。
请带我走一遍:在您上一个参与的系统里,从工程师合并一个变更,到这个变更开始承接生产流量,中间都发生了什么。
What a strong answer shows
他们脑子里装的是整条路径,还是只有自己碰过的那一段。好的回答会说出各道关卡、每道关卡验证什么、哪里需要人来介入以及为什么,还有他们认为哪一步是最薄弱的一环。
一次部署刚刚把情况弄得更糟,而您还不知道原因。您首先做什么?
What a strong answer shows
压力之下的运维直觉。期待的形态是先恢复、后排查——同时清楚哪些变更不能简单地反向撤销,尤其是涉及数据的那些。
您如何判断什么样的情况值得配一条会在半夜叫醒人的告警?
What a strong answer shows
他们是基于用户可见的症状告警,还是基于机器状态告警。注意听其中的分寸感:呼叫很少,但每一次都值得处理,其余的都被路由到不会打断人的地方。
请描述一次您参与过的事故。背后的原因是什么,最后又因此改变了什么?
What a strong answer shows
排查的深度,以及组织层面的落实。原因应当是一个系统属性,而不是某个人的失误;由此产生的改动应当具体到您可以去核实它们是否真的发生了。
您的测试套件要跑四十分钟,而且大约每十次里有一次是因为与本次变更无关的原因而失败。您从哪里入手?
What a strong answer shows
他们是把不稳定当作缺陷,还是当作背景噪音。好的回答会先隔离并度量,再谈优化,并且认识到一道不被信任的关卡比没有关卡更糟——它既消耗时间,又教会人们去重试。
流水线为了完成部署需要一些凭据,您如何处理它们?
What a strong answer shows
可操作的安全实践,而不是背诵制度。关注短期身份、按环境收窄权限范围、让凭据值不进日志,以及一套不依赖某个人记性的轮换方案。
请说一件您的团队一直在手工做、而您决定不去自动化的事。
What a strong answer shows
关于自动化在哪里能收回自身维护成本的判断力。条件反射式的自动化,会围绕罕见的任务造出脆弱的机械;好的回答会权衡频率、风险,以及这套机械逐渐过时的代价。
What this looks like in practice
A hypothetical scenario, written to show how the working model applies. It does not describe a Talent.ID client or a completed project.
- Challenge
- 某个工程团队交付得很稳,但发布得很慢。部署要排期,其中一部分步骤靠手工,事前还要演练;各套环境已经漂移到这样的程度:在预发环境上的测试,不再能预测生产环境会发生什么。团队清楚需要改变什么,但在路线图持续推进的同时,腾不出空间去做这件事。
- Approach
- 新增的工程力量在团队已有的流程之内工作——他们正在使用的分支模型、团队认可的评审约定、业务要求的变更管控,以及他们在自己的规划中定下的优先级。流水线和部署方面的工作,是与日后维护它的工程师并肩完成的,而不是在最后阶段移交出去。
- What this adds to the team
- 团队在保留对自身架构和发布策略的决定权的同时,获得了去做那些一直被推迟的交付工作的空间。这套流程应该变成什么样,由日后运行它的工程师来决定。
Related disciplines
Frequently asked questions
- DevOps 工程师和平台工程师有什么区别?
- DevOps 工程师处理的是变更的流动——一次提交进入生产的路径,以及从中返回的反馈——通常在交付团队内部或紧邻交付团队。平台工程师构建的是面向其他工程师的内部产品:一个自助式的界面,上面铺设了得到良好支持的路径,组织中其他人无需理解底层是什么就能使用。区别在于面向谁、产出什么。DevOps 的工作,用变更抵达用户的安全程度和频率来衡量;平台的工作,用其他工程师能否不必开口问人就拿到自己需要的东西来衡量。
- DevOps 工程师和云工程师有什么不同?
- 云工程师的研究对象是云厂商这一层:账户与网络拓扑、身份与权限、托管服务的选型、让系统在某个区域故障时仍然可用的安排,以及整个资源盘子的运行成本。DevOps 工程师的研究对象,是运行在既有基础设施之上的交付流程——无论那是云还是别的什么。在规模较小的组织里,通常一个人两边都做;随着资源盘子变大,两者会分开,因为对云厂商的深度和对交付的深度,已经装不进同一份工作里。
- DevOps 是一个岗位,还是一种文化?
- 两者都是,而且这中间的张力是真实的,不只是措辞之争。按最初的主张,它描述的是一种分配责任的方式:由同一批人既构建也运行软件,而不是在两个群体之间立一堵墙。作为职位名称,它通常指一位专门做自动化、让共担责任变得可行的工程师。只招这个头衔而不改变责任的分配方式,往往会把那堵墙在新的位置上重新砌起来,并让一个人站在墙的另一边。
- 监控和可观测性有什么区别?
- 监控回答的是有人事先决定要问的问题:队列在增长吗,错误率是否超过阈值,磁盘是不是快满了。可观测性是系统的一种属性,它让你能提出一个没有人预料到的问题——通常借助链路追踪、结构化事件和高基数属性,这些可以在事后任意切分。监控告诉你出了问题。而当原因是一组没有人会为之建看板的条件组合时,你需要的是可观测性——大多数难搞的故障正是这种情形。
- DevOps 工程师应该参与 on-call 吗?
- 通常应该,而且最好不要独自承担。一位从不背 on-call 的工程师,会失去让告警保持诚实的那份反馈,久而久之会造出部署起来愉快、运行起来难受的系统。而一位独自背着它的工程师,会成为组织中关于系统如何运作的唯一记忆,这是一种无声增长的集中风险。更健康的安排,是让构建某个服务的人进入它的轮值,由交付方向的专家分担这份负荷,而不是代所有人吸收它。
- 这个角色一旦变成一个工单队列,为什么就会失效?
- 因为工作此时优化的是关闭请求,而不是消除这些请求被提出的原因。一个人一件件地处理环境申请、权限申请和流水线改动,就没有余力让其中任何一件变得不再必要,而队列增长的速度会快过它被清空的速度。真正从这门学科上拿到回报的组织,会把重复出现的请求当作一个设计缺陷——这意味着要允许某个人停下清理队列的工作,久到足以把它修好。
- DevOps 工程师如何与现有的工程团队协作?
- 他们在您已有的交付流程之内工作——您的流水线、您的运行手册、您的变更管理和您的 on-call 轮值——由您的工程师设定优先级并在日常中主导工作。产品决策、路线图、架构和工程标准仍然属于您。Talent.ID 负责雇佣关系、薪资发放和员工福利,以及人才管理和持续的员工关系。
Tell us what your team needs
Describe the gap — the work, the stack, the way your team runs — and we will tell you what we can support. If it is not something we can help with, we will say so.