来自/etc/resolv.conf的Nginx解析器地址


Answers:


16

不幸的是,没有简单的方法可以做到这一点,因为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编码器不满意(为您的眼睛多一点血液做准备),您仍然可以编写替代性的补丁或模块以使其以这种方式工作。


6

对于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程序生成an nginx.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的答案


2
Awk,学习它,它是用于文本调整的绝佳工具:export NAMESERVER=$(awk '/^nameserver/{print $2}' /etc/resolv.conf)。无需catgreptr在那里。
j0057

这在Kubernetes上不起作用。
金·

1

如果您的系统使用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的绝对路径。


1

如果您使用的是nginx的Openresty版本,则可以localresolver指令中使用其特殊参数,将其设置为时local=on,意味着/etc/resolv.conf解析程序将使用的标准路径(有关更多详细信息,请参阅Openresty resolver docs):

resolver local=on;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.