我正在尝试根据环境变量将请求代理到不同的目标。我的方法是将目标url放入自定义变量$ target并将其提供给proxy_pass。
但是使用带有proxy_pass的变量似乎不起作用。这个简单的配置导致来自nginx的“502 Bad Gateway”响应。
server {
listen 8080;
server_name myhost.example.com;
access_log /var/log/nginx/myhost.access.log;
location /proxy {
set $target http://proxytarget.example.com;
proxy_pass $target;
}
}
没有变量的相同配置有效:
server {
listen 8080;
server_name myhost.example.com;
access_log /var/log/nginx/myhost.access.log;
location /proxy {
proxy_pass http://proxytarget.example.com;
}
}
是否真的不可能以这种方式使用proxy_pass,或者我只是做错了什么?
答案 0 :(得分:60)
我最近偶然发现了这种需求并发现为了在proxy_pass目的地中使用变量,你需要设置一个解析器,因为你的error.log很可能包含no resolver defined to resolve ...
我的解决方案是使用Google进行DNS解析设置以下内容:
location ~ /proxy/(.*) {
resolver 127.0.0.1 [::1];
proxy_pass http://$1;
}
在你的情况下,这应该有效:
location /proxy {
resolver 127.0.0.1 [::1];
set $target http://proxytarget.example.com;
proxy_pass $target;
}
要使解析器127.0.0.1正常工作,您需要在本地安装bind9。 对于Debian / Ubuntu:
sudo apt-get install bind9
有关nginx和动态proxy_pass
的更多信息:http://www.nginx-discovery.com/2011/05/day-51-proxypass-and-resolver.html
编辑: 将以前的公共DNS替换为本地DNS以确保安全issues。
答案 1 :(得分:7)
即使@soulseekah的答案是完整而正确的,我也想为使用Nginx的人们在一个容器集群中(即Kubernetes或Docker Compose中的那些容器)发布一个答案。
基本上,您必须使用实际DNS解析器的地址为Nginx配置解析器。对于Docker,它是127.0.0.11
的{{3}},对于Kubernetes,请参考always
在docker网络内部,我能够通过以下方式成功配置动态proxy_pass
:
resolver 127.0.0.11 [::1];
set $bcknd http://$http_XBackend$uri$is_args$args;
proxy_pass $bcknd;
请注意,this answer添加了$uri$is_args$args
,因为否则代理传递不考虑路径和查询字符串。
PS:在我的示例中,我正在使用$http_XBackend
变量读取标头。头由客户端以XBackend: host
的形式传递,此处host
应该是您要转接呼叫的主机名。我尝试使用没有破折号的标头,但必须使用没有破折号的标头。
答案 2 :(得分:0)
偶然发现同样的问题
proxy_pass没有解析我的变量,直到我们发现我们的DNS服务器出现问题
可以使用此cmd检查
nslookup your-domain your-dns-ip
答案 3 :(得分:-1)
location / {
if ($args ~ "^url=(.+)") { #gets the "url" get parameter
set $key1 $1;
proxy_pass $key1;#use the parameter as proxy address
}
}