Docker 中的 NGINX 和 Consul 模板
NGINX & Consul-Template in Docker
我在使用 EC2、AWS、Docker、Consul-Template、Consul 和 NGINX 进行一致的服务发现时遇到了问题。
我有多个服务,每个服务都 运行在它自己的 EC2 实例上。在这些情况下,我 运行 以下容器(按此顺序):
- cAdvisor(监控)
- 节点导出器(监控)
- Consul(运行代理模式)
- 注册人
- 我的服务
- 自定义容器运行nginx 和 consul-template
自定义容器具有以下Docker文件:
FROM nginx:1.9
#Install Curl
RUN apt-get update -qq && apt-get -y install curl
#Install Consul Template
RUN curl -L https://github.com/hashicorp/consul-template/releases/download/v0.10.0/consul-template_0.10.0_linux_amd64.tar.gz | tar -C /usr/local/bin --strip-components 1 -zxf -
#Setup Consul Template Files
RUN mkdir /etc/consul-templates
COPY ./app.conf.tmpl /etc/consul-templates/app.conf
# Remove all other conf files from nginx
RUN rm /etc/nginx/conf.d/*
#Default Variables
ENV CONSUL consul:8500
CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf && consul-template -consul=$CONSUL -template "/etc/consul-templates/app.conf:/etc/nginx/conf.d/app.conf:/usr/sbin/nginx -s reload"
app.conf 文件如下所示:
{{range services}}
upstream {{.Name}} {
least_conn;{{range service .Name}}
server {{.Address}}:{{.Port}};{{end}}
}
{{end}}
server {
listen 80 default_server;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://cart/cart/;
}
location /cart {
proxy_pass http://cart/cart;
}
{{range services}}
location /api/{{.Name}} {
proxy_read_timeout 180;
proxy_pass http://{{.Name}}/{{.Name}};
}
{{end}}
}
一切似乎都启动得很好,但在启动后的某个时刻(我还没有确定),consul-template 似乎 return 没有可用于特定服务的服务器.这意味着该服务的 upstream
部分不包含任何服务器,我最终在日志中看到:
2015/12/04 07:09:34 [emerg] 77#77: no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
2015/12/04 07:09:34 [ERR] (runner) error running command: exit status 1
Consul Template returned errors:
1 error(s) occurred:
* exit status 1
2015/12/04 07:09:34 [DEBUG] (logging) setting up logging
2015/12/04 07:09:34 [DEBUG] (logging) config:
{
"name": "consul-template",
"level": "WARN",
"syslog": false,
"syslog_facility": "LOCAL0"
}
2015/12/04 07:09:34 [emerg] 7#7: no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
此后,NGINX 将不再接受请求。
我确定我遗漏了一些明显的东西,但我已经把自己束缚在事件顺序等问题上。我认为可能发生的是 NGINX 崩溃,但因为 consul-template 仍然存在运行ning,Docker 容器没有重新启动。我实际上并不关心容器本身是否重新启动,或者只是 NGINX 重新启动。
有人可以帮忙吗?
Consul 模板将在编写 returns 非零退出代码后运行的脚本退出。 See here for the documentation.
文档建议在重启(或重新加载)命令之后放置一个 || true
。这将使 Consul 模板 运行 独立于退出代码。
您可以考虑将重启包装在它自己的 shell 脚本中,该脚本在触发重新加载之前首先测试配置(使用 nginx -t
)。您甚至可以将 nginx 的初始启动移动到此脚本,因为只有在编写第一个(有效)配置后才启动 nginx
才有意义?!
我在使用 EC2、AWS、Docker、Consul-Template、Consul 和 NGINX 进行一致的服务发现时遇到了问题。
我有多个服务,每个服务都 运行在它自己的 EC2 实例上。在这些情况下,我 运行 以下容器(按此顺序):
- cAdvisor(监控)
- 节点导出器(监控)
- Consul(运行代理模式)
- 注册人
- 我的服务
- 自定义容器运行nginx 和 consul-template
自定义容器具有以下Docker文件:
FROM nginx:1.9
#Install Curl
RUN apt-get update -qq && apt-get -y install curl
#Install Consul Template
RUN curl -L https://github.com/hashicorp/consul-template/releases/download/v0.10.0/consul-template_0.10.0_linux_amd64.tar.gz | tar -C /usr/local/bin --strip-components 1 -zxf -
#Setup Consul Template Files
RUN mkdir /etc/consul-templates
COPY ./app.conf.tmpl /etc/consul-templates/app.conf
# Remove all other conf files from nginx
RUN rm /etc/nginx/conf.d/*
#Default Variables
ENV CONSUL consul:8500
CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf && consul-template -consul=$CONSUL -template "/etc/consul-templates/app.conf:/etc/nginx/conf.d/app.conf:/usr/sbin/nginx -s reload"
app.conf 文件如下所示:
{{range services}}
upstream {{.Name}} {
least_conn;{{range service .Name}}
server {{.Address}}:{{.Port}};{{end}}
}
{{end}}
server {
listen 80 default_server;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://cart/cart/;
}
location /cart {
proxy_pass http://cart/cart;
}
{{range services}}
location /api/{{.Name}} {
proxy_read_timeout 180;
proxy_pass http://{{.Name}}/{{.Name}};
}
{{end}}
}
一切似乎都启动得很好,但在启动后的某个时刻(我还没有确定),consul-template 似乎 return 没有可用于特定服务的服务器.这意味着该服务的 upstream
部分不包含任何服务器,我最终在日志中看到:
2015/12/04 07:09:34 [emerg] 77#77: no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
2015/12/04 07:09:34 [ERR] (runner) error running command: exit status 1
Consul Template returned errors:
1 error(s) occurred:
* exit status 1
2015/12/04 07:09:34 [DEBUG] (logging) setting up logging
2015/12/04 07:09:34 [DEBUG] (logging) config:
{
"name": "consul-template",
"level": "WARN",
"syslog": false,
"syslog_facility": "LOCAL0"
}
2015/12/04 07:09:34 [emerg] 7#7: no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/app.conf:336
此后,NGINX 将不再接受请求。
我确定我遗漏了一些明显的东西,但我已经把自己束缚在事件顺序等问题上。我认为可能发生的是 NGINX 崩溃,但因为 consul-template 仍然存在运行ning,Docker 容器没有重新启动。我实际上并不关心容器本身是否重新启动,或者只是 NGINX 重新启动。
有人可以帮忙吗?
Consul 模板将在编写 returns 非零退出代码后运行的脚本退出。 See here for the documentation.
文档建议在重启(或重新加载)命令之后放置一个 || true
。这将使 Consul 模板 运行 独立于退出代码。
您可以考虑将重启包装在它自己的 shell 脚本中,该脚本在触发重新加载之前首先测试配置(使用 nginx -t
)。您甚至可以将 nginx 的初始启动移动到此脚本,因为只有在编写第一个(有效)配置后才启动 nginx
才有意义?!