如果在上游找不到主机,则安装nginx不会崩溃
我们在Docker的公共域下有几个rails应用程序,我们使用nginx将请求定向到特定的应用程序如果在上游找不到主机,则安装nginx不会崩溃,nginx,url-rewriting,proxypass,Nginx,Url Rewriting,Proxypass,我们在Docker的公共域下有几个rails应用程序,我们使用nginx将请求定向到特定的应用程序 our_dev_server.com/foo # proxies to foo app our_dev_server.com/bar # proxies to bar 配置如下所示: upstream foo { server foo:3000; } upstream bar { server bar:3000; } # and about 10 more... server {
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
配置如下所示:
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...
}
如果其中一个应用程序未启动,则nginx将失败并停止:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
我们不需要它们全部启动,但nginx在其他方面会失败。
如何使nginx忽略失败的上游
503
resolver
指令指向可以解析主机的内容,无论主机当前是否处于运行状态
位置
级别解决此问题(这将允许Nginx启动/运行):
使用
上游
的主要优点是定义一组服务器,这些服务器可以侦听不同的端口,并在它们之间配置负载平衡和故障切换
在您的情况下,每个上游只定义一个主服务器,因此它必须启动
相反,请为您的代理过程使用变量,并记住处理目标服务器关闭时可能出现的错误(404s、503s)。您不能使用--link
选项,而是可以使用端口映射并将nginx绑定到主机地址
示例:使用-p 180:80
选项运行第一个docker容器,使用-p 280:80
选项运行第二个容器
运行nginx并为代理设置以下地址:
proxy_pass http://192.168.1.20:180/; # first container
proxy_pass http://192.168.1.20:280/; # second container
对我来说,@Justin/@dashwuff答案的选项3解决了问题,但我必须将解析器IP更改为127.0.0.11(Docker的DNS服务器):
但正如@Justin/@dashwuff所提到的,您可以使用任何其他外部DNS服务器。我遇到了相同的“找不到主机”问题,因为我的主机的一部分是使用$uri
而不是$request\u uri
进行映射的:
proxy_pass http://one-api-service.$kubernetes:8091/auth;
当请求更改为auth子请求时,$uri
将丢失其初始值。将映射更改为使用$request\u uri
而不是$uri
解决了我的问题:
map $request_uri $kubernetes {
# ...
}
另一个简单快捷的解决方案是,我可以在主服务器没有爆炸的情况下启动和停止
extra_hosts:
- "dockerhost:172.20.0.1" # <-- static ipv4 gateway of the network ip here thats the only sorta downside but it works for me, you can ifconfig inside a container with the network to find yours, kinda a noob answer but it helped me
networks:
- my_network
您是将应用程序容器与Nginx容器链接,还是将它们彼此分开运行?如果上游
块中的主机在运行时未解析,则Nginx将以上述错误退出…如果您可以使用IP,则它将正常启动。在你的情况下使用resolver
()有效吗?@Justin我们每个应用都在单独的容器中,nginx也是如此。将它们与docker@Justin启动顺序很好,nginx在其他应用程序之后启动。我们只想运行其中的一些:)我有一个类似的设置(Nginx容器和appcontainer)。我们创建了一个Nginx映像,其中包含一个proxy.sh
脚本,该脚本读取环境变量,并为每个变量动态添加上游
条目,然后启动Nginx。这非常有效,因为当我们运行代理容器时,可以在运行时传入所需的上游。您可以做一些类似的事情,在启动时启用/禁用某些上游(或者像我的设置一样,只是在运行时添加所需的上游)。您的选项3对我来说非常有用。如果我没有指定解析程序,您知道nginx将缓存它解析的IP多长时间吗?谢谢!仅仅使用一个变量似乎会让nginx对itI不那么精明。我发现一个regex捕获组允许我跳过这个变量:location~ ^/foo/(.*)${proxy\u passhttp://foo/$1;}
这对于TCP代理是如何工作的?似乎没有办法尝试tcp代理的选项3。@Charlie nginx中的此类错误几乎总是与缺少“;”在行尾签名:)>有关。相反,请为代理过程使用变量,并记住处理目标服务器停机时可能出现的错误(404、503)。你能详细说明一下怎么做吗?如果我执行设置$variablehttp://foo
和proxy\u pass$variable
并保持foo“上游”(保持您提到的优势),然后我仍然在讨论OP提到的问题。正如您在其他示例中所看到的,它将是set$variable foo
和proxy\u pass http://$variable
@danielgpm,如您所述,使用proxy_pass变量非常有效,解决了我的问题。如果你能更新你的答案,并举例说明这一点,那会对其他人有所帮助。如果我有不止一个答案,而我想忽略那些无法解决的答案,那该怎么办?你找到解决办法了吗?
map $request_uri $kubernetes {
# ...
}
extra_hosts:
- "dockerhost:172.20.0.1" # <-- static ipv4 gateway of the network ip here thats the only sorta downside but it works for me, you can ifconfig inside a container with the network to find yours, kinda a noob answer but it helped me
networks:
- my_network
server {
listen 80;
server_name servername;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass https://dockerhost:12345;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}