Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Не такие уж динамические обновления

Оригинал: Not So Dynamic Updates
Автор: Kyle Rankin
Дата публикации: 30 марта 2015 г.
Перевод: А.Панин
Дата перевода: 30 августа 2015 г.

В тех случаях, когда сеть находится под моим полным контролем, я чаще всего предпочитаю выделять статические IP-адреса для серверов. Использовать действительно статические IP-адреса (жестко заданные на уровне конфигурационных файлов сетевых соединений узла) или настраивать сервер DHCP для присваивания статических IP-адресов гораздо удобнее тогда, когда есть уверенность в том, что сервер будет всегда иметь один и тот же IP-адрес. К сожалению, в стандартном окружении Amazon EC2 вы не можете как-либо влиять на механизм выделения IP-адреса для вашего сервера. При запуске сервера в окружении EC2 сервер DHCP компании Amazon выделяет для него практически случайный IP-адрес. Сервер будет работать с данным IP-адресом даже после нескольких перезагрузок до того момента, пока узел не будет выключен. Если же вы выключите машину, то после следующего включения с высокой вероятностью ваш сервер будет запущен на отличном аппаратном обеспечении с отличным IP-адресом.

Специальные директивы dhclient

Для исправления ситуации с непредсказуемым выделением IP-адресов я в течение нескольких лет активно использовал механизм динамических обновлений зон DNS в рамках моих окружений EC2. При первом запуске узла с последующей настройкой или при каждой смене IP-адреса, узел будет обновлять данные внутренних серверов DNS, передавая им новый IP-адрес. В общем случае данный подход неплохо работал, но все же он был связан с одной сложностью. В том случае, если бы я контролировал сервер DHCP, я бы использовал при его настройке IP-адреса моих серверов DNS. Но так как компания Amazon контролирует сервер DHCP, мне приходится настраивать свои узлы с целью изменения адресов серверов DNS, полученных от сервера DHCP, на адреса моих серверов. Я использую клиент DHCP от ISC, следовательно, данная задача решается добавлением трех строк в файл конфигурации /etc/dhcp/dhclient.conf в системе на основе дистрибутива Debian.

supersede domain-name "example.com";
supersede domain-search "dev.example.com", "example.com";
supersede domain-name-servers 10.34.56.78, 10.34.56.79;

Благодаря данным директивам после перезапуска сети (или перезагрузок машины) введенные адреса будут добавляться в файл /etc/resolv.conf:

domain example.com
search dev.example.com. example.com
nameserver 10.34.56.78
nameserver 10.34.56.79

Я зашел так далеко, что даже добавил в директорию /etc/dhcp/dhclient-exit-hooks.d/ сценарий bash, который запускался каждый раз при изменении IP-адреса системы. Для защиты от отказов я создал несколько мастер-серверов Puppet, благодаря которым при отправке запроса DNS, направленного на поиск имени узла сервера Puppet возвращалось несколько IP-адресов. Упомянутые сценарии отправляли запрос DNS с целью идентификации ближайшего мастер-сервера Puppet и добавления малоизвестной директивы sortlist в файл rsolv.conf в соответствии с полученной информацией. Директива sortlist указывает вашей системе разрешения доменных имен на строку с IP-адресом, которую следует предпочесть в том случае, если если в результате запроса получено несколько адресов. Таким образом, в том случае, если, к примеру, мастер-сервер Puppet, который я хочу использовать, имеет IP-адрес 10.72.52.100, мне следует добавить следующую строку в файл resolv.conf:

sortlist 10.72.52.100/255.255.255.255

При последующих обработках результатов запросов имен узлов, представленных множеством записей типа A, предпочтение всегда отдавалось обозначенному с помощью упомянутой директивы IP-адресу даже при наличии других адресов. С помощью утилиты ping, вы можете убедиться в том, что пакеты всегда будут отправляться узлу, адрес которого выделен с помощью директивы sortlist, даже в том случае, если утилита dig или nslookup возвращает множество IP-адресов в произвольном порядке. В том случае, если первый узел окажется неработоспособным, при условии наличия корректной поддержки множества записей типа A в вашем клиенте, будет использован следующий сервер из списка.

dhclient не настолько динамический

