当系统变的负责,配置项越来越多,一方面配置管理变得繁琐,另一方面配置修改后需要重新上线同样十分痛苦。这时候,需要有一套集中化配置管理系统,一方面提供统一的配置管理,另一方面提供配置变更的自动下发,及时生效。
说到统一配置管理系统,大家应该比较熟悉,常见的:zookeeper、etcd、consul、git 等等。
上述的集中配置中心使用的时候,部署图大致是这样的:
server 端只需要调用 config-server 对应客户端获取配置,和监听配置变更就可以了。总体来说没有太大难度。
接下来要说一下 confd,它地宫了一种新的集成思路。confd 的存在有点类似于快递员,买了东西不需要自己到店去取货了,confd 这个快递员会把货取过来,然后送到家里,并且通知你货已经送到了。加入 confd 之后的架构大致是这样的:
confd 使用时有几个概念需要熟悉,并且熟悉他们之间的依赖关系,才能理解如何配置 confd,不然会比较懵。这里我们先看一下 confd 配置的几个概念之间是如何交互的:
以 Linux 系统为例
下载 confd 的二进制文件,下载地址为:https://github.com/kelseyhightower/confd/releases。例如:
# Download the binary
wget https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64
# 重命名二进制文件,并移动到PATH的目录下
mv confd-0.16.0-linux-amd64 /usr/local/bin/confd
chmod +x /usr/local/bin/confd
# 验证是否安装成功
confd --help
confd 通过读取后端存储的配置信息来动态更新对应的配置文件,对应的后端存储可以是 etcd 、redis 等,其中 etcd 的 v3 版本对应的存储后端为 etcdv3.
confdir 底下包含两个目录:
sudo mkdir -p /etc/confd/{conf.d,templates}
模板源配置文件是 TOML 格式的文件,主要包含配置的生成逻辑,后端存储对应的 keys,命令执行等。默认目录在 /etc/confd/conf.d。
参数说明:
必要参数
可选参数:
例子
例如:/etc/confd/conf.d/myapp-nginx.toml
[template]
prefix = "/myapp"
src = "nginx.tmpl"
dest = "/tmp/myapp.conf"
owner = "nginx"
mode = "0644"
keys = [
"/services/web"
]
check_cmd = "/usr/sbin/nginx -t -c {{.src}}"
reload_cmd = "/usr/sbin/service nginx reload"
Template 定义了单一应用配置的模板,默认存储在 /etc/confd/templates目录下,模板文件符合Go的text/template格式。
模板文件常用函数有 base、get、gets、lsdir、json 等。具体可参考
https://github.com/kelseyhightower/confd/blob/master/docs/templates.md。
{{range $dir := lsdir "/services/web"}}
upstream {{base $dir}} {
{{$custdir := printf "/services/web/%s/*" $dir}}{{range gets $custdir}}
server {{$data := json .Value}}{{$data.IP}}:80;
{{end}}
}
server {
server_name {{base $dir}}.example.com;
location / {
proxy_pass {{base $dir}};
}
}
{{end}}
以 etcdv3 存储为例,在 etcd 中创建以下数据。
etcdctl --endpoints=$endpoints put /services/web/cust1/2 '{"IP": "10.0.0.2"}'
etcdctl --endpoints=$endpoints put /services/web/cust2/2 '{"IP": "10.0.0.4"}'
etcdctl --endpoints=$endpoints put /services/web/cust2/1 '{"IP": "10.0.0.3"}'
etcdctl --endpoints=$endpoints put /services/web/cust1/1 '{"IP": "10.0.0.1"}'
confd 支持以 daemon 或者 onetime 两种模式运行,当以 daemon 模式运行时, confd 会监听后端存储的配置变化,并根据配置模板动态生成目标配置文件。
如果以 daemon 模式运行,则执行以下命令:
confd -watch -backend etcdv3 -node http://172.16.5.4:12379 &
以下以 onetime 模式运行为例。其中对应的后端存储类型是 etcdv3
# 执行命令
confd -onetime -backend etcdv3 -node http://172.16.5.4:12379
# output
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO Backend set to etcdv3
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO Starting confd
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO Backend source(s) set to http://172.16.5.4:12379
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO /root/myapp/twemproxy/conf/twemproxy.conf has md5sum 6f0f43abede612c75cb840a4840fbea3 should be 32f48664266e3fd6b56ee73a314ee272
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO Target config /root/myapp/twemproxy/conf/twemproxy.conf out of sync
2018-05-11T18:04:59+08:00 k8s-dbg-master-1 confd[35808]: INFO Target config /root/myapp/twemproxy/conf/twemproxy.conf has been updated
在 在/etc/confd/conf.d/myapp-nginx.toml中定义的配置文件的生成路径为/tmp/myapp.conf。
[root@k8s-dbg-master-1 dest]# cat myapp.conf
upstream cust1 {
server 10.0.0.1:80;
server 10.0.0.2:80;
}
server {
server_name cust1.example.com;
location / {
proxy_pass cust1;
}
}
upstream cust2 {
server 10.0.0.3:80;
server 10.0.0.4:80;
}
server {
server_name cust2.example.com;
location / {
proxy_pass cust2;
}
}