Назад | Перейти на главную страницу

BIND Ответы о недоступности порта ICMP

У меня возникают случайные проблемы с преобразователем DNS, работающим под управлением BIND 9.8.2 (RHEL6) за балансировщиком нагрузки.

Балансировщик нагрузки активно проверяет сервер с помощью DNS-запроса, чтобы определить, жив ли он, и то и дело получает сообщение «В соединении отказано» (ICMP) для порта 53, что на короткое время делает сервер недоступным для обслуживания в пуле серверов балансировщика нагрузки.

Это происходит периодически (LB проверяет каждые 10 секунд, и мы обычно видим 1 или 2 сбоя, за которыми следуют успехи) в течение нескольких минут за раз, а затем останавливается, это происходит во время пиковой нагрузки, но было обнаружено, когда трафик на самом низком.

Когда возникает проблема, BIND запущен и работает, что сбивает с толку сообщение «Соединение отказано», я бы ожидал, что это будет от сервера без службы прослушивания на порту 53, что не так. Даже если разрешение DNS для записи зондирования не удалось, ответом будет NXDOMAIN или SERVFAIL, а не категорическое отклонение UDP.

Журналы запросов не показывают неисправные зонды, что означает, что пакет UDP отклоняется перед доставкой в ​​BIND для обработки.

Я предполагаю, что это вызвано каким-то исчерпанием ресурсов, но я не могу понять, что именно. Мы отслеживаем открытые файловые дескрипторы, net.netfilter.nf_conntrack_count, Процессор, память, recursive-clientsи т. д., и ни один из этих индикаторов даже не приближается к пределу, когда возникает проблема.

Ни в одном из файлов журнала нет соответствующих сообщений об ошибках на момент возникновения проблемы.

Итак, мой вопрос: какие сетевые показатели / параметры мне следует изучить?

Конфигурация

/ и т.д. / sysconfig / с именем

OPTIONS="-4 -n10 -S 8096 "

named.conf

options {
        directory "/var/named";
        pid-file "/var/run/named/named.pid";
        statistics-file "/var/named/named.stats";
        dump-file "/var/named/named_dump.db";
        zone-statistics yes;
        version "Not disclosed";
        listen-on-v6 { any; };
        allow-query { clients; privatenets; };
        recursion yes;                             // default
        allow-recursion { clients; privatenets; };
        allow-query-cache { clients; privatenets; };
        recursive-clients 10000;
        resolver-query-timeout 5;
        dnssec-validation no;
        //querylog no;

        allow-transfer { xfer; };
        transfer-format many-answers;
        max-transfer-time-in 10;
        notify yes;                                // default

        blackhole { bogusnets; };

        // avoid reserved ports
        avoid-v4-udp-ports { 1935; 2605; 4321; 6514; range 8610 8614; };
        avoid-v6-udp-ports { 1935; 2605; 4321; 6514; range 8610 8614; };

        max-cache-ttl 10800; // 3h

        response-policy {
                zone "rpz";
                zone "rpz2";
                zone "static";
        };
        rate-limit {
                window 2; // seconds rolling window
                ipv4-prefix-length 32;

                nxdomains-per-second 5;
                nodata-per-second 3;
                errors-per-second 3;
        };
};

Изменить: UDP получать ошибки

$ netstat -su
IcmpMsg:
    InType3: 1031554
    InType8: 115696
    InType11: 178078
    OutType0: 115696
    OutType3: 502911
    OutType11: 3
Udp:
    27777696664 packets received
    498707 packets to unknown port received.
    262343581 packet receive errors
    53292481120 packets sent
    RcvbufErrors: 273483
    SndbufErrors: 3266
UdpLite:
IpExt:
    InMcastPkts: 6
    InOctets: 2371795573882
    OutOctets: 13360262499718
    InMcastOctets: 216

Редактировать 2: размер сетевой памяти

$ cat /proc/sys/net/core/rmem_max
67108864
$ cat /proc/sys/net/ipv4/udp_mem
752928  1003904 1505856

Изменить 3: нет проблем с UdpInErrors

Произошло событие сбоя зонда без соответствующего увеличения количества ошибок приема пакетов UDP, так что это, похоже, исключено как причина.

Изменить 4: здесь могут быть 2 проблемы, некоторые экземпляры сбоев имеют соответствующее увеличение UdpInErrors, а некоторые нет

Я нашел случай, который коррелирует с проблемой с ошибками приема UDP:

Я уже увеличил значения памяти ядра до:

# cat /proc/sys/net/core/wmem_max
67108864
# cat /proc/sys/net/core/rmem_max
67108864
# cat /proc/sys/net/ipv4/udp_rmem_min
8192
# cat /proc/sys/net/ipv4/udp_wmem_min
8192

