Mor*_*zov 94 nginx url-rewriting proxypass
我们在Docker的常见域下有几个rails应用程序,我们使用nginx将请求定向到特定应用程序.
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
Run Code Online (Sandbox Code Playgroud)
Config看起来像这样:
upstream foo {
server foo:3000;
}
upstream bar {
server bar:3000;
}
# and about 10 more...
server {
listen *:80 default_server;
server_name our_dev_server.com;
location /foo {
# this is specific to asset management in rails dev
rewrite ^/foo/assets(/.*)$ /assets/$1 break;
rewrite ^/foo(/.*)$ /foo/$1 break;
proxy_pass http://foo;
}
location /bar {
rewrite ^/bar/assets(/.*)$ /assets/$1 break;
rewrite ^/bar(/.*)$ /bar/$1 break;
proxy_pass http://bar;
}
# and about 10 more...
}
Run Code Online (Sandbox Code Playgroud)
如果其中一个应用程序未启动,则nginx将失败并停止:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
Run Code Online (Sandbox Code Playgroud)
我们并不需要它们全部启动,但nginx失败了.如何让nginx忽略失败的上游?
Jus*_*tin 76
如果您可以使用静态IP,那么只需使用它,它就会启动,503
如果它没有响应则返回.
使用该resolver
指令指向可以解析主机的内容,无论它是否正在运行.
location
如果您不能执行上述操作,则在该级别解析它(这将允许Nginx启动/运行):
location /foo {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
Run Code Online (Sandbox Code Playgroud)dan*_*gpm 13
使用的主要优点upstream
是定义一组服务器,而不是可以在不同端口上侦听,并在它们之间配置负载平衡和故障转移.
在您的情况下,您只为每个上游定义1个主服务器,因此必须启动它.
相反,为您的proxy_pass
(es)使用变量并记住处理目标服务器关闭时可能出现的错误(404s,503s).
neu*_*ann 13
对我来说,@ Justin / @ duskwuff的答案的选项3解决了这个问题,但是我不得不将解析器IP更改为127.0.0.11(Docker的DNS服务器):
location /foo {
resolver 127.0.0.11 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.11 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
Run Code Online (Sandbox Code Playgroud)
但是正如@ Justin / @ duskwuff所述,您可以使用任何其他外部DNS服务器。
我们遇到了类似的问题,我们通过在上游容器中动态包含conf文件来解决它,这些文件是由side-car容器生成的,该容器对docker.sock上的事件做出反应,并在上游配置中使用通配符包含文件:
include /etc/upstream/container_*.conf;
Run Code Online (Sandbox Code Playgroud)
如果列表为空,我们添加了一个永久关闭的服务器条目 - 因此有效服务器列表不为空。该服务器条目永远不会收到任何请求
server 127.0.0.1:10082 down;
Run Code Online (Sandbox Code Playgroud)
最后一个条目指向 nginx 中托管错误页面的(内部)服务器(例如 503)
server 127.0.0.1:10082 backup;
Run Code Online (Sandbox Code Playgroud)
所以最终的上游配置如下所示:
upstream my-service {
include /etc/upstream/container_*.conf;
server 127.0.0.1:10082 down;
server 127.0.0.1:10082 backup;
Run Code Online (Sandbox Code Playgroud)
}
在 nginx 配置中,我们添加了一个监听错误端口的服务器:
server {
listen 10082;
location / {
return 503;
add_header Content-Type text/plain;
}
error_page 503 @maintenance;
location @maintenance {
internal;
rewrite ^(.*)$ /503.html break;
root error_pages/;
}
}
Run Code Online (Sandbox Code Playgroud)
如前所述,每个上游容器的配置文件是由一个脚本(bash、curl、jq)生成的,该脚本使用curl与docker.socket交互,它的rest api获取所需的信息(ip、端口)并使用此模板生成文件。
server ${ip}:${port} fail_timeout=5s max_fails=3;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
39641 次 |
最近记录: |