consul-template + nginx部署高可用負載均衡

https://www.cnblogs.com/duanxz/p/9734597.html

https://juejin.im/post/5b2a6bc351882574cf66a211

consul-template + nginx部署高可用負載均衡

一、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

複製代碼

[root@localhost consul-template]# tar -xvf consul-template_0.20.0_linux_amd64.tgz 
consul-template
[root@localhost consul-template]# ll
總用量 12696
-rwxr-xr-x. 1  501 games 9451232 2月  20 08:39 consul-template
-rw-r--r--. 1 root root  3543379 3月  22 09:57 consul-template_0.20.0_linux_amd64.tgz
[root@localhost consul-template]# cd consul-template
-bash: cd: consul-template: 不是目錄
[root@localhost consul-template]# cp consul-template /usr/local/bin
[root@localhost consul-template]# consul-template -v 
consul-template v0.20.0 (b709612c)
[root@localhost consul-template]#

複製代碼

三、Consul-Template使用幫助

查看幫助

執行consul-template -h即可看到consul-temple的使用參數

  -auth=<user[:pass]>      設置基本的認證用戶名和密碼
  -consul=<address>        設置Consul實例的地址
  -max-stale=<duration>    查詢過期的最大頻率,默認是1s
  -dedup                   啓用重複數據刪除,當許多consul template實例渲染一個模板的時候可以降低consul的負載
  -ssl                     使用https連接Consul使用SSL
  -ssl-verify              通過SSL連接的時候檢查證書
  -ssl-cert                SSL客戶端證書發送給服務器
  -ssl-key                 客戶端認證時使用的SSL/TLS私鑰
  -ssl-ca-cert             驗證服務器的CA證書列表
  -token=<token>           設置Consul API的token
  -syslog                  把標準輸出和標準錯誤重定向到syslog,syslog的默認級別是local0。
  -syslog-facility=<f>     設置syslog級別,默認是local0,必須和-syslog配合使用
  -template=<template>     增加一個需要監控的模板,格式是:'templatePath:outputPath(:command)',多個模板則可以設置多次
  -wait=<duration>         當呈現一個新的模板到系統和觸發一個命令的時候,等待的最大最小時間。如果最大值被忽略,默認是最小值的4倍。
  -retry=<duration>        當在和consul api交互的返回值是error的時候,等待的時間,默認是5s。
  -config=<path>           配置文件或者配置目錄的路徑
  -pid-file=<path>         PID文件的路徑
  -log-level=<level>       設置日誌級別,可以是"debug","info", "warn" (default), and "err"
  -dry                     Dump生成的模板到標準輸出,不會生成到磁盤
  -once                    運行consul-template一次後退出,不以守護進程運行
  -reap                    子進程自動收割

Consul-Template模版語法

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

下面看看配置模板到底怎麼寫,模板文件的語法和Go template的格式一樣,confd也是遵循Go template的。

先看看API 功能語法:

datacenters:在consul目錄中查詢所有的datacenters,{{datacenters}}
file:讀取並輸出本地磁盤上的文件,如果無法讀取,則報錯,{{file "/path/to/local/file"}}
key:查詢consul中該key的值,如果無法轉換成一個類字符串的值,則會報錯,{{key "service/redis/maxconns@east-aws"}} east-aws指定的是數據中心,{{key "service/redis/maxconns"}}
key_or_default:查詢consul中該key的值,如果key不存在,則使用指定的值代替,{{key_or_default "service/redis/maxconns@east-aws" "5"}}
ls:在consul中查詢給定前綴的key的頂級域值,{{range ls "service/redis@east-aws"}} {{.Key}} {{.Value}}{{end}}
node:查詢consul目錄中的單個node,如果不指定node,則是當前agent的,{{node "node1"}}
nodes:查詢consul目錄中的所有nodes,你也可以指定datacenter,{{nodes "@east-aws"}}
service:查詢consul中匹配的service組,{{service "release.web@east-aws"}}或者{{service "web"}},也可以返回一組HealthService服務{{range service "web@datacenter"}}  server {{.Name}} {{.Address}}:{{.Port}}{{end}},默認值返回健康的服務,如果你想返回所有服務,則{{service "web" "any"}}
services:查詢consul目錄中的所有services,{{services}},也可以指定datacenter:{{services "@east-aws"}}
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,如下:

複製代碼

