mikea 发表于 2018-10-4 10:42:17

基于Docker的DevOps实现

本帖最后由 adminlily 于 2018-10-4 10:45 编辑

主题简介:

1、传统开发模式的问题分析

2、DevOps的完成流程详解

3、基于Docker的DevOps实现步骤详解和案例分享

一、传统开发模式的问题分析

众所周知,传统开发模式已经面临了诸多难题。首先,在代码集成方面,因为没有合适粒度的代码合并,大规模的合并会有很大的风险,且传统开发模式中没有自动化测试,以至于测试周期特别长,人力成本高昂。其次,传统开发中的单体应用,通常都很庞大,单体应用把所有模块都包含在一个应用中,升级单个模块也需要对整个应用进行升级,所以升级和创新都很不方便,常见的如银行系统就是如此。

同时,传统的开发模式中单独采用微服务的情况也会由于服务数量多而没有有效管理,在大批量的部署和测试的时候容易出现问题。除此之外,传统开发模式更面临着开发和测试的环境不一致,以及由于没有有效的升级方式导致业务停止的问题。

二、DevOps的完成流程详解
(如何一步步实现DevOps)


为了解决传统开发模式中的问题,目前一个比较流行和彻底的方案是:DevOps流程+微服务理论+使用容器和容器编排工具。在这里展示给大家的是一个理论上的基于容器的CI/CD流程,实际上,DevOps的前身就是CI/CD,实现了CI/CD后,再加上一些发布、部署等标准和管理就构成了DevOps。
(基于容器的CI/CD流程)


三、基于Docker的DevOps实现步骤详解和案例分享

1、实现DevOps之自动化测试

那么,如何完整地实现DevOps呢?通常情况下,传统开发模式转向DevOps的第一步是解决自动化问题。要想持续地集成代码,没有自动化测试来保证快速地进行合并后的验证,风险是很高的,而且没有自动化测试,测试环境很有可能成为整个开发环节的瓶颈。只要是经常使用的测试用例,需要尽量自动化每一个操作。

自动化工具很多,对自动化工具和测试框架的选择需要根据具体应用来决定,这里只列举其中常用的一小部分——Jenkins、Python、Robot Framework、Shell Script、Selenium、Ansible和Docker Container Orchestration——这些都是我们面对客户需求的时候经常用到的。然而,不是每次集成都需要跑完所有的测试用例,因而对测试用例进行管理,可提高持续集成的效率。
(自动化测试)


如何来判断自动化测试用例和框架是否有效?常见的判断依据有三个,首先是自动化测试的覆盖率。如果通过率再高,覆盖率低,那么自动化测试就不是一个有效的,目前企业级比较认可的覆盖率是75%左右,再提高也比较困难。其次是看漏测率,有时候自动化用例本身也可能有Bug,前期阶段通过比较手动测试、自动化测试的结果来判断自动化测试是否有效。最后,当产品发布后根据从客户来源的bug数目来判断自动化测试用例是否有效。另外,要稳定一套自动化用例,一般需要2个版本周期或者更长。

2、实现DevOps之持续集成和持续交付

持续集成一个主要的功能是让每个工程师的代码提交都不会影响到Mainline,以保证Mainline的可发布状态。实施持续集成时,需要注意的地方:指定规则,提交代码时要一并提交新功能的测试用例。

集成的粒度和频度也很关键。一般一个小模块,不超过1周的时间。
(持续集成)


持续集成通过后,根据应用程序的特点,在经过系统集成测试、性能测试、稳定的自动化测试通过率以及管理层的批准后,才是可持续交付和部署的应用程序。

持续交付有两种方式,一种就是基于DevOps的自动持续发布,一种是多个功能一并发布。在持续交付的过程中需要注意三个问题:


[*]部署到生产环境后也要有相应的测试;


[*]使用Toggle控制功能是否生效;


[*]要有回滚的手段(灰度发布)。

3、实现DevOps之微服务化

有了自动化测试、持续集成和持续交付三块,已经基本实现了DevOps的粗略流程,而为了提高DevOps的效率, 往往需要结合微服务。一个微服务理论上只做一件事,并能用任何语言编写。微服务是松耦合的,意味着一个应用的微服务可以被部署到不同机器上并通过RestAPI/RPC来通信,当定义好微服务的API之后,每个team便能独立开发。因此,微服务更容易被测试和实现CI/CD。
(微服务的最佳实践)


在微服务的最佳实践中,首先不得不提容器。容器的轻量化让微服务启动很快,同时容器的跨平台性保证了微服务可以在不同的平台启动起来。第二种是使用代理服务器来访问微服务,现在最常见的方式是前端连接一个代理服务器,后端再连接运行同一个微服务的几个相同容器。一个大的应用会使用几十上百个微服务,和微服务不相关的库文件不建议放在容器中。实践微服务中,建议使用配置管理工具(ansible, puppet等)和容器服务编排工具(K8s,Swarm,EcOS等)。
(康威定律)


