随着Docker技术的火热发展, Docker在代码构建发布中扮演着越来越重要的角色。Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到流行的 Linux 机器上。Docker 非常适用于如下场景:
-应用容器的自动化打包和发布;
这次主要和大家聊聊应用容器在配置管理中遇到的问题。首先是介绍现有容器常用的配置文件加载方式,接下来重点介绍 数人云 组件在自动化打包和发布遇到的问题和解决方法。
现有的主要Docker加载配置的方式
首先简单介绍下现有容器的加载配置文件的方式。
挂载宿主机配置文件的方式
通过docker run -v 参数将宿主机上的配置文件挂载到容器指定目录中如:
docker run -v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf --name myredis redis redis-server /usr/local/etc/redis/redis.conf
这种方式对于单实例应用比较方便。
- 下载配置中心文件的方式
这种方法首先需要建立配置中心,例如用nginx等web服务组件,提前将配置文件放在指定目录,在Dokcerfile entrypoint中拉取配置中心文件的脚本,之后容器启动就自动拉取配置中心的配置。
- 通过环境变量传入到容器中
通过docker run -e 参数将将环境变量传入到容器如:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6
数人云在应用容器的自动化打包和发布中遇到的问题
数人云组件采用微服务架构,将服务拆分,分别采用相对独立的服务对各方面进行管理,彼此之间使用统一的接口来进行交流,架构变得复杂,但优势非常明显。为了保证高可用,这些容器一般都运行在多个VM上,服务实例前是一层诸如HAPROXY的负载均衡器,它们负责在各个实例间分发请求。数人云分测试、演示、生产三种环境进行持续集成、发布,同时数人云组件通过Docker+mesos+marathon进行应用容器的封装下发和管理。首先说下我们容器发布遇到的问题——配置文件多,如何进行统一的管理?
我们由于采用微服务架构,就产生了各个模块的配置,导致配置文件过多;其次数人云的三套环境,如mysql等基础组件ip、port 等配置不同,导致配置成倍增加;最后采用高可用架构,也造成了配置文件的增多。 下面是数人云Mesos系统架构流程图:
marathon、Jenkins 作为Framework注册在mesos-master上,动态调度mesos-slave资源。
mesos Framework 截图如下:
若单纯-v 的挂载方式需提前将配置文件放在mesos-slave所在的宿主机上,新加slave时也需进行相同的操作,且当配置文件需要更新时,需更新每台mesos-slave宿主机上的配置文件,这显然不够灵活,所以我们刚开始采用应用容器启动下载配置中心文件的方式。
早期的配置中心,如下图所示:
此时存在的问题有:
我们用Jenkins把它们整体串起来,我们的第一个工作是把所有的配置文件抽象化,各种环境的文件抽象出来一个模板,放在Gitlab上。它的数据是放在数据库里面,这样组合起来是一个完整的配置文件。各个环境的值是不一样的。 我们的运维平台触发Jenkins,Jenkins去调度我们的ConfigCenter API,它传入两个参数,一个是需要更新的环境,另一个是更新哪个服务。之后API去做对比,从数据库去读现有的配置文件的模板Tag,再去读新模板的Tag进行对比。
如果这个文件需要更新,把它从数据库拉过来,数据做匹配,渲染成我们最终的配置文件,再传到Gitlab上。剩下的通过Jenkins 触发 Configserver去调Gitlab下载最新的配置文件到Configserver服务器,Jenkins再去调用Marathon去重启服务,服务就会成功更新配置文件。 这很好解决了配置文件对应文件,但还是存在以下一些问题:
后来我们对应用进行env化改造,统一配置文件格式,且配置通过变量传递给marathon,使得所有配置在marathon界面上可见 。
以下是具体的工作,我们对开发进行了规约。
产品模块 GitHub 目录规约结构
除了代码和产品开发的一些文件外,还需要规约一下目录结构:
module_name -
|
- deploy -
|
- env
|
- deploy-marathon.sh
|
- compile.sh
|
- dockerfiles -
|
- Dockerfile_compile_env
|
- Dockerfile_runtime
在github中更新env文件,这个由开发提供维护,里面有对应env文件如下图:
改进后具体的流程图如下:
以上主要对配置文件进行env化,减少配置替换复杂度,将配置存在于marathon发布脚本中。
更新后产生的marathon applist
单个应用容器配置
以上就是数人云组件配置管理碰到的问题,以及env化解决方式,欢迎大家提出宝贵意见。
QA
1、mesos 运行一个任务,如果发现该任务运行过程中需要加大资源,mesos 如何做到对任务资源的弹性扩容?如果采用 docker 的话,是新建更多的 docker 容器还是直接扩大现有 docker 的大小?
答:一般是扩展更多的docker 容器个数,除非是某个任务有最小资源要求,才要扩大单个docker的大小。
2、开发人员使用的本地环境变量如何管理?例如一个应用,有数据库,有搜索引擎,还有两个Java APP,不同开发可能需要嗯环境不同,例如我是搜索功能的开发,需要链接公共的数据库,而有些开发需要自己有数据库,搜索引擎却需要链接公共的。这种配置,如何管理?
答:这种最好将数据库环境变了进行区分,配置两个或多个类似环境变量。
3、请问mysql数据库怎么随dockers迁移?备份和恢复有什么好的建议吗?
答:mysql 现在是固定主机 主从同步,没有对mysql做迁移,我们的数据现在备份是定时全备份 ,正在尝试使用MariaDB集群Galera Cluster ,但还没有上生产,当然有共享存储的话就最好不过啦.
4、请问线上服务更新war包,如何能使对外服务不间断吗?
答:数人云目前采用代码版本和镜像版本统一,对外服务不间断,数人云目前的做法是对应用进行无状态改造,后通过marathon put 更新容器。
5、请问 配置文件的话生产环境和开发环境怎么区分?
答:生产环境和测试环境都是隔离的,配置文件配置不同的参数即可。
6、请问对类似java应用jdbc,spring.xml等配置文件如何管理?
答: xml配置 通过sed替换传入的环境变量。
7、生产上配置项变更怎么操作?
答:生产配置的值需要修改时 ,在configcenter页面中修改,再触发jenkins更新配置文件的job, 生产新的配置文件 ,再调用marathon API 更新task进行更新
8、业务的配置是和环境配置放在一起的么?
答:是的,都是通过envfile进行统一的。
9、请问你们针对应用弹性扩展是自感应的吗?如果是,请问是基于什么策略做的,监控报警还是什么?
答:数人云是通过监控报警触发弹性扩展的,如监控接口返回的时间,容器内存使用率等
10、请问你们对环境变量是采用什么样的管理方法?有相应的命名规范吗?环境变量多了,会出现管理方面的问题吧。
答:环境变量键值由开发维护,运维需要提前了解新增环境变量,目前在配置中心里维护,容器环境变量变量命名规范很重要,我们目前采用服务名+需连接的组件名+属性 进行命名的,且环境变量全部大写。