服务发现如何与现代 docker/docker-compose 一起工作?
How does service discovery work with modern docker/docker-compose?
我正在使用 Docker 1.11.1 和 docker-compose 1.8.0-rc2。
在过去的美好时光(去年),您可以像这样设置一个 docker-compose.yml
文件:
app:
image: myapp
frontend:
image: myfrontend
links:
- app
然后像这样启动环境:
docker scale app=3 frontend=1
并且您的前端容器可以检查环境变量
对于名为 APP_1_PORT
、APP_2_PORT
等的变量来发现
可用的后端主机并相应地自行配置。
时代变了。现在,我们这样做...
version: '2'
services:
app:
image: myapp
frontend:
image: myfrontend
links:
- app
...我们得到的不是环境变量,而是 DNS。所以里面
frontend
容器,我可以要求 app_app_1
或 app_app_2
或
app_app_3
并得到对应的ip地址。我也可以要求
app
并获取 app_app_1
.
的地址
但是我如何发现所有可用的后端容器?我
我想我可以循环 getent hosts ...
直到它失败:
counter=1
while :; do
getent hosts app_$counter || break
backends="$backends app_$counter"
let counter++
done
但这看起来又丑又脆弱。
我听说过关于循环 dns 的谣言,但是 (a) 似乎没有
在我的测试环境中发生,并且 (b) 不一定
如果您的前端需要同时连接到后端,请提供帮助。
简单的容器和服务发现意味着如何在
现代 Docker 世界?
Docker 的 built-in 名称服务器和负载均衡器
Docker 附带一个 built-in nameserver。默认情况下,可以通过 127.0.0.11:53
.
访问服务器
默认情况下,每个容器在 /etc/resolv.conf
中都有一个名称服务器条目,因此不需要从容器中指定名称服务器的地址。这就是为什么您可以使用 service
或 task_service_n
.
从网络中找到您的服务的原因
如果你task_service_n
那么你会得到相应的服务副本的地址。
如果你只请求 service
docker 将在同一网络中的容器之间执行 internal load balancing
和 external load balancing
来处理来自外部的请求。
使用swarm时,docker会额外使用两个特殊网络
ingress network
,它实际上是一个 overlay network 并处理进入 swarm 的流量。它允许从集群中的任何节点查询任何服务。
docker_gwbridge
,bridge network,它将各个主机的覆盖网络连接到它们的物理网络。 (包括入口)
当使用 swarm 到 deploy services 时,除非将 endpointmode 设置为 dns roundrobin 而不是 vip,否则以下示例中描述的行为将不起作用。
endpoint_mode: vip - Docker assigns the service a virtual IP (VIP) that acts as the front end for clients to reach the service on a network. Docker routes requests between the client and available worker nodes for the service, without client knowledge of how many nodes are participating in the service or their IP addresses or ports. (This is the default.)
endpoint_mode: dnsrr - DNS round-robin (DNSRR) service discovery does not use a single virtual IP. Docker sets up DNS entries for the service such that a DNS query for the service name returns a list of IP addresses, and the client connects directly to one of these. DNS round-robin is useful in cases where you want to use your own load balancer, or for Hybrid Windows and Linux applications.
例子
例如从dig/docker-compose.yml
部署三个副本
version: '3.8'
services:
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
DNS 查询
您可以使用 dig or nslookup 等工具对 同一网络.
中的名称服务器进行 DNS 查找
docker run --rm --network dig_default tutum/dnsutils dig whoami
; <<>> DiG 9.9.5-3ubuntu0.2-Ubuntu <<>> whoami
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58433
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;whoami. IN A
;; ANSWER SECTION:
whoami. 600 IN A 172.28.0.3
whoami. 600 IN A 172.28.0.2
whoami. 600 IN A 172.28.0.4
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Nov 16 22:36:37 UTC 2020
;; MSG SIZE rcvd: 90
如果您只对IP感兴趣,可以提供+short
选项
docker run --rm --network dig_default tutum/dnsutils dig +short whoami
172.28.0.3
172.28.0.4
172.28.0.2
或寻找特定服务
docker run --rm --network dig_default tutum/dnsutils dig +short dig_whoami_2
172.28.0.4
负载均衡
默认负载均衡发生在传输层或 OSI Model 的第 4 层。所以它是基于 TCP/UDP 的。这意味着无法使用此方法检查和操作 http headers。在企业版中,显然可以使用类似于 treafik 在更下方的示例中使用的标签。
docker run --rm --network dig_default curlimages/curl -Ls http://whoami
Hostname: eedc94d45bf4
IP: 127.0.0.1
IP: 172.28.0.3
RemoteAddr: 172.28.0.5:43910
GET / HTTP/1.1
Host: whoami
User-Agent: curl/7.73.0-DEV
Accept: */*
这是来自 10 次 curl 的主机名:
Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: eedc94d45bf4
Hostname: d922d86eccc6
Hostname: d922d86eccc6
Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: d922d86eccc6
健康检查
Health checks,默认情况下,是通过检查主机内核上容器的进程 ID (PID) 来完成的。如果进程 运行 成功,则容器被认为是健康的。
通常还需要进行其他健康检查。容器可能是 运行 但里面的应用程序已经崩溃了。在许多情况下,首选 TCP 或 HTTP 检查。
可以将自定义健康检查烘焙到图像中。例如,使用 curl 执行 L7 健康检查。
FROM traefik/whoami
HEALTHCHECK CMD curl --fail http://localhost || exit 1
也可以在启动容器时通过cli指定健康检查。
docker run \
--health-cmd "curl --fail http://localhost || exit 1" \
--health-interval=5s \
--timeout=3s \
traefik/whoami
Swarm 示例
正如最初提到的,swarms 行为的不同之处在于它会默认为服务分配一个虚拟 IP。它实际上没有什么不同它只是 docker 或 docker-compose 不创建真正的服务,它只是模仿 swarm 的行为但仍然正常运行容器,因为服务实际上只能由管理器创建节点。
请记住,我们在 swarm 管理器上,因此默认模式是 VIP
创建一个普通容器也可以使用的覆盖网络
$ docker network create --driver overlay --attachable testnet
使用 2 个副本创建一些服务
$ docker service create --network testnet --replicas 2 --name digme nginx
现在让我们再次使用 dig 并确保我们将容器附加到同一网络
$ docker run --network testnet --rm tutum/dnsutils dig digme
digme. 600 IN A 10.0.18.6
我们看到确实只返回了一个IP地址,看来这是docker分配的虚拟IP。
在这种情况下,Swarm 实际上允许获取单个 IP 而无需 显式设置端点模式。
我们可以查询 tasks.<servicename>
在这种情况下是 tasks.digme
$ docker run --network testnet --rm tutum/dnsutils dig tasks.digme
tasks.digme. 600 IN A 10.0.18.7
tasks.digme. 600 IN A 10.0.18.8
这给我们带来了 2 个指向各个副本的 A 记录。
现在让我们创建另一个服务,endpointmode 设置为 dns roundrobin
docker service create --endpoint-mode dnsrr --network testnet --replicas 2 --name digme2 nginx
$ docker run --network testnet --rm tutum/dnsutils dig digme2
digme2. 600 IN A 10.0.18.21
digme2. 600 IN A 10.0.18.20
这样我们就可以得到两个 IP 而无需添加前缀 tasks
.
服务发现和负载均衡策略
如果内置功能不够,可以实施一些策略来实现更好的控制。下面是一些例子。
HAProxy
Haproxy can use the docker nameserver in combination with dynamic server templates to discover the running container. Then the traditional proxy features can be leveraged to achieve powerful layer 7 load balancing with http header manipulation and chaos engeering等重试
version: '3.8'
services:
loadbalancer:
image: haproxy
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
ports:
- 80:80
- 443:443
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
...
resolvers docker
nameserver dns1 127.0.0.11:53
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 10s
hold refused 10s
hold nx 10s
hold timeout 10s
hold valid 10s
hold obsolete 10s
...
backend whoami
balance leastconn
option httpchk
option redispatch 1
retry-on all-retryable-errors
retries 2
http-request disable-l7-retry if METH_POST
dynamic-cookie-key MY_SERVICES_HASHED_ADDRESS
cookie MY_SERVICES_HASHED_ADDRESS insert dynamic
server-template whoami- 6 whoami:80 check resolvers docker init-addr libc,none
...
Traefik
前面的方法已经很不错了。但是,您可能已经注意到,它需要知道应该发现哪些服务以及要发现的副本数量是硬编码的。 Traefik, a container native edge router, solves both problems. As long as we enable Traefik via label,服务将被发现。这分散了配置。就好像每个服务都在注册自己。
标签也可以用来inspect and manipulate http headers.
version: "3.8"
services:
traefik:
image: "traefik:v2.3"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.rule=PathPrefix(`/`)"
- "traefik.http.services.whoami.loadbalancer.sticky=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=MY_SERVICE_ADDRESS"
deploy:
replicas: 3
领事
Consul是一个服务发现和配置管理的工具。必须通过 API 请求注册服务。这是一个更复杂的解决方案,可能只在更大的集群中才有意义,但可能非常 p太棒了。通常它建议 运行 在裸机上而不是在容器中。您可以将它与集群中每个服务器上的 docker 主机一起安装。
在此示例中,它已与 registrator image 配对,负责在领事目录中注册 docker 服务。
可以通过多种方式利用该目录。其中之一是使用 consul-template.
请注意,consul 带有自己的 DNS 解析器,因此在这种情况下,docker DNS 解析器在某种程度上被忽略了。
version: '3.8'
services:
consul:
image: gliderlabs/consul-server:latest
command: "-advertise=${MYHOST} -server -bootstrap"
container_name: consul
hostname: ${MYHOST}
ports:
- 8500:8500
registrator:
image: gliderlabs/registrator:latest
command: "-ip ${MYHOST} consul://${MYHOST}:8500"
container_name: registrator
hostname: ${MYHOST}
depends_on:
- consul
volumes:
- /var/run/docker.sock:/tmp/docker.sock
proxy:
build: .
ports:
- 80:80
depends_on:
- consul
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
ports:
- "80"
Docker支持 consul 模板的自定义代理图像文件。
FROM nginx
RUN curl https://releases.hashicorp.com/consul-template/0.25.1/consul-template_0.25.1_linux_amd64.tgz \
> consul-template_0.25.1_linux_amd64.tgz
RUN gunzip -c consul-template_0.25.1_linux_amd64.tgz | tar xvf -
RUN mv consul-template /usr/sbin/consul-template
RUN rm /etc/nginx/conf.d/default.conf
ADD proxy.conf.ctmpl /etc/nginx/conf.d/
ADD consul-template.hcl /
CMD [ "/bin/bash", "-c", "/etc/init.d/nginx start && consul-template -config=consul-template.hcl" ]
Consul 模板获取一个模板文件,并根据 consuls 目录的内容呈现它。
upstream whoami {
{{ range service "whoami" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 80;
location / {
proxy_pass http://whoami;
}
}
修改模板后,执行重启命令
consul {
address = "consul:8500"
retry {
enabled = true
attempts = 12
backoff = "250ms"
}
}
template {
source = "/etc/nginx/conf.d/proxy.conf.ctmpl"
destination = "/etc/nginx/conf.d/proxy.conf"
perms = 0600
command = "/etc/init.d/nginx reload"
command_timeout = "60s"
}
特征Table
Built In
HAProxy
Traefik
Consul-Template
Resolver
Docker
Docker
Docker
Consul
Service Discovery
Automatic
Server Templates
Label System
KV Store + Template
Health Checks
Yes
Yes
Yes
Yes
Load Balancing
L4
L4, L7
L4, L7
L4, L7
Sticky Session
No
Yes
Yes
Depends on proxy
Metrics
No
Stats Page
Dashboard
Dashboard
您可以查看部分代码samples in more detail on github。
我正在使用 Docker 1.11.1 和 docker-compose 1.8.0-rc2。
在过去的美好时光(去年),您可以像这样设置一个 docker-compose.yml
文件:
app:
image: myapp
frontend:
image: myfrontend
links:
- app
然后像这样启动环境:
docker scale app=3 frontend=1
并且您的前端容器可以检查环境变量
对于名为 APP_1_PORT
、APP_2_PORT
等的变量来发现
可用的后端主机并相应地自行配置。
时代变了。现在,我们这样做...
version: '2'
services:
app:
image: myapp
frontend:
image: myfrontend
links:
- app
...我们得到的不是环境变量,而是 DNS。所以里面
frontend
容器,我可以要求 app_app_1
或 app_app_2
或
app_app_3
并得到对应的ip地址。我也可以要求
app
并获取 app_app_1
.
但是我如何发现所有可用的后端容器?我
我想我可以循环 getent hosts ...
直到它失败:
counter=1
while :; do
getent hosts app_$counter || break
backends="$backends app_$counter"
let counter++
done
但这看起来又丑又脆弱。
我听说过关于循环 dns 的谣言,但是 (a) 似乎没有 在我的测试环境中发生,并且 (b) 不一定 如果您的前端需要同时连接到后端,请提供帮助。
简单的容器和服务发现意味着如何在 现代 Docker 世界?
Docker 的 built-in 名称服务器和负载均衡器
Docker 附带一个 built-in nameserver。默认情况下,可以通过 127.0.0.11:53
.
默认情况下,每个容器在 /etc/resolv.conf
中都有一个名称服务器条目,因此不需要从容器中指定名称服务器的地址。这就是为什么您可以使用 service
或 task_service_n
.
如果你task_service_n
那么你会得到相应的服务副本的地址。
如果你只请求 service
docker 将在同一网络中的容器之间执行 internal load balancing
和 external load balancing
来处理来自外部的请求。
使用swarm时,docker会额外使用两个特殊网络
ingress network
,它实际上是一个 overlay network 并处理进入 swarm 的流量。它允许从集群中的任何节点查询任何服务。docker_gwbridge
,bridge network,它将各个主机的覆盖网络连接到它们的物理网络。 (包括入口)
当使用 swarm 到 deploy services 时,除非将 endpointmode 设置为 dns roundrobin 而不是 vip,否则以下示例中描述的行为将不起作用。
endpoint_mode: vip - Docker assigns the service a virtual IP (VIP) that acts as the front end for clients to reach the service on a network. Docker routes requests between the client and available worker nodes for the service, without client knowledge of how many nodes are participating in the service or their IP addresses or ports. (This is the default.)
endpoint_mode: dnsrr - DNS round-robin (DNSRR) service discovery does not use a single virtual IP. Docker sets up DNS entries for the service such that a DNS query for the service name returns a list of IP addresses, and the client connects directly to one of these. DNS round-robin is useful in cases where you want to use your own load balancer, or for Hybrid Windows and Linux applications.
例子
例如从dig/docker-compose.yml
部署三个副本version: '3.8'
services:
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
DNS 查询
您可以使用 dig or nslookup 等工具对 同一网络.
中的名称服务器进行 DNS 查找docker run --rm --network dig_default tutum/dnsutils dig whoami
; <<>> DiG 9.9.5-3ubuntu0.2-Ubuntu <<>> whoami
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58433
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;whoami. IN A
;; ANSWER SECTION:
whoami. 600 IN A 172.28.0.3
whoami. 600 IN A 172.28.0.2
whoami. 600 IN A 172.28.0.4
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Nov 16 22:36:37 UTC 2020
;; MSG SIZE rcvd: 90
如果您只对IP感兴趣,可以提供+short
选项
docker run --rm --network dig_default tutum/dnsutils dig +short whoami
172.28.0.3
172.28.0.4
172.28.0.2
或寻找特定服务
docker run --rm --network dig_default tutum/dnsutils dig +short dig_whoami_2
172.28.0.4
负载均衡
默认负载均衡发生在传输层或 OSI Model 的第 4 层。所以它是基于 TCP/UDP 的。这意味着无法使用此方法检查和操作 http headers。在企业版中,显然可以使用类似于 treafik 在更下方的示例中使用的标签。
docker run --rm --network dig_default curlimages/curl -Ls http://whoami
Hostname: eedc94d45bf4
IP: 127.0.0.1
IP: 172.28.0.3
RemoteAddr: 172.28.0.5:43910
GET / HTTP/1.1
Host: whoami
User-Agent: curl/7.73.0-DEV
Accept: */*
这是来自 10 次 curl 的主机名:
Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: eedc94d45bf4
Hostname: d922d86eccc6
Hostname: d922d86eccc6
Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: d922d86eccc6
健康检查
Health checks,默认情况下,是通过检查主机内核上容器的进程 ID (PID) 来完成的。如果进程 运行 成功,则容器被认为是健康的。
通常还需要进行其他健康检查。容器可能是 运行 但里面的应用程序已经崩溃了。在许多情况下,首选 TCP 或 HTTP 检查。
可以将自定义健康检查烘焙到图像中。例如,使用 curl 执行 L7 健康检查。
FROM traefik/whoami
HEALTHCHECK CMD curl --fail http://localhost || exit 1
也可以在启动容器时通过cli指定健康检查。
docker run \
--health-cmd "curl --fail http://localhost || exit 1" \
--health-interval=5s \
--timeout=3s \
traefik/whoami
Swarm 示例
正如最初提到的,swarms 行为的不同之处在于它会默认为服务分配一个虚拟 IP。它实际上没有什么不同它只是 docker 或 docker-compose 不创建真正的服务,它只是模仿 swarm 的行为但仍然正常运行容器,因为服务实际上只能由管理器创建节点。
请记住,我们在 swarm 管理器上,因此默认模式是 VIP
创建一个普通容器也可以使用的覆盖网络
$ docker network create --driver overlay --attachable testnet
使用 2 个副本创建一些服务
$ docker service create --network testnet --replicas 2 --name digme nginx
现在让我们再次使用 dig 并确保我们将容器附加到同一网络
$ docker run --network testnet --rm tutum/dnsutils dig digme
digme. 600 IN A 10.0.18.6
我们看到确实只返回了一个IP地址,看来这是docker分配的虚拟IP。
在这种情况下,Swarm 实际上允许获取单个 IP 而无需 显式设置端点模式。
我们可以查询 tasks.<servicename>
在这种情况下是 tasks.digme
$ docker run --network testnet --rm tutum/dnsutils dig tasks.digme
tasks.digme. 600 IN A 10.0.18.7
tasks.digme. 600 IN A 10.0.18.8
这给我们带来了 2 个指向各个副本的 A 记录。
现在让我们创建另一个服务,endpointmode 设置为 dns roundrobin
docker service create --endpoint-mode dnsrr --network testnet --replicas 2 --name digme2 nginx
$ docker run --network testnet --rm tutum/dnsutils dig digme2
digme2. 600 IN A 10.0.18.21
digme2. 600 IN A 10.0.18.20
这样我们就可以得到两个 IP 而无需添加前缀 tasks
.
服务发现和负载均衡策略
如果内置功能不够,可以实施一些策略来实现更好的控制。下面是一些例子。
HAProxy
Haproxy can use the docker nameserver in combination with dynamic server templates to discover the running container. Then the traditional proxy features can be leveraged to achieve powerful layer 7 load balancing with http header manipulation and chaos engeering等重试
version: '3.8'
services:
loadbalancer:
image: haproxy
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
ports:
- 80:80
- 443:443
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
...
resolvers docker
nameserver dns1 127.0.0.11:53
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 10s
hold refused 10s
hold nx 10s
hold timeout 10s
hold valid 10s
hold obsolete 10s
...
backend whoami
balance leastconn
option httpchk
option redispatch 1
retry-on all-retryable-errors
retries 2
http-request disable-l7-retry if METH_POST
dynamic-cookie-key MY_SERVICES_HASHED_ADDRESS
cookie MY_SERVICES_HASHED_ADDRESS insert dynamic
server-template whoami- 6 whoami:80 check resolvers docker init-addr libc,none
...
Traefik
前面的方法已经很不错了。但是,您可能已经注意到,它需要知道应该发现哪些服务以及要发现的副本数量是硬编码的。 Traefik, a container native edge router, solves both problems. As long as we enable Traefik via label,服务将被发现。这分散了配置。就好像每个服务都在注册自己。
标签也可以用来inspect and manipulate http headers.
version: "3.8"
services:
traefik:
image: "traefik:v2.3"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.rule=PathPrefix(`/`)"
- "traefik.http.services.whoami.loadbalancer.sticky=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=MY_SERVICE_ADDRESS"
deploy:
replicas: 3
领事
Consul是一个服务发现和配置管理的工具。必须通过 API 请求注册服务。这是一个更复杂的解决方案,可能只在更大的集群中才有意义,但可能非常 p太棒了。通常它建议 运行 在裸机上而不是在容器中。您可以将它与集群中每个服务器上的 docker 主机一起安装。
在此示例中,它已与 registrator image 配对,负责在领事目录中注册 docker 服务。
可以通过多种方式利用该目录。其中之一是使用 consul-template.
请注意,consul 带有自己的 DNS 解析器,因此在这种情况下,docker DNS 解析器在某种程度上被忽略了。
version: '3.8'
services:
consul:
image: gliderlabs/consul-server:latest
command: "-advertise=${MYHOST} -server -bootstrap"
container_name: consul
hostname: ${MYHOST}
ports:
- 8500:8500
registrator:
image: gliderlabs/registrator:latest
command: "-ip ${MYHOST} consul://${MYHOST}:8500"
container_name: registrator
hostname: ${MYHOST}
depends_on:
- consul
volumes:
- /var/run/docker.sock:/tmp/docker.sock
proxy:
build: .
ports:
- 80:80
depends_on:
- consul
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
ports:
- "80"
Docker支持 consul 模板的自定义代理图像文件。
FROM nginx
RUN curl https://releases.hashicorp.com/consul-template/0.25.1/consul-template_0.25.1_linux_amd64.tgz \
> consul-template_0.25.1_linux_amd64.tgz
RUN gunzip -c consul-template_0.25.1_linux_amd64.tgz | tar xvf -
RUN mv consul-template /usr/sbin/consul-template
RUN rm /etc/nginx/conf.d/default.conf
ADD proxy.conf.ctmpl /etc/nginx/conf.d/
ADD consul-template.hcl /
CMD [ "/bin/bash", "-c", "/etc/init.d/nginx start && consul-template -config=consul-template.hcl" ]
Consul 模板获取一个模板文件,并根据 consuls 目录的内容呈现它。
upstream whoami {
{{ range service "whoami" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 80;
location / {
proxy_pass http://whoami;
}
}
修改模板后,执行重启命令
consul {
address = "consul:8500"
retry {
enabled = true
attempts = 12
backoff = "250ms"
}
}
template {
source = "/etc/nginx/conf.d/proxy.conf.ctmpl"
destination = "/etc/nginx/conf.d/proxy.conf"
perms = 0600
command = "/etc/init.d/nginx reload"
command_timeout = "60s"
}
特征Table
Built In | HAProxy | Traefik | Consul-Template | |
---|---|---|---|---|
Resolver | Docker | Docker | Docker | Consul |
Service Discovery | Automatic | Server Templates | Label System | KV Store + Template |
Health Checks | Yes | Yes | Yes | Yes |
Load Balancing | L4 | L4, L7 | L4, L7 | L4, L7 |
Sticky Session | No | Yes | Yes | Depends on proxy |
Metrics | No | Stats Page | Dashboard | Dashboard |
您可以查看部分代码samples in more detail on github。