Кажется, это не связано с нагрузкой, аналогичные серверы с такими же и даже большими рабочими нагрузками не показывают проблем, в то время как другой сервер за тем же балансировщиком нагрузки показал точно такое же поведение в течение этого периода времени.

Изменить 5: обнаружены некоторые свидетельства проблем TCP в данных статистических каналов BIND

Обнаружена корреляция между высокими ошибками приема пакетов UDP и TCP4ConnFail и TCP4SendErr метрики от BIND статистические каналы данные.

Хотя увеличение не имеет того же масштаба, что и UDPInErrors, оно сильно коррелирует с ним, поскольку в другое время этого эффекта нет.

Изменить 6: сюжет сгущается ... syslog, похоже, способствует

Затронутые DNS-серверы настроены на регистрацию журналов запросов в системный журнал. local0 средство, которое, в свою очередь, перенаправляет их через UDP на удаленный сервер. Это было причиной проблем с производительностью в прошлом, на самом деле мы не включали его на самых загруженных DNS-серверах по этой причине.

Я попытался отключить ведение журнала запросов, и, похоже, udpInErrors проблемы исчезают, поэтому я поставил эксперимент. У нас есть 2 сервера за одним и тем же балансировщиком нагрузки, я сохранил serverA с активным ведением журнала запросов в качестве элемента управления и отключил ведение журнала запросов (и, следовательно, пересылку системного журнала) на serverB. Проблема перестала возникать на обоих серверах в то же самое время.

Затем я снова включил ведение журнала запросов на serverB, и проблема снова возникла. на обоих серверах!

Это было испробовано в двух разных случаях: один раз при небольшой нагрузке, другой - в самое загруженное время, и это проявлялось только в самое загруженное время, поэтому, похоже, это частично связано с нагрузкой.

На графиках ниже показана взаимосвязь между сетевым трафиком и ошибками приема UDP.

ServerB

ServerA

Такой же эффект увеличения можно найти и в индикаторах TCP, упомянутых в редакции 5.

Итак, основная причина, по-видимому, связана с сетью, которая каскадирует и создает все показанные симптомы. Сложность заключается в том, что эти серверы (на самом деле виртуальные машины) работают в отдельной инфраструктуре (иногда в разных стойках, даже комнатах), поэтому между ними не должно быть никакого распространения эффекта.

Похоже, что это не связано с ведением журнала запросов, иначе эффекты не распространялись бы между серверами.

Одна вещь, которая пришла мне в голову, заключается в том, что получающий сервер системного журнала не имеет обратной маршрутизации на эти серверы, поэтому мы никогда не получаем никаких ответных пакетов (если они есть), поэтому системный журнал действует по принципу «выстрелил и забыл». . Может ли это быть причиной?

Udp:
    27777696664 packets received
    ...
    262343581 packet receive errors

105,88 датаграмм, полученных на каждую 1 ошибку приема UDP, - это чрезвычайно высокий коэффициент потери пакетов DNS, и это указывает на то, что у вас есть узкое место в программном обеспечении. Если очередь приема, связанная с сокетом UDP, заполнена, когда ядро ​​пытается передать пакет, пакет теряется, и этот счетчик увеличивается. Это означает, что вы проиграли более двухсот миллионов пакетов к этому явлению с момента последней перезагрузки только на этом сервере.

Полная очередь приема означает, что программное обеспечение не удаляет пакеты из ядра достаточно быстро, создавая отставание, которое в конечном итоге превышает размер буфера. Следующим шагом должно быть определение Зачем очередь слишком высока. Как пример, один из наших пользователей обнаружил, что система была переполнена iowait из-за большого количества журналов на диске. Я не могу предоставить исчерпывающего руководства для определения основной причины, кроме как предложить вам просмотреть все свои метрики производительности SNMP и найти корреляцию. Если вы не можете найти никакой корреляции, возможно, вы работаете на полную мощность своего аппаратного + программного стека, и проблему лучше решить, добавив к ней больше серверов.

В качестве примечания, можно увеличить размер очереди приема, но это лучше всего рассматривать как вашу способность справляться с пакетным трафиком. Если бурный трафик не является почему вы испытываете переполнение очереди, больший размер очереди приведет к увеличению времени обработки трафика, который вы делать accept, что, вероятно, нежелательно. BIND будет использовать глубину очереди приема до 32 КБ, но ограничено значением, указанным в /proc/sys/net/rmem_max. Это число можно увеличить, перекомпилировав BIND с --with-tuning = большой вариант, что увеличивает максимальный потенциал с 32К до 16М.