在公司成立之前,我们团队就已经开始应用 DevOps 实践,而我个人,早在十年前,在另一家公司担任系统管理员的时候,就第一次接触到了这种新鲜的思维方式。那个时候,还没有 DevOps 这种标准说法,但是当时实践的人也自己摸索出了一些相关的概念与原则。
- 持续集成;
- 自动交付;
- 每位团队成员都对产品负有责任;
- 与客户直接沟通;
- 收集并分析业务 / 应用程序指标;
- 说明文档等;
后来证明以上这一切都是对敏捷倡议中各项实践的逻辑扩展,而催生出这些方法的温床,则是开发者不再单纯为本地主机编写代码这一基本前提。
Atlassian 提出的 DevOps 原理
由 Atlassian 提出的 DevOps 模式直到今天仍然非常重要。从本质上讲,其代表着产品开发与交付的现代化周期,同时涵盖产品启动之后的运作流程。
1. 前 DevOps 时代:管理员与开发者之间的鸿沟
长久以来,产品的运营与开发工作彼此割裂。这条鸿沟的一端是勤劳朴实的开发人员,另一端则是开发者眼中那些如同行尸走肉般的系统管理员。系统管理员不参与开发,也不会与开发团队沟通,他们通常只是直接拿到代码包,然后尝试在某个位置加以运行。每一次运行尝试都痛苦万分,管理员们需要花几天时间慢慢查看日志、寻找种种难以理解的错误、分析数据库查询、陷入无穷无尽的 strace 过程等。而很多时候的事实都证明,只需要定义一项新的环境变量或者添加一个新参数,问题就能迎刃而解。但遗憾的是,开发者从来不会、也没有机会把情况告知管理员,后者唯一了解的就是产品的名称及其用什么语言编写而成……
2. 十年前的“DevOps”工作
十年之前,我刚开始在团队中担任管理员,当时的公司思维比较灵活,我不像《IT 狂人》的剧情那样被安排在地下室某个阴暗的小房间里,而是在开发者当中拥有了自己的办公桌。从那一刻开始,我也踏上了自己的 DevOps 工程师之旅。
在公司的工作中,我很快意识到,虽然知识和技能都很重要,但从沟通及运营角度审视并影响产品的能力更值得关注。我有权提出异议、表达自己的担忧,并在距离最终交付还有很久的时候就及时向开发者传达观点或提醒他们调整编写方法。这才是真正的管理员,他们不该被“囚禁”在地下室里!
事实很快证明,将产品的设计、开发与运营等元素进行综合审视,确实能够带来巨大的收益。只有每一个人都对产品负责,并清楚意识到产品将在怎样的生产环境中运行时,开发流程将真正与生产流程融合起来。这一切如今人们习以为常的思路,在当时不啻为一种文化冲击——开发者与管理员真正携起手来,天下再无难事!而这一切,都是被沟通鸿沟所严重割裂的传统流程所无法实现的。
但如果 DevOps 只是一种敏捷开发流程,而且在其中引入了开发阶段的概念,那么 DevOps 工程师又是干什么的?DevOps 世界中的核心职责究竟是什么?这就带来了另一个重要问题:DevOps 团队的理想领袖应该是谁?
团队负责人的角色可以由中层专业人士担任,而且对职位或背景没有特别明确的要求(可以是开发人员、管理员甚至是质量保证人员)。DevOps 之所以存在,主要目的就是填补产品在持续集成、交付以及运行周期中的种种空白。
从个人的主观角度出发,我认为 DevOps 领导者最好具有管理员背景(而非选择所谓的「技术骨干」)。以此为基础,他 / 她能够将与数据库升级、配置管理或者一切其他令开发者分心或烦恼的底层基础设施相关因素剥离出来。这里,我还要提出另一项管理员有更适合担任 DevOps 领导工作的观点:随着产品的发展与成熟,DevOps 团队也将随之扩大,因此需要投入的时间及精力会同步增长。如果指定开发人员领导您的 DevOps 团队,其将很难全神贯注继续处理开发工作。最后一个理由:管理员更易于上手 DevOps 工作,所以起步速度会更快一些。
3. DevOps 工程师该懂些什么?
DevOps 工程师们应该懂点什么,又该会做些什么?本文整理了一份 DevOps 工程师的技能清单,当然列举的可能不完整,只涵盖工程师们应当具备的部分核心技能。
敏捷开发原则
这也是现代开发世界中最重要的技能之一(特别是在远程协作开发场景之下)。其中不仅包括区分 Kanban 与 Scrum 间的差异,同时也要求我们能够与团队顺畅沟通、了解客户价值、跟踪时间进度,以及整理出易于理解的工作日志、独立报告与清晰说明文档的能力。
自动化 + 万物即代码
大家应该尽快摆脱手动操作的困扰。时至今日,几乎一切日常工作都对应着自动化工具。如果找不到现成的工具,您也可以使用 Python 及 bash 自行编写。例如,如果需要创建虚拟机镜像,请使用 Packer。如果需要配置 10 台以上的主机,请使用 Ansible。如果您在 Google Cloud Platform 中创建 Kubernertes 集群,或者需要在 Amazon 上使用 CDN,请使用 Terraform 以简化操作流程。总而言之,从通过网络加载新的裸机服务器到在现有集群中部署新容器,一切都应以自动化方式进行。另外,您编写的代码应该具有可复制性与幂等性,提交内容必须经过跟踪程序的审核,且严格遵循以上要求。
云与混合架构
目前,我们发现大多数企业都不会只使用一家云服务供应商(为了避免供应商锁定问题)。没错,一切不该简单粗暴地交给云方案处理,我们可以将服务中的不同部分运行在 AWS、Heroku 以及其他 IaaS、PaaS 与 SaaS 之上。请努力找到最理想的解决方案,并保证能够在特定时段内完成不同平台之间的服务迁移。另外,也别忘了之前提到的自动化原则,自动化程度越高、迁移难度就越低。
可扩展性与高可用性要求
最重要的是意识到企业能够在特定时段内承受怎样的停机与数据丢失影响。明确这一点之后,大家会发现长达 24 个小时的资源停机假设将毫无意义。另外,资源哪怕只宕机一个小时,造成的损失就可能高于一整年的完整热备份服务使用成本。借助云服务与容器化技术,扩大系统规模变得愈发轻松。但是,基础设施与服务本身也需要为这种灵活扩展能力做好准备(这里再次向本地对象存储开炮,这简直就是麻烦的终极根源)。
监控与警报
为了及时做出回顾、预测与响应,我们当然有必要收集系统、应用程序及业务中的一切可用指标。这些指标就像团队的眼睛,而且无法通过单一监控解决方案全面实现。每种云服务或平台都提供自己的一组可用指标与警报,但大家还需要结合需求使用 Librato 或 Datadog 等外部系统,或者在 Prometheus 上构建自定义监控服务。总之,一切选择都应该以合理的预算、时间及任务需求为基础。
安全性
安全保障确实不是 DevOps 工程师的核心职责。但是,大家必须掌握相关安全基础知识。端点上部署 SSL,策略中没有 * 号,不存在公开或可写入的存储桶、分区需要进行加密,注意部署封闭的防火墙、安全组以及多因素验证等等。另外,DevOps 还应该与安全部门合作,在实现流程自动化的同时快速在服务中应用新的安全策略。
4. DevOps 工程师的作用
不需要 DevOps 工程师,太阳似乎也会照常升起……
如果整个业务体系已经配置完成并能够正常工作,还需要 DevOps 专家干嘛?说得没错,不少开发人员已经建立起一套完善的环境,包括良好运行的数据库甚至是自动规模伸缩组。当然,更实际的情况,应该是他们在 Heroku 上启动了相关应用、添加了必要插件,警报和监控指标已经轻松实现,一切看起来都无缘美好。
在这种情况下,仍有以下问题需要解决。
- 所有操作通常只能手动完成,如果您的云服务供应商出了问题,您将无法复制架构或者对架构进行部分还原。
- 由于缺乏对资源消耗的有效控制,这种方案的运营成本很高。在配置完成后,很多服务可能根本没有发挥作用,但您仍然需要为此付费。一般来讲,快速发布是开发流程的重中之重,但同时又缺少必要的优惠选项及替代方案等成本调整空间。另外,这类方案大多没有充分发挥预留实例的成本优势。
- 部署流程不够完善。由于缺少统一的测试方法,集成测试往往只是空谈。大部分运行测试只能由开发人员在本地执行。
- 某些奇怪的错误只出现在生产环境中,但却无法在本地重现。这会影响客户对于 IT 部门的信任,最终 IT 部门与项目负责人将成为不共戴天的死对头。
- 性能问题时常出现,但原因总不明确。单点故障无处不在,解决与修复需要耗费大量时间,甚至会进一步拖慢已经非常缓慢的开发进程。
- 需要将您的服务迁移至另一平台,并为快速增长的业务做好架构层面的准备。
- 监控警报来得太晚,来不及采取行动。开发团队很可能是最后一帮意识到出了问题的人。在最极端的情况下,甚至用户和客户那边已经怒火中烧,开发团队却仍被蒙在鼓里。
这份清单当然不够完整,我们还可以添加更多问题,其中一些可以通过及时沟通来解决,也有一些需要配合交付与开发流程层面的优化。但要完成这些优化,就得探讨纯粹的技术技能或者与特定平台相关的知识,因此本文暂不讨论。