转载

DockOne微信分享(二零三):骞云科技DevOps实践

【编者的话】随着公司业务的快速发展,需要加快开发流程的规范化和自动化,以提高产品的开发效率和交付效率。之前的开发测试和资源管理主要是半自动化的,个人生产力和资源利用率仍有很大提升空间。在DevOps的具体实践中,一方面, Gerrit + GitLab + Jenkins + CMP(Ansible)共同构建了更好的 CI/CD 流程,对自动化持续交付流水线进行了优化;另一方面,CMP(Self-Service Portal)帮助建立了自服务自运维门户,公司所有人员都可以通过统一的门户自助申请各类资源,并自助完成日常运维。

为什么我们要加强 DevOps?

在公司创立早期,为了尽快实现产品从0到1的转化,我们将更多的资源投入到了产品的新功能开发上,在产品开发自动化方面的投入并不高。

随着公司业务的迅速发展,一方面,团队规模不断扩大,服务器资源也越来越多;另一方面,产品的功能逐渐丰富,开发代码工程数和分支数增加,而开发测试和资源管理仍以半自动化为主。

面临的问题:

人力资源浪费

手工打包、手工创建虚机、手工部署、手工升级、较低程度的自动化测试,这些重复且低效的开发测试模式导致开发测试人员不能将宝贵的时间用于更加有创造力的工作上,不利于个人和公司的快速发展。

IaaS资源管理混乱

我们的开发测试环境主要构建在内部的vSphere和OpenStack云台上,当然也会在Aliyun、AWS、Azure等公有云上创建资源。在日常工作过程中,我们经常会听到这样的声音:“我的环境怎么这么卡”、“阿里云上又没钱啦”、“OpenStack上的机器我要删了啊”、“谁删了我的机器,我的数据还在上面呢”。由于没有权限控制导致资源随意创建,资源不及时释放导致大量资源闲置和浪费,另外还存在资源误删除情况。

内部系统运维成本居高不下

我们没有专职的内部系统运维人员,平时开发过程中,遇到CPU/Memory调整、磁盘物理卷/逻辑卷扩容、操作系统故障、应用故障等一系列问题都会占用研发人员大量的时间和精力。

产品交付难度大

为满足稳定性、高可用性、可扩展性等交付需求,我们的产品在软件架构设计上具有较高的复杂度,这样一来安装部署实施的难度也就比较大。售前团队到客户现场做POC,想要快速部署一套公司产品比较困难;售后团队在项目交付的过程中也经常遇到各种各样的安装配置问题。

基于上述问题,我们希望通过对DevOps工作流程进行改造和增强,以提高产品开发效率和交付效率,以及提升个人生产力和资源利用率。

DevOps整体规划

我们将DevOps工作流程改造分为了两个方面,一个是对CI/CD工作流的优化,一个是搭建自服务自运维门户。

CI/CD目标

  • 所有代码工程能够自动化打包
  • 所有代码提交后能够自动构建编译检查以及单元测试任务
  • 每小时完成一次软件集成、部署以及核心功能的集成测试(API&UI)
  • 每天完成一次完整功能的集成测试(API&UI)
  • 每周完成一次7x24小时Longrun系统测试
  • 自动更新经过测试的nightly build到开发测试环境
  • 自动发布经过测试的weekly build到Demo环境

自服务自运维目标

公司所有人员,都可以通过一个统一门户Portal,自助申请各种类型的IaaS资源,如: x86物理服务器、vSphere虚拟机、OpenStack虚拟机、Kubernetes上的容器服务,以及Aliyun、AWS、Azure等公有云上的云资源;自助申请日常开发所需的软件应用,如:Nginx、Tomcat、MySQL、RabbitMQ,以及SmartCMP等。

  • 开发Dev,测试QA,售前交付需要使用不同的资源,做到资源隔离;
  • 资源的使用需要有权限控制;
  • 需要能够一键部署单节点和HA多节点应用系统;
  • 提供环境自动初始化,一键升级能力;
  • 提供系统和应用级别的监控告警;
  • 资源需要能够定期回收。

构建更好的CI/CD流程

概述

我们的DevOps工具链由 GitLab、Gerrit、Jenkins、CMP 构成。

  • GitLab:代码托管
  • Gerrit:代码审查
  • Jenkins:单元测试、自动化打包、集成测试
  • CMP:vSphere、OpenStack、Kubernetes等云资源统一管理,应用系统自动化部署,版本更新

具体的工作流如下图所示:

DockOne微信分享(二零三):骞云科技DevOps实践

开发人员提交代码后,触发Jenkins完成代码编译检查和单元测试,Jenkins返回代码检查结果给Gerrit,人工Review后merge代码,触发Jenkins完成该项目的打包。Jenkins定时完成各个工程的集成打包,然后通过调用CMP的API触发自动化部署,部署完成后进行场景化的集成测试,测试完成后卸除资源。

DockOne微信分享(二零三):骞云科技DevOps实践

持续集成(Jenkins)

起初我们使用GitLab Runner实现CI,在每个代码工程中添加“.gitlab-ci.yaml”文件,不同项目各自创建和维护自己的.gitlab-ci.yaml脚本,这样的实现可以解决各自工程的编译测试和打包问题,在代码工程数量较少时,我们也使用了较长一段时间。

现在我们的代码工程数量已超过20个,每个代码工程都设置了访问权限,如果需要专人维护CI脚本的话,那他需要能够访问所有代码工程,显然这样是不合理的,而且把集成打包脚本放在哪个工程里都不合适。

考虑到Jenkins有强大的CI能力:通过安装插件就能快速与Gerrit、GitLab集成,能够参数化执行各种类型的脚本。所以,我们使用Jenkins代替gitlab-runner完成CI,通过Jenkins可以统一管理各个工程的编译、测试、打包,而且比较方便构建流水线完成较多工程集成打包及测试。

DockOne微信分享(二零三):骞云科技DevOps实践

持续部署(Ansible)

我们的产品由20多个服务组成,可部署在一个或多个虚拟机上,使用Shell脚本或Python脚本已经很难完成这么多服务程序的自动化安装部署配置。

恰巧团队有使用Ansible做复杂系统部署的经验,Ansible的学习成本也较低,所以我们选择使用Ansible Playbook 实现这20多个服务程序的统一编排部署和配置,并且可以同时支持单节点和HA多节点自动化部署。

下图是Ansible自动化部署拓扑图:

DockOne微信分享(二零三):骞云科技DevOps实践

我们设计Ansible Playbook时,将每个服务都独立成一个角色,这样保证了各个服务部署的独立性,这种分布式部署架构为将来容器化部署和微服务化奠定了基础。

Ansible自动化标准化部署不仅大大缩短了部署时间,也极大地降低了部署出错的概率。原先,按照HA架构部署一套产品需要1天时间来完成各个服务的部署和配置,通过使用Ansible playbook,我们只需要45分钟,而且中间过程完全可以放手去做别的事情。

集成测试(Robot Framework)

目前,我们在Jenkins中使用Robot Framework框架做集成测试。Robot Framework(以下简称RF)是一个基于Python的、可扩展的、关键字驱动的测试自动化框架。

选用RF的原因:

  • 一致性:目前公司的UI自动化测试使用的就是RF框架,RF框架也完全有能力做集成测试,因此使用RF框架做集成测试,可以降低学习成本,提高可维护性。
  • 复用性:在安装了Robot-Framework-JMeter-Library后,RF可以运行JMeter脚本,并且将JMeter运行结果转为Html格式。公司目前性能测试用的就是JMeter,对于相同场景,只要小幅修改JMeter脚本即可将其复用到集成测试上面。

DockOne微信分享(二零三):骞云科技DevOps实践

选用RF也存在一些问题:

  • 如果不复用JMeter脚本,编写的API测试用例的成本非常高。
    RF对于变量类型的规定堪称僵硬(当然,这么规定带来的好处是方便类型检测),RF中对于字典类型的创建非常麻烦(嵌套的字典实例如下),对于我们公司API请求中携带大量参数的情况,只能创建关键字来解决,不管是采取RF自带创建字典的方法,还是创建关键字的方法,都比较浪费时间(因为难以复用)。
    DockOne微信分享(二零三):骞云科技DevOps实践
  • RF可以轻松扩展关键字,也因此可能带来乱扩展关键字的问题,导致测试用例可读性和可维护性差的问题。

在RF中,关键字其实就是Python/Java的类方法,因此扩展起来非常容易,但是关键字一旦多起来,一个同事写的测试用例,其他人(甚至他自己过了一段时间)维护就非常麻烦(需要回去看关键字是如何规定的)。因此需要严格规定关键字的创建规范是一件值得深入讨论的事情。

建立自服务自运维门户

我们使用云管理平台(以下简称CMP,Cloud Management Platform)管理公司内部资源,使得公司所有人员,都可以通过CMP提供的自服务门户(Self-Service Portal),完成计算/存储/网络等IaaS资源和软件应用自助申请,并且能够自助进行日常运维操作。

CMP平台准备工作

通过LDAP方式将公司AD账户导入CMP平台中,为开发、测试、售前售后团队创建不同的业务组和资源池,每个资源池给到不同的资源配额,做到资源合理分配和资源相互隔离。为每个业务组设定一个管理员,审批业务组成员的资源申请。

DockOne微信分享(二零三):骞云科技DevOps实践

我们使用Shell、Python脚本或Ansible配置管理工具将内部常用的一些软件及应用系统的安装过程进行封装,并发布到CMP平台中,提供标准化蓝图方便大家申请。

DockOne微信分享(二零三):骞云科技DevOps实践

自服务自运维门户

在门户中,大家可以看到已经发布好的服务卡片,通过点击服务卡片即可完成IaaS资源或应用系统的自助申请,在平时的开发测试过程中,我们不再需关心底层复杂的系统或网络配置。

DockOne微信分享(二零三):骞云科技DevOps实践

在门户中,大家也可以清晰地看到自己所管理的资源的性能情况,还可以简单便捷地完成一些日常的基础运维操作:重启、调整配置、添加逻辑卷、扩展逻辑卷等。

DockOne微信分享(二零三):骞云科技DevOps实践

此外,使用管理账号登录CMP管理平台,可以清晰地看到公司内部资源的总体使用情况。

DockOne微信分享(二零三):骞云科技DevOps实践

DockOne微信分享(二零三):骞云科技DevOps实践

DockOne微信分享(二零三):骞云科技DevOps实践

总结与建议

在骞云科技的DevOps实践中,一方面,我们将GitLab、Gerrit、Jenkins、Ansible、JMeter、Robot Framework等成熟的开源工具开源技术和企业内部的云管理平台相结合,实现了较高程度的开发测试流程自动化,推动了产品的持续集成和持续交付,减少了大量的重复劳动,提高了开发测试效率。

另一方面,通过使用云管理平台,将复杂异构的IaaS资源服务化,降低了使用难度;结合业务部门需求合理划分资源,减少了资源浪费,加强了资源的有效隔离,避免了误操作;自服务自运维的模式,也极大地提升了公司整体研发效率。

我们的DevOps实践方案适用的场景非常多样,比如:弹性伸缩、迁移、负载均衡。在传统IT、金融、互联网、游戏等行业也具有普适性。

未来发展方向

在介绍Ansible自动化部署时有提到,我们的业务系统由20多个服务组成,符合服务化的架构设计,目前已经可以满足私有化的部署需求。随着新功能的不断引入,部分业务子系统复杂度和团队开发耦合度会逐渐升高,协作效率和部署效率会变得低下。另外,当前的软件架构和部署架构不能满足将来的SaaS化部署。所以,我们仍需要将服务进行更细粒度的拆分,逐步向微服务架构转变并使用容器化部署,进一步降低开发和部署成本。

Q&A

Q:CMP和各个云平台打通都使用了平台的jar,并且需要各种资源生成,这个工作量也不小吧?并且如果api更新代码量也大吧?

A:我们的核心业务就是做云管理平台,我们产品已经完成了对各个云平台的对接,主要调用各个云平台的API。公有云的API更新频率并不是很高,每当API有更新时,我们也及时去适配。

Q:Jenkins初次提交也能触发构建吗?每次自动化构建版本号是如何更新的呢?

A:我们的项目代码具备构建条件后,才在Jenkins上创建了项目构建Job,所以并没有在初次提交时触发构建。每次构建的版本号由两部分组成,一部分是产品的Release大版本号,另一部分直接使用的Jenkins build number这个环境变量。

Q:有了Gerrit,为什么还要GitLab,Gerrit也可以托管代码啊?

A:这个是有历史背景的,我们是先选择使用GitLab做代码托管,后期才加入Gerrit做code review。Gerrit在代码review方面比GitLab的merge request要方便许多,更适合企业内部使用。关于这个,我的想法是,要么将GitLab迁移到Gerrit,要么不用Gerrit,可以使用GitLab的merge request来进行review,那GitLab其实是可以不要的。

以上内容根据2019年2月26日晚微信群分享内容整理。分享人 夏飞,骞云科技SmartCMP云管理平台后端开发负责人,负责云管理平台的建设和推广,目前负责公司内部DevOps工作流程的改造 。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesd,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

原文  http://dockone.io/article/8622
正文到此结束
Loading...