是否可以resolver
在Nginx代理配置中设置来自的地址/etc/resolv.conf
?
例如,在docker或虚拟环境中,它可能很有用。
是否可以resolver
在Nginx代理配置中设置来自的地址/etc/resolv.conf
?
例如,在docker或虚拟环境中,它可能很有用。
Answers:
不幸的是,没有简单的方法可以做到这一点,因为nginx使用了它自己的解析器实现。我看到的两个解决方案是:
1)您从脚本生成解析器列表并将其包括在内,例如:
echo resolver $(awk 'BEGIN{ORS=" "} $1=="nameserver" {print $2}' /etc/resolv.conf) ";" > /etc/nginx/resolvers.conf
http {
include resolvers.conf;
}
2)您可以使用第三方模块(例如(非常)实验性的perl模块)重新编译nginx 并编写变量处理程序:
http {
perl_modules perl/lib;
perl_set $resolvers '
sub {
return system("awk BEGIN{ORS=\" \"} /nameserver/{print \$2}" /etc/resolv.conf");
};
resolver "$resolvers";
}
现在,如果您对C编码器不满意(为您的眼睛多一点血液做准备),您仍然可以编写替代性的补丁或模块以使其以这种方式工作。
对于Docker用户,可在此处找到解决方案:
这是使用Docker的人们的解决方法。
export NAMESERVER=`cat /etc/resolv.conf | grep "nameserver" | awk '{print $2}' | tr '\n' ' '`
这样做是从中获取所有
nameserver
条目/etc/resolv.conf
并将其打印在一行中,因此您可以将它们与nginx的resolver
指令一起使用。您的Dockerfile将需要一个用于生成配置文件然后启动nginx的入口点的自定义脚本。假设您有一个名为的文件nginx.conf.template
,看起来像:
...snip...
http {
server {
resolver $NAMESERVER valid=10s;
...snip....
}
}
}
然后,您的启动脚本可以使用该
envsubst
程序生成annginx.conf
,然后启动nginx。例如:
#!/bin/bash
if [ "$NAMESERVER" == "" ]; then
export NAMESERVER=`cat /etc/resolv.conf | grep "nameserver" | awk '{print $2}' | tr '\n' ' '`
fi
echo "Nameserver is: $NAMESERVER"
echo "Copying nginx config"
envsubst '$NAMESERVER' < /nginx.conf.template > /nginx.conf
echo "Using nginx config:"
cat /nginx.conf
echo "Starting nginx"
nginx -c /nginx.conf -g "daemon off;"
请注意,在docker中,这往往会导致产生相同的文件,因为默认情况下,docker嵌入式DNS服务器是docker127.0.0.11
,请参阅Docker Network Nginx Resolver的答案。
如果您的系统使用resolvconf(许多虚拟机都使用resolvconf,但不幸的是Docker不使用,请参阅man 8 resolvconf
),则可以在中创建nginx resolvers.conf
(与其他答案一样)/etc/resolvconf/update-libc.d/nginx
。即使在极少的动态更改解析器的情况下,这也表现良好。
#!/bin/sh
conf="resolver $(/usr/bin/awk 'BEGIN{ORS=" "} $1=="nameserver" {print $2}' /etc/resolv.conf);"
[ "$conf" = "resolver ;" ] && exit 0
confpath=/etc/nginx/conf.d/resolvers.conf
if [ ! -e $confpath ] || [ "$conf" != "$(cat $confpath)" ]
then
echo "$conf" > $confpath
service nginx reload >/dev/null
fi
exit 0
一些Linux发行版包含/etc/nginx/conf.d/*.conf
在其默认配置中。当服务未运行时,通常会忽略重新加载。请注意,脚本可能没有/usr/bin
在PATH中运行,因此您可能需要awk的绝对路径。
如果您使用的是nginx的Openresty版本,则可以local
在resolver
指令中使用其特殊参数,将其设置为时local=on
,意味着/etc/resolv.conf
解析程序将使用的标准路径(有关更多详细信息,请参阅Openresty resolver docs):
resolver local=on;
export NAMESERVER=$(awk '/^nameserver/{print $2}' /etc/resolv.conf)
。无需cat
,grep
或tr
在那里。