kai.kzLab

Сбой Datadog 8 марта 2023 года: как автоматическое обновление systemd отключило сеть на десятках тысяч узлов

Команда KAI Lab · · 8 мин чтения

8 марта 2023 года в 06:03 UTC платформа мониторинга Datadog перестала работать сразу в пяти регионах — US1, EU1, US3, US4 и US5. Причина — автоматическое обновление безопасности systemd на Ubuntu 22.04: при перезапуске systemd-networkd удалил маршруты, которыми управлял сетевой плагин Cilium, и десятки тысяч узлов между 06:00 и 07:00 UTC потеряли сеть.

Регионы Datadog не связаны между собой по сети, но окно автоматических обновлений в ОС по умолчанию одно на всех: с 06:00 до 07:00 UTC. Первые признаки восстановления появились в 09:13 UTC, все сервисы во всех регионах заработали 9 марта в 08:58 UTC, а полностью инцидент закрыли 10 марта в 06:25 UTC.

Главное о сбое в одной таблице

ВопросОтвет
Когда8 марта 2023, 06:03 UTC
Гдерегионы US1, EU1, US3, US4, US5, все сервисы
Причинаавтообновление безопасности systemd; при перезапуске systemd-networkd удалил маршруты Cilium
Масштабдесятки тысяч узлов потеряли сеть между 06:00 и 07:00 UTC
Почему везде сразуокно автообновлений в ОС по умолчанию — 06:00–07:00 UTC, одно для всех регионов
Мониторы клиентовне работали и не присылали алерты
Восстановлениевеб — в 09:13, все сервисы — 9 марта в 08:58, инцидент закрыт 10 марта в 06:25 UTC
Разбор16 мая 2023, блог Datadog

Хронология сбоя Datadog

Время (UTC)Что произошло
8 марта, 06:00–07:00Автообновление systemd срабатывает на узлах в окне по умолчанию, десятки тысяч узлов теряют сеть
06:03Начало сбоя во всех пяти регионах
06:31Первая запись на статус-странице
09:13Первые признаки восстановления: вернулся веб-доступ
16:44Первый крупный сервис объявлен рабочим
9 марта, 08:58Все сервисы работают во всех регионах
10 марта, 06:25Инцидент полностью закрыт
16 маяОпубликован подробный разбор

Что сломалось: systemd-networkd против Cilium

На узлах Kubernetes у Datadog работал сетевой плагин (CNI) Cilium. Он сам прописывает в ядро маршруты и правила маршрутизации, по которым ходят пакеты между контейнерами. Для systemd-networkd, который управляет сетью хоста, эти маршруты «чужие»: их нет в его файлах .network.

У systemd-networkd на такой случай есть две настройки из networkd.conf. ManageForeignRoutes= появилась в версии 246, ManageForeignRoutingPolicyRules= — в версии 249. Обе по умолчанию yes: networkd удаляет маршруты и правила, которых нет в его конфигурации.

На свежем или перезагруженном узле это ничего не ломает. systemd-networkd всегда стартует раньше, чем Cilium успевает прописать свои правила, и удалять ему нечего. Ловушка срабатывает, только если networkd перезапускается на уже работающем узле. Именно это сделало обновление безопасности пакета systemd. Datadog называет это скрытым неблагоприятным взаимодействием в сетевом стеке Ubuntu 22.04 с systemd v249: networkd перезапустился и принудительно удалил маршруты Cilium. Контейнеры на узле остались без сети.

Почему упали сразу пять регионов

Регионы Datadog изолированы: между ними нет прямой сетевой связи. Но у них был общий базовый образ ОС, а в нём — включённый устаревший канал обновлений безопасности. Он ставил пакеты сам, мимо процесса управления изменениями Datadog. Время установки задавала ОС по умолчанию, окно с 06:00 до 07:00 UTC. В Ubuntu за это отвечает таймер apt-daily-upgrade.timer: запуск в 6:00 со случайной задержкой до часа.

Изоляция регионов защищает от сбоя, который распространяется из одного места в другое. От одинакового изменения, которое по часам происходит везде, она не защищает.

Почему восстановление заняло больше суток

Облака повели себя по-разному. Там, где узел достаточно было перезагрузить, восстановление шло намного быстрее, особенно для сервисов с данными. Другой облачный провайдер сразу заменял нездоровый узел новым. Данные на старом узле терялись, их приходилось восстанавливать, а массовая замена машин упёрлась в региональные лимиты провайдера. Datadog называет это thundering herd — «стадо», которое ломится в одну дверь.

Проблема пряталась от обычных проверок. Она проявлялась только при обновлении systemd на работающем узле. Новые узлы и перезагрузки её не показывали.

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

После сбоя Datadog отключила устаревший канал обновлений во всех затронутых регионах и изменила настройку systemd-networkd так, чтобы при перезапуске он не трогал таблицу маршрутизации.

Уроки для DevOps

1. Автообновление — это деплой без ревью и без канарейки

Пакет, который сам ставится на тысячи машин, — такое же изменение прода, как релиз. Проверьте, что делают ваши узлы сами по себе:

# когда узел ставит обновления и включены ли они
systemctl list-timers apt-daily-upgrade.timer
cat /etc/apt/apt.conf.d/20auto-upgrades
# что уже поставилось автоматически
grep -i systemd /var/log/unattended-upgrades/unattended-upgrades.log | tail -n 5

