confd+etcd配置同步

一、etcd集群安装配置

参考 etcd集群部署与使用.md

二、confd介绍与资料

confd是一个轻量级的配置管理工具。通过查询后端存储,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload。

对应的后端存储可以是etcd,redis、zookeeper等等。我们使用etcd v3作为后端存储。

github文档:https://github.com/kelseyhightower/confd/tree/master/docs

confd的使用:https://blog.csdn.net/huwh_/article/details/82286934

confd+etcd实现高可用自动发现: https://www.cnblogs.com/chenqionghe/p/10503949.html

中文版confd模板语法详解:https://wandouduoduo.github.io/articles/9d4187fa.html#%E7%94%A8%E6%B3%95

三、confd安装与配置

1.confd安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 下载编译好的进程或者下载源码自己编译,示例直接下载了编译好的进程。
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 --version
confd --help

2.confd配置

2.1创建配置文件目录

1
mkdir -p /etc/confd/{conf.d,templates}

confd配置文件默认在/etc/confd中,可以通过参数-confdir指定。

目录中包含两个子目录,分别是:conf.d templates。

  • conf.d:confd的配置文件,主要包含配置的生成逻辑,例如模板源,后端存储对应的keys,命令执行等。
  • templates:配置模板Template,即基于不同组件的配置,修改为符合 Golang text templates的模板文件。

confd会先读取conf.d目录中的配置文件(toml格式),然后根据文件指定的模板路径去渲染模板,再执行<reload_cmd>,也可以配置check_cmd等。

2.2.confd.toml配置

confd.toml为confd服务本身的配置文件,主要记录了使用的存储后端、协议、confdir等参数。是进程启动时读取的参数。

默认路径:/etc/confd/confd.toml

其中watch参数表示实时监听后端存储的变化,如有变化则更新confd管理的配置。
如果没有启动watch参数,则会依据interval参数定期去存储后端拿取数据,并比较与当前配置数据是否有变化(主要比较md5值),如果有变化则更新配置,没有变化则定期再去拿取数据,以此循环

1
2
3
4
5
6
7
8
9
vim /etc/confd/confd.toml

backend = "etcdv3"
confdir = "/etc/confd"
log-level = "info"
#interval = 5
nodes = ["http://10.0.8.116:2379","http://10.0.8.159:2379","http://10.0.8.122:2379"]
scheme = "http"
watch = true

2.3.模板源配置文件

模板源配置文件是TOML格式的文件,主要包含配置的生成逻辑,例如模板源,后端存储对应的keys,命令执行等。

默认目录在/etc/confd/conf.d。 示例配置文件:/etc/confd/conf.d/test-samba.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[template]
# 模板文件路径
src = "test-samba.tmpl"
# 生成最终文件路径
dest = "/root/test/test-samba.conf"
keys = [
        "/nas_001/samba_global",
        "/nas_001/samba/",
]
# 生成文件后执行的命令
check_cmd = "echo 'run check_cmd' >> /root/test/confd-reload-samba.txt"
reload_cmd = "echo 'run reload_cmd' >> /root/test/confd-reload-samba.txt"

关键字描述:
src:The relative path of a configuration template. 模块文件路径。 confd是根据模板文件生成配置文件的。

dest:The target file. 最终生成的配置文件,测试使用的是/root/drx/test/samba.conf 。实际应用应该是/etc/samba/smb.conf。

keys:An array of keys. 实际应用就是etcd中的键值。confd需要从这些key值中更新数据。

reload_cmd:The command to reload config. 修改配置后,配置对相关服务实现重载。

还有部分可选参数没有列出,以下列出,某些应用可能会用到。
gid (int) - The gid that should own the file. Defaults to the effective gid.

mode (string) - The permission mode of the file.

uid (int) - The uid that should own the file. Defaults to the effective uid.

reload_cmd (string) - The command to reload config.

check_cmd (string) - The command to check config. Use {{.src}} to reference the rendered source template.

prefix (string) - The string to prefix to keys.

2.4.创建模板文件

Template定义了单一应用配置的模板,默认存储在/etc/confd/templates目录下。

模板文件常用函数有basegetgetslsdirjson等。具体可参考https://github.com/kelseyhightower/confd/blob/master/docs/templates.md。

例子 /etc/confd/templates/test-samba.tmpl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{{range gets "/nas_001/samba_global"}}[global]{{$value := json .Value}}
        workgroup = {{$value.workgroup}}
        netbios name = {{$value.netbios_name}}
        server string = {{$value.server_string}}
        {{if $value.unix_charset}}unix charset = {{$value.unix_charset}}{{else}}charset = UTF8 {{end}}
{{end}}
{{range gets "/nas_001/samba/*"}}[{{base .Key}}]{{$value := json .Value}}
        path = {{$value.path}}
        create mask = {{$value.create_mask }}
{{end}}

samba配置文件相对来说比较复杂的配置,因为配置项目较多。以下进行详细说明:
语法:Go标准库template语法,用go标准库应该会更加容易。

说明

1
{{range gets "/nas_001/samba_global"}}[global]{{$value := json .Value}}

其中:range gets 表示获取/nas_001/samba_global的值
“[global]“表示输出固定字符串global。
{{$value := json .Value}}表示获取json字符串并传给value。json表示将获取的key内容转换为json。

