如何使用 consul 模板在 nginx 配置上设置自动注册服务

How can i set automaticly registered services on nginx config using consul template

我在 docker 上使用 consul、consul-template 和 nginx。添加每个新服务时,我必须再次更改 consul-template 源文件。 顺便说一句,我们都在使用 soap 服务和代理。他们都有服务 uri。 我怎么写 nginx.ctmpl ? 示例 Web 服务端点:

 1.1.1.1:123/Service1.asmx

在 consul-config 中,添加如下:

"services": [
  {
    "id": "Svc0",
    "name": "Service",
    "port": 3307,
    "address": "1.1.1.1",
    "checks": [
      {
      "http": "http://1.1.1.1:123/service1.asmx",
      "method": "GET",
      "interval": "10s",
      "timeout": "1s"
      }]
  }
  ]

在nginx.ctmpl。我想将这部分更改为动态,但由于服务器部分我找不到任何解决方案。

upstream backend {

{{ range service "Service" }}
  server {{ .Address }}:{{ .Port }};{{ end }}
}
server {
        listen                443 ssl;
        server_name           domainname.com.tr;
        proxy_set_header      X-Forwarded-Port 443;
        ssl_certificate       /etc/nginx/tls/..crt;
        ssl_certificate_key   /etc/nginx/tls/..key;
        
   location / {
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_pass https://domainanother;
        }
        
   location  ^~ /Service1.asmx {
 
            proxy_pass http://backend;
            proxy_redirect off;
        }
        access_log /etc/nginx/log/gw/https/access.log;
        error_log /etc/nginx/log/gw/https/error.log;
}

这应该可以满足您的要求。

给定以下服务配置:

# services.hcl
services {
  id = "svc1"
  name = "service1"
  address = "1.1.1.1"
  port = 8080
}

services {
  id = "svc2"
  name = "service2"
  address = "1.1.1.1"
  port = 8081
  check = {
    http = "http://1.1.1.1/Service1.asmx"
    method = "GET"
    interval = "10s"
    timeout = "1s"
  }
}

和以下模板:

{{- /*

  Upstream template

  This template is used to the upstream configuration for the service.
  It takes an array of service health objects as input and returns the template
  as a string.

*/ -}}
{{- define "upstream-template" -}}
### Upstream configuration for {{ . }}
upstream {{ . }} {
  zone upstream_{{ . }} 128k;
  {{ range service . "any" }}
  # Instance: {{ printf "%s-%s" .ID .Name }}

  {{- /* Mark the backend as down if the health status is critical */ -}}
  {{- $is_down := sprig_ternary " down" "" (eq .Status "critical") }}
  server {{ printf "%s:%d%s" .Address .Port $is_down -}};
  {{ end }}
}
{{ end -}}

{{- /* Obtain list of services from the catalog */ -}}
{{- $servicesList := services -}}

{{- /* Generate upstream configurations for each logical service */ -}}
{{- range $servicesList -}}
  {{- if and (ne .Name "consul") (.Name | contains "sidecar" | not) -}}
    {{- executeTemplate "upstream-template" .Name -}}
  {{- end -}}
{{- end -}}

server {
  listen                443 ssl;
  server_name           domainname.com.tr;
  proxy_set_header      X-Forwarded-Port 443;
  ssl_certificate       /etc/nginx/tls/..crt;
  ssl_certificate_key   /etc/nginx/tls/..key;

  access_log /etc/nginx/log/gw/https/access.log;
  error_log /etc/nginx/log/gw/https/error.log;

  location / {
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass https://domainanother;
  }

  {{- /*
    Generate the location blocks for each logical service.
    Ignore the 'consul' service itself, and any sidecar services.
  */ -}}
  {{ range $servicesList -}}
  {{- if and (ne .Name "consul") (.Name | contains "sidecar" | not) }}
  location ^~ /{{ .Name | sprig_title }}.asmx {
    proxy_pass http://{{ .Name }};
    proxy_redirect off;
  }
  {{ end -}}
  {{- end }}
}

Consul 模板将生成以下 nginx 配置。

### Upstream configuration for service1
upstream service1 {
  zone upstream_service1 128k;
  
  # Instance: svc1-service1
  server 1.1.1.1:8080;
  
}
### Upstream configuration for service2
upstream service2 {
  zone upstream_service2 128k;
  
  # Instance: svc2-service2
  server 1.1.1.1:8081;
  
}
server {
  listen                443 ssl;
  server_name           domainname.com.tr;
  proxy_set_header      X-Forwarded-Port 443;
  ssl_certificate       /etc/nginx/tls/..crt;
  ssl_certificate_key   /etc/nginx/tls/..key;

  access_log /etc/nginx/log/gw/https/access.log;
  error_log /etc/nginx/log/gw/https/error.log;

  location / {
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass https://domainanother;
  }
  location ^~ /Service1.asmx {
    proxy_pass http://service1;
    proxy_redirect off;
  }
  
  location ^~ /Service2.asmx {
    proxy_pass http://service2;
    proxy_redirect off;
  }
  
}