2015-09-18YingQian Hu

GeneDock基于Docker的部署运维实践

(本文由GeneDock实习工程师胡英谦撰写,原文地址 转载请保留作者信息和原文链接)

如何基于Docker容器技术,构建一个自动化、易管理、高可用的运维部署系统。本文希望分享GeneDock的经验和教训。


GeneDock的系统是典型的微服务架构:超过二十个模块分别负责平台的各项功能,例如接口、权限、资源管理、编译、调度、监控等,模块之间通过RESTful接口相互通讯。模块这么多,如果没有自动部署工具,运维工程师全凭手工操作,在敏捷开发的快节奏下,升级部署会成为一个大坑。

于是需求来了:用程序代替人,实现脚本化甚至自动化部署。


先干什么?大多数工程师都会想到两件事:

       1.采用Docker技术发布和部署所有服务。
       2.编写脚本,自动完成代码下载、构建镜像、启动服务的流程。

真挽起袖子来干活儿,就发现问题:最初模块之间还未隔离干净,存在代码和路径依赖。因此每个服务的Docker镜像制作脚本都不相同,藏了很多黑魔法在里面。例如从其他模块拷贝某个源代码文件过来,甚至是多个服务不得不共享一个镜像。新版本代码稍有变化,部署脚本就得改,很容易出错。

Bad Smell!完美主义的GDers热情高涨,开始重构:

       1.拆分,保证每个Docker镜像里只启动一个逻辑独立的服务;
       2.将跨服务的调用解耦为 RESTful 接口调用,禁止跨模块import代码;
       3.有些公用基础类库(例如加密算法),被做成了规范的 Pypi 包,使用pypiserver自建私有的Pypi源,然后将这些包放到DockerFile里面去;
       4.规范各个服务的目录结构、启动方式、日志格式。所有服务的docker采用相同的方式挂载代码、数据和日志。这样就解决了目录混乱不一的问题。

经过精心重构,我们达到了以下目标:

       1.实现了所有模块的代码独立,去除跨模块代码级依赖;
       2.实现了所有服务的Docker化发布;
       3.实现了自动化部署的脚本,测试环境定时自动从GitHub master分支更新版本;


虽然引入了 Docker,实现了自动化。但是部署过程还有点漫长:

       1.将服务代码从GitHub服务下载到服务器本地;
       2.通过Docker工具创建镜像;
       3.启动Docker容器;
       4.确定服务已经正常启动,向相关工程师发监控微信。

事实上,已经有许多专业的第三方云服务功能强大且聚焦,能够帮助我们大大提高部署效率,花的费用也不多。所以,作为云服务信徒的我们使用了以下代表先进生产力的服务:

  • 使用GitHub管理代码,防止代码的丢失与混乱,提高团队协作效率;
  • 使用Travis CI进行持续集成,在每次提交新代码时自动做代码检查及单元测试,在每次发布时发布系统会自动构建Docker镜像,并推送到Docker Hub上;
  • 使用Docker Hub 维护镜像,Docker Hub具有完善的版本号支持,与自建私有的Docker Registry 相比更加方便。

采用了以上服务,实现了发布与部署的分离。发布时只需 在GitHub上打一个Tag,部署系统就会在服务器上通过执行命令docker run从官方Docker Hub 上拉下服务镜像然后启动容器,能够方便地支持异地部署与回滚。这样真正发挥了 Docker 的好处:服务装箱,下载即用。

GitHub 和 Docker Hub都有着完善的私有化和权限支持。对于自建的pypi源与其他可能被外网访问的服务,我们使用了 Nginx 反向代理进行转发,在转发时使用 Nginx 的基本认证进行鉴权,兼顾了便利性与安全性。

也就是说,经过再次完善,我们又有进步:
       1.极大简化了部署流程,大幅减轻运维工程师的负担;
       2.运维工程师不再需要接触代码,明确了运维与开发的边界;
       3.基本消除了安全性隐患。


最终,GeneDock 目前的部署运维系统架构大致如图:

  • 代码在 GitHub 上管理,通过 Travis 自动化代码检查与单元测试
  • Docker 镜像 由 Docker Hub 管理,Travis 进行持续集成与部署
  • 配置使用 MongoDB 统一管理,MongoDB 相关配置统一路径后挂载到 Docker 容器中
  • 部署与测试由 Travis 进行监控,如果失败会报警
  • 运行的容器借助 Docker 的事件机制进行监控
  • 服务端系统日志使用Docker的高级特性Data Volume来存储,以供相关日志服务分析和收集

构建这套系统时,除了自己摸索,还参考了一些最佳实践与文档,甚至阅读了Docker源码,每个公司情况不同,需要结合实际确定具体方案。任何意见和建议欢迎联系我们,如果你对以上技术感兴趣甚至能做得更好,欢迎给我们投简历 hr@genedock.com,具体职位信息请见 https://genendock.com/joinus/。

参考资料如下
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04
http://crosbymichael.com/advanced-docker-volumes.html
http://container42.com/2014/11/03/docker-indepth-volumes/
http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/
https://github.com/wsargent/docker-cheat-sheet#best-practices
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04
https://docs.docker.com/compose/
https://docs.docker.com/articles/dockerfile_best-practices/
https://docs.docker.com/reference/logging/overview/