一、Consul-Template简介

Consul-Template是基于Consul的自动替换配置文件的应用。在Consul-Template没出现之前,大家构建服务发现系统大多采用的是Zookeeper、Etcd+Confd这样类似的系统。

Consul官方推出了自己的模板系统Consul-Template后,动态的配置系统可以分化为Etcd+Confd和Consul+Consul-Template两大阵营。Consul-Template的定位和Confd差不多,Confd的后端可以是Etcd或者Consul。

Consul-Template提供了一个便捷的方式从Consul中获取存储的值,Consul-Template守护进程会查询Consul实例来更新系统上指定的任何模板。当更新完成后,模板还可以选择运行一些任意的命令。

Consul-Template的使用场景

Consul-Template可以查询Consul中的服务目录、Key、Key-values等。这种强大的抽象功能和查询语言模板可以使Consul-Template特别适合动态的创建配置文件。例如:创建Apache/Nginx Proxy Balancers、Haproxy Backends、Varnish Servers、Application Configurations等。

Consul-Template特性

  • Quiescence:Consul-Template内置静止平衡功能,可以智能的发现Consul实例中的更改信息。这个功能可以防止频繁的更新模板而引起系统的波动。
  • Dry Mode:不确定当前架构的状态,担心模板的变化会破坏子系统?无须担心。因为Consul-Template还有Dry模式。在Dry模式,Consul-Template会将结果呈现在STDOUT,所以操作员可以检查输出是否正常,以决定更换模板是否安全。
  • CLI and Config:Consul-Template同时支持命令行和配置文件。
  • Verbose Debugging:即使每件事你都做的近乎完美,但是有时候还是会有失败发生。Consul-Template可以提供更详细的Debug日志信息。

项目地址:https://github.com/hashicorp/consul-template

二、Consul-Template安装

Consul-Template和Consul一样,也是用Golang实现。因此具有天然可移植性(支持 Linux、windows 和macOS)。安装包仅包含一个可执行文件。Consul-Template安装非常简单,只需要下载对应系统的软件包并解压后就可使用。
只需要下载可执行文件:https://releases.hashicorp.com/consul-template/
将执行文件解压放到/usr/local/bin/下即可,如下:

我下载的是:consul-template_0.20.0_linux_amd64.tgz

  1. [root@localhost consul-template]# tar -xvf consul-template_0.20.0_linux_amd64.tgz
  2. consul-template
  3. [root@localhost consul-template]# ll
  4. 总用量 12696
  5. -rwxr-xr-x. 1 501 games 9451232 2 20 08:39 consul-template
  6. -rw-r--r--. 1 root root 3543379 3 22 09:57 consul-template_0.20.0_linux_amd64.tgz
  7. [root@localhost consul-template]# cd consul-template
  8. -bash: cd: consul-template: 不是目录
  9. [root@localhost consul-template]# cp consul-template /usr/local/bin
  10. [root@localhost consul-template]# consul-template -v
  11. consul-template v0.20.0 (b709612c)
  12. [root@localhost consul-template]#

三、Consul-Template使用帮助

查看帮助

执行consul-template -h即可看到consul-temple的使用参数

  1. -auth=<user[:pass]> 设置基本的认证用户名和密码
  2. -consul=<address> 设置Consul实例的地址
  3. -max-stale=<duration> 查询过期的最大频率,默认是1s
  4. -dedup 启用重复数据删除,当许多consul template实例渲染一个模板的时候可以降低consul的负载
  5. -ssl 使用https连接Consul使用SSL
  6. -ssl-verify 通过SSL连接的时候检查证书
  7. -ssl-cert SSL客户端证书发送给服务器
  8. -ssl-key 客户端认证时使用的SSL/TLS私钥
  9. -ssl-ca-cert 验证服务器的CA证书列表
  10. -token=<token> 设置Consul APItoken
  11. -syslog 把标准输出和标准错误重定向到syslogsyslog的默认级别是local0
  12. -syslog-facility=<f> 设置syslog级别,默认是local0,必须和-syslog配合使用
  13. -template=<template> 增加一个需要监控的模板,格式是:'templatePath:outputPath(:command)',多个模板则可以设置多次
  14. -wait=<duration> 当呈现一个新的模板到系统和触发一个命令的时候,等待的最大最小时间。如果最大值被忽略,默认是最小值的4倍。
  15. -retry=<duration> 当在和consul api交互的返回值是error的时候,等待的时间,默认是5s
  16. -config=<path> 配置文件或者配置目录的路径
  17. -pid-file=<path> PID文件的路径
  18. -log-level=<level> 设置日志级别,可以是"debug","info", "warn" (default), and "err"
  19. -dry Dump生成的模板到标准输出,不会生成到磁盘
  20. -once 运行consul-template一次后退出,不以守护进程运行
  21. -reap 子进程自动收割

