「你构建,你运行」与持续交付
作为一个帮助普及持续交付理念的人,我有些关于 DevOps 的不同想法。可能与其他人不同的是,我认为持续交付是更基本的概念,而 DevOps 是帮助我们实现持续交付的重要运动之一。的确,是一个重要的思想启蒙运动,推动它的人是我们的盟友,我们一起努力构建更好的软件。
我想探讨的是:DevOps 的核心思想——你构建它,你运行它——这意味着什么?以这种方式合作的实际意义和影响是什么?
嗨,大家好,我是《持续交付 2.0》作者,乔梁。如果你以前没有关注我的公众号,请点击关注,第一时间获得更新。
DevOps 有很多种定义,不同的人对它的定义不同。其中有一种定义是:DevOps 是人、流程和技术的联合,以实现对我们最终用户的持续价值。这个定义不错。
在我看来,DevOps 是实现持续交付的一种方式。它不是实现持续交付的唯一方式,但如果没有它作为 DevOps 核心的协作,就很难实现持续交付。
在我看来,没有持续交付(Continuous Delivery,CD)的 DevOps 几乎没有任何意义。它不是一个角色,也不是一种技术,它也没有定义一个团队。在持续交付这个基本想法出现之前,一些愚蠢的用法使得DevOps 变得含糊不清。
DevOps 的目标是帮助我们实现持续交付,它们每个人都在应对相同的挑战和各自贡献的基础上形成,相互加强。向用户持续交付价值的核心思想是一个重要的概念,"持续"这个词意味着一个时间维度。我更喜欢将持续交付描述为一种方法,即我们的软件总是处于可发布的状态。虽然这种提法可能不够准确,但更准确的说法可能更像是将我们的系统保持在一种可关联的状态。这里的区别在于,将系统维护在可发布状态的想法不仅仅是在构建新功能时保持系统可发布,我们还需要在环境变化时保持系统可发布。这意味着我们必须检测环境中的变化,并能够理解我们看到的是什么并做出反应。通过变更系统使其再次可发布。那么在这种情况下,我们真正所说的可发布是什么意思?
我们的意思是,我们的系统在技术和功能上是足够正确的,可以为我们的用户提供价值。如果对我们的服务的需求上升到我们的系统总是崩溃的程度,那么我们的系统就不再真正为我们的用户增加价值,所以不能以任何实际的方式真正地发布。因此,除了知道我们的变更是安全的并且它们做了我们的用户期望它们做的事情之外,我们还必须跟踪我们的系统在生产中的行为,以防外部的一些情况因素改变了我们系统的用户体验。我们需要以允许我们快速、高效地生产的方式工作,这样我们就可以将我们的软件保持在理想的、有用的、可发布的状态。
所以现在我们回到了一个需要持续保持警觉的状态。我们希望能够持续跟踪我们的软件系统,因为我们不知道什么时候可能会发生变化,从而导致我们的软件不能发布。
要保持系统永久处于发布状态的最有效方法就是:在问题发展成灾难之前及早发现问题。如果我们持续跟踪系统的使用情况,我们可能会幸运地发现变化,并看到需求增加的警告。
现在,我们可以绘制趋势并找出需求的方向。虽然我们肯定有时会犯错,但在达到容量限制之前就开始增加系统的容量或可伸缩性,这要容易得多,也比等待系统在不可预见的负载下崩溃要好得多。
最终,我们从生产环境中的系统行为中获得的知识,一定会改变我们构建软件的方式。
开发团队需要了解软件的运行情况,并能够根据事件做出反应。这些信息的拥有者是为构建开发团队提供有关软件运行情况的最佳场所,因为他们能够实施措施并了解软件的运行情况。
纯粹从效率的角度来看,这些来自生产环境的信息往往非常复杂且不可预测,而我们并不总是有很多时间来做出反应。因此,我们应该真正希望的是:让开发团队保持在这个反馈循环中,确保他们能够看到正在生产环境中发生的事情。这取决于所在组织的结构,可能还有其他人也在关注这些事情,但你需要让开发团队了解实际发生的事情的细节,并能够在事件发生时对其做出反应。
我记得曾经在一个比较不稳定的生产系统上工作过。它会变得非常缓慢,有时甚至会崩溃。
我们一直努力保持系统稳定,但有一段时间它并不是很稳定。我和其他人花费了很多时间观察这个负载很重、成千上万用户在使用的系统中的插头。由于系统有太多的日志和信息,我们无法真正清楚地了解到整个情况。但经过一段时间观察,我们开始看到一些似乎与崩溃相关的模式。我们编写了一些代码,以使这些模式在日志中更清晰、更明显。最终,当出现警告信号时,我们附加了警报,我们发现,如果我们重新启动特定的服务,当这些警告信号明显时,我们可以避免系统崩溃,从而减少对整个系统的影响。
这是 DevOps 哲学的技术实践部分,它强调让构建者在实际使用中从开发团队的角度来看他们的工作有多有价值。这种哲学和方法有很多优势,因为开发者可以看到他们的工作对用户有用或者至少同样重要的是,他们还可以看到他们的工作对用户没有用处。这让他们对自己的软件有更强的归属感。这听起来有点像管理人员和企业的任务,但对于开发团队成员来说,看到他们的软件被使用也是非常有价值的。希望他们能够更有效地迭代解决问题。
在上述故事中,我们改变了记录错误的方式,以便我们可以更容易、更可靠地检测崩溃的前兆。所以,与生产系统进行交互,最大限度地减少延迟,增加沟通的清晰度和直接性的方式,是让开发人员监控他们所负责开发的系统。
在生产过程中,作为开发者,你应该直接构建并运行软件。然而,我发现有些开发团队对于托管他们代码的生产环境了解甚少,甚至一无所知。尽管这种情况有所改善,但对于DevOps哲学而言,你的软件运行的环境对于软件本身具有重要影响。如果环境发生变化,软件可能会受到破坏。
因此,对于这个事实,只有两种明智的反应:要么掌控环境,要么以防御性的方式编写系统代码,使其能够在主机环境变更的情况下仍能正常运行。
这两种方法都是开发团队的责任,而不能将这些策略的责任都交给运维团队。只有通过修复宿主环境,运维团队才能保护你的软件。保持基础架构的最新状态可以减少恶意攻击的风险。
类似地,你不能指望你的产品经理或销售团队来考虑将你的移动应用或桌面应用程序与操作系统或配置变更隔离的技术细节,并确定优先顺序。这是开发团队最适合的技术工作。
开发团队需要理解他们所创建的软件在哪种环境下运行最佳。软件体系结构和基础架构不是开发团队以外的人的工作。我们需要考虑了解和控制我们的软件在其中运行的生产环境。这在很大程度上是云计算与其他形式的不同之处。云服务是自助服务。它们是软件驱动的,因此基础架构可以定义和配置,并进行版本控制和主机环境的调配,从而更具可重复性和可控性。
让开发团队自己负责定义软件的生产配置是更容易改变系统偏好的方法。不同的背景可能导致人们对此持不同的态度。传统的大型公司可能会对此表示怀疑,但实际上这种方法在全球范围内都可以运作。这种方法的争议程度与云计算的影响有关。
这种方法将许多责任转嫁给开发团队,而这可能会导致组织以错误的方式处理这些责任。基于角色的组织竖井是一个低效、官僚作风的方法,它不利于协作,增加了对变化的障碍。相反,团队拓扑结构是一种更好的模型,它将面向用户的变更的责任交给所谓的“流对齐(flow aligned)”团队。这些团队管理自己的认知负载,并由平台和复杂的子系统团队提供支持。这些团队由不同角色混合的成员组成,他们的工作是通过那些“流对齐”团队向用户交付价值。
(图片来源于网络)
这种微妙的重点变化是非常重要的,它并不意味着平台或复杂子系统团队的责任被传递给与流对齐团队,构建系统。这些团队也是要负责在生产中监控和运行它们,就像我前面已经说过的一样。
然而,你构建它,你运行它,还有一个争议的点:如果软件在凌晨3点出现故障,谁来负责?实际答案是构建软件的人。你如何处理这个问题可能取决于你的组织在DevOps或持续交付过程中的位置。对于开发团队来说,这通常是一个很大的要求。虽然老实说,运营团队处理非工作时间停机的情况就像这是他们几十年来的正常工作一样。那么为什么这对实际开发软件的人来说是一个未决问题么?
首先,让我们明确一点,没有人希望在凌晨3点接到电话。
其次,要认识到的是,无论你的运维团队有多么优秀,他们可以用来解决问题的反应速度要比最初开发这个软件的人更有限。因此,在所有条件相同的情况下,开发团队处于更好的应对生产事件的状态,因为他们对系统的理解,和对可能发生的任何问题的反应能力都是比较理想的。
当问题出现时,开发团队可以随时待命,即使是在凌晨3点。如果你是一名开发人员,你可能不喜欢随叫随到,但从组织和个人角度来看,这样做有一个好处,即一旦你在凌晨3点被叫醒处理停机,你将更加努力地避免再一次像这样工作。因此,你现在真正意识到做得更好的重要性。
我认为理想组织的标志之一是每个人,无论他们的工作是什么,都能看到他们决策的结果,并对这些结果做出反应,纠正不太理想的结果。
因此,如果你在凌晨3点被叫醒随叫随到处理问题,一旦你解决了问题,并打了一个补丁,你就永远不会再被同一个问题在深夜叫醒。这给我们带来了构建更好软件的压力。DevOps 想法的真正目的是明确责任:构建软件的人有责任做好。他们应该努力做好,应该致力于做好工作。参与凌晨3点的游戏是提醒每个人做不好工作是有代价的一个很好的方式。