在开发微服务中康威定律起到了很大的作用。康威定律指出任何软件代码都是用来反映组织机构而产生的,如果要采用微服务的开发方法,就需要是把团队划分成多个小团队,由每个小团队负责一个或多个微服务。所以如果要转成DevOps和CI/CD的开发模式,就需要采用这种敏捷开发模式,一个团队7-8个人比较合适。

4、实现DevOps之容器技术

另外一个实现DevOps的重要手段是Docker容器技术。和传统的Hypervisor相比,Docker没有自己的操作系统,它使用宿主机的操作系统,而Hypervisor需要建立虚拟机,每个虚拟机需要装一个操作系统,因此Docker效率更高更节约资源。如果一台物理机可以操作20个虚拟机,便至少可以启动200个容器,且启动容器的时间是秒级。


Docker和Hypervisor的对比


使用容器编排工具可以实现对容器的健康检查、动态伸缩、灰度发布和蓝绿发布等功能。而我们提到的容器编排技术,比如K8s,Mesos和Swarm,都是开源的工具,这里我们把精灵云自研的容器编排工具EcOS和开源工具进行了简单对比。
(几种常见容器编排技术的比较)


K8s是由谷歌发起的开源框架,最大的问题是太笨重,对使用者来说操作很复杂,学习周期很长。Swarm是Docker公司开发的工具,Docker本身不能支持的功能,Swarm也是无法支持的。如图所示,EcOS是精灵云自主开发的容器编排技术,最大的特点是结合了开源工具的优点,在应用编排上完全可视化。

5、实现DevOps之灰度发布

如果一个服务由多个相同的容器运行,灰度发布则先对其中的部分容器先进行升级,可混合让老版本和新版本的容器同时提供服务。如发现新服务没有什么问题,则可以把所有剩下的微服务再全部进行升级。
(灰度发布)


6、实现DevOps之版本控制

DevOps下版本控制的原则是始终在Mainline上进行新功能的开发,并经由持续集成的自动化测试对代码进行验证。当功能开发到一定阶段的时候,对可RC的代码创建分支,该分支上停止新功能的开发,只求稳定。当产品发布后,如发现问题,可出hotfix。根据时间点和具体需要,可把其他分支的hotfix merge到Mainline上。
(版本控制原理)
Q&A

Q1:微服务是一个抽象概念还是说有具体的工具来实现?

A1:微服务是一种软件架构风格,它以专注于单一责任与功能的小型功能模块为基础,利用模块化的方式组合出复杂的大型应用程序。另一方面,也可以说微服务是一种编程思维,如果是想要开发出能在云上运行的微服务,可参考云原生的12因素法则。

Q2:请问传统的非常庞大的单体应用如何逐步改成微服务?

A2:1)新的功能开发使用微服务方式。

      2)把边缘模块换成微服务方式。

      3)将前端和后端分离

      4)抽出服务,逐步替换。这一步尤为复杂,需要由经验丰富的架构师来主导。

Q3:请问一下刚所说的75%覆盖率,是前后端全部的?

A3:平均覆盖率为75%。

Q4:你们这边Devops应用在什么量级别?

A4:Ghostcloud已经结合Jenkins和EcOS,完全实现了自动化的持续集成。但是目前还有一些手动的系统集成测试和性能测试。

Q5:您所说的企业级应用指的哪种类型的?包括一些复杂的SaaS应用吗?有没有一些实际的项目事例的自动化测试覆盖率供参考?

A5:银行的管理系统,电商的平台,企业的云平台管理软件等,大型的由企业使用的软件都可以叫企业级应用。SaaS当然可以算是企业级应用。国外很多大公司的代码覆盖率都是这个70%~80%值,可以看一下这篇文章:minimum.html

Q6:web ui的自动化测试用的什么工具,比如input框如何search到?

A6:web ui的测试工具很多,比如Robot Framework的Selenium. 对于input框这类元素,可使用xpath来定位。


Q7:负载均衡有啥好的方案?怎么自动发现应用拓扑(ip)变化?

A7:我们目前使用的是HAProxy,并且正在开发Nginx的支持。自动发现使用的是ETCD+DNS+Wather的方式,当容器IP地址发生改变,可自动捕获,并更新代理服务器的配置文件。

Q8:之前我们在搭建PaaS平台时,花费了很多时间在环境搭建、定位环境问题上,请问对于平台的搭建维护,有什么好的建议?

A8:建议试一下EcOS,一键部署。

Q9:traefik专门用来做微服务负载均衡,国内用得多吗?

A9:大多数还是用的HAProxy和Nginx吧。

原创:乔融 Ghostcloud精灵云CTO
页: [1]
查看完整版本: 基于Docker的DevOps实现