Описанный метод изменения порядка следования адресов серверов работал вполне корректно в таком динамичном окружении, как EC2 в большинстве случаев. Хотя, данный метод и имел свои сложности. Основная сложность использования данного метода в рамках подобной системы заключалась в том, что IP-адреса самих серверов DNS могли изменяться. Это не проблема - можете сказать вы. Действительно, так как я управляю содержимым файла конфигурации dhclient.conf с помощью системы управления конфигурацией, я могу просто отправить на сервер новую версию файла dhclient.conf. Но проблема данного подхода заключается в том, что демон dhclient не предоставляет какого-либо способа перезагрузки конфигурационного файла dhclient.conf помимо перезапуска демона (приводящего к временному нарушению работы сети), который я в состоянии был бы обнаружить. Как вы видите, при наличии возможности управления сервером DHCP, имелась бы и возможность обновления параметров DNS сервера DHCP, которые бы отправились клиентам при следующем запросе IP-адреса с их стороны. В моем случае смена IP-адреса сервера DNS означала нарушение работы сети в рамках всего окружения.

Я столкнулся с этим требованием на практике. После перезапуска сервера DNS в файл dhclient.conf на всех моих серверах был успешно записан новый IP-адрес. Для страховки я также убедился в том, что файл /etc/resolv.conf был обновлен силами моей системы управления конфигурацией и содержит новый IP-адрес. Изменения прошли успешно и окружение на первый взгляд корректно функционировало, поэтому я незамедлительно отключил сервер DNS. Почти сразу же после этого в рамках моего рабочего окружения произошла небольшая катастрофа.

Я начал замечать, что попытки осуществления внутренних проверок работоспособности все чаще заканчиваются по истечении максимального периода ожидания; узел стал чрезвычайно медленным и неотзывчивым, а спустя длительный промежуток времени после того, как должно было быть заменено содержимое файла resolv.conf узла, оказалось, что это содержимое было изменено вновь. После того, как я исследовал новое содержимое файла resolv.conf на некорректно работающих системах, я обнаружил, что в этих файлах используется устаревшая схема распределения IP-адресов несмотря на то, что DNS-серверы с приведенными адресами не функционировали уже очень давно. В конце концов я понял, что несмотря на обновление содержимого файла конфигурации dhclient.conf, сценарий демона dhclient никогда не обрабатывал внесенные в этот файл изменения, поэтому после нескольких часов в процессе обновления конфигурации в файл resolv.conf записывались старые IP-адреса серверов DNS!

Нарушение работы сети с отголосками по всему миру

Я понял, что практически на каждом узле в данном рабочем окружении будет осуществлено аналогичное обновление адресов серверов в течение следующих нескольких часов, поэтому на уровне каждого узла сети должны быть проведены манипуляции, направленные на принятие нового файла конфигурации dhclient.conf. В это время мои сотрудники изменяли параметры групп серверов. Реальная проблема состояла не в том, что изменение файла конфигурации демона dhclient приведет к нарушению работы сети окружения, а в том, что это нарушение будет выглядеть как отказ окружения, который будет длиться в течение нескольких секунд. Мы работали с кластерами баз данных, которые некорректно обрабатывают ситуации, связанные с отключением сети. По крайней мере, они рассматривают такие ситуации (грубо говоря) как отказ узла и немедленно активируют механизмы отказоустойчивой работы и восстановления кластера базы данных. Узлы всего лишь затрачивают гораздо больше времени, чем обычно, на восстановление работоспособности сети, в то время, как активация механизмов отказоустойчивой работы кластера в некоторых случаях приводит к необходимости ручного восстановления данных.

К нашему счастью, данная проблема коснулась лишь рабочего окружения отдела разработки, но нам пришлось перезапускать серверы DNS также и в окружении для промышленной эксплуатации, в котором также не удалось избежать проблем. Я начал исследовать проблему и после того, как подтвердилась информация о том, что невозможно обновить файл конфигурации dhclient.conf без нарушения работы сети, я приступил к рассмотрению вопроса о том, почему работоспособность сети так долго восстанавливается. Мой сценарий dhclient-exit-hook был наиболее интересным объектом исследования. В рамках данного сценария я устанавливал период ожидания длительностью в пять секунд для гарантированной настройки сети, после чего использовал утилиту dig. Это означало, что после перенастройки сети отправка запросов DNS по старым IP-адресам должна была завершиться истечением их срока действия и бездействием узла до момента окончательной настройки сети. Моим решением была замена вызовов функций ожидания и утилиты dig на шаблон и вызов функции echo, предназначенный для добавления директивы sortlist в файл resolv.conf. Моя система управления конфигурацией могла самостоятельно выполнить запрос DNS и обновить шаблон. Располагая новым, более быстрым сценарием, я убедился, что при перенастройке сети не возникает каких-либо последствий. После того, как я внедрил данный сценарий, у меня появилась возможность перенастройки сетевого соединения на любом из узлов без каких-либо негативных последствий. Последним доказательством стало изменение IP-адреса сервера DNS в окружении для промышленной эксплуатации без каких-либо последствий.