Адрес преобразователя Nginx из /etc/resolv.conf

18

Можно ли установить resolverадрес в конфигурации прокси nginx из /etc/resolv.conf?

Это может быть полезно, например, в докере или в виртуальной среде.

Николай Голуб
источник

Ответы:

16

К сожалению, нет простого способа сделать это, потому что 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 (подготовьте глаза к крови), вы все равно можете написать альтернативный патч или модуль, чтобы он работал таким образом.

Ксавье Лукас
источник
6

Для пользователей Docker решение можно найти здесь :

Вот обходной путь для людей, использующих Docker.

export NAMESERVER=`cat /etc/resolv.conf | grep "nameserver" | awk '{print $2}' | tr '\n' ' '`

Для этого нужно взять все nameserverзаписи /etc/resolv.confи напечатать их в строке, чтобы вы могли использовать их с resolverдирективой nginx . Ваш 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;"

ОБРАТИТЕ ВНИМАНИЕ, что в docker это приводит к тому же файлу, как и по умолчанию встроенный в Docker DNS-сервер 127.0.0.11, см. Этот ответ в Docker Network Nginx Resolver .

FelikZ
источник
2
Awk, выучи это, это фантастический инструмент для поиска текста export NAMESERVER=$(awk '/^nameserver/{print $2}' /etc/resolv.conf). Нет необходимости cat, grepили trтам.
1800 года
это не работает на Kubernetes все же.
Ким
1

Если ваша система использует 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/binPATH, поэтому вам может понадобиться абсолютный путь к awk.

Марко Кохтала
источник
1

Если вы используете версию nginx для Openresty, то вы можете использовать их специальный localаргумент для resolverдирективы, который при значении local=onозначает, что стандартный путь /etc/resolv.confбудет использоваться для распознавателя (более подробную информацию см. В документах по разделителю разрешения Openresty ):

resolver local=on;
Пирз
источник