[root@localhost consul-template]# curl http://10.200.110.90:8500/v1/catalog/service/service-front
[{"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、創建模板文件

複製代碼

[root@localhost config]# vi tmpltest.ctmpl
[root@localhost config]# cat tmpltest.ctmpl 
{{range services}}
{{.Name}}
{{range .Tags}}
{{.}}{{end}}
{{end}}
[root@localhost config]

複製代碼

 2.2、調用模板文件生成查詢結果

[root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template "tmpltest.ctmpl:result" -once
[root@localhost config]#

 命令說明:
-consul-addr:指定Consul的API接口 ,默認是8500端口。
-template:模板參數,第一個參數是模板文件位置,第二個參數是結果輸出位置。
-once:只運行一次就退出。

查看模板渲染的結果

複製代碼

[root@localhost config]# ll
總用量 8
-rw-r--r--. 1 root root 143 3月  22 11:08 result
-rw-r--r--. 1 root root  66 3月  22 11:05 tmpltest.ctmpl
[root@localhost config]# cat result 

consul


service-consumer


service-demo

jar

service-front

duan
front-dev,這是個前置應用,網關層
local-dev

service-producter


[root@localhost config]#

複製代碼

 輸出結果說明:

  • consul是系統自帶的服務;
  • service-front是通過consul的配置方式註冊的服務,其Tags爲【duan front-dev,這是個前置應用,網關層 local-dev】;

2.3、根據已註冊的服務動態生成Nginx配置文件

新建Nginx配置模板文件

複製代碼

[root@localhost config]# vi nginx.conf.ctmpl
[root@localhost config]# cat nginx.conf.ctmpl 
{{range services}} {{$name := .Name}} {{$service := service .Name}}
upstream {{$name}} {
  zone upstream-{{$name}} 64k;
  {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}
} {{end}}

server {
  listen 80 default_server;

  location / {
    root /usr/share/nginx/html/;
    index index.html;
  }

  location /stub_status {
    stub_status;
  }

{{range services}} {{$name := .Name}}
  location /{{$name}} {
    proxy_pass http://{{$name}};
  }
{{end}}
}
[root@localhost config]#

複製代碼

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

複製代碼

[root@localhost config]# consul-template -consul-addr 10.200.110.90:8500 -template="nginx.conf.ctmpl:default.conf" -once
[root@localhost config]# cat default.conf 
  
upstream consul {
  zone upstream-consul 64k;
  server 10.200.110.90:8300 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.91:8300 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.93:8300 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-consumer {
  zone upstream-service-consumer 64k;
  server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-demo {
  zone upstream-service-demo 64k;
  server 10.200.110.97:8071 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-front {
  zone upstream-service-front 64k;
  server 10.200.110.97:8001 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-producter {
  zone upstream-service-producter 64k;
  server 10.200.110.95:8081 max_fails=3 fail_timeout=60 weight=1;
  
} 

server {
  listen 80 default_server;

  location / {
    root /usr/share/nginx/html/;
    index index.html;
  }

  location /stub_status {
    stub_status;
  }

 
  location /consul {
    proxy_pass http://consul;
  }
 
  location /service-consumer {
    proxy_pass http://service-consumer;
  }
 
  location /service-demo {
    proxy_pass http://service-demo;
  }
 
  location /service-front {
    proxy_pass http://service-front;
  }
 
  location /service-producter {
    proxy_pass http://service-producter;
  }

}
[root@localhost config]#

複製代碼

 如果想生成Nginx配置文件後自動加載配置,可以這樣:

[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
[root@localhost config]#

 生成的nginx配置如下:

複製代碼

[root@localhost config]# cat /usr/local/nginx/conf/conf.d/default.conf
  
upstream consul {
  zone upstream-consul 64k;
  server 10.200.110.90:8300 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.91:8300 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.93:8300 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-consumer {
  zone upstream-service-consumer 64k;
  server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;
  server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-demo {
  zone upstream-service-demo 64k;
  server 10.200.110.97:8071 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-front {
  zone upstream-service-front 64k;
  server 10.200.110.97:8001 max_fails=3 fail_timeout=60 weight=1;
  
}   
upstream service-producter {
  zone upstream-service-producter 64k;
  server 10.200.110.95:8081 max_fails=3 fail_timeout=60 weight=1;
  
} 

server {
  listen 80 default_server;

  location / {
    root /usr/share/nginx/html/;
    index index.html;
  }

  location /stub_status {
    stub_status;
  }

 
  location /consul {
    proxy_pass http://consul;
  }
 
  location /service-consumer {
    proxy_pass http://service-consumer;
  }
 
  location /service-demo {
    proxy_pass http://service-demo;
  }
 
  location /service-front {
    proxy_pass http://service-front;
  }
 
  location /service-producter {
    proxy_pass http://service-producter;
  }

}
[root@localhost config]#;
  }
 
  location /service-demo {
    proxy_pass http://service-demo;
  }
 
  location /service-front {
    proxy_pass http://service-front;
  }
 
  location /service-producter {
    proxy_pass http://service-producter;
  }

}
[root@localhost config]#

複製代碼

 注意,/usr/local/nginx/conf/nginx.conf的配置裏增加一行,加載conf.d目錄下的其它動態生成的配置文件:

複製代碼

[root@localhost sbin]# vi ../conf/nginx.conf

worker_processes  1;

#error_log  /var/log/nginx/error.log warn;
#pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    #include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;
    server_tokens off;
    underscores_in_headers on;

    keepalive_timeout  65;

    gzip on;
    gzip_min_length 1024;
    gzip_buffers 4 1k;
    #gzip_http_version 1.0;
    gzip_comp_level 8;
    gzip_types text/plain application/json application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
    gzip_vary off;
    gzip_disable "MSIE [1-6]\.";


    include /usr/local/nginx/conf/conf.d/*.conf;
}

複製代碼

consul-template的模板如下:

複製代碼

[root@localhost config]# cat tmplconsumer.ctmpl 
## Settings for a TLS enabled server.
upstream frontend {
    {{range service "service-consumer" }} {{$name := .Name}}
    ##upstream {{$name}} 
    ##zone upstream-{{$name}} 64k;
    server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
    {{else}}server 127.0.0.1:65535; # force a 502
    {{end}}
}

server {
  listen       80;
  server_name  localhost;  #appci.mydomain.net;

    #location /h5/ {
        #index index.html
        #root /usr/share/nginx/html/h5;
        #proxy_pass http://xxxxxoms/;
    #}

  location / {
    #if ($request_method ~ ^(HEAD)$) {
    #    access_log off;
    #}
    add_header 'Access-Control-Allow-Origin' '*';
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    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';
    if ($request_method = 'OPTIONS') {
        return 204;
    } 
    proxy_pass http://frontend/;
    
    #Proxy Settings
    proxy_set_header Host $host;
    proxy_set_header   Referer $http_referer;
    proxy_set_header   Cookie $http_cookie;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;
    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;
  }

  error_page 404 /404.html;
      location = /40x.html {
  }
  error_page 500 502 503 504 /50x.html;
      location = /50x.html {
  }
}
[root@localhost config]#

複製代碼

 執行

[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配置文件如下:

複製代碼

## Settings for a TLS enabled server.
upstream frontend {

        ##upstream service-consumer
        ##zone upstream-service-consumer 64k;
        server 10.200.110.89:8091 max_fails=3 fail_timeout=60 weight=1;

        ##upstream service-consumer
        ##zone upstream-service-consumer 64k;
        server 10.200.110.90:8091 max_fails=3 fail_timeout=60 weight=1;

}

server {
  listen       80;
  server_name  localhost;  #appci.mydomain.net;

        #location /h5/ {
                #index index.html
                #root /usr/share/nginx/html/h5;
                #proxy_pass http://xxxxxoms/;
        #}

  location / {
        #if ($request_method ~ ^(HEAD)$) {
        #       access_log off;
        #}
        add_header 'Access-Control-Allow-Origin' '*';
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        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';
        if ($request_method = 'OPTIONS') {
                return 204;
        }
        proxy_pass http://frontend/;

        #Proxy Settings
        proxy_set_header Host $host;
        proxy_set_header   Referer $http_referer;
        proxy_set_header   Cookie $http_cookie;
        proxy_set_header   X-Real-IP  $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
  }

複製代碼

用瀏覽器訪問測試: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必須同一臺機器)

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

訪問如下,也是成功的。

consul-template以服務方式運行

上面兩個例子都是consul-template運行一次後就退出了,如果想運行爲一個服務可以這樣:

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

查詢Consul實例同時渲染多個模板,然後重啓相關服務。如果API故障則每30s嘗試檢測一次值,consul-template運行一次後退出。

複製代碼

consul-template \
  -consul-addr=10.200.110.90:8500 \
  -retry 30s \
  -once \
  -template "nginx.ctmpl:/etc/nginx/nginx.conf:service nginx restart" \
  -template "redis.ctmpl:/etc/redis/redis.conf:service redis restart" \
  -template "haproxy.ctmpl:/etc/haproxy/haproxy.conf:service haproxy restart"

複製代碼

查詢一個實例,Dump模板到標準輸出。主要用作測試模板輸出。

4.2、配置文件方式

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

複製代碼

consul {

  auth {
    enabled  = true
    username = "test"
    password = "test"
  }

  address = "192.168.2.210:8500"
  token = "abcd1234"

  retry {
    enabled = true
    attempts = 5
    backoff = "250ms"
  }

  ssl {

    enabled = true
    verify = false
    cert = "/path/to/client/cert"
    key = "/path/to/client/key"
    ca_cert = "/path/to/ca"
    ca_path = "path/to/certs/"
    server_name = "my-server.com"
  }
}

reload_signal = "SIGHUP"
dump_signal = "SIGQUIT"
kill_signal = "SIGINT"
max_stale = "10m"
log_level = "warn"
pid_file = "/path/to/pid"


wait {
  min = "5s"
  max = "10s"
}

vault {
  address = "https://vault.service.consul:8200"
  token = "abcd1234"
  unwrap_token = true
  renew_token = true
  retry {
    # ...
  }

  ssl {
    # ...
  }
}


syslog {
  enabled = true
  facility = "LOCAL5"
}


deduplicate {
  enabled = true
  prefix = "consul-template/dedup/"
}


exec {
  command = "/usr/bin/app"
  splay = "5s"
  env {

    pristine = false
    custom = ["PATH=$PATH:/etc/myapp/bin"]
    whitelist = ["CONSUL_*"]
    blacklist = ["VAULT_*"]
  }

  reload_signal = ""
  kill_signal = "SIGINT"
  kill_timeout = "2s"
}

template {

  source = "/path/on/disk/to/template.ctmpl"
  destination = "/path/on/disk/where/template/will/render.txt"
  contents = "{{ keyOrDefault \"service/redis/maxconns@east-aws\" \"5\" }}"
  command = "restart service foo"
  command_timeout = "60s"
  perms = 0600
  backup = true
  left_delimiter  = "{{"
  right_delimiter = "}}"

  wait {
    min = "2s"
    max = "10s"
  }
}

複製代碼

更多詳細的參數可以參考這裏: https://github.com/hashicorp/consul-template#configuration-file-format

注意: 上面的選項不都是必選的,可根據實際情況調整。爲了更加安全,token也可以從環境變量裏讀取,使用CONSUL_TOKENVAULT_TOKEN。強烈建議你不要把token放到未加密的文本配置文件中。

接下來我們看一個簡單的實例,生成Nginx配置文件並重新加載:

複製代碼

vim nginx.hcl

consul {
address = "10.200.110.90:8500"
}

template {
source = "nginx.conf.ctmpl"
destination = "/usr/local/nginx/conf/conf.d/default.conf"
command = "service nginx reload"
}

複製代碼

注:nginx.conf.ctmpl模板文件內容還是和前面的一樣。

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

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中的配置信息假定爲

複製代碼

複製代碼

{
    "redis":{
      "servers": ["127.0.0.1:6378""127.0.0.1:6379"],
      "master": "127.0.0.1:6378"
    } 
}

複製代碼

複製代碼

註冊Redis健康監測及配置中心維護Redis的Master節點信息

  將Redis的所有節點註冊到Consul,並應用Consul進行健康監測。

複製代碼

複製代碼

{
   "services": [{
     "id":"redis1",
     "name":"redis",
     "tags":["redis1"],
     "address": "127.0.0.1",
     "port":6378,
     "checks": [
       {
         "Tcp": "127.0.0.1:6378",
         "interval": "3s"
       }
     ]
   },{
     "id":"redis2",
     "name":"redis",
     "tags":["redis2"],
     "address": "127.0.0.1",
     "port":6379,
     "checks": [
       {
         "Tcp": "127.0.0.1:6379",
         "interval": "3s"
       }
     ]
   }
   ]
} 

複製代碼

複製代碼

  Redis正常運行的狀態如下:

 

  對於Master的節點信息,這裏採用配置中心進程存儲

 到這裏基本工作算是完成了

創建Consul-template模板並註冊

  consul-template會通過Http請求從Consul中讀取集羣中的數據,數據發生變更時 consul-template會觸發更新指定配置文件的操作。此處根據XXX.BusinessService.Sample.Redis.json的數據格式創建.ctmpl模板文件,內容如下(配置格式參考 Consul-template文檔):

複製代碼

複製代碼

{
    "redis":{
      "servers": [{{range service "redis" "passing"}}"{{.Address}}:{{.Port}}"{{end}}],
      "master": "{{key "service/redis/master"}}"
    } 
}

複製代碼

複製代碼

  然後進行註冊(此處以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完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章