Можно ли установить resolver
адрес в конфигурации прокси nginx из /etc/resolv.conf
?
Это может быть полезно, например, в докере или в виртуальном окружении.
К сожалению, нет простого способа сделать это, потому что nginx использует собственную реализацию преобразователя. Я вижу два решения:
1) Вы создаете список преобразователей из скрипта и включаете его, например :
echo resolver $(awk 'BEGIN{ORS=" "} $1=="nameserver" {print $2}' /etc/resolv.conf) ";" > /etc/nginx/resolvers.conf
http {
include resolvers.conf;
}
2) Вы перекомпилируете nginx с помощью стороннего модуля, такого как (очень) экспериментальный модуль perl и напишите обработчик переменной:
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
и распечатайте их в строке, чтобы вы могли использовать их с nginxresolver
директива. В вашем Dockerfile должен быть пользовательский сценарий для точки входа, который генерирует файл конфигурации и затем запускает nginx. Допустим, у вас есть файл с именемnginx.conf.template
это выглядит примерно так:
...snip...
http {
server {
resolver $NAMESERVER valid=10s;
...snip....
}
}
}
Затем ваш сценарий запуска может использовать
envsubst
программа для создания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;"
ПРИМЕЧАНИЕ, что в докере это, как правило, приводит к тому же файлу, поскольку по умолчанию встроенный DNS-сервер докера 127.0.0.11
, видеть этот ответ на Docker Network Nginx Resolver.
Если вы используете версию nginx Openresty, вы можете использовать их специальные local
аргумент к resolver
директива, которая при установке на local=on
, означает стандартный путь /etc/resolv.conf
будет использоваться преобразователем (подробнее см. Документы резолвера Openresty):
resolver local=on;
Если ваша система использует 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.