Syn-Ack Хабр! Меня зовут Сергей Минаев, я руководитель направления администрирования веб-сервисов в компании «Спортмастер».

В преддверии наступающего Нового года хочется, чтобы было спокойно и тихо, можно было кушать оливье, спокойно отдыхать, а не вот это вот все: пожар, караул, SRE взбунтовались! Говорят, резервирование — ненастоящее!



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

Данная статья — не более чем повествование и рассуждение о возможности инженерной мысли, заключенной в рисование котиков красными линиями. Все совпадения реальные, герои – не выдуманные, все происходило взаправду.

Какая у нас задача и какая проблематика




Из всего списка рассмотренных нами проблем выбивается баг прошивки пограничных коммутаторов.

Мы получили зависание пограничных коммутаторов и как следствие полную недоступность всех наших сервисов, включая DNS-серверы. Перестал работать резолв почти всех наших доменных имен.

И если Split-Brain или локальные проблемы (например, залипание ARP) наши сетевые администраторы решают просто подняв бровь, то при недоступности всей площадки нужно думать как-то иначе.

Видел чудеса техники, но такого!




С этапом постановки проблематики и цели мы закончили, теперь переходим ко второму этапу – осмотримся. ИТ-инфраструктура у нас построено достаточно канонична, с соблюдением бест-практисов и “здравого смысла”:

  • Две площадки или еще одна маленькая площадочка
  • Разные каналы от разных провайдеров
  • SDN
  • Дублирующее оборудование

Для доступа из интернета мы используем балансировщики. Это несколько парных кластеров серверов, которые располагаются на разных площадках, подключены в разные коммутаторы по LACP, внешняя сеть растянута между площадками, IP резервируются по VRRP (keepalived).
Вполне себе джентльменский набор техник, а не простое “авось”. Но, возвращаясь к опыту: на Деда Мороза надейся, а сам не плошай.

А какие вообще варианты? Огласите весь список, пожалуйста


Если посмотреть по сторонам, крупными блоками можно попробовать выделить два направления улучшения доступности:

  • Несколько площадок с резервированием “уровня инфраструктуры”
  • Резервирование на уровне ПО

С первого взгляда, никакого rocket science нет: делаем несколько независимых точек присутствия, репликация данных, независимая обработка данных и глобальная блокировка.



Чтобы сделать несколько точек присутствия, для начала нужно как-то направить к ним трафик клиентов. Если делать “глобальный” балансировщик – он тоже может стать недоступным. Значит, нужно переходить немного вбок и на другой уровень.

Самое простое, что приходит в голову – эта балансировка на уровне DNS. Никаких особых настроек она не требует, добавляй только адреса и дополнительные DNS серверы на разных площадках.

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

Но, не все так просто, как кажется… — закон Мерфи.

Что мы делаем? Тестируем!




Мы собрали небольшой локальный тестовый стенд в корпоративной сети, этого вполне достаточно, технология-то нетребовательная. Стенд – два сервера с Nginx, да настройка двух IP-адресов на одно имя, TTL занижен. Все готово, приступаем.

Вооружившись литературой, мы пропустили шаг тестирования “пингами”. Все равно подобные инструменты выбирают один из двух IP-адресов, и это никак не регламентируется. Сразу приступаем к натурным испытаниям при помощи curl с настройками по умолчанию (IP-адреса изменены):

curl -v 'https://dnsrr.test.local'
* Trying 5.6.7.300:443...
* connect to 5.6.7.300 port 443 failed: Время ожидания соединения истекло
* Trying 1.2.3.256:443...
* Connected to dnsrr.test.local (1.2.3.256) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none


Ну, какое-то переключение есть. Вот только тайм-аут по умолчанию – 1 минута. Можно его, конечно, скрутить вниз, но ведь никто не будет менять параметры у себя. Но давайте ради эксперимента все же попробуем:

