我们总是在提DevOps,敏捷管理,但大家未必真的明白什么是DevOps。本文是将向大家介绍到底什么是DevOps,DevOps的初衷到底是为了解决什么问题?它能够如何实现?能够带来哪些价值?来让大家对DevOps有一个全面的了解。
一、Devops是什么
❝ DevOps维基百科定义 DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。❞
这里先给出维基百科的定义,没指望你一下子看懂,先有个概念了解一下。
二、Devops概念提出
1. 单体架构+瀑布模式
以电商系统为例,单体应用架构为 LNMP,这个时候只有 DEV 没有 OPS,DEV 就是全栈,就跟我们上大学玩的 demo 一样,项目开发好,找台服务器安装好环境,把 jar 包 scp 到远程服务器,放上去开启服务就可以。
这个时候服务监控也简单,服务出了问题,直接去线上看一下运行日志,为了解放双手监控服务,开发者会写一些脚本分析日志,服务器少,部署简单,通常开发就可以完成运维的工作,不需要专门的运维来做部署,所以开发模式很简答,直接按照瀑布流方式开发就可。
2. 分布式架构+敏捷开发模式
随着业务体量发展越来越大,一台机器扛不住,那么就加机器,单机变多机,业务架构也开始加入了 nginx,cdn,缓存等通用基础服务,业务变多肯定会招人,就涉及到多人协同开发,多人多机器模式。
多人协同开发问题:
先说说多人协同开发问题,人员一多,为了更好的分工,大多会将项目进行拆分,每个人负责专注于一部分,有点包干到户的感觉,敏捷开发的核心理念就是既然我们无法充分了解用户的真实需求是怎样的,将一个大的目标不断拆解,把它变成一个个可交付的小目标,然后通过不断迭代,以小步快跑的方式持续开发。
另外,一个项目是很大的,为了保证项目质量,测试环节不可减少,为了加快速度增大开发效率,QA的工作最好是和开发同步交替进行的,需要将测试环节从后面注入到整个开发环节当中,每次可交付的都是一个可用的功能集合,对开发交付的内容进行持续验证。这样开发产品的可控性也更强,遇到了“善变”甲方的时候,阶段性的让他检验一下项目成果,防止画鸡成鸭。
多机器问题:
再说说多机器问题,之前机器很少架构简单的时候,开发就可以干运维的活,就算加了几台服务器,那也是脚本将 JAR 包同时发布到这些机器上,好像也挺简单,但是会有两个人同时上线部署被覆盖的问题,所以大家在上线之前可能会去群里吆喝一声,”我要上线了,大家先别上线哈“,可想而知这样效率也很低下。
公司业务一大,像大公司的动不动就是几千台服务器,就需要专门的运维介入了,一方面是因为开发分工每个人都专注于自己的事情,不会那么用心进行维护,另一方面是运维的学习成本确实变高了,开发人质量参差不齐,服务器要是每个人都可以上估计领导每天晚上都要做噩梦。
但是这个时候也不是 DEVOPS,而是DEV+OPS,这时 Ops 的主要职责就是:硬件维护、网络设备维护、DBA 、基础服务维护、数据监控等,运维们擅长写各种部署,监控脚本,减少机械的重复工作,开发模式变成了敏捷开发模式。
开发和运维角色的天生对立问题:
加入运维,就要协调人员配合,运维的宿命就是维稳,他们是很讨厌变动的;开发的天职确是不断地推代码上线,进行代码变动,更替迭代,这两个工种天生就是对立的。
很多大公司有那种,开发人员想要上线,需要提交各种审批,层层签字画押,多少人的上线激情被一句冷冰冰的‘还没到窗口发布期’给泼的透心凉。所以,敏捷开发解决了协同开发和多机器部署开发问题,但是没有解决内部人员的矛盾,留着这个矛盾在公司,开发和运维随时都可能‘约架’。
3. 微服务架构+DEVOPS
❝ wiki定义微服务: 微服务(英语:Microservices)是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic)的API集相互通信。❞
上面是我摘自wiki对微服务的定义,注意几个关键词:软件架构风格,小型功能区块,模块化,语言无关。
第一,公司发展到BAT这种体量,会招很多人,JAVA,PHP,GO 技术栈都会有,需要协调技术栈;
第二,项目到后期往往会变得很大,全部都怼到一个项目里,最直接的后果就是项目变得很大,上线项目启动时间变长,一个BUG可能导致整个业务全线崩溃,最终的后果就是项目变得越来越难以维护,加一个改一个东西几乎搞不动,而且还越来越难重构,牵一发而动全身。
所以,拆分解耦是最终的出路,将项目拆成一个个小的服务单独部署,以电商项目为例如图,将整个项目拆分为用户服务,商品服务,订单服务,积分服务......每个服务单独部署,之间通过互相调用的方式来交互,而且可以将一些基础服务例如上传图片,发送短信等很多服务都需要的基础东西,抽象到一个单独的服务,也就是前些年鼓吹的很厉害的‘中台服务’。
拆分部署催生出DEVOPS, 再看看这种架构下的开发模式DEVOPS运维需要做的上线工作,主要就是将代码部署到对应的机器里面,微服务有那么多的服务,每个大点的公司几百个服务不算多,而且还可能随时搞一个服务出来,如果还按照原始的脚本部署方式,可能最后连是哪个脚本都找不到。而且,如果每个服务上线都需要运维来同意,开发也太卑微了,估计要天天求着运维同意发布,运维也会烦不胜烦。
那么为何不能再远程部署一些机器,专门用来管理代码,进行上线工作,由运维事先把上线的规则都给定义好了,开发只要按照他的规则都访问这台服务器进行各自的代码合成和发布,自己上线呢,能用代码自动完成的事情就绝不要手动解决,这是每个开发人员都在想的东西。
运维需要做的事情,慢慢的都沉淀到了各个平台上面,例如监控,有专门的监控组件和可视化,基础服务例如服务器,CDN,负载均衡等基础服务可以外包到云服务厂商,日志也有专门的日志工具,链路追踪也有专门的组件和可视化,还有网关等,渐渐的,只要这些都配置好了,开发也可以做运维的部分工作,毕竟开发才是最了解代码的人,哪里出了问题看看监控日志,可以最快速度定位到问题,于是DEVOPS开发模式诞生了,开发也是运维。
三、Devops深度理解
我们知道,一个软件从零开始到最终交付,大概包括以下几个阶段:产品规划、开发编码、构建、QA测试、发布、部署和维护。
最初大家说到DEVOPS,都是指的‘开发运维一体化’,如下图:
现在大家说的 DevOps 已经是扩大到“端到端”的概念了,如下图:
DevOps 的三大支柱之中,即人(People)、流程(Process)和平台(Platform)。即:
DevOps = 人 + 流程 + 平台
人 + 流程 = 文化
流程 + 平台 = 工具
平台 + 人 = 赋能
四、Devops实现相关工具
人自然不用多说,开发前后中涉及到的所有人,流程前期是产品出原型,UI出设计,然后前后端代码开发,QA测试,最终部署上线。
这里重点来看看devops平台搭建工具,工具很多,组件很多,百家争鸣,这里我列举的大多数是我公司用的,也是大部分公司都在用的。
1. Devops平台搭建工具
项目管理(PM):jira。运营和产品可以上去提问题,可以看到各个问题的完整的工作流,待解决未解决等;
代码管理:gitlab。jenkins或者K8S都可以集成gitlab,进行代码管理,上线,回滚等;
持续集成CI(Continuous Integration):gitlab ci。开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。
持续交付CD(Continuous Delivery):gitlab cd。完成单元测试后,可以把代码部署到连接数据库的 SIT环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境中。
镜像仓库:VMware Harbor,私服nexus。
容器:Docker。
编排:K8S。
服务治理:Consul。
脚本语言:JAVA。
日志管理:ELK。
系统监控:Prometheus。
负载均衡:Nginx。
网关:Kong,zuul。
链路追踪:Zipkin。
产品和UI图:蓝湖。
公司内部文档:语雀。
报警:推送到钉钉工作群。
有了这一套完整的流程工具,整个开发流程涉及到人员都可以无阻碍的进行协调工作了,开发每天到公司,先看看jira,看看线上日志,出了问题看看监控日志,运营同学反馈问题不着急的去JIRA,着急的群里吆喝,产品和UI的图直接蓝湖看,运维关注监控着大盘,一幅和谐的画面~
五、DevOps应该如何落地
1. DevOps在行业落地都有哪些姿势
大部分企业落地DevOps都是从CI/CD开始进行推动的。主要的包含一下集中方式:
我们先看看我们对于CI/CD的定义:
CI持续集成,我们通常定义为从代码提交到编译打包,再到SIT的过程
CD中的持续交付,我们通常定义为从代码提交到UAT的过程
有些项目里,没有用DevOps做CI的项目,也可变相为从编译打包到UAT的过程
CD中的持续部署,我们通常定义为从代码提交到最后生产部署的全过程
有些项目中,有可能变通为从编译打包到生产部署的过程
总结来看,项目结果不同,或者接入DevOps应用系统也有可能处于不同的阶段,这造成了,CI/CD的过程随项目实际情况会有些差异。
DevOps项目在售前、招标或前期阶段,我们通常看到是小圈里面的内容:CI/CD、自动化部署及回滚、与现有云平台的接口、流程的图形化编排调度等,但这些只是DevOps的内核,真正去落地一个DevOps项目的时候,其实你会看到外面大圈的这些内容,换句话讲,需要梳理组织整个软件生产的全过程!
姿势一:小范围CI+CD,再全公司推广
先看看Capital one的案例,美国第一资本金融公司,美国排名前十的银行。
痛点:
2014年当时:
Capital One的软件开发实践和很多传统做法没有什么不同:大量外包,瀑布模型,季度发布,手工流程,变更请求。在某次代码检查会上,大家发现一个测试失败是由于某个XML文件里的tag不配对造成的。按理说,这么小的问题改了再提交就可以了。但是:开发工作是由另外一家公司负责,他们需要发起漫长的变更请求;代码修改后的构建流程(编译、测试、部署等)就需要至少2天时间。这个小小的问题让Capital One的技术团队开始反思他们的构建流程,并决定从这里下手。他们从一个小的团队开始实践DevOps,最终把时间从2天缩短到几分钟。于是,这个实践逐渐在Capital One蔓延开来,所谓星星之火,可以燎原。
2015年的成绩:
代码提交频率:从之前的不固定到每天100多次的提交
代码集成频率:从每月1次到每15分钟一次
部署流程:手工变成自动化
部署到QA和Perf(性能)环境频率:从每月1次到每天4次
部署到生产环境频率:从每月或每个季度1次到每个迭代1次
单元测试覆盖:从没概念到>90%
2016年的成绩:
发布到产品环境的频率:从每个迭代一次到每天至少1次
自动发布的应用软件数量达20个
一个应用软件每天最多可以发布34次
总结DevOps在Capital one的落地姿势:先小范围做全套,再全公司大范围推广。
姿势二:先CI,后CD
我们看看中国银行的案例
在项目之初,中国银行首先对软件生产的全流程进行了重新梳理和规划,其中包含流程、规范、度量体系和反馈机制。
在实践阶段分了三步走,研发层面的持续集成、运维层面的持续交付,最终打通研发和运维实现DevOps全流程。
从试点效果来看,单就自动化部署层面就比之前提高了2-5倍的效率。并且在软件质量和规范落实层面有了长足的进步。
姿势三:先CD,后CI
这是一家地方商业银行,也是因为今年要上新核心,并且伴随新核心,有5个系统要重新建设,110套系统要配套改造,行领导提出的目标:在9月8日上线时,利用DevOps做一键式的统一部署!所以项目一期的重点就放在了CD上,短期目标是满足110多套系统的短期大量版本的提测后的自动化部署,最终目标,是要将1+5+110这些系统能够可视化的一键式部署。项目的二期重点,是在CI,配合诸多研发管理的落地实施,全流程的应用和推广以及自动化测试的接入。
2. DevOps在行业落地的套路
总结了五步:确定目标、选好姿势、梳理全流程、制定规范、最后分步实施。我们细看一下这五步:
第一步:确定目标
示例一:
这是农行对于DevOps设定的目标:1个平台、能够连接开发、测试、运维3个角色,打通需求、开发、测试、部署、运维5个环节。
示例二:
我们再看看招商银行设定的目标:DevOps是作为打造精益研发体系的一个重要组成部分。
第二步:选好姿势
第一种姿势:小范围CI+CD,之后全公司推广CI+CD , 并打通全流程
第二种姿势:先CI,后CD,打通全流程第
三种姿势:先CD,后CI ,打通全流程。
第三步:梳理全流程
示例一:
这是对一家商业银行全流程的梳理,以及DevOps需要集成的IT系统,如项目管理系统、JIRA以及测试管理系统。
示例二:
这是招商银行的全流程梳理,将DevOps平台切成了两个平台协同工作平台和持续交付流水线平台。
示例三:
以上是农行的全流程梳理方式。
第四步:制定规范
在将整个软件生产全流程梳理完之后,会很对DevOps及各原有IT系统的集成界面和分工非常清晰。接下来就要进行第四步规范的梳理和制定,规范包含哪些呢?
开发规范
持续集成规范
持续部署规范
持续交付规范
介质管理规范
文档命名规范
开发分支管理策略
测试管理规范
运维管理规范……
那规范制定的目的是什么呢?
有效管控软件生产线上的各个活动和环节
建立统一质量和衡量标准
软件生产活动能被持续度量、反馈、优化
通过DevOps进行有效落实
简单来讲,没有规范的制约,没有统一标准,大家各做各的,DevOps项目不可能成功。
第五步:分步实施
接下来,就是第五步,要具体的落地实施了,但也要有前有后,分轻重缓急。我们建议调些试点项目来,如何来调呢,原则是啥?
DevOps试点项目的选择建议原则:
基于互联网渠道,需要快速迭代的项目
需求、产品、开发、测试、运维都在一个团队的项目
有一定脚本化或CI/CD积累的项目
基于JAVA Maven的项目
DevOps试点项目执行原则:
制定规范与试点项目执行并行,来验证规范可落地、可实施,而非空中楼阁
通过试点项目总结出类似项目推行DevOps的规定动作,如:Demo脚本、CI/CD流程、自动化测试脚本、Maven二方库和三方库的管理经验等等
DevOps与试点项目团队混编,定期举行回顾会,巩固成果,总结教训,关键——肯定成绩和收获
DevOps试点项目执行的苦恼:一个巴掌拍不响:
需要坚持对目标的执念
“两口子过日子”理论
3. DevOps将软件生产线数字化
从横向角度来看,DevOps产生的数据可以分3个部分:管理数据、开发数据和运营数据,其实这些数据是涵盖了软件生产的全过程,我们可以通过这些数据或直播,来反哺到我们的生产过程,优化我们的不足。
我们从另一个角度DevOps的质量视图、从纵向角度来看,我们也可以从周期、效率、治理和技术的角度来去制定指标考核。
4. 一些DevOps最佳实践总结
持续集成的原则
鼓励开发人员在开发分支上频繁的提交代码,随后触发CI流程,在CI过程中可以加入单元测试和代码质量检查等动作,这样产生代码冲突的几率会下降,并且代码质量也会提高的;
在下班之前,构建必须处于成功状态,原因是你的代码在第二天有可能是其它同事开发工作的基础,如何无法保证构建成功,会影响其它的人工作质量和效率,团队氛围也会产生坏的影响;
让开发环境上快速体现最新程序包;
让程序、配置、数据分离,其实现在好多的单体应用开发时,是将程序、配置、数据裹在一起的,改一处,要解决一堆的依赖,改一处,牵扯到很多地方都要做更新,这些降低了版本迭代的效率,并且很可能会出现遗漏;
maven模式下,pom依赖尽量不要用system本地依赖模式,而是将二方库和三方库依赖到统一的类似Nexus介质库,整个组织一份,来屏蔽本地jar依赖差异导致的编译错误。
持续集成的最佳实践
构建过程,建议等待构建的结果,不要同时做其它的事情,尤其是构建失败之后不要提交新代码,这样很可能会错上加错,最后不知道到底是谁的错,这些错误的回溯会产生很大的成本;
提交之前在本地运行所有的提交测试;
提交之前请更新本地代码,保证代码是最新的,冲突解决了,再提交;
记得更新数据库、配置文件等;
等构建成功后再继续其他工作;
下班之前,构建必须处于成功状态;
以十分钟为界限,如果代码提交后构建错误,十分钟之内无法解决问题,需要将新代码撤回,否则可能会影响其它同事的工作。
自动化部署的原则
原则1:确保从开发、各类测试到生产,使用相同版本的中间件和操作系统,保证从操作系统、到补丁包、到应用运行环境基线是一致的;
原则2:同一套脚本,解决各类环境的部署问题,不要试图通过脚本来解决环境的差异性,因为环境的差异性本应该是不存在的,否则改了脚本,之前的各个环境还需要做脚本的回归测试;
原则3:部署之前,事先设计回滚与零停机发布的策略;
原则4:全量发布优先,尽量不要用增量发布,因为引入增量发布,就会引入手工操作,人工去选择哪些做增量;
原则5:详细记录部署活动的整个过程。
自动化部署的最佳实践
要做到自动化部署,要确保自动化部署的成功,最最重要的关键为:保障一致性!将要部署的各个环境一致;在各个环境执行的部署脚本一致;要部署的安装包也要一致!
从提测之后,所有环境运行的是同一个介质包,不要在SIT、UAT、准生产和生产等环节重复的打包;
保证各个环境的操作系统、补丁和软件运行环境的基线一致;
保证使用同一的二方和三方库依赖,推荐Nexus;
关于配置文件,建议: 配置文件与代码的版本保持一致;
配置项清晰、规范、统一命名;
配置项模块化、且封闭;
每个配置项都是唯一的,避免顾此失彼;
避免过分设计,尽量简单;
建议逐步过渡到Apollo这样的统一配置中心,以key/value的形式管理各环境的配置项