Consul-Template模版语法

Consul-Template模板文件的语法和Go Template的格式一样,Confd也是遵循Go Template的。

下面看看配置模板到底怎么写,模板文件的语法和Go template的格式一样,confd也是遵循Go template的。

先看看API 功能语法:

  1. datacenters:在consul目录中查询所有的datacenters,{{datacenters}}
  2. file:读取并输出本地磁盘上的文件,如果无法读取,则报错,{{file "/path/to/local/file"}}
  3. key:查询consul中该key的值,如果无法转换成一个类字符串的值,则会报错,{{key "service/redis/maxconns@east-aws"}} east-aws指定的是数据中心,{{key "service/redis/maxconns"}}
  4. key_or_default:查询consul中该key的值,如果key不存在,则使用指定的值代替,{{key_or_default "service/redis/maxconns@east-aws" "5"}}
  5. ls:在consul中查询给定前缀的key的顶级域值,{{range ls "service/redis@east-aws"}} {{.Key}} {{.Value}}{{end}}
  6. node:查询consul目录中的单个node,如果不指定node,则是当前agent的,{{node "node1"}}
  7. nodes:查询consul目录中的所有nodes,你也可以指定datacenter,{{nodes "@east-aws"}}
  8. service:查询consul中匹配的service组,{{service "release.web@east-aws"}}或者{{service "web"}},也可以返回一组HealthService服务{{range service "web@datacenter"}} server {{.Name}} {{.Address}}:{{.Port}}{{end}},默认值返回健康的服务,如果你想返回所有服务,则{{service "web" "any"}}
  9. services:查询consul目录中的所有services,{{services}},也可以指定datacenter:{{services "@east-aws"}}
  10. tree:查询consul中给定前缀的所有K/V值,{{range tree "service/redis@east-aws"}} {{.Key}} {{.Value}}{{end}}

再看看辅助函数语法:

byKey、byTag、contains、env、explode、in、loop、trimSpace、join、parseBool、parseFloat、parseInt、parseJSON、parseUint、regexMatch、regexReplaceAll、replaceAll、split、timestamp、toJSON等函数可以使用,具体用法看官文

四、Consul-Template使用实例

在进行以下测试前,你首先得有一个Consul集群。如果你还没有,可参考「consul分布式集群搭建」 一文搭建一个。当然单节点Consul环境也是可以的,如果你只想做一下简单的测试也可以参考「Consul入门」一文先快速搭建一个单节点环境。

4.1、命令行方式

1、输出已注册服务的名称和Tags。

接着《consul分布式集群搭建》文章后面的service-front示例,通过命令行方式输出已经注册服务的名称和Tags,如下:

  1. [root@localhost consul-template]# curl http://10.200.110.90:8500/v1/catalog/service/service-front
  2. [{"ID":"d1b05900-4f8f-b956-5ba6-5a3c798d93d3","Node":"10.200.110.91","Address":"10.200.110.91","Datacenter":"shenzhen","TaggedAddresses":{"lan":"10.200.110.91","wan":"10.200.110.91"},"NodeMeta":{"consul-network-segment":""},"ServiceKind":"","ServiceID":"service-front-10-200-110-100-8001","ServiceName":"service-front","ServiceTags":["front-dev,这是个前置应用,网关层","duan"],"ServiceAddress":"10.200.110.100","ServiceWeights":{"Passing":1,"Warning":1},"ServiceMeta":{},"ServicePort":8001,"ServiceEnableTagOverride":false,"ServiceProxyDestination":"","ServiceProxy":{},"ServiceConnect":{},"CreateIndex":11382,"ModifyIndex":11382},{"ID":"382f88c2-4482-e1f7-1453-28f94ff65108","Node":"10.200.110.97","Address":"10.200.110.97","Datacenter":"shenzhen","TaggedAddresses":{"lan":"10.200.110.97","wan":"10.200.110.97"},"NodeMeta":{"consul-network-segment":""},"ServiceKind":"","ServiceID":"front1","ServiceName":"service-front","ServiceTags":["local-dev"],"ServiceAddress":"","ServiceWeights":{"Passing":1,"Warning":1},"ServiceMeta":{},"ServicePort":8001,"ServiceEnableTagOverride":false,"ServiceProxyDestination":"","ServiceProxy":{},"ServiceConnect":{},"CreateIndex":11976,"ModifyIndex":11976}][root@localhost consul-template]#

