Etcd介绍
etcd是CoreOS团队2013年6月发起的开源项目使用Go开发,它的目标是构建一个高可用的分布式的key/value数据库,内部采用raft一致性算法。一般用于配置共享或服务注册与发现
Confd介绍
confd配置生成工具使用Go开发,后端支持etcd、consul、redis、file、zookeeper等,通过读取后端存储的配置信息来动态更新对应的配置文件。
confd的watch功能,通过HTTP API定期监测对应的etcd的配置变化,获取最新的Value,然后渲染模板,更新配置文件。
开始手册:https://github.com/kelseyhightower/confd/blob/master/docs/quick-start-guide.md
应用场景
自动生成Nginx或者Haproxy配置文件
安装(下载二进制文件直接解压即可)
etcd下载地址:https://github.com/etcd-io/etcd/releases
confd下载地址:https://github.com/kelseyhightower/confd/releases
目标(生成如下配置)
upstream myapp {
server 192.168.1.2:80; (动态生成)
}
server {
listen 80;
server_name www.myapp.com; (动态生成)
location / {
proxy_pass http://myapp; (动态生成)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
}
创建配置目录
mkdir -p ./confd/{conf.d,templates}
创建资源模板
vim ./confd/app01.conf.toml
[template]
src = "app01.conf.tmpl" # 默认在./confd/templates目录下
dest = "/usr/local/nginx/conf/vhost/app01.conf" # 要更新的配置文件
keys = [
"/nginx", # 监测的key
]
reload_cmd ="/usr/local/nginx/sbin/nginx -s reload"
创建模板文件
vim ./confd/templates/app01.conf.tmpl
upstream {{getv "/nginx/www/server_name"}} {
{{range getvs "/nginx/www/upstream/*"}}
server ``.``;
`end`
}
server {
listen 80;
server_name www.{{getv "/nginx/www/server_name"}}.com;
location / {
proxy_pass http://{{getv "/nginx/www/server_name"}};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
etcd添加k/v (使用etcdctl客户端操作etcd)
etcdctl set /nginx/www/server_name myapp
etcdctl set /nginx/www/upstream/server01 "192.168.1.10:80"
etcdctl set /nginx/www/upstream/server02 "192.168.1.11:80"
etcdctl set /nginx/www/upstream/server03 "192.168.1.12:80"
启动confd监测etcd的keys
./confd -watch -backend etcd -node http://127.0.0.1:2379
当启动时confd就会从etcd中获取key的值并填充到Nginx配置模板中,并且更新到nginx配置目下,reload重新加载nginx服务
etcd REST API使用
curl -X PUT http://192.168.1.11:2379/v2/keys/test/a_key -d value="789" # 增改key
curl -X DELETE http://192.168.1.11:2379/v2/keys/test/a_key # 删除key
curl http://192.168.1.11:2379/v2/keys/test/a_key # 查询key的值
curl -X PUT http://192.168.1.11:2379/v2/keys/dir -d dir=true # 创建目录
curl http://192.168.1.11:2379/v2/keys # 查看所有keys
curl -X PUT http://192.168.1.11:2379/v2/keys/ttlvar -d value="ttl_value" -d ttl=10 # 创建过期时间的key,单位秒
curl http://192.168.1.11:2379/version # 查看etcd版本
curl http://192.168.1.11:2379/v2/members # 列出所有集群成员
curl http://192.168.1.11:2379/v2/stats/leader # 查看leader
curl http://192.168.1.11:2379/v2/stats/self # 节点自身信息
curl http://192.168.1.11:2379/v2/stats/store # 查看集群运行状态
总结
总体来说,etcd+confd要比自己写脚本来实现要简单的多,但也会增加运维成本,如果用于生产环境还需要进一步的优化和考量,如果线上有redis可以使用redis作为存储。由于配置的变化每次都会reload的,在小流量的情况下并没什么影响,如果在高并发下可能会丢连接的情况,可以考虑使用lua动态加载nginx配置。
当然我们也不止用于Nginx配置生成,也可以做其他应用的配置文件生成,如果对Go有了解也可以自己手动对confd进行二次开发。