背景
今年部门主要对外输出自研产品,为此需要设计一套快速交付项目的方案,目标一天部署完成十几个独立应用。
应用包括ELK/DB/Python后端/Java后端/Node前端等。
整体思路
为实现快速部署,有以下几个基本思想:
- 不同应用尽量使用统一的部署方法,且尽量不需要改动现有代码;
- 减少部署过程中需要手动操作的步骤;
- 根据项目及依赖为不同应用分组;
- 与部署环境有关的参数(比如mysql地址)放到配置文件中方便修改;
- 配置文件统一存放,部署人员无需关注不同应用之间的差别。
根据公司应用实际情况,使用如下方案:
- 除agent等特殊组件(比如osquery、salt-minion、prometheus node等),其他所有应用均使用Docker部署;
- 默认需要手动操作的逻辑尽量改为自动操作(比如salt-master的minion accept,sync_modules,及项目初始化数据等);
- 使用
docker-compose
为应用分组; - 使用docker-compose原生的
.env
修改配置/环境变量; - 应用配置统一到同目录下。
人员职责
为了更清晰地区分部署阶段,将部署过程涉及的人员分为三类:开发人员、打包人员、部署人员。
开发人员
应用的开发人员不需要关注部署过程,只需要为打包做好一些准备:
- 确保配置为独立文件(或可通过环境变量修改);
- 确保应用能使用docker正常运行;
- 提供配置文件挂载路径及所需的持久化数据挂载路径;
- 初始数据尽量改为自动导入,无需手动操作;
- 编写应用首次运行的验证文档。
开发人员只要提供符合要求的代码分支即可。
打包人员
为了真正实现快速部署,需要有人负责整合所有应用并编写打包相关脚本,总体来说是要实现“把原始代码转换成可以在客户现场部署的状态”。
具体任务包括:
优化应用Dockerfile(包括减小image大小、去掉image内无关或机密数据等);
根据项目实际情况为应用及依赖组件分组(比如某个项目的前后端一定要同时运行才能正常使用,这样就可以分为一组),同一组的应用放在同个docker-compose.yml文件内;
- 编写docker-compose.yml;
- 为简化每次打包流程,编写打包相关脚本(包括整合代码加密、npm build、maven package、统一修改配置等);
- 编写整体部署文档(应先假定部署者非开发者及打包者,部署文档需清晰完整。);
- 根据客户实际环境填写配置,并完成打包、导出image。
假设有以下几个应用:app1_backend、app1_front、app2_api,依赖以下组件:mysql、redis。打包人员每次打包完成,实际产出文件示例:
1 | 部署文档.txt |
为方便传输,可以统一压缩为tar.gz。
部署人员
部署人员需要熟悉docker相关运行及调试命令,遇到应用本身运行问题要配合开发人员远程调试。
Q&A
为什么一台机器不使用同一个docker-compose.yml,而是根据不同分组使用多个?
如果几十个应用放在同个docker-compose里同时启动,启动日志太多影响问题排查。且一个docker-compose文件太长也不方便修改。
为什么不是开发人员优化docker镜像,而是打包人员优化?
优化docker镜像涉及到一些docker相关知识,所有应用的开发者都要去研究一遍费时费力,打包人员根据目标统一优化节省人力成本。
为什么不使用打包后的代码直接部署,需要导出docker image?
理论上打包以后的代码就可以拿到客户现场部署了,并且代码文件比image小很多。不过部署代码过程中需要联网下载基础镜像、依赖包等,这对网络要求比较高,并且如果应用没做好严格的依赖版本限制,可能会出现不兼容现场下载的依赖包。
所以,除非客户现场对部署需要使用的文件大小有严格限制,否则直接使用docker image部署会更快。