2、通过consul-template生成nginx配置文件

2.1、创建模板文件

  1. [root@localhost config]# vi tmpltest.ctmpl
  2. [root@localhost config]# cat tmpltest.ctmpl
  3. {{range services}}
  4. {{.Name}}
  5. {{range .Tags}}
  6. {{.}}{{end}}
  7. {{end}}
  8. [root@localhost config]
 2.2、调用模板文件生成查询结果
  1. [root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template "tmpltest.ctmpl:result" -once
  2. [root@localhost config]#

命令说明:
-consul-addr:指定Consul的API接口 ,默认是8500端口。
-template:模板参数,第一个参数是模板文件位置,第二个参数是结果输出位置。
-once:只运行一次就退出。

查看模板渲染的结果

  1. [root@localhost config]# ll
  2. 总用量 8
  3. -rw-r--r--. 1 root root 143 3 22 11:08 result
  4. -rw-r--r--. 1 root root 66 3 22 11:05 tmpltest.ctmpl
  5. [root@localhost config]# cat result
  6.  
  7. consul
  8.  
  9. service-consumer
  10.  
  11. service-demo
  12.  
  13. jar
  14.  
  15. service-front
  16.  
  17. duan
  18. front-dev,这是个前置应用,网关层
  19. local-dev
  20.  
  21. service-producter
  22.  
  23. [root@localhost config]#

输出结果说明:

  • consul是系统自带的服务;
  • service-front是通过consul的配置方式注册的服务,其Tags为【duan front-dev,这是个前置应用,网关层 local-dev】;

2.3、根据已注册的服务动态生成Nginx配置文件

新建Nginx配置模板文件

  1. [root@localhost config]# vi nginx.conf.ctmpl
  2. [root@localhost config]# cat nginx.conf.ctmpl
  3. {{range services}} {{$name := .Name}} {{$service := service .Name}}
  4. upstream {{$name}} {
  5. zone upstream-{{$name}} 64k;
  6. {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  7. {{else}}server 127.0.0.1:65535; # force a 502{{end}}
  8. } {{end}}
  9.  
  10. server {
  11. listen 80 default_server;
  12.  
  13. location / {
  14. root /usr/share/nginx/html/;
  15. index index.html;
  16. }
  17.  
  18. location /stub_status {
  19. stub_status;
  20. }
  21.  
  22. {{range services}} {{$name := .Name}}
  23. location /{{$name}} {
  24. proxy_pass http://{{$name}};
  25. }
  26. {{end}}
  27. }
  28. [root@localhost config]#

调用模板文件生成Nginx配置文件

  1. [root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template="nginx.conf.ctmpl:default.conf" -once
  2. [root@localhost config]# cat default.conf
  3.  
  4. upstream consul {
  5. zone upstream-consul 64k;
  6. server 10.200.110.90:8300 max_fails=3 fail_timeout=60 weight=1;
  7. server 10.200.110.91:8300 max_fails=3 fail_timeout=60 weight=1;
  8. server 10.200.110.93:8300 max_fails=3 fail_timeout=60 weight=1;
  9.  
  10. }
  11. upstream service-consumer {
  12. zone upstream-service-consumer 64k;
  13. server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;
  14. server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;
  15.  
  16. }
  17. upstream service-demo {
  18. zone upstream-service-demo 64k;
  19. server 10.200.110.97:8071 max_fails=3 fail_timeout=60 weight=1;
  20.  
  21. }
  22. upstream service-front {
  23. zone upstream-service-front 64k;
  24. server 10.200.110.97:8001 max_fails=3 fail_timeout=60 weight=1;
  25.  
  26. }
  27. upstream service-producter {
  28. zone upstream-service-producter 64k;
  29. server 10.200.110.95:8081 max_fails=3 fail_timeout=60 weight=1;
  30.  
  31. }
  32.  
  33. server {
  34. listen 80 default_server;
  35.  
  36. location / {
  37. root /usr/share/nginx/html/;
  38. index index.html;
  39. }
  40.  
  41. location /stub_status {
  42. stub_status;
  43. }
  44.  
  45. location /consul {
  46. proxy_pass http://consul;
  47. }
  48.  
  49. location /service-consumer {
  50. proxy_pass http://service-consumer;
  51. }
  52.  
  53. location /service-demo {
  54. proxy_pass http://service-demo;
  55. }
  56.  
  57. location /service-front {
  58. proxy_pass http://service-front;
  59. }
  60.  
  61. location /service-producter {
  62. proxy_pass http://service-producter;
  63. }
  64.  
  65. }
  66. [root@localhost config]#

如果想生成Nginx配置文件后自动加载配置,可以这样:

  1. [root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template="nginx.conf.ctmpl:/usr/local/nginx/conf/conf.d/default.conf:service nginx reload" -once
  2. [root@localhost config]#

生成的nginx配置如下:

  1. [root@localhost config]# cat /usr/local/nginx/conf/conf.d/default.conf
  2.  
  3. upstream consul {
  4. zone upstream-consul 64k;
  5. server 10.200.110.90:8300 max_fails=3 fail_timeout=60 weight=1;
  6. server 10.200.110.91:8300 max_fails=3 fail_timeout=60 weight=1;
  7. server 10.200.110.93:8300 max_fails=3 fail_timeout=60 weight=1;
  8.  
  9. }
  10. upstream service-consumer {
  11. zone upstream-service-consumer 64k;
  12. server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;
  13. server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;
  14.  
  15. }
  16. upstream service-demo {
  17. zone upstream-service-demo 64k;
  18. server 10.200.110.97:8071 max_fails=3 fail_timeout=60 weight=1;
  19.  
  20. }
  21. upstream service-front {
  22. zone upstream-service-front 64k;
  23. server 10.200.110.97:8001 max_fails=3 fail_timeout=60 weight=1;
  24.  
  25. }
  26. upstream service-producter {
  27. zone upstream-service-producter 64k;
  28. server 10.200.110.95:8081 max_fails=3 fail_timeout=60 weight=1;
  29.  
  30. }
  31.  
  32. server {
  33. listen 80 default_server;
  34.  
  35. location / {
  36. root /usr/share/nginx/html/;
  37. index index.html;
  38. }
  39.  
  40. location /stub_status {
  41. stub_status;
  42. }
  43.  
  44. location /consul {
  45. proxy_pass http://consul;
  46. }
  47.  
  48. location /service-consumer {
  49. proxy_pass http://service-consumer;
  50. }
  51.  
  52. location /service-demo {
  53. proxy_pass http://service-demo;
  54. }
  55.  
  56. location /service-front {
  57. proxy_pass http://service-front;
  58. }
  59.  
  60. location /service-producter {
  61. proxy_pass http://service-producter;
  62. }
  63.  
  64. }
  65. [root@localhost config]#;
  66. }
  67.  
  68. location /service-demo {
  69. proxy_pass http://service-demo;
  70. }
  71.  
  72. location /service-front {
  73. proxy_pass http://service-front;
  74. }
  75.  
  76. location /service-producter {
  77. proxy_pass http://service-producter;
  78. }
  79.  
  80. }
  81. [root@localhost config]#

注意,/usr/local/nginx/conf/nginx.conf的配置里增加一行,加载conf.d目录下的其它动态生成的配置文件:

  1. [root@localhost sbin]# vi ../conf/nginx.conf
  2.  
  3. worker_processes 1;
  4.  
  5. #error_log /var/log/nginx/error.log warn;
  6. #pid /var/run/nginx.pid;
  7.  
  8. events {
  9. worker_connections 1024;
  10. }
  11.  
  12. http {
  13. #include /etc/nginx/mime.types;
  14. default_type application/octet-stream;
  15.  
  16. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  17. '$status $body_bytes_sent "$http_referer" '
  18. '"$http_user_agent" "$http_x_forwarded_for"';
  19.  
  20. #access_log /var/log/nginx/access.log main;
  21.  
  22. sendfile on;
  23. #tcp_nopush on;
  24. server_tokens off;
  25. underscores_in_headers on;
  26.  
  27. keepalive_timeout 65;
  28.  
  29. gzip on;
  30. gzip_min_length 1024;
  31. gzip_buffers 4 1k;
  32. #gzip_http_version 1.0;
  33. gzip_comp_level 8;
  34. gzip_types text/plain application/json application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
  35. gzip_vary off;
  36. gzip_disable "MSIE [1-6]\.";
  37.  
  38. include /usr/local/nginx/conf/conf.d/*.conf;
  39. }

consul-template的模板如下:

  1. [root@localhost config]# cat tmplconsumer.ctmpl
  2. ## Settings for a TLS enabled server.
  3. upstream frontend {
  4. {{range service "service-consumer" }} {{$name := .Name}}
  5. ##upstream {{$name}}
  6. ##zone upstream-{{$name}} 64k;
  7. server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  8. {{else}}server 127.0.0.1:65535; # force a 502
  9. {{end}}
  10. }
  11.  
  12. server {
  13. listen 80;
  14. server_name localhost; #appci.mydomain.net;
  15.  
  16. #location /h5/ {
  17. #index index.html
  18. #root /usr/share/nginx/html/h5;
  19. #proxy_pass http://xxxxxoms/;
  20. #}
  21.  
  22. location / {
  23. #if ($request_method ~ ^(HEAD)$) {
  24. # access_log off;
  25. #}
  26. add_header 'Access-Control-Allow-Origin' '*';
  27. add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
  28. add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
  29. if ($request_method = 'OPTIONS') {
  30. return 204;
  31. }
  32. proxy_pass http://frontend/;
  33.  
  34. #Proxy Settings
  35. proxy_set_header Host $host;
  36. proxy_set_header Referer $http_referer;
  37. proxy_set_header Cookie $http_cookie;
  38. proxy_set_header X-Real-IP $remote_addr;
  39. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  40. proxy_connect_timeout 90;
  41. proxy_send_timeout 90;
  42. proxy_read_timeout 90;
  43. proxy_buffer_size 4k;
  44. proxy_buffers 4 32k;
  45. proxy_busy_buffers_size 64k;
  46. proxy_temp_file_write_size 64k;
  47. }
  48.  
  49. error_page 404 /404.html;
  50. location = /40x.html {
  51. }
  52. error_page 500 502 503 504 /50x.html;
  53. location = /50x.html {
  54. }
  55. }
  56. [root@localhost config]#

执行

  1. [root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template="tmplconsumer.ctmpl:/usr/local/nginx/conf/conf.d/default.conf:service nginx reload" -once

生成的nginx配置文件如下:

  1. ## Settings for a TLS enabled server.
  2. upstream frontend {
  3.  
  4. ##upstream service-consumer
  5. ##zone upstream-service-consumer 64k;
  6. server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;
  7.  
  8. ##upstream service-consumer
  9. ##zone upstream-service-consumer 64k;
  10. server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;
  11.  
  12. }
  13.  
  14. server {
  15. listen 80;
  16. server_name localhost; #appci.mydomain.net;
  17.  
  18. #location /h5/ {
  19. #index index.html
  20. #root /usr/share/nginx/html/h5;
  21. #proxy_pass http://xxxxxoms/;
  22. #}
  23.  
  24. location / {
  25. #if ($request_method ~ ^(HEAD)$) {
  26. # access_log off;
  27. #}
  28. add_header 'Access-Control-Allow-Origin' '*';
  29. add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
  30. add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
  31. if ($request_method = 'OPTIONS') {
  32. return 204;
  33. }
  34. proxy_pass http://frontend/;
  35.  
  36. #Proxy Settings
  37. proxy_set_header Host $host;
  38. proxy_set_header Referer $http_referer;
  39. proxy_set_header Cookie $http_cookie;
  40. proxy_set_header X-Real-IP $remote_addr;
  41. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  42. proxy_connect_timeout 90;
  43. proxy_send_timeout 90;
  44. proxy_read_timeout 90;
  45. proxy_buffer_size 4k;
  46. proxy_buffers 4 32k;
  47. proxy_busy_buffers_size 64k;
  48. proxy_temp_file_write_size 64k;
  49. }

用浏览器访问测试:http://10.200.110.90/consumer3/showbook6/1

如果不生效,可以如下排查:

首先,检查生成的nginx配置文件中是否有了对应的服务的配置信息。

再检查,nginx是否重加载成功,可以[root@localhost config]# /usr/local/nginx/sbin/nginx -s reload试试。

多台nginx+consul-template

上面的示例中的nginx是单节点的,有单点故障的问题。那么再+nginx时,是怎样的呢?

先放一个图:

将consul-template的虚拟机克隆下,新ip为99,在启动consul-template,consul关联的还是90(consul-template和consul可以不再同一台机器上,但consul-template和nginx必须同一台机器)

  1. consul-template -consul-addr 10.200.110.90: -template="tmplconsumer.ctmpl:/usr/local/nginx/conf/conf.d/default.conf:service nginx reload" -once

访问如下,也是成功的。

consul-template以服务方式运行

上面两个例子都是consul-template运行一次后就退出了,如果想运行为一个服务可以这样:

  1. consul-template -consul-addr=10.200.110.90:8500 -template "tmpltest.ctmpl:test.out"

查询Consul实例同时渲染多个模板,然后重启相关服务。如果API故障则每30s尝试检测一次值,consul-template运行一次后退出。

  1. consul-template \
  2. -consul-addr=10.200.110.90:8500 \
  3. -retry 30s \
  4. -once \
  5. -template "nginx.ctmpl:/etc/nginx/nginx.conf:service nginx restart" \
  6. -template "redis.ctmpl:/etc/redis/redis.conf:service redis restart" \
  7. -template "haproxy.ctmpl:/etc/haproxy/haproxy.conf:service haproxy restart"

查询一个实例,Dump模板到标准输出。主要用作测试模板输出。

4.2、配置文件方式

以上参数除了在命令行使用也可以直接配置在文件中,下面看看Consul-Template的配置文件,简称HCL(HashiCorp Configuration Language),它是和JSON兼容的。下面先看看官方给的配置文件格式:

  1. consul {
  2.  
  3. auth {
  4. enabled = true
  5. username = "test"
  6. password = "test"
  7. }
  8.  
  9. address = "192.168.2.210:8500"
  10. token = "abcd1234"
  11.  
  12. retry {
  13. enabled = true
  14. attempts = 5
  15. backoff = "250ms"
  16. }
  17.  
  18. ssl {
  19.  
  20. enabled = true
  21. verify = false
  22. cert = "/path/to/client/cert"
  23. key = "/path/to/client/key"
  24. ca_cert = "/path/to/ca"
  25. ca_path = "path/to/certs/"
  26. server_name = "my-server.com"
  27. }
  28. }
  29.  
  30. reload_signal = "SIGHUP"
  31. dump_signal = "SIGQUIT"
  32. kill_signal = "SIGINT"
  33. max_stale = "10m"
  34. log_level = "warn"
  35. pid_file = "/path/to/pid"
  36.  
  37. wait {
  38. min = "5s"
  39. max = "10s"
  40. }
  41.  
  42. vault {
  43. address = "https://vault.service.consul:8200"
  44. token = "abcd1234"
  45. unwrap_token = true
  46. renew_token = true
  47. retry {
  48. # ...
  49. }
  50.  
  51. ssl {
  52. # ...
  53. }
  54. }
  55.  
  56. syslog {
  57. enabled = true
  58. facility = "LOCAL5"
  59. }
  60.  
  61. deduplicate {
  62. enabled = true
  63. prefix = "consul-template/dedup/"
  64. }
  65.  
  66. exec {
  67. command = "/usr/bin/app"
  68. splay = "5s"
  69. env {
  70.  
  71. pristine = false
  72. custom = ["PATH=$PATH:/etc/myapp/bin"]
  73. whitelist = ["CONSUL_*"]
  74. blacklist = ["VAULT_*"]
  75. }
  76.  
  77. reload_signal = ""
  78. kill_signal = "SIGINT"
  79. kill_timeout = "2s"
  80. }
  81.  
  82. template {
  83.  
  84. source = "/path/on/disk/to/template.ctmpl"
  85. destination = "/path/on/disk/where/template/will/render.txt"
  86. contents = "{{ keyOrDefault \"service/redis/maxconns@east-aws\" \"5\" }}"
  87. command = "restart service foo"
  88. command_timeout = "60s"
  89. perms = 0600
  90. backup = true
  91. left_delimiter = "{{"
  92. right_delimiter = "}}"
  93.  
  94. wait {
  95. min = "2s"
  96. max = "10s"
  97. }
  98. }

更多详细的参数可以参考这里: https://github.com/hashicorp/consul-template#configuration-file-format

注意: 上面的选项不都是必选的,可根据实际情况调整。为了更加安全,token也可以从环境变量里读取,使用CONSUL_TOKENVAULT_TOKEN。强烈建议你不要把token放到未加密的文本配置文件中。

接下来我们看一个简单的实例,生成Nginx配置文件并重新加载:

  1. vim nginx.hcl
  2.  
  3. consul {
  4. address = "10.200.110.90:8500"
  5. }
  6.  
  7. template {
  8. source = "nginx.conf.ctmpl"
  9. destination = "/usr/local/nginx/conf/conf.d/default.conf"
  10. command = "service nginx reload"
  11. }

注:nginx.conf.ctmpl模板文件内容还是和前面的一样。

执行以下命令就可渲染文件了:

  1. consul-template -config "nginx.hcl"

更多官方例子可参考:https://github.com/hashicorp/consul-template/tree/master/examples

===============================================================================================

五、Consul-Template的redis读写分离的一个应用(转载,未验证)

  此处假定一个高可用redis集群读写分离的场景,存在一个业务服务BusinessService.Sample,通过对配置文件XXX.BusinessService.Sample.Redis.json中Redis的集群信息的读取来维持Redis客户端的正常读写,配置文件中的数据发生变化时。Redis客户端会进行更新(假定场景- -只表达大致意思,勿喷)。

XXX.BusinessService.Sample.Redis.json中的配置信息假定为

  1. {
  2. "redis":{
  3. "servers": ["127.0.0.1:6378""127.0.0.1:6379"],
  4. "master": "127.0.0.1:6378"
  5. }
  6. }

注册Redis健康监测及配置中心维护Redis的Master节点信息

  将Redis的所有节点注册到Consul,并应用Consul进行健康监测。

  1. {
  2. "services": [{
  3. "id":"redis1",
  4. "name":"redis",
  5. "tags":["redis1"],
  6. "address": "127.0.0.1",
  7. "port":6378,
  8. "checks": [
  9. {
  10. "Tcp": "127.0.0.1:6378",
  11. "interval": "3s"
  12. }
  13. ]
  14. },{
  15. "id":"redis2",
  16. "name":"redis",
  17. "tags":["redis2"],
  18. "address": "127.0.0.1",
  19. "port":6379,
  20. "checks": [
  21. {
  22. "Tcp": "127.0.0.1:6379",
  23. "interval": "3s"
  24. }
  25. ]
  26. }
  27. ]
  28. }

  Redis正常运行的状态如下:

  对于Master的节点信息,这里采用配置中心进程存储

到这里基本工作算是完成了

创建Consul-template模板并注册

  consul-template会通过Http请求从Consul中读取集群中的数据,数据发生变更时 consul-template会触发更新指定配置文件的操作。此处根据XXX.BusinessService.Sample.Redis.json的数据格式创建.ctmpl模板文件,内容如下(配置格式参考 Consul-template文档):

  1. {
  2. "redis":{
  3. "servers": [{{range service "redis" "passing"}}"{{.Address}}:{{.Port}}"{{end}}],
  4. "master": "{{key "service/redis/master"}}"
  5. }
  6. }

  然后进行注册(此处以windows作为实例,Linux操作一样)

consul-template.exe -consul "127.0.0.1:8500" -template="C:\Users\admin\Desktop\consul064\consul-temp\templates\XXX.BusinessService.Sample.Redis.json.ctmpl:C:\Users\admin\Desktop\BusinessService.Sample\BusinessService.Sample\BusinessService.Sample\XXX.BusinessService.Sample.Redis.json">> C:\Users\admin\Desktop\consul064\consul-temp\templates\logs\consul.log 2>&1

  -consul后是consul的webui接口 ,用web管理consul就用的8500端口。

  -template 后面是模板参数 第一个是模板地址 。冒号后的第二个参数是输出位置。

  >> 后为日志输出路径

  注册完成后即可动态触发XXX.BusinessService.Sample.Redis.json文件的动态修改了,比如关闭一个Redis实例或者Master节点发生变更时即可及时完成更新。

Redis的Master节点更新

  master节点的更新此处可以通过监听redis哨兵的+switch-master事件监听,触发修改Consul配置中心中指定Redis Key完成。

consul-template + nginx部署高可用负载均衡的更多相关文章

  1. 使用Ansible实现nginx+keepalived高可用负载均衡自动化部署

    本篇文章记录通过Ansible自动化部署nginx的负载均衡高可用,前端代理使用nginx+keepalived,端web server使用3台nginx用于负载效果的体现,结构图如下: 部署前准备工 ...

  2. [转]搭建Keepalived+Nginx+Tomcat高可用负载均衡架构

    [原文]https://www.toutiao.com/i6591714650205716996/ 一.概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最 ...

  3. Keepalived + Nginx + Tomcat 高可用负载均衡架构

    环境: 1.centos7.3 2.虚拟ip:192.168.217.200 3.192.168.217.11.192.168.217.12上分别部署Nginx Keepalived Tomcat并进 ...

  4. Keepalived+Nginx实现高可用负载均衡集群

    一 环境介绍 1.操作系统CentOS Linux release 7.2.1511 (Core) 2.服务keepalived+nginx双主高可用负载均衡集群及LAMP应用keepalived-1 ...

  5. Nginx+Keepalived高可用负载均衡

    转自 https://www.jianshu.com/p/da26df4f7d60 Keepalived+Nginx实现高可用Web负载均衡 Master backup vip(虚拟IP) 192.1 ...

  6. 【Nginx】如何实现Nginx的高可用负载均衡?看完我也会了!!

    写在前面 不得不说,最近小伙伴们的学习热情是越来越高,不断向冰河提出新的想学习的技术.这不,又有小伙伴问我:冰河,你在[Nginx专题]写的文章基本上都是Nginx单机版的,能不能写一篇关于Nginx ...

  7. Consul&Nginx&Registrator&ConsulTemplate部署高可用负载均衡

    1. Consul Server 创建consul server虚拟主机 docker-machine create consul 出现如下内容即创建成功 Running pre-create che ...

  8. 基于MySQL+MHA+Haproxy部署高可用负载均衡集群

    一.MHA 概述 MHA(Master High Availability)是可以在MySQL上使用的一套高可用方案.所编写的语言为Perl 从名字上我们可以看到.MHA的目的就是为了维护Master ...

  9. LVS+Keepalived+Nginx+Tomcat高可用负载均衡集群配置(DR模式,一个VIP,多个端口)

    一.概述 LVS作用:实现负载均衡 Keepalived作用:监控集群系统中各个服务节点的状态,HA cluster. 配置LVS有两种方式: 1. 通过ipvsadm命令行方式配置 2. 通过Red ...

随机推荐

  1. array的方法 没记住的

    reserve() 是倒叙: sort() 拍序,按字符编码排序,可以传一个参数 reduce() 实例:判断一个数组里参数的个数 var arr = ["apple"," ...

  2. HDU 1260:Tickets(DP)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. java-Random类

    1.Random类的概述和方法使用 * A:Random类的概述 * 此类用于产生随机数 * 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数 ...

  4. 获奖感想和JAVA阶段性学习总结

    一.获奖感想 事实上,这次能够获得小黄衫,实在是出乎我的意料.毕竟班级中还有不少比我优秀的人,但我不会妄自菲薄.我知道,这件小黄衫不仅仅是老师对我的奖励,更是对我的一种鞭策,一种激励.它要求我要在以后 ...

  5. 《DSP using MATLAB》Problem 5.5

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  6. IDEA 热部署- 自动编译设置

    原文:https://www.cnblogs.com/TechSnail/p/7690829.html    &&   https://blog.csdn.net/qq_3129357 ...

  7. Js 向表单中添加多个元素

    @{ ViewBag.title = "地图导航"; } @model YT.XWAJ.Public.Application.MapNavigation.Dto.MapNaviga ...

  8. nginx实现集群高可用

    大家知道NGINX作为反向代理服务器可以实现负载均衡,同时也可以作为静态文件服务器,它的特点就是并发支持大,单机可同时支持3万并发,现在很多网站都把NGINX作为网关入口来统一调度分配后端资源.但是如 ...

  9. java.lang.NoClassDefFoundError: org/apache/jute/CsvOutputArchive

    1. 问题 看到上面的错误 你怎么想? 包冲突?我这里不是.项目用到了zookeeper,这个类是zookeeper的核心包里的类. 控制台一直打印这个错误 但是项目不影响使用,奇怪! 2. 解决办法 ...

  10. classLoader卸载与jvm热部署

    以下的相关介绍都是在未使用dcevm的情况 classLoader的卸载机制 jvm中没有提供class及classloader的unload方法.那热部署及osgi中是通过什么机制来实现的呢?实现思 ...