Если в 20auto-upgrades стоит APT::Periodic::Unattended-Upgrade "1";, узел обновляется сам. Для серверов в кластере надёжнее выключить это и выкатывать обновления так же, как всё остальное: новым образом, партиями, с проверкой после каждой.

2. Одинаковое окно везде убивает изоляцию

Даже если автообновления нужны, их окна должны отличаться по регионам и группам узлов. Сначала канареечная группа, через сутки — остальные. Тот же принцип провалился у CrowdStrike, когда обновление контента ушло на все машины сразу: разбор — в статье про сбой CrowdStrike 2024.

3. Хост и CNI делят одну таблицу маршрутов

Если сетью хоста управляет systemd-networkd, а подами — Cilium, Calico или другой плагин, решите, кто владеет маршрутами. Документация systemd даёт для этого прямые настройки:

# /etc/systemd/networkd.conf.d/10-cni.conf — не трогать чужие маршруты и правила
[Network]
ManageForeignRoutes=no
ManageForeignRoutingPolicyRules=no

Проверять старую настройку перезапуском systemd-networkd на рабочем узле не стоит: вы воспроизведёте ровно этот сбой. Маршруты и правила, которые ставит CNI, видно в ip route show table all и ip rule show. Как читать состояние и журналы юнитов, мы разбирали в статье systemd: сервис не запускается.

4. Тестируйте обновление на работающем узле, а не только чистую установку

Ошибка Datadog не проявлялась ни на новых узлах, ни после перезагрузки. Тест, который собирает узел с нуля, пропустит весь класс проблем «пакет обновился под нагрузкой». Похожая слепая зона сработала и в сбое Reddit 2023: обновление сняло метку, от которой молча зависела сеть кластера.

5. Автоматическое восстановление может усилить аварию

Замена нездоровых узлов — хорошая автоматика, пока нездоровых мало. Когда их десятки тысяч, она упирается в лимиты облака и стирает локальные данные. Ограничьте скорость автозамены и знайте, как ведёт себя ваш провайдер при массовом отказе.

6. Мониторинг — тоже зависимость

Если ваш мониторинг — внешний сервис, заранее решите, что делать без него. Нужны простая внешняя проверка «сайт открывается», второй канал алертов и понимание, какие метрики можно снять руками прямо с серверов.

Что проверить у себя завтра:

  • ставят ли ваши серверы обновления сами и в какое время;
  • одинаковое ли это время во всех регионах и кластерах;
  • кто владеет маршрутами на узлах Kubernetes — ОС или CNI;
  • как вы узнаете о проблемах, если ляжет сам мониторинг.

Реши сам

Два вопроса по этому сбою. Ответы — под спойлером.

Вопрос 1. Почему сбой случился одновременно в пяти независимых регионах?

  1. Все регионы работали в одном дата-центре
  2. На всех узлах сработало автообновление в одном и том же окне по умолчанию, 06:00–07:00 UTC
  3. Атака на сеть Datadog
  4. Ошибка в коде приложения Datadog
Показать ответ

Верный ответ — 2. Регионы не связаны по сети, но у них был общий образ ОС с одинаковым расписанием обновлений. Изоляция не помогает против одного и того же изменения, которое везде происходит по часам.

Вопрос 2. Почему перезагруженные узлы работали нормально, а обновлённые на ходу — нет?

  1. После перезагрузки ставилась другая версия systemd
  2. При загрузке systemd-networkd стартует раньше, чем Cilium прописывает свои правила, и удалять ему нечего
  3. Перезагрузка отключает Cilium
  4. Перезагрузка сбрасывает лимиты облака
Показать ответ

Верный ответ — 2. Маршруты стирались только при перезапуске networkd на работающем узле, когда правила Cilium уже были в ядре. Поэтому там, где узел можно было просто перезагрузить, восстановление шло быстрее.

Частые вопросы

Что случилось с Datadog 8 марта 2023 года? Автоматическое обновление безопасности systemd перезапустило systemd-networkd на узлах Ubuntu 22.04. Он удалил маршруты сетевого плагина Cilium, и десятки тысяч узлов в пяти регионах потеряли сеть.

Сколько длился сбой Datadog? Сбой начался 8 марта в 06:03 UTC. Все сервисы во всех регионах заработали 9 марта в 08:58 UTC, а полностью инцидент закрыли 10 марта в 06:25 UTC.

Какие регионы пострадали? US1, EU1, US3, US4 и US5, во всех сервисах.

Что Datadog изменила после сбоя? Отключила устаревший канал автоматических обновлений безопасности во всех затронутых регионах и настроила systemd-networkd так, чтобы при перезапуске он не менял таблицу маршрутизации.

Пройти похожий сбой самому

В симуляторе DevOps KAI Lab восьмой месяц посвящён мониторингу. В нём есть разбор сбоя Datadog и дежурство в ночь Чёрной пятницы, где среди алертов — узел Kubernetes в NotReady. А в пятом месяце, про Ansible, есть тикет «Playbook упал на одном сервере с „Could not get lock“» — тоже про то, что сервер делает сам, пока вы не смотрите. Все разборы собраны в подборке 18 сбоев, которые должен знать DevOps-инженер.

Начать можно бесплатно: тест навыков и первые задания первого месяца.

Источники

Читать дальше