curl --connect-timeout 2 -vs 'https://dnsrr.test.local' -o /dev/null
* Trying 5.6.7.300:443...
* After 998ms connect time, move on!
* connect to 5.6.7.300 port 443 failed: Время ожидания соединения истекло
* Trying 1.2.3.256:443...
* Connected to dnsrr.test.local (1.2.3.256) port 443 (#0)
* ALPN, offering h2


Ну, в принципе, оно работает, пускай и в очень лабораторных условиях. А вот Postman отказался воспринимать DNS RR. Хорошо, попробуем подключиться “реальными приложениями” – Chrome, Firefox. Все становится несколько интереснее:

  • Если один из балансировщиков полностью недоступен, Chrome требуется около 15 секунд на переключение, Firefox – около 5
  • Если на одном из серверов не отвечает порт 80/443, оба браузера переключаются за 2-3 секунды

На мобильных устройствах Safari и Chrome (Android) могут “залипнуть” на достаточно продолжительно время, вплоть до 20–30 секунд. Клиенты в приложениях мы не тестировали, предполагаем, что нам придется дописывать логику для резолва всех IP из записей и обработку доступности-недоступности балансировщиков.

Сыровато, но хоть какой-то результат.

Вместо заключения


DNS Round Robin используется большинством интернет-гигантов, так что она, конечно же, имеет право на жизнь. Скорее всего, мы чего-то не учитываем.
Из плюсов технологии: можно делать две технически независимые точки для подключения, есть шанс, что падение одной точки не заденет другую.
Без минусов никуда: веса настроить нельзя, распределение клиентов как повезет
Опосля всех рассуждений и мысленных экспериментов, подкрепленных натурными проверками, мы остановились на следующем:
  1. Все новое – хорошо забытое старое, чем проще – тем лучше, минус на минус дает плюс. DNS-балансировке быть, хотя бы в продолжительном пилотном режиме.
  2. Чтобы не настроить подпорок и улучшить доступность, вторую точку входа (балансировщик) мы будем размещать в облаке
  3. На начальном этапе – пропускаем трафик на наши площадки, если они не отвечают – отдаем заглушку < — Мы где-то здесь
  4. Доработка наших систем для работы без доступности всех макро- и микросервисов. Например, можно показывать каталог товаров, но отключать корзину.
  5. Доработка наших систем для работы в распределенном режиме: синхронизации, блокировки и весь остальной набор головной боли. Это поможет нам балансировать трафик и направлять на “локальную“ площадку относительно пользователя. В идеале – балансировка на удаленную, если локальная недоступна.

Комментарии (8)


  1. amarao
    23.12.2021 18:15
    +1

    У "гигантов" DNS в RR - это эникаст адреса, которые в первую очередь делают шардирование, а не резервирование. Т.е. они отдают пачку адресов, которые ведут на пачку серверов, чтобы если конкретный сервер воспламенился, то это задело не всех, а только запросы части клиентов.

    Нормальное резервирование высокого уровня делают с участием сети. Например, делают ibgp на пачку серверов, у которых med разный. Как только предыдущий победитель сдох, автоматически есть следующий, и переключение занимает единицы секунд (или даже меньше).


  1. lexore
    23.12.2021 18:18
    +1

    Попробуйте BGP балансировку. Она гораздо более управляемая, чем DNS.

    Одна и та же /24 подсеть анонсируется с обоих площадок в интернет. ip адрес сайта входит в эту /24 сеть. Дальше ваши сетевые инженеры уже подкрутят распределение трафика между площадками. Хоть active/standby, хоть 50/50.

    Можно настроить одну площадку, как active, а вторую, как standby. Это удобно с точки зрения того, где держать мастер БД.

    Кстати, правильная DNS балансировка - это когда какой-то сервис чекает доступность площадки. И отдает ее IP адрес, только если она живая. Как в кубере, например.


    1. myz0ne
      23.12.2021 21:44

      Как с bgp-балансировкой и вышеуказанной схемой предлагаете обрабатывать перестроение машрутов у клиентов? Судя по ripestat это довольно часто происходит. Представьте что посередине tcp-сессии у кого-то на пути трафика поменялись приоритеты и трафик клиента полетел на другую площадку на другой сервер, которому это tcp-соединение совершенно незнакомо.

      Я примерно представляю как это решается, но в вашей схеме с "ip адрес сайта входит в эту /24 сеть" это не особо очевидно.


      1. lexore
        24.12.2021 15:07

        Судя по ripestat это довольно часто происходит.

        Смотря что считать "часто". Например, раз в сутки или раз в неделю - это часто или нет?) На ровном месте маршруты не меняются так, чтобы трафик всея рунета стал течь в другой ДЦ. Это какие-то изменения или аварии. А они происходят не так часто. Кроме того, у сетевых инженеров огромные возможности для управления анонсами для разных сетей.

        С другой стороны, web - это на 99% короткие tcp сессии. Время их жизни измеряются секундами, не минутами. Браузер умеет в переповторы. Поэтому, клиенты почти не чувствуют результатов перестроений.

        Я это рассказываю, имея опыт нескольких лет работы в ivi.ru. Там годами используются и несколько ДЦ, и CDN в десятках городах. И все работает не основе анонсов сетей по BGP.


        1. myz0ne
          24.12.2021 16:51

          Ну вот сейчас посмотрел для https://stat.ripe.net/widget/bgplay#w.resource=91.233.218.122 и это 242 события за два дня. Понятно что не все приведут к тому что трафик полетит в другой ДЦ и если не мониторить те же rst-пакеты, то про проблему можно и не заметить. Опять же если это статика, наверное даже клиенты не всегда её замечают или просто перезагружают страницу. Для statefull клиентов она заметна сильнее.

          Что самое плохое - чтобы заметить её надо знать что она моет проявиться и кто в группе риска. В основном это клиенты, которые находятся где-то посередине между двумя ДЦ. Более того, подобную проблему находил и репортил гуглу с их глобальными ип-адресами.


  1. Dzzzen
    24.12.2021 09:45
    +1

    Google DNS 8.8.8.8 больше не поддерживает DNS RR

    https://habr.com/ru/company/southbridge/blog/282638/

    DNS Round Robin has never been an effective means of load-balancing, and is less so today, as applications switch from gethostbyname to getaddrinfo for IPv6 support


    1. minaevsergei Автор
      24.12.2021 18:48

      Перепроверили резолв на 8.8.8.8 - на нашей внешней тестовой среде отдает два IP адреса для одной A записи.

      Cloudflare DNS тоже отдает два IP.


      1. Dzzzen
        25.12.2021 12:33

        DNS-сервер не только должен отдавать два IP-адреса, но еще и менять их местами. Можно несколько раз запустить nslookup и проверить, что порядок меняется.

        Кстати, сейчас проверил, но 8.8.8.8 опять поддерживает RoundRobin. Наверное, почили по просьбам трудящихся