项目的环境配置化

发布包往往依赖于一些环境配置,比如项目的数据库连接地址等, 在现在的云方案中,有etcd/condf,Apollo等方案,以相对独立的方式对配置进行管理。但对于传统项目,配置文件经常与Jar、War等文件,或与源代码在同一目录下进行管理。

传统项目的配置文件通常有以下三种。

  1. 编译参数选择,通过编译时指定不同的参数,将源代码中不同的配置文件打包至二进制文件。
  2. 线上文件目录指定。二进制文件固定读取某一指定目录下的配置文件。
  3. 二进制文件替换配置。由于Java工程下的Jar、War实际结构是zip包,而且其配置文件是明文文本文件。所以,对于此类伪二进制目标文件,可以先采用解压包,替换二进制文件,再封装包的方式进行配置更新。该方式即可达到配置文件更新的目的,又可以保证测试环境和生产环境的二进制包的一致性。

建立配置模板文件、配置文件

在config库中,根据项目名称samples,建立 以下文件:

---
# file: projects/samples/vars/main.yml
# configure_files选项,其指定配置文件列表。系统将从main,prod,uat等文件中所获得变量文件,对src模板文件进行替换,生成实际的配置文件,最后替换jar包中的dest文件。

hellowar:
tomcat:
service_name: "tomcat-hellowar"
port: 8080
configurations_files:
- { src: "{{ project_dir }}/hellowar/config.properties.j2", dest: "WEB-INF/classes/config.properties" }
# file: projects/samples/hellowar/config.properties.j2
# 一个测试的配置

config.site.name={{ config.site.name }}
---
# file: projects/samples/vars/prod.yml
# 生产环境的变量值

config:
site:
name: "I am a production site"
---
# file: projects/samples/vars/uat.yml
# UAT环境的变量值

config:
site:
name: "I am a test site"

Ansible文件

---
# 用Ansible文件将上述配置连接起来。注意增加: role: app.config; configurations_files: "{{ hellowar.configurations_files }}" 即可。

- hosts: "&samples:hellowar"
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
tags: "always"
vars:
project_name: "samples"
roles:
- role: app.config
- role: app.war
vars:
type: "tomcat"
vars:
project_name: "samples"
service_name: "{{ hellowar.tomcat.service_name }}"
workspace: "{{ app_root }}/war/{{ service_name }}"
container:
type: "tomcat"
service_name: "{{ service_name }}"
jdk_home: "{{ jdk8_home }}"
warfile: "hello.war"
TARGET_FILE: "hello-0.0.1-SNAPSHOT.war" #this file path will be replace by jenkins
war_unachive: false
target_type: "war"
configurations_files: "{{ hellowar.configurations_files }}"
service:
name: "{{ service_name }}"
port: "{{ hellowar.tomcat.port }}"

详细工作原理可以阅读 app.war 中的源代码。

加密配置管理

基于安全考虑,生产服务器中的数据库密钥、付费业务的Key/Value对,通常应该进行保密处理,不应该将明文暴露在Config代码库中。Ansible的变量文件可以通过Vaults工具进行加密管理。

另一个好的建议是对公用资源的管理,如数据库、缓存等。 运维应按照业务需要、资源配置需求,对公用资源进行分组管理。开发人员无需了解实际的资源连接IP、密码等细节,只需要了解组名、以及该类型资源下存在的键即可。

以MySQL配置为例,说明配置组和加密配置使用:

---
# file: configs/vaults/test.yml

mysql:
group_sample:
host: 192.158.31.100
port: 3306
user: root
password: "password"

文件定义了 mysql 的sample组。 其键包括 host、port,password等。

在应用的配置模板文件中,按照应用的格式要求,填写资源.组.键即可:

server:
sql:
# 开发环境
host: {{ mysql.group_jkt.host }} # 192.158.31.100
port: {{ mysql.group_jkt.port }}
username: {{ mysql.group_jkt.user }}
password: {{ mysql.group_jkt.password }}

建立加密的prod配置文件

$ cd configs/vaults
$ ansible-vault create prod.yml
New Vault password:
Confirm New Vault password:

输入密钥文件,回车之后,会进入vi编辑页面。 填入与test.yml文件相同的结构和正确的密码,保存。 特别注意,在配置文件更新时,要保证prod和test环境的同步,prod环境缺少配置键而到时上线失败。

查看prod.yml应形如如下内容:

$ cat prod.yml
$ANSIBLE_VAULT;1.1;AES256
6466356161366165386166393136336233
3762383566393964366661313962636264

该文件仅能通过ansible-vault edit prod.yml ,并输入密码后再次进行编辑。无密码之人是无法对文件进行查看和修改的。所以,放心的将prod.yml加入到git版本库进行管理。

还有一个步骤,你需要将这个密钥告诉Ansbile发布机。登录到发布机后,修改ansbile.cfg文件,增加行:

vault_password_file = ~/.ansbile/vault_password_file

创建~/.ansbile/vault_password_file文件,并将密钥明文写入到文件中。

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据