本文要点 $ ]* q1 J5 [: y1 {2 b: {6 ~
作为最流行的敏捷框架,Scrum的发展早于DevOps;正因如此,Scrum(及其他敏捷框架)实践过度专注于广义上被定义为软件交付的开发方面,而忽视了运维方面。 * r& z/ `4 t7 R$ @* Z
3 D5 ]' s& L! }; f5 ~( B/ [1 h
混合了DevOps方法就需要围绕团队、待办事项、如何编写用户故事等做些反思。例如,待办事项应该包含可扩展性、可部署性、监控,等等。 ) A: A( N5 `; _5 \6 K
( y2 i) [; [# _' Q! Y
冲刺计划应该包含DevOps的某些方面,那样,你就可以既讨论产品功能,也讨论运维特性。
5 ^) n* t( [8 @0 E) l/ e
4 q# L: z& K& C& ^4 ~4 ^* O
传统的Scrum管理员可能不完全适合这种混合方法——该角色更多的是一名敏捷教练。
" O, U% n a% m
% U/ x2 N4 h+ o
从雇佣团队成员的那一刻起我们就需要考虑DevOps,从产品规划和构建到最终退役。
3 e+ ?; o& g9 }( A5 e' m
如果你构建了一款超级炫酷、功能超级强大、客户也感觉超棒的产品,但却无法部署、运维及在它正式上线后提供技术支持,那么它是没有意义的。 . d$ z" z3 j% K$ Y
在敏捷的世界里,为了确保能够在合理的预算内按时交付客户期望的产品,我们已经付出了巨大的努力。我们还不遗余力地帮助客户确定优先级最高的特性,那样,我们就可以专注于交付高业务价值。我们尽量提前并经常交付,以便定期获得相关的反馈。我们使用“用户故事”帮助我们从用户的角度进行思考,我们每次提交时都会测试代码,从而确保我们不会破坏自己的代码库。
1 I0 ^8 G E l$ M
这很好,但是所有那些聪明的技巧和技术呢?那些设计用来确保我们可以交付可部署、可扩展的高性能产品的技术,让产品可以实时升级,自构建完成那一刻起就可以监控,日常管理不需要一个团队的支持工程师。 - M" _8 h4 D7 Q; ~2 n2 h3 {
敏捷借用(并不断发展)了源自汽车行业、神经科学、古代哲学、军事和数学等领域的伟大思想(如精益生产、认知偏差、仆人式领导、规划和相对大小)。现在,是时候借用DevOps场景的一些思想来确保敏捷仍然是最合适、最成功的产品交付原则和实践。 ! _% w! ]3 L: T' K$ s, a
对于大多数产品而言,推出之后的支持和运维(Bug修复、特性发布和增强)占据了其生命周期的绝大部分时间。管理这些工作(滚动发布“在线”服务的变更、在“准运行环境”中测试等等)的可行方法以及如何扩展产品提升性能被视为“运维特性(Operational Features)”,这些内容在产品待办事项中通常找不到。
/ }" k$ g# W8 `0 T
根据ZDNet最近的报道,咨询公司CEB调查发现,“57%的预算会流向维护和必须的合规性活动,较2011年的63%有所下降”,而根据Gartner 2006年的报告,这一数值是80%。 - `8 Y8 O6 ^! ]3 x" { U0 H) L
DevOps告诉我们,运维特性或“可操作性(Operability)”真得是一等公民,应该和其他产品特性一样同等对待。为此,最好的方法是培养一种在开发团队和运维团队之间开展合作的强大文化。的确,如何实现这种合作是另外一个问题,“DevOps”模型差别很大,从Amazon的“谁构建,谁运行”方法(开发和运维活动存在于同一个产品团队)到部分谷歌团队采用的“DevOps即平台”方法。 % l' P7 w. r, x \+ D5 l* Y9 E
DevOps的必要性 , i4 G8 B0 B- S. K1 X" i
现在,敏捷和DevOps已经共存了多年,对于两者之间的关系,已经有许多讨论。 U. ?: E9 P8 D; H/ r( Y$ }4 B1 R# v
有人将DevOps看作是敏捷的子集,有人将DevOps视为“正确践行敏捷(agile done right)”,还有人将DevOps看作一套有关自动化的做法,与敏捷总体上关系不大。这完全取决于你对DevOps的定义。但是,不管你如何看待DevOps,交付可工作的软件——可以轻松管理、维护、扩展、获得支持及升级——这一宗旨是软件交付世界急需的。 5 i5 l8 n8 r" \3 C a2 T* z9 @
自从敏捷框架被发明出来以后,软件的运行和运维方式发生了巨大的变化。Scrum始于1993年,XP著作于1999年出版,DSDM于1994年推出。那时,我们编写MSI安装程序,烧录到磁盘,然后寄给人们! / Y8 v5 ^7 ^# B" Y# Z
通常,大多数软件开发人员都不以任何方式参与软件的运行、维护、操作。
, V* q7 u Z, s) `+ F
后来,情况发生了重大转变,转向了SaaS和PaaS,生产环境随手可得。开发人员现在可以主动参与其系统的运维和支持,但是,我们仍然遵循与我们的工作方式变化不相适应的框架。 3 F+ w: q+ K+ ?0 m6 j
持续交付来救援,差点
/ T5 z. F1 j# y x9 @# e
持续交付需要部署自动化。这是朝着正确方向迈出的一步,但即使这样做了,在部分组织中,仍会不经意间创造出持续交付工程师这样一个衍生职位(这通常会创建出另外一个筒仓)。随着基础设施管理日益重要,持续交付工程师逐渐变成了持续交付团队,最终成了“平台团队”。在许多情况下,持续交付的这个方面分离出来变成单独的团队似乎很自然,这让许多敏捷团队回归了他们感觉最舒服的方式——开发软件,而不是交付。 ' F3 G8 n4 i3 y5 F( ]
遗憾的是,这非常符合Scrum框架——开发团队专注于设计、开发和测试软件,持续交付团队专注于管理他们部署的系统和底层的基础设施。 , F3 U, ~0 m W8 \" y4 D) ~* U
不用说,这种方式的问题是割裂了构建和部署自动化工作以及基础设施管理任务,从敏捷团队的角度出发,我们必定会将那些工作视为“其他人的问题”,而“可操作性”再次消失在后台。
! C0 g2 F5 X2 I3 C: t9 y4 Z; V
许多团队确实使用“正确地方式”实施了持续交付,这使他们能够采用“我们构建,我们运行”的方式进行软件交付(结果,他们获得了更强烈的归属感和更高的产品质量),但并不是每个人都这样。显然,在特定的敏捷框架中引入新的做法会遇到相当大的阻力,即使本质上讲,这些做法本身也是“敏捷的”。现在,我们面临的事情和DevOps一样了。
& y- D2 T' N1 _) _" K7 Z! O$ O- t$ `
DevOps反模式
. j3 _) z. {! j$ J# L9 A
DevOps的重点是消除Dev和Ops之间的鸿沟,减少让人痛苦的工作交接,加强合作,以便类似“可部署性”、可扩展性、监控和技术支持这样的工作不会被简单地视为计划外的东西。 + r6 k: S3 C& _8 }; u# Z# j$ f
不过,我们已经开始看到DevOps场景中出现了强大的反模式,比如,Dev团队和DevOps团队的隔离,导致另一个筒仓的产生,而没有做多少工作来加强合作。 问题是,从实践角度讲,关于如何将这种新的DevOps方法融入敏捷开发团队的信息极少。
4 n* C3 C, ? L; h N" n7 S我们需要采用什么做法?我们需要停止什么做法?我们如何开始?我们的团队应该配备什么角色?在很大程度上,这些问题仍然悬而未决。因此,团队只是“追加”了DevOps,而没有将其完全整合到他们的软件开发流程。 在这个典型的DevOps反模式中,我们完成了所有的敏捷仪式以及许多常规的DevOps实践,但是,最终的结果没有比以前更好——可操作性仍然是后期问题,产品针对开发优化,而不是交付和运维。这都是因为他们只是“追加”了关键的DevOps实践,而没有从一开始就合并进来。 / r/ Z O0 Q) x4 u' |7 r) {" Z
不用说,解决方案就是从一开始就将这些好的DevOps实践合并进来,把它们吸收到我们日常的敏捷流程和实践中——这需要我们对敏捷框架做些调整。
+ V1 }* p* s- ?5 q0 P
升级敏捷实践 6 _5 a) F+ A9 C8 [! [
那么,我们可以做些什么来保证我们正在用敏捷的方式开发软件,同时又让产品和服务的交付与维护符合DevOps部分最新最棒的最佳实践?好,很简单——只要左移一下! i6 c9 O0 e* B8 L; ]1 n+ ]* E
好吧,那听上去比做起来要简单许多,但思想是相当明确的。为了强调这一点,我们将与可操作性相关的任务/故事添加到待办事项列表中,和用户故事放在一起。我们的待办事项列表很快就变成了所有产品成功交付所需的一整套史诗、故事和任务,然后是上线后的维护(而不只是从最终用户角度出发的一系列功能特性)。
$ A* y8 u; I. p0 x/ I$ g
从表面上看,这可能听上去很简单,但是有多个方面需要考虑,如:
% H9 }4 `+ E, N5 ?( F0 U
谁将负责这些可操作性故事/任务? % K8 u/ |7 W1 s; ?# w0 E7 Y" w3 _
2 P- `% K- L7 }9 c$ e/ H& E/ J% P
如果没有最终用户,如何编写可操作性故事? + S7 v! x. W& ]! y. r6 F1 `& ]
, z1 n U; G6 u7 p) U8 _: V9 P0 n6 g
这些所谓的DevOps最佳实践是什么? % S {- r0 Z7 n( @
' N3 A2 L& q3 N2 ^7 p6 q
希望产品经理如何应对这种情况? , g' ?( P3 u# P7 B* H0 ~
7 @4 o2 [- Y' g0 k9 w
所有这些问题的答案是:“需要改进的东西”。
- J o. Q9 r0 H( B2 O
团队 " X, A* |) A! ?. ^4 l
我们共事过的大部分敏捷团队都不包含Ops、技术支持或基础设施专家。你可能会反驳说,并不是每个敏捷团队都有配备此类专家的强烈需求,你可能是对的,但不要忘了,对于测试人员、架构师、数据库工程师、UX等,人们的说法也是完全一样的。 # w }* [. ?" n7 H/ e% b! \
如果那种交付、支持、升级、扩展和维护产品的方式是重要的,你的团队就需要这些技能。
2 S; h9 n) Q; g0 u% M1 h
这意味着你要打破杰夫·贝索斯“两个披萨团队”的原则吗?也许吧。但是,如果你的那份披萨对你特别重要,那么就不断提高自己的技能吧!☺(那实际上没有听上去那么难——我们越趋向X即服务的世界,我们所需要的核心系统管理知识就越少。取而代之,我们都需要对云函数及相关服务有一个很好的了解。)
/ U4 k* ^* U O8 {4 n- R8 M/ n' B
待办事项列表 $ j5 W/ }6 S9 ]. ?. j" t
如果我们有跨职能团队,那么我们就会需要跨职能的待办事项列表。 0 I/ z( ]9 P6 j: _
忘掉传统的产品待办事项列表——是时候采用一种包括服务操作性方面的全新方法了。我们有意使用了“服务”一词,因为现如今我们倾向于构建的实际上是服务,而不是用收缩塑料薄膜包装的产品。服务是需要部署、扩展、维护、监控和支持的产品,而我们的待办事项列表需要反映出来。
; E! I! x* ~, A6 N
我们看到的大多数Scrum产品待办事项列表,90%的内容是传统特性,这些特性可以描述为一个最终用户期望特性的集合。剩下的10%往往是与性能相关的东西,或者是与准备工作相关的东西(配置开发环境、准备数据库等)。很明显,这样的列表侧重于最终用户功能/产品特性。我不能确定,这是Scrum框架本身造成的,还是产品经理对最终用户存在偏见导致的(或者完全是另外一回事)。 5 c N* G0 p6 r- W0 M6 E/ u! s, Y
因此,新式的服务待办事项列表(除了用户功能外)应该描述如下内容: + R$ E: ?" m/ ]) ?! H
产品/服务的可扩展性(向上、向下、向内、向外——以及何时)
5 u, n+ R! B1 I
$ a2 o: g" f, N3 j5 f) i
可部署性(需要在线部署而不停机吗?)
5 C0 Z$ h; B; @ t3 T( J
; B9 _0 B# Z8 m' u4 f
服务监控(哪些方面需要监控?每次变更后如何升级监控?)
( F9 S$ z/ A/ e1 v. m8 m5 Q8 i
`5 t7 }8 _7 ?( P; `& m2 [# E
日志(日志应该记录什么信息?采用什么格式?)
6 O! _7 q) _* g- G, p& Z
& s+ Y- G6 T8 D* @3 T8 t8 `$ f& D
报警(谁?何时?如何?为什么?) % f" [, v* m; e
# R& I; t/ j8 b5 X' L
服务的可测试性 7 E6 r0 b7 ~# C- {& x! Q% J6 i" H
8 `. T6 O8 @$ }& k( {' A5 }
安全和法规遵从性方面,如加密模型、数据保护、PCI法规遵从性、数据法规,等等
' m8 z6 w) O z
! m" r3 w2 Z( q2 E6 I! c+ V
操作性能 $ ~' E3 C: W2 B$ Q
! L% K$ Y+ J; }& i( u$ A
Skelton说:“为了避免在开始时‘使用旧的构建方式’,我们需要将相当一部分产品预算(和团队时间)用在运维方面。我发现,一般来说,将大约30%的产品预算用在运维方面就会产生不错的结果,我们由此就可以获得可维护、可部署、可诊断、多年以后仍然可以有效运行的系统。” - {+ T* _3 a3 p' u6 S
需要注意的是,这些操作性和安全方面的需求会不断地变化,会随产品/服务演化,因此,我们不能只是在发布初期把所有那些工作完成,然后就转向传统的产品特性。例如,在系统取得商业成功之前实现系统自动扩展方案可能并不划算。又或者,为了符合新的安全规范,你需要修改加密模型。同样地,当在新的地方上线时,你可能需要修改那个部署模型。此外,当应用程序的功能发生任何大的变更时,监控通常都需要升级。
9 l' X- Q: d. e/ [9 o' s- l! _+ M
用户故事
4 E& L5 c9 z o
从获得预期结果的角度看,用户故事是一种获产品需求的好方法。用户故事已经帮助许多开发人员(包括我们自己)从最终用户的角度出发考虑问题,专注于问题的解决方案,而不是简单地执行命令。不用说,我所说的用户故事侧重的是“什么”而不是“如何”(一个好的用户故事描述问题,而将解决方案留给开发人员)。
1 ^" T9 {( U/ a# p
用户故事通常使用下面的格式编写: 这促使我们从用户的角度出发编写用户故事(虽然不一定是最终用户)。 6 E! u( B$ L! b4 L( r4 R' u8 x
但是,这些年来,我发现,使用这种格式编写操作故事并未真正带来同等的改善效果。这可能是因为“用户角度”没有影响解决方案的技术实现方式。不管怎样,如果你是自己实现解决方案,那么写上“作为一名系统管理员”或者“作为一名开发人员”就感觉有点多余。 - V' s4 B8 S0 E, s1 w! | ?
在编写待办事项列表中的“技术待办事项”时,不使用“作为……我希望……以便……”这种格式的情况并不少见,类似地,我不推荐使用这种格式编写操作特性。取而代之,我更喜欢使用“什么和为什么”格式,只是简单地列出需要做什么以及为什么做(提供上线文)。 冲刺 5 g, P) ^7 F' f
感觉为期两周的冲刺正好可以开发新特性、测试u0026amp;部署,然后向相关人员展示。再长一点就很难保持注意力,而反馈循环的数量会增长到一个让人稍微有点不适的数量。再短一点,比如一个周,那么临时会议和其他仪式在实际冲刺时间中的占比就会过高,就是说,你可以完成的工作就会很少。因此,对许多人来说,两个周刚好。这么长一段时间刚好可以让你铺下身子,专心完成你承诺的工作。 ]. A+ W( A1 b) M/ C
如果你在开发一款新产品,这很好,但如果你是在进行一些改进迭代或者开发产品的下一个版本呢? ; N" J( q) J% U- t
谁将负责生产平台上不断出现的所有问题?
+ F" g7 |$ O- B. t' Z
如果你相当频繁地被这类事情打断(或者遭遇不同程度的此类干扰),那么你就会知道,这会严重地妨碍你兑现冲刺承诺。从帮助人们专注于现实目标来看,为期两周的冲刺似乎带来了很大的价值,但在一个不可预测的环境里,很难准确地确定你可以在多大程度上完成待办事项列列表上的内容。很难,但并不是不可能。
( p, g9 U" T# }; ]" W. a' X
如果可以度量出待办事项列表上的工作我们平均能够完成多少,以及生产平台的问题平均打断我们多少次,那么我们大致上可以推导出两个速度。
# F- d1 Y) Q0 x$ @+ h
待办事项速度是指我们可以以什么样的速度完成产品/服务待办事项列表上“计划好”的工作,而“计划外”速度是冲刺期间意外产生的工作量。跟踪这两个速度,我们可以做出有效的计划。 ; g. F# _) C/ S2 {9 G# I4 ]
当然,看板也是一种选择,可以兼顾计划好的和计划外的工作,不太清楚一周后要做什么的团队通常会选择这个框架。该框架还可以非常高效地交付周期较长的项目/版本,但需要很强的纪律性来确保可以动态、恰当地调整待办事项的优先级。
4 k2 M0 {3 m$ ?& l7 H; e1 @' _" W
冲刺计划
" c3 H! G- B, F
如果你在做冲刺,就需要做冲刺计划。将DevOps引入冲刺计划,需要做以下工作:
0 g9 u, L( B2 o2 ~* }+ v
邀请运维/基础设施/支持人员参加计划会议 + {7 B* C4 J' G
' F) j: ^" y6 x. P+ o3 ~ {5 N( c
不仅要讨论产品功能,还要讨论操作特性 % L1 j9 H; v9 z/ g5 e) i9 ?, f
1 y2 B; P; Q2 [; Q) g$ h
把它们加入接下来的冲刺 j4 r0 Z$ x2 X$ h( W
8 i- \+ t7 H( N$ m& v
把“打断”可能占用的时间u0026amp;精力考虑进来——就是来自产品平台的计划外工作,如Bug修复、升级等(这个值就是“计划外速度”,它会显著降低待办事项速度。计划外速度越高,待办事项速度就越低) ! P- }; u" U- H5 j3 f
2 M' u' J3 r' U7 H8 k% @, x& E
完工定义
4 S" _" ?4 i x# w* O7 I
一个流行的完工定义是“通过UAT”,这基本上就是“业务人员已经对功能进行签字确认”的另一种说法。但是,在很大程度上,这忽视了操作性、安全性、性能等等。一个故事需要已经做好上线准备才能视为“已完工”(或者最好是已经在生产环境中)。也就是说,它需要可扩展、性能好、可监控、安全性好,并且明显可部署!如果故事没有满足所有这些条件,就没有完工。
& |9 W$ b& L6 C' N: N
Scrum管理员
2 d2 |, q2 m0 P% F% j
请记住,我们需要改变或破坏一些已有的Scrum规则(参见上面的例子),这给Scrum管理员带来了问题。即使你想要维护一个非常像Scrum的流程,但事实是,那不是Scrum;那是Scrum和DevOps的混合。
) Z7 n) [, Z# d# i+ p! |& V
Scrum管理员角色的某些职责仍然完全有效——比如清除障碍,但是,Scrum管理员现在不仅要清除软件开发的障碍,还需要清除软件交付及维护的障碍。 . a E/ a5 y/ u" S# a. ?/ V
另一种选择是转变为敏捷教练角色,遵循敏捷的原则和价值观,但是要用和新流程一致的方式,而不受Scrum框架的指定性规则所限制。你最不希望发生的事情是,Scrum管理员不理解DevOps的用途;那只会加大开发和运维双方的分歧。
: c* O9 ?9 v5 F: J( i* _0 [
产品经理
( a- n: k% p1 ?% F; k
在敏捷和DevOps的混合环境中,产品经理应该比任何人都更了解可操作性的重要性。
& \4 B! B0 ?; {6 I$ O
在SaaS、PaaS和无服务器环境中,许多价值是隐藏的——不在前端。该价值源于我们的服务如何工作。它可以带来时间和成本的节省、性能的提升、风险的降低、可靠性的提高及其他“隐藏的”价值。产品经理现在就需要有这个认识,因为他们最终会负责管理优先级。 ( d/ N, r8 i R1 F' ]/ Y- b
持续集成(CI)和持续交付(CD) * u7 P4 g* r0 T' P
有人建议,将CI和CD工具分开,这大概是因为CI更侧重于开发,而CD有一个更全面的视图。 3 `& p" O3 z! u( b1 @+ t
不管你怎么看,CI和CD都不只是工具,它们是实际的工作方式。有CI系统和做持续集成有很大的差别。持续交付同样如此。 ! ]5 e! D) z' n5 }1 s5 k7 f
在DevOps/敏捷的混合环境中,重要的是,我们不仅使用CD作为交付机制,还是作为一组指导原则和实践方法。这很重要,因为持续交付把开发和运维纳入了同一个框架。一个好的CD管道就下面这个那样,可以可视化软件定期交付的所有重要步骤——你可以自己看下,可用的测试基础设施、可靠的测试框架、良好的监控和部署自动化是多么重要。 请记住Dave Farley总结的持续交付的八大原则和四大实践,特别注意下其中一些关键的实践,比如,“只构建一次二进制文件”,“部署到每个环境时,都使用完全相同的机制”,“如何任何地方失败了,就停止这个过程!”,但特别需要注意的是,“每个人都对发布过程负有责任”。
& t, Y& u; N7 v# T
小结
9 ^# P8 S9 T% I, ^
Scrum是最流行的敏捷框架,设计它的时候,团队通常不需要考虑运维问题,如可扩展性、可部署性、监控和维护。 A5 \4 y( p! k5 G6 S
因此,Scrum(及其他敏捷框架)的实践过度专注于广义上被定义为软件交付的开发方面,而忽视了运维方面。
* \1 h9 @/ M" m
DevOps有助于纠正这种不平衡,但对开发阶段本身的实践影响很小。有关DevOps的定义以及规范框架的缺失意味着有关如何将DevOps思维融入敏捷软件开发过程的信息很少或完全没有。
+ P, ^) F3 ~' _. i
为了最大化敏捷和DevOps的价值,你必须在开发过程开始之初就实现其中一些DevOps原则,因为最后加入一点部署自动化不会帮助你构建更可扩展、部署和管理的解决方案。
- ^# Y5 ]3 _3 p
我们应该从雇佣团队成员的那一刻起就考虑DevOps,贯穿产品的规划和构建,一直到它们最终退役。
6 u8 n' K4 W- m# R
这就是说,我们必须以全新的眼光看待一些公认的敏捷概念,如技能集和产品团队里的角色、产品待办事项本身以及我们如何计划和执行迭代。
# f: Q I/ X# b5 W! a
许多团队已经成功采用了敏捷实践,变得更符合DevOps,但是没有一种解决方案是通用的,有的只是一组很好的模式。
H0 b. n- f) h+ G+ N7 q) z0 z
4 @4 `3 Y! F* P2 e: P6 c9 a6 c( A& Q* V! f1 O
|