跳到主要内容

Cloud & Platform

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

Working model

这个角色如何与您的团队协作

工程师在您的团队内部工作,遵循您的优先级和标准。日常开发方向由您掌握,Talent.ID 负责雇佣关系。下面的分工就是全部安排。

由您掌握

  • 产品
  • 业务优先级
  • 路线图
  • 架构
  • 冲刺优先级
  • 工程标准
  • 日常技术协作

由 Talent.ID 负责

  • 雇佣关系
  • 薪资发放
  • 员工福利
  • 人才管理
  • 持续的员工关系

合作如何一步步展开

示例场景

实际协作大致是这样

这是一个假设场景,用于说明协作方式如何落地。它并不描述 Talent.ID 的客户或已完成的项目。

挑战
某个工程团队交付得很稳,但发布得很慢。部署要排期,其中一部分步骤靠手工,事前还要演练;各套环境已经漂移到这样的程度:在预发环境上的测试,不再能预测生产环境会发生什么。团队清楚需要改变什么,但在路线图持续推进的同时,腾不出空间去做这件事。
做法
新增的工程力量在团队已有的流程之内工作——他们正在使用的分支模型、团队认可的评审约定、业务要求的变更管控,以及他们在自己的规划中定下的优先级。流水线和部署方面的工作,是与日后维护它的工程师并肩完成的,而不是在最后阶段移交出去。
为团队带来什么
团队在保留对自身架构和发布策略的决定权的同时,获得了去做那些一直被推迟的交付工作的空间。这套流程应该变成什么样,由日后运行它的工程师来决定。

常见问题

常见问题

DevOps 工程师和平台工程师有什么区别?
DevOps 工程师处理的是变更的流动——一次提交进入生产的路径,以及从中返回的反馈——通常在交付团队内部或紧邻交付团队。平台工程师构建的是面向其他工程师的内部产品:一个自助式的界面,上面铺设了得到良好支持的路径,组织中其他人无需理解底层是什么就能使用。区别在于面向谁、产出什么。DevOps 的工作,用变更抵达用户的安全程度和频率来衡量;平台的工作,用其他工程师能否不必开口问人就拿到自己需要的东西来衡量。
DevOps 工程师和云工程师有什么不同?
云工程师的研究对象是云厂商这一层:账户与网络拓扑、身份与权限、托管服务的选型、让系统在某个区域故障时仍然可用的安排,以及整个资源盘子的运行成本。DevOps 工程师的研究对象,是运行在既有基础设施之上的交付流程——无论那是云还是别的什么。在规模较小的组织里,通常一个人两边都做;随着资源盘子变大,两者会分开,因为对云厂商的深度和对交付的深度,已经装不进同一份工作里。
DevOps 是一个岗位,还是一种文化?
两者都是,而且这中间的张力是真实的,不只是措辞之争。按最初的主张,它描述的是一种分配责任的方式:由同一批人既构建也运行软件,而不是在两个群体之间立一堵墙。作为职位名称,它通常指一位专门做自动化、让共担责任变得可行的工程师。只招这个头衔而不改变责任的分配方式,往往会把那堵墙在新的位置上重新砌起来,并让一个人站在墙的另一边。
监控和可观测性有什么区别?
监控回答的是有人事先决定要问的问题:队列在增长吗,错误率是否超过阈值,磁盘是不是快满了。可观测性是系统的一种属性,它让你能提出一个没有人预料到的问题——通常借助链路追踪、结构化事件和高基数属性,这些可以在事后任意切分。监控告诉你出了问题。而当原因是一组没有人会为之建看板的条件组合时,你需要的是可观测性——大多数难搞的故障正是这种情形。
DevOps 工程师应该参与 on-call 吗?
通常应该,而且最好不要独自承担。一位从不背 on-call 的工程师,会失去让告警保持诚实的那份反馈,久而久之会造出部署起来愉快、运行起来难受的系统。而一位独自背着它的工程师,会成为组织中关于系统如何运作的唯一记忆,这是一种无声增长的集中风险。更健康的安排,是让构建某个服务的人进入它的轮值,由交付方向的专家分担这份负荷,而不是代所有人吸收它。
这个角色一旦变成一个工单队列,为什么就会失效?
因为工作此时优化的是关闭请求,而不是消除这些请求被提出的原因。一个人一件件地处理环境申请、权限申请和流水线改动,就没有余力让其中任何一件变得不再必要,而队列增长的速度会快过它被清空的速度。真正从这门学科上拿到回报的组织,会把重复出现的请求当作一个设计缺陷——这意味着要允许某个人停下清理队列的工作,久到足以把它修好。
DevOps 工程师如何与现有的工程团队协作?
他们在您已有的交付流程之内工作——您的流水线、您的运行手册、您的变更管理和您的 on-call 轮值——由您的工程师设定优先级并在日常中主导工作。产品决策、路线图、架构和工程标准仍然属于您。Talent.ID 负责雇佣关系、薪资发放和员工福利,以及人才管理和持续的员工关系。

告诉我们您的团队需要什么

描述一下缺口——工作内容、技术栈、团队的运作方式——我们会告诉您能支持到什么程度。如果这不是我们能帮上忙的事情,我们会直说。