传统开发流程
DevOps 是一种新型的业务研发流程,业务的开发人员:
- 负责业务代码的开发
- 负责业务的测试
- 负责上线发布
真正做到掌控服务全流程。
DevOps
实现 DevOps,就必须开发完成代码开发后,能自动进行测试,测试通过后,能自动发布到线上。对应的这两个过程就是 CI 和 CD,具体来讲就是:
- CI(Continuous Integration),持续集成。开发完成代码开发后,能自动地进行代码检查、单元测试、打包部署到测试环境,进行集成测试,跑自动化测试用例。
- CD(Continuous Deploy),持续部署。代码测试通过后,能自动部署到类生产环境中进行集成测试,测试通过后再进行小流量的灰度验证,验证通过后代码就达到线上发布的要求了,就可以把代码自动部署到线上。
DevOps的关键是如何实现代码开发自测通过,自动部署到测试环境,验证通过后再自动部署到生产环境,小流量验证后再自动发布到线上去。
在传统的采用物理机部署服务的时代,代码环境的可移植性差,经常会出现开发环境中运行通过的代码,部署到测试环境就运行不了的问题。
而容器化正好解决了代码环境的可移植性的问题,使得 DevOps 取得了突飞猛进的发展,并成为业界推崇的开发模式。
业界主流方案:Jenkins或者GitLab。
持续集成
确保每一次代码的 Merge Request 都测试通过,可随时合并到代码的 Develop 分支,主要包括四个阶段:
- build 阶段(开发分支代码的编译与单元测试)
- package 阶段(开发分支代码打包成 Docker 镜像)
- deploy 阶段(开发分支代码部署到测试环境)
- test 阶段(开发分支代码集成测试)
持续交付
确保所有代码合并 Merge Request 到 Develop 分支后,Develop 分支的代码能够在生产环境中测试通过,并进行小流量灰度验证,可随时交付到线上。主要包括五个阶段:
- build 阶段(Develop 分支的代码编译与单元测试)
- package 阶段(Develop 分支的代码打包成 Docker 镜像)
- deploy 阶段(Develop 分支的代码部署到测试环境)
- test 阶段(Develop 分支的代码集成测试)
- canary 阶段(Develop 分支的代码的小流量灰度验证)
持续部署
合并 Develop 分支到 Master 主干,并打包成 Docker 镜像,可随时发布到线上。主要包括四个阶段:
- build 阶段(Master 主干的代码编译与单元测试)
- package 阶段(Master 主干的代码打包成 Docker 镜像)
- clear 阶段(Master 主干的代码 Merge 回 Develop 分支)
- production 阶段(Master 主干的代码发布到线上)
DevOps关键
持续集成阶段
保证每一次开发的代码都没有问题,即使合并到主干也能正常工作,这里主要依靠三部分的作用:
- 代码检查。发现代码潜在的一些 bug,实际执行时可以在集成类似Sonarqube之类的工具实现代码检查。
- 单元测试。针对每个具体代码模块的,单元测试的覆盖度越高,各个代码模块出错的概率就越小。
- 集成测试。将各个代码的修改集成到一起,统一部署在测试环境中进行测试。为了实现整个流程的自动化,集成自测阶段主要的任务就是跑每个服务的自动化测试用例,所以自动化测试用例覆盖的越全,集成测试的可靠性就越高。这里就要求开发和测试能及时沟通,在新的业务需求确定时,就开始编写测试用例。
持续交付阶段
保证最新的业务代码,能够在类生产环境中可能够正常运行,一般做法是从线上生成环境中摘掉两个节点,然后在这两个节点上部署最新的业务代码,再进行集成测试,集成测试通过后再引入线上流量,来观察服务是否正常。通常需要解决两个问题:
- 如何从线上生产环境中摘除两个节点。接入线上的容器管理平台,从线上生产环境中摘除某个节点,然后部署最新的业务代码。
- 如何观察服务是否正常。由于这两个节点上运行的代码是最新的代码,在引入线上流量后可能会出现内存泄露等在集成测试阶段无法发现的问题,所以这个阶段这两个节点上运行最新代码后的状态必须与线上其他节点一致。观察节点本身的状态,如 CPU、内存、I/O、网卡等,观察业务运行产生的 warn、error 的日志量的大小。
持续部署阶段
把在类生产环境下运行通过的代码自动的发布到线上所有节点中去,关键点在于实际的线上发布阶段并不是想象中的那么直接。
实际发布的时候,考虑到线上服务的稳定性,并不是说按照一定的步长,自动把所有服务池都发布了。这个阶段,采用了手动发布的方式以控制风险,或者只做到持续交付阶段,对于持续部署并不要求自动化。