confd笔记
好记性不如烂笔头。
昨天完成了项目的 etcd + confd + openresty 的反代部分,在这里记录一下。这东西学起来还是有点时间的,文档也说的不明白,没个example可以看。
etcd 部分
单点etcd启动:
docker volume create etcd_data
docker run -dti --network host \
-v etcd_data:/default.etcd \
-e ETCD_LISTEN_PEER_URLS=http://10.170.1.31:2380 \
-e ETCD_LISTEN_CLIENT_URLS=http://10.170.1.31:2379 \
-e ETCD_ADVERTISE_CLIENT_URLS=http://10.170.1.31:2379 \
quay.io/coreos/etcd:latest
然后这个 quay.io/coreos/etcd:latest
镜像隔着我国比较远,所以不如用我的镜像 wrfly/etcd
pull 的时候会快一点。 (2017-3-12 version: latest)
confd 配置部分
confd启动的时候需要一些配置:
backend = "etcd"
confdir = "/etc/confd"
log-level = "info"
watch = true
noop = false
prefix = "/"
scheme = "http"
node = [
"1.2.3.4:2379",
"4.3.2.1:2379",
"1.4.2.3:2379",
]
node 部分是 etcd 的地址,如果你的 backend 不是 etcd 的话,那就是你用的数据库的地址。具体情况具体分析。
启动 confd 的时候可以指定一些参数,比起 etcd,有一点不好,就是不能通过读环境变量的方式来传入,所以要通过命令行传递:
全部说明: Documents
有几个参数说明一下(针对etcd):
-
watch = true : 这里是通过 watch 来检测 etcd 中数据变化的,就跟通过
curl http://etcd:2379/v2/keys/xxx/xxx?watch=true
一样。这样就不用通过时间间隔来抓数据了,所以通过watch配置的文件都是 real-time 的。 -
-basic-auth
和-password
讲真这两个参数我没用过,但是以后一定要用的。 所以在这里 TODO 一下。
confd 配置模板
[template]
src = "nginx.http.tmpl"
dest = "/etc/nginx/conf.d/http.conf"
keys = [
"/",
]
check_cmd = "nginx -t -c /etc/nginx/nginx.conf"
reload_cmd = "nginx -s reload"
来看一下这个配置模板文件,src
指的是模板文件的地址,就是依据那个模板生成我们的配置文件;dest
则就是生成的配置文件存放的位置了。
keys 是 keys (array of strings) - An array of keys.
我也不知道具体能起什么效果,可能模板中需要?
全部文档 -> link
模板语法
展示一下最终成果:
然后 pretty print 一下:
然后说明一下 etcd 中的键值结构:
/challenges/xx-xx-xx/url = www.baidu.com
/challenges/xx-xx-xx/service/nginx
/challenges/xx-xx-xx/service/nginx/pub = 30000
/challenges/xx-xx-xx/service/nginx/tgt = 80
/challenges/xx-xx-xx/service/ubuntu
/challenges/xx-xx-xx/service/ubuntu/pub = 0
/challenges/xx-xx-xx/service/ubuntu/tgt = 0
/nodes/
/nodes/a = 192.168.1.101
/nodes/b = 192.168.1.102
然后说一下语法,看完语法之后,再回头看就会明白多了。
首先是 range
, 以 {{ range $var }} 开头, 以 {{end}} 结尾,最近相邻配对。其中里面的 $var 可以是 ls
或者 lsdir
一个可以list的对象,或者 $var 就是一个 list,类似于 golang 里面的 for i,v := range variable
。
然后在 range 和 end 中间,我们就可以搞点事情了。
首先是赋值,注意到上面的 printf 了吗,printf 接受两个参数,第一个是格式,第二个是变量,然后用 :=
赋值给一个变量。
还忘记说上面的 lsdir
: lsdir
会返回这个 dir 下面所有的带有 subdir的 dir 的 name。而 ls
则是返回相反的东西,即返回 dir
下面所有 key 的 value。
然后就是 getv, getv 接受的参数是一个 key, 也就是上面 /challenge/xxx-xxx-xxx/url
这样的键,然后返回键的值。
与之对应的是 getvs, 顾名思义,其返回 匹配的 key 的全部值,如果没有值用来返回,则会报错。
还有 get
和 gets
,与上面的区别是, get 会同时返回 Key 和 Value, 而getv则只是返回了 Key 的Value。gets 同样。
接着是 if
这个东西,它也是需要以 {{end}} 来表示结尾的。中间是判断一个 bool 值,比如上面的 ne $pubV "0"
。 其中 ne 的意思是不相等,同样的还有 eq, gt, lt 等等等等。具体看这里:HERE
然后是getenv
,这个就是读取一个环境变量。
其他
举例: {{ $upstream := replace (base $challengeID) "-" "" -1 }}
这行定义了一个 $upstream 的变量,它将 {{base $challengeID}} 的结果作为 replace 的第一个参数(因为外面已经有{{ }}
了,所以里面要用括号),然后replace接收的第二个参数是要替换的字符,第三个参数是替换为的字符,第四个参数则是替换的数量,-1代表全部替换。
还有这个 split 也是对字符进行操作的:
(OK,中间被其他事情打断了,导致想不起要说什么了,就这样吧。)
官方文档 -> link