workgroup = {{$value.workgroup}} 表示:输出固定字符串"workgroup = “,{{$value.workgroup}}表示输出获取到json子串中的workgroup对应的值。

netbios name/server string同上。

{{if $value.unix_charset}}unix charset = {{$value.unix_charset}}{{else}}charset = UTF8 {{end}}

如果value.unix_charset存在,执行:unix charset = {{$value.unix_charset}},否则输出固定字符串:charset = UTF8。

以上是global部分的打印(global部分实际不止这么多的配置,测试用例只是书写了一部分!)。

共享逻辑配置:

1
2
3
4
{{range gets "/nas_001/samba/*"}}[{{base .Key}}]{{$value := json .Value}}
        path = {{$value.path}}
        create mask = {{$value.create_mask }}
{{end}}

说明:{{range gets “/nas_001/samba/*"}} 表示获取/nas_001/samba/*下所有key!也可以所有共享使用一个key,但是考虑到samba共享配置可能较多,因此,每个共享使用一个key,前缀都是相同的。
其余语法与global完全一样。当然也只写了部分配置。

/nas_001/samba/中,nas_001是表示NAS集群id,如果有多个NAS集群,可以建立多个key。

3.在etcd中创建数据

(如果使用其他backend,这里肯定会不同)

1
2
3
etcdctl put /nas_001/samba_global '{"workgroup":"WORKGROUP", "netbios_name": "INFINITY", "server_string": "yes"}'
etcdctl put /nas_001/samba/drxtest1 '{"path": "/infinityfs1/drxtest1", "create_mask": "0777"}'
etcdctl put /nas_001/samba/drxtest2 '{"path": "/infinityfs1/drxtest2", "create_mask": "0777"}'

示例中使用json存储samba相关的配置,例如:'{“workgroup”:“WORKGROUP”, “netbios_name”: “INFINITY”, “server_string”: “yes”}'。
其中不同的字段表示不同的值。

4.启动confd服务

  1. confd启动模式

confd支持以daemon或者onetime两种模式运行,当以daemon模式运行时,confd会监听后端存储的配置变化,并根据配置模板动态生成目标配置文件。

1
2
3
4
5
#onetime模式:只会生成一次配置,之后key无论变化不会再生成
confd -onetime -backend etcd -node http://127.0.0.1:2379

#daemon模式:confd会监听后端存储的配置变化,根据配置模板动态生成目标配置文件。
confd -watch -backend etcd -node http://127.0.0.1:2379 &
  1. 设置系统服务并开机启动
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
vim /etc/systemd/system/confd.service 

[Unit]
Description=confd
After=network.target

[Service]
Type=simple
PIDFile=/var/run/confd.pid
ExecStart=/usr/local/bin/confd
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always
PrivateTmp=true
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target
1
2
3
4
systemctl daemon-reload
systemctl enable confd
systemctl start confd
systemctl status confd
  1. 执行后,cat 输出的测试文件如下:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[root@node1 /etc/confd]# cat /root/test/test-samba.conf
[global]
        workgroup = WORKGROUP
        netbios name = INFINITY
        server string = yes
        charset = UTF8 

[drxtest1]
        path = /infinityfs1/drxtest1
        create mask = 0777
[drxtest2]
        path = /infinityfs1/drxtest2
        create mask = 0777


可以看到已经生成了我们需求的测试文件了。

3)修改完成配置后重启confd服务

1
systemctl restart confd

4)查看confd日志

1
journalctl -u confd

/usr/lib/systemd/system/confd.service

5.测试

1) 修改etcd中key值:

1
etcdctl put /nas_001/samba/drxtest1 '{"path": "/infinityfs1/drxtest1", "create_mask": "0555"}'

查看控制日志:

1
2
3
4
5
[root@node1 /etc/confd]# etcdctl put /nas_001/samba/drxtest1 '{"path": "/infinityfs1/drxtest1", "create_mask": "0555"}'
OK
2022-01-27T15:46:36+08:00 node1 confd[4185]: INFO /root/test/test-samba.conf has md5sum e46f2b98e112032be87b230472a95ff4 should be 432a956f145c5d613e3736c5d8ed34ce
2022-01-27T15:46:36+08:00 node1 confd[4185]: INFO Target config /root/test/test-samba.conf out of sync
[root@node1 /etc/confd]# 2022-01-27T15:46:36+08:00 node1 confd[4185]: INFO Target config /root/test/test-samba.conf has been updated

检查是否同步:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[root@node1 /etc/confd]# cat /root/test/test-samba.conf
[global]
        workgroup = WORKGROUP
        netbios name = INFINITY
        server string = yes
        charset = UTF8 

[drxtest1]
        path = /infinityfs1/drxtest1
        create mask = 0555
[drxtest2]
        path = /infinityfs1/drxtest2
        create mask = 0777

检查reload是否完成:

1
2
3
4
[root@node20 templates]# tailf /root/test/confd-reload-samba.txt
run check_cmd 

run reload_cmd 

四.思考扩展-confd能做些什么

我们大概知道了confd的原理 1.读取配置文件 -> 2.使用模板生成指定文件 -> 3.运行重载命令(可选)

所以基本使用配置和reload命令的地方都可以使用confd,比如下边的需求

  • nginx动态生成upstream实现服务发现
  • prometheus动态生成prometheus.yml实现自动报警
  • php-fpm动态生成php.ini文件实现动态性能调参
  • 动态生成报表文件再发送通知