知乎专栏 |
首先DevOps 不是一个产品,其次说它是软件工程方法论也不准确。他是过程、方法和系统的统称,更类似笔者提出的多维度架构思想。
DevOps 这个词是由开发 Development(Dev) 和运维 Operations(Ops) 组成。它包含了三个维度,开发,测试,运维,但在实际工作中,我们也会将产品、设计、运营也纳入其中。
在 DevOps 模式下,产品,设计,开发,测试和运维团队更紧密地结合在一起,贯穿应用程序的整个生命周期。通过自动化工具替代手工操作,实现快速,高效,安全的测试,构建,部署项目。
传统软件企业以软件开发为主,开发部是最大的部门,根据项目分组,下设需求,开发,测试等岗位,并没有将运维纳入其中,这种模式已经不适合互联网企业。互联网企业通常是设置产品部,开发部,测试部,运维部,运营部,客服部等部门,但这样的组织架构带来了新的问题。
产品部关注用户体验,不考虑性能与开发合理性。开发部门的驱动力通常是“频繁交付新特性”,完成产品部提出的需求。测试部关注的是产品的BUG以及是否按照需求文档完成所有的功能。运维部更关注7*24小时无故障运行。从产品->开发->测试->运维过程看似完美,但他们目标不匹配,就在这些部门之间造成了鸿沟,从而减慢了交付业务的速度。
随着管理学的不断完善,例如工商管理,被细分为很多纵深领域,行政管理,人事管理,财务管理,营销管理,项目管理……等等。
而软件管理又被细分为:时间管理,范围管理,需求管理,质量管理,风险管理,成本管理......
由于组织架构的需要,又把人分成很多岗位,每个岗位上紧紧需要一种知识体系。企业按照自身的需要只招聘某个领域的人才。
同时我们学校也按照知识体系划分院系,本科教育程专科趋势,不重视通识教育,最终学生紧紧掌握了微观的知识。
如果说哲学是科学的科学,那么 DevOps 就是管理的管理。所以我认为 DevOps 是多维度宏观管理学。
实施DevOps 第一个遇到的问题就是人才,DevOps 需要经验丰富的跨界人才。第二个问题就是没有案例可循,无法借鉴和参考。
实施DevOps需要具备管理,开发,测试,运维等等背景的人才。每个领域至少也需要三年的积累,至少需要 3+3+3+3 = 12 年工作经验,多少公司员工都比较年轻,普遍在 3~5年。 一般员工工作10年以上,遍开始转向管理岗位,或者寻找其他出路。即使转管理岗的员工紧紧负责开发管理或者测试管理…… 不太可能10年的开发,转运维部重头开始。
我上面说过我们教育模式有问题,本科教育应该培养 “T” 型人才,专科教育培养 “I” 型人才,本科教育呈专科化。学校只教会学生一项技能(如Java 开发),而没有教会学生如何学习。
在中国企业的年龄歧视 “T” 型人才流失严重。“I”人才只能掌握一项技能解决一个领域的问题,无法完成DevOps 的实施。
DevOps 不是产品,是一种管理思想,每个企业根据自身特点,制定自己的DevOps规范,所以第二个难点就是,没有案例可循,无法参考。
传统软件工程学出现的年代互联网还不普及,主要是单机运行的软件,或者C/S结构的软件,其特点是开发周期长,迭代慢,每半年或者一年交付一次。流程主张:
需求->设计->开发->测试->交付
进入互联网时代,已B/S为主的软件,交付周期缩短到一个月,在传统软件工程做了改进,放弃了瀑布开发模式,提出了快速迭代,螺旋上升,管理上也逐步完善。出现了软件项目管理,CMM5软件开发成熟度模型。
互联网快速发展,使传统软件企业面临挑战,理论上互联网应用程序没有稳定版,新的特性源源不断加入,如果出现稳定版就意味着企业停滞。
互联网企业面临的问题是
随着Web 2.0 和 云计算思想的提出,软件也在发生变化,软件运行不在限于一台物理机,而是多台服务器的集群中,传统的模块或原件,被独立部署在世界各地。
软件的开发面临前所未有的挑战:
这时便出现了极限编程,敏捷开发….等等,同时诞生了新的岗位“产品”,新的思想不断提出,但是仍然无法解决面临的问题。
测试环境无法重现,开发人员直接在线上修改代码,跳过测试直接将代码交给运维升级
运维事故严重影响运营和广告投放
人员流动导致代码丢失
问题的原因在于,他们紧紧从各自部门的角度解决问题,同时 KPI 考核也不合理:
实际上现在的软件已经不是当年交付后一个网管就能搞定剩下的工作。同时软件开发交付周期缩的更短,一周甚至每天升级数次,遇到突发事件要做好随时准备升级。
总结这个时期实际上是: 软件项目管理 加 ITSM (IT Service Management) IT服务管理
所以聚焦微观管理解决宏观管理问题的做法是错误的,于是诞生了 DevOps。 DevOps 是多维度宏观管理学,是管理的管理。
很多企业实施DevOps 紧紧是软件堆砌,根本没有深入理解 DevOps 思想,仅仅是 devops 相关的软件全部安装上,然后做系统集成。使用时需要打开好几个软件,有些时项目管理软件,有些时代码管理,有些时缺陷管理,有些时持续集成……
这时各部门一片抱怨声:
可能用户需要打开浏览器数个窗口,频繁切换才能完成具体工作。
时不时就能听到有人在公司的QQ群、微信群、钉钉上有人喊,XXXX 环境又挂了。
改变现有的工作方式是非常痛苦的,任何不合理的流程和工作方式已经使用了多年,习惯已经根深蒂固。
实施 devops 需要各部门收集意见,对各个部门培训,改变现有的工作流程,等各部门理解了 DevOps 原理和流程后,才能实施。
持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。
持续集成只是 DevOps 中的一个小小的环节,并不是最主要的核心工作。
持续集成可以解决什么问题
持续集成不能解决什么问题
持续集成智能单向操作,例如
代码->构建->测试->部署 等等
持续集成中我们遇到很多问题
例如就是通过 git hook 触发 Jenkins 实现持续集成,自动构建项目。问题来了,任何提交都会触发一次 pipeline 脚本,当项目频繁提交时,第一个构建过程还未运行完毕,第二个进程便启动。导致构建排队,阻塞,同时 pipeline 可能会争夺资源(多个进程读写同一个文件),产生冲突,轻则稍等片刻,重则测试环境崩溃。
另外通过CI 持续集成部署代码也不靠谱,会出现和上面相同问题,例如第一个进程用 scp 复制 jar 包到远程主机,还未传输完成,第二个进程便做同样的操作。
还有,第一个进程重启 tomcat ,tomcat 还未停止退出,第二个请求便发出。最终导致 tomcat 崩溃。
以上的特性,你敢在生产环境上使用吗?一旦发布失败,或者需要回撤,持续集成并没有很好的解决方案。
我认为,持续集成尚不完善,测试环境玩玩可以,生产环境还是不要了。
持续集成、持续交付、持续部署是一系列的软件工程实践方法,使用自动化手段达到完成软件。
持续交付(Continuous Delivery)和持续部署(Continuous Deployment)的区别
请不要再混淆持续交付与持续部署了。
本章节重点谈自动化部署,每个人对自动化部署都有自己的理解,每个企业对自动化部署的需求也不同。
目前很多云平台开始推出一些列 DevOps 工具,体验了一下,仍然处在初级阶段,也不十分成熟。严格的说他们实现的 CD (持续交付)。
前面讲过持续集成不是 DevOps,这里我要说持续部署也不是 DevOps。自动化部署是从CI/CD中分离出来的,将部署单独提炼出来。
自动化部署远比 CD(Continuous Delivery) 持续交付要复杂,涉及包括
所以 CD (持续交付)解决不了企业的生产环境自动化部署需求,CD紧紧是CI (持续集成)运行完成后,将构建物部署到指定的运行环境中。通常CD并不提供回撤功能,所以极少由企业使用 CD 部署生产环境。
Git -> 编译 -> 测试 -> 打包 -> 构建物 -> 部署 -> 运行
CI/CD 的流水线作业只能部署单一项目,对于大型网站就无能为例
例如很多大型网站
很多 DevOps 方案注重 Docker,K8s解决方案。但实际情况 Docker 并不适用于所有场景,更多是物理服务器,虚拟机,云主机,刀片服务器…
使用 Docker 的前提是,Docker必须部署在宿主主机上,在云主机中部署 Docker 意义不大。
很多企业大量使用云主机,对 Docker 并无强烈的需求。
运维需要怎样的自动化部署工具
持续集成与持续交付和持续部署的关系:
持续集成(CI) -> 构建物 --> 持续交付(CD) --> 交付验收环境 (Alpha)--> 验收成功 \ | \................................................../ | V 持续部署 ----> 生产环境 (Beta/Preview/Release) ----> 生产环境验收
实施DevOps前需要收集各部门问题
问题如下
有了这些数据,在DevOps工具选型是,你才能判断是否符合你的需求。例如很多商用工具的 License 是按照用户数收费的。有些则按照部署节点收费。
技术部门常常会陷入技术思维,恨不得将所有主流技术都使用上,却忽略了他们兼容性,以及对该技术的掌握程度。
当团队没有100%掌握某项技术是,风险是巨大的,我们常常会看到网上有这种文章《XXX踩过的坑》,无疑是拿生产环境练手,为自己的职业生涯打怪升级。
大炮打蚊子,很多需求根本无需使用复杂的技术,最终变成庞然大物。
尽量使用一种技术解决所有问题,而不是使用所有技术解决一种问题。这样技术团队学习起来不会太吃力,且团队人力资源可以共享,测试难度和运维难度都会降低。
技术思维另一个误区就是,拆整为零,模块化。例如,用户中心,商品中心,订单中心,物流中心 ……
用户中心 —---—- 商品中心, | \ / | | \ / | | X | | / \ | | / \ | 订单中心 ——---- 物流中心
看这个架构多么清晰
技术人员的成就感飘飘然,然票票。运维根据需求将上面四个中心使用四台高配置服务器部署起来。
市场部需求
平时没有什么问题,订单量一大所有问题都暴漏出来, 积分添加失败,库存数据出错,物流下单失败……
这种模式的问题有很多,例如
任何一个系统都不能简单的进行拆分,抓中拆分同样是我们教育的问题,导致思维方式产生问题。
15年前我就意识到这种问题所在,15年后去一下电商公司面试,发现他们仍然在采用这种模式。
在持续集成和持续部署中数据库常常被忽略。
实施 DevOps 对于 DBA 都不那些诉求呢?
这里我列举一些DBA的诉求
上面每一项都需要单独拿出来分析,例如监控。
数据库监控有可以细分为
等等
总之 DBA 需要知道,谁,什么时候,登陆了数据库服务器,做了什么操作。随时可以备份数据,恢复数据。
另外还有数据文件一致性的需求
什么是数据文件一致性?举一个例子,用户头像是一张图片,存储在用户数据表中如下
ID | USERNAME | ICON ------------------------------ 1 | neo | /images/neo/Avatar.jpg
可能存在数据存在,图片找不到;或者有图片,没有数据的情况。这里只是一个例子,实际场景更复杂,例如银行票据,合同等等。
DevOps 需要一个核心仓库,用来管理构开发包,容器,以及建物等等。
仓库可以分为三种类型,分别是
基础设施库包括: Yum,Apt,Snap
容器仓库包括 Docker, Helm
软件依赖仓库包括
为什么需要建立这些仓库呢?
首先构建物是公司的私有资产,不可能放在开放的仓库内。其次,使用外部仓库严重影响构建速度,例如下来速度慢和一些不可控的因素,挂起,闪断等等。
通常我们将私有自建的仓库和DevOps系统放在一起,以加速构建速度。
缓存可以帮助构建程序显著提高执行速度,DevOps 涉及到的缓存包含
另外,软件开发包缓存和构建物缓存的版本通常是递增的,所有无需考虑缓存过期的问题,但是需要考虑下载过程中出现的损害。
常见的损坏包括