技术干货 | 骞云科技 DevOps 实践发表时间:2019-02-07 12:00 本周二(2月26日) 20:30 - 22:00,骞云科技在 DockOne 社区进行了主题为「骞云科技 DevOps 实践」的在线直播,反响热烈。分享内容及问答整理如下: 摘要 随着公司业务的快速发展,需要加快开发流程的规范化和自动化,以提高产品的开发效率和交付效率。之前的开发测试和资源管理主要是半自动化的,个人生产力和资源利用率仍有很大提升空间。 在DevOps的具体实践中,一方面, Gerrit + GitLab + Jenkins + CMP(Ansible)共同构建了更好的 CI/CD 流程,对自动化持续交付流水线进行了优化;另一方面,CMP(Self-Service Portal)帮助建立了自服务自运维门户,公司所有人员都可以通过统一的门户自助申请各类资源,并自助完成日常运维。 主要内容: 1. 为什么我们要加强DevOps? 2. DevOps整体规划 3. DevOps实践(一):构建更好的CI/CD流程 4. DevOps实践(二):建立自服务自运维门户 5. 总结与建议 6. 未来发展方向 为什么我们要加强 DevOps? 在公司创立早期,为了尽快实现产品从0到1的转化,我们将更多的资源投入到了产品的新功能开发上,在产品开发自动化方面的投入并不高。 随着公司业务的迅速发展,一方面,团队规模不断扩大,服务器资源也越来越多;另一方面,产品的功能逐渐丰富,开发代码工程数和分支数增加,而开发测试和资源管理仍以半自动化为主。 面临的问题 问题一:人力资源浪费 手工打包、手工创建虚机、手工部署、手工升级、较低程度的自动化测试,这些重复且低效的开发测试模式导致开发测试人员不能将宝贵的时间用于更加有创造力的工作上,不利于个人和公司的快速发展。 问题2:IaaS资源管理混乱 我们的开发测试环境主要构建在内部的vSphere和OpenStack云台上,当然也会在Aliyun、AWS、Azure等公有云上创建资源。 在日常工作过程中,我们经常会听到这样的声音:“我的环境怎么这么卡”、“阿里云上又没钱啦”、“OpenStack上的机器我要删了啊”、“谁删了我的机器,我的数据还在上面呢”。 由于没有权限控制导致资源随意创建,资源不及时释放导致大量资源闲置和浪费,另外还存在资源误删除情况。 问题3:内部系统运维成本居高不下 我们没有专职的内部系统运维人员,平时开发过程中,遇到CPU/Memory调整、磁盘物理卷/逻辑卷扩容、操作系统故障、应用故障等一系列问题都会占用研发人员大量的时间和精力。 问题4:产品交付难度大 为满足稳定性、高可用性、可扩展性等交付需求,我们的产品在软件架构设计上具有较高的复杂度,这样一来安装部署实施的难度也就比较大。 售前团队到客户现场做POC,想要快速部署一套公司产品比较困难;售后团队在项目交付的过程中也经常遇到各种各样的安装配置问题。 基于上述问题,我们希望通过对DevOps工作流程进行改造和增强,以提高产品开发效率和交付效率,以及提升个人生产力和资源利用率。 DevOps 整体规划 我们将DevOps工作流程改造分为了两个方面,一个是对CI/CD工作流的优化,一个是搭建自服务自运维门户。 CI/CD目标
自服务自运维目标 公司所有人员,都可以通过一个统一门户Portal,自助申请各种类型的IaaS资源,如:x86物理服务器、vSphere虚拟机、OpenStack虚拟机、Kubernetes上的容器服务,以及Aliyun、AWS、Azure等公有云上的云资源;自助申请日常开发所需的软件应用,如:Nginx、Tomcat、MySQL、RabbitMQ,以及SmartCMP等。
DevOps 实践(一):构建更好的CI/CD流程 概述 我们的 DevOps 工具链由 GitLab、Gerrit、Jenkins、CMP 构成。
![]() 开发人员提交代码后,触发Jenkins完成代码编译检查和单元测试,Jenkins返回代码检查结果给Gerrit,人工Review后merge代码,触发Jenkins完成该项目的打包。 Jenkins定时完成各个工程的集成打包,然后通过调用CMP的API触发自动化部署,部署完成后进行场景化的集成测试,测试完成后卸除资源。 ![]() 持续集成(Jenkins) 起初我们使用GitLab Runner实现CI,在每个代码工程中添加“.gitlab-ci.yaml”文件,不同项目各自创建和维护自己的.gitlab-ci.yaml脚本,这样的实现可以解决各自工程的编译测试和打包问题,在代码工程数量较少时,我们也使用了较长一段时间。 现在我们的代码工程数量已超过20个,每个代码工程都设置了访问权限,如果需要专人维护CI脚本的话,那他需要能够访问所有代码工程,显然这样是不合理的,而且把集成打包脚本放在哪个工程里都不合适。 考虑到Jenkins有强大的CI能力:通过安装插件就能快速与Gerrit、GitLab集成,能够参数化执行各种类型的脚本。所以,我们使用Jenkins代替gitlab-runner完成CI,通过Jenkins可以统一管理各个工程的编译、测试、打包,而且比较方便构建流水线完成较多工程集成打包及测试。 ![]() 持续部署(Ansible) 我们的产品由20多个服务组成,可部署在一个或多个虚拟机上,使用Shell脚本或Python脚本已经很难完成这么多服务程序的自动化安装部署配置。 恰巧团队有使用Ansible做复杂系统部署的经验,Ansible的学习成本也较低,所以我们选择使用Ansible Playbook 实现这20多个服务程序的统一编排部署和配置,并且可以同时支持单节点和HA多节点自动化部署。 ![]() 我们设计Ansible Playbook时,将每个服务都独立成一个角色,这样保证了各个服务部署的独立性,这种分布式部署架构为将来容器化部署和微服务化奠定了基础。 Ansible自动化标准化部署不仅大大缩短了部署时间,也极大地降低了部署出错的概率。原先,按照HA架构部署一套产品需要1天时间来完成各个服务的部署和配置,通过使用Ansible playbook,我们只需要45分钟,而且中间过程完全可以放手去做别的事情。 集成测试(Robot Framework) 目前,我们在Jenkins中使用Robot Framework框架做集成测试。Robot Framework(以下简称RF)是一个基于Python的、可扩展的、关键字驱动的测试自动化框架。 选用RF的原因:
![]() 选用RF也存在一些问题:
RF对于变量类型的规定堪称僵硬(当然,这么规定带来的好处是方便类型检测),RF中对于字典类型的创建非常麻烦(嵌套的字典实例如下),对于我们公司API请求中携带大量参数的情况,只能创建关键字来解决,不管是采取RF自带创建字典的方法,还是创建关键字的方法,都比较浪费时间(因为难以复用)。 ![]()
在RF中,关键字其实就是Python/Java的类方法,因此扩展起来非常容易,但是关键字一旦多起来,一个同事写的测试用例,其他人(甚至他自己过了一段时间)维护就非常麻烦(需要回去看关键字是如何规定的)。因此需要严格规定关键字的创建规范是一件值得深入讨论的事情。 DevOps 实践(二):建立自服务自运维门户 我们使用云管理平台(以下简称CMP,Cloud Management Platform)管理公司内部资源,使得公司所有人员,都可以通过CMP提供的自服务门户(Self-Service Portal),完成计算/存储/网络等IaaS资源和软件应用自助申请,并且能够自助进行日常运维操作。 CMP平台准备工作 通过LDAP方式将公司AD账户导入CMP平台中,为开发、测试、售前售后团队创建不同的业务组和资源池,每个资源池给到不同的资源配额,做到资源合理分配和资源相互隔离。为每个业务组设定一个管理员,审批业务组成员的资源申请。 ![]() 我们使用Shell、Python脚本或Ansible 配置管理工具将内部常用的一些软件及应用系统的安装过程进行封装,并发布到CMP平台中,提供标准化蓝图方便大家申请。 ![]() 自服务自运维门户 在门户中,大家可以看到已经发布好的服务卡片,通过点击服务卡片即可完成IaaS资源或应用系统的自助申请,在平时的开发测试过程中,我们不再需关心底层复杂的系统或网络配置。 ![]() 在门户中,大家也可以清晰地看到自己所管理的资源的性能情况,还可以简单便捷地完成一些日常的基础运维操作:重启、调整配置、添加逻辑卷、扩展逻辑卷等。 ![]() 此外,使用管理账号登录CMP管理平台,可以清晰地看到公司内部资源的总体使用情况。 ![]() ![]() ![]() 总结与建议 在骞云科技的DevOps实践中,一方面,我们将GitLab、Gerrit、Jenkins、Ansible、JMeter、Robot Framework等成熟的开源工具开源技术和企业内部的云管理平台相结合,实现了较高程度的开发测试流程自动化,推动了产品的持续集成和持续交付,减少了大量的重复劳动,提高了开发测试效率。 另一方面,通过使用云管理平台,将复杂异构的IaaS资源服务化,降低了使用难度;结合业务部门需求合理划分资源,减少了资源浪费,加强了资源的有效隔离,避免了误操作;自服务自运维的模式,也极大地提升了公司整体研发效率。 我们的DevOps实践方案适用的场景非常多样,比如:弹性伸缩、迁移、负载均衡。在传统IT、金融、互联网、游戏等行业也具有普适性。 未来发展方向 在介绍Ansible自动化部署时有提到,我们的业务系统由20多个服务组成,符合服务化的架构设计,目前已经可以满足私有化的部署需求。 随着新功能的不断引入,部分业务子系统复杂度和团队开发耦合度会逐渐升高,协作效率和部署效率会变得低下。另外,当前的软件架构和部署架构不能满足将来的SaaS化部署。 所以,我们仍需要将服务进行更细粒度的拆分,逐步向微服务架构转变并使用容器化部署,进一步降低开发和部署成本。 Q&A |