说在前面

在《持续交付》的第二章配置管理的小结里说到:

配置管理是本书其他内容的基础。没有配置管理,根本谈不上持续集成、发布管理以及部署流水线。它对交付团队内部的协作也会起到巨大的促进作用。

再怎么强调配置管理的重要性也不为过,特别是在多环境下。然而大家都知道重要,又少有人告诉我们具体如何做,所以实在难受。

本文总结了我在多环境配置管理实践方面的一点心得,希望对大家有帮助。

Ansible 介绍

你可以简单地把它理解为一个自动化运维工具。本文将会使用这个工具下 inventory 概念来实现多环境配置。简单一点来说,inventory是一个文本文件,你可以在这个文件里记录下所有的机器,并对这些机器进行分组(分类)。

当然,其它的自动化运维工具也可以使用同样的思路来实践。本文只以 Ansible 为例。

例子

比如我们有两个环境,分别有一台机器。使用Ansible的 inventory 来管理这些机器,就会像下面这样:

## inventory[aws-prod-app]10.171.32.158
[aws-test-app]10.161.158.221

所有的 app 应用都是同一份代码,而且都会涉及操作数据库。当然,不同环境下的 app 读取的数据库的配置项的值是不样的。比如 aws-test 环境下配置是

db:  url: test.mysql.url  username: testu1  password: passwordtest

而生产环境 aws-prod 环境下配置:

db:  url: prod.mysql.url  username: produ1  password: passwordprod

这时,因为机器少,我们可以使用 Ansible 的 inventory 变量实现不同环境的配置隔离,比如:

## inventory[aws-prod-app]10.171.32.158
## [分组名:vars] 这样的写法是 Ansible inventory的约定## 按照这个约定来写,Ansible就可以识别了[aws-prod-app:vars]db.url = test.mysql.urldb.username = testu1db.password = passwordtest
[aws-test-app]10.161.158.221
[aws-test-app:vars]db.url = prod.mysql.urldb.username = produ1db.password = passwordprod

接着,如果环境上要部署新应用呢?而且还是很多呢?我们的 inventory 就会变成这样:

## inventory[aws-prod-app]10.171.32.158
[aws-prod-appX]10.171.32.159
## 还有更多的 aws-prod-app...
[aws-prod-app:vars]db.url = prod.mysql.urldb.username = produ1db.password = passwordprod
[aws-prod-appX:vars]db.url = prod.mysql.urldb.username = produ1db.password = passwordprod
## 还有更多的 aws-prod-app:vars ...
[aws-test-app]10.161.158.221
[aws-test-appX]10.161.158.222
## 还有更多的 aws-test-app...
[aws-test-app:vars]db.url = test.mysql.urldb.username = testu1db.password = passwordtest
## 还有更多的 aws-test-app:vars ...

好吧,面对这种配置冗余,后期维护会很恐怖。有两种办法解决:

  1. 不增加新应用

  2. 想办法解决这个问题

不要觉得第一种办法可笑,现实中真的存在,只是不同环境下的具体形态不一样。

解决这个问题的办法就是使用 Ansible 的分组的分组的变量。说起来是有点绕。简单的说就是对我们刚刚的分组,再进行一次分组,然后再给这一更高层次的分组设置变量。

接着我们上面的例子,我们使用分组的分组变量进行重写:

## inventory[aws-prod-app]10.171.32.158
[aws-prod-appX]10.171.32.159
## 注意,我们将所有的生产环境的## 分组又加入到 aws-prod分组下[aws-prod:children]aws-prod-appaws-prod-appX
## 这样,aws-prod 分组的变量又可以## 应用到所有的 aws-prod 环境下所有的机器[aws-prod:vars]db.url = prod.mysql.urldb.username = produ1db.password = passwordprod
[aws-test-app]10.161.158.221
[aws-test-appX]10.161.158.222
[aws-test:children]aws-test-appaws-test-appX
[aws-test:vars]db.url = test.mysql.urldb.username = testu1db.password = passwordtest

Ansible 这个分组概念设计得非常妙。仔细看,你会发现,利用分组的概念,你可以轻松地、简单地实现多种环境的配置管理。

当然,所有的配置都放一个 inventory 里就不合适了,所以,我们使用了Ansible的 group_vars 文件夹来进行管理,重构后如下:

目录结构.├── group_vars│   ├── aws-prod│   └── aws-test└── inventory
## inventory
[aws-prod-app]
10.171.32.158


[aws-prod-appX]
10.171.32.159


[aws-prod:children]
aws-prod-app
aws-prod-appX


[aws-test-app]
10.161.158.221


[aws-test-appX]
10.161.158.221


[aws-test:children]
aws-test-app
aws-test-appX
## group_vars/aws-proddb.url = prod.mysql.urldb.username = produ1db.password = passwordprod

到这里,我们简单的多环境管理的例子就算讲完了。

如果觉得不够直观,可以访问我在Github的代码样例

https://github.com/zacker330/ansible-inventory-example

小结

当环境少的时候,开发人员和测试人员会争抢环境;当环境多的时候,配置管理又会成为一个头大的问题。不论当哪种情况,都会增加我们研发成本。

而利用 Ansible 的分组概念同时加上它的自动化,就可以很轻松地解决多环境的配置管理问题,同时又降低我们的研发成本。

来源:https://showme.codes/2018-03-11/ansible-inventory-configuration/

点个“在看”,少个“bug”

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