kai.kzLab

Сбой AWS S3 28 февраля 2017 года: как неверный параметр в команде из плейбука остановил S3 в us-east-1

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

28 февраля 2017 года в 9:37 по тихоокеанскому времени (17:37 UTC) инженер AWS запустил команду из утверждённого плейбука, чтобы вывести из работы несколько серверов S3, но один из параметров ввёл неправильно — и из работы ушло гораздо больше серверов, в том числе те, на которых работали подсистемы индекса и размещения. S3 в регионе us-east-1 перестал обслуживать запросы и полностью восстановился только в 13:54, через 4 часа 17 минут.

Вместе с S3 в регионе пострадали консоль S3, запуск новых инстансов EC2, тома EBS, которым нужны были данные из снапшотов, и AWS Lambda. Исправляли после сбоя не человека, а инструмент: теперь он выводит ёмкость медленнее и не даёт опустить подсистему ниже минимально необходимого уровня.

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

ВопросОтвет
Когда28 февраля 2017, 9:37–13:54 PST (17:37–21:54 UTC)
Гдерегион us-east-1 (Северная Вирджиния)
Что делалиотлаживали медленную работу биллинга S3 и выводили из работы несколько серверов одной из его подсистем
Что пошло не такодин из параметров команды ввели неправильно, и из работы ушло намного больше серверов
Что сломалосьподсистема индекса — метаданные и расположение всех объектов региона — и подсистема размещения, которая выделяет место под новые объекты. Обе пришлось перезапускать целиком
Кого ещё заделоконсоль S3, запуск новых инстансов EC2, тома EBS из снапшотов, AWS Lambda
Почему долгополностью эти подсистемы в крупных регионах не перезапускали много лет, а S3 за это время сильно вырос
Что изменилиинструмент выводит ёмкость медленнее и не опускает подсистему ниже минимума; проверка других инструментов; дробление индекса на ячейки; консоль страницы статуса в нескольких регионах

Хронология сбоя AWS S3

Время (PST)Что произошло
9:37Инженер S3 по утверждённому плейбуку запускает команду. Из-за неверного параметра выведено больше серверов, чем планировали, в том числе серверы подсистем индекса и размещения
Сразу послеОбе подсистемы требуют полного перезапуска. S3 в us-east-1 не обслуживает запросы, вместе с ним страдают EC2, EBS и Lambda
9:37–11:37Статусы сервисов на AWS Service Health Dashboard не обновить: консоль администрирования панели сама зависит от S3. Новости идут через Twitter @AWSCloud и баннер на панели
12:26Подсистема индекса набрала достаточно ёмкости: снова работают GET, LIST и DELETE
13:18Индекс полностью восстановлен
13:54Подсистема размещения восстановлена, заработал PUT, S3 работает нормально. Другие сервисы ещё разбирают накопившиеся очереди

Что произошло: одна команда из плейбука

Команда S3 разбиралась, почему система биллинга работает медленнее, чем должна. Часть работы — вывести из эксплуатации небольшое число серверов одной из подсистем, которой пользуется биллинг. Операция штатная: AWS пишет, что с самого запуска S3 опирается на возможность выводить и заменять ёмкость, а подсистемы рассчитаны на потерю заметной её части почти без влияния на клиентов.

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

  • Подсистема индекса хранит метаданные и расположение всех объектов S3 в регионе. Без неё не работают GET, LIST, PUT и DELETE — то есть всё.
  • Подсистема размещения выделяет место под новые объекты при PUT и сама не работает без индекса.

Потеря значительной части ёмкости потребовала полного перезапуска обеих. Пока они перезапускались, S3 в регионе не обслуживал запросы.

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

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

Первым поднимали индекс: в 12:26 он смог отвечать на GET, LIST и DELETE, к 13:18 восстановился полностью. Размещение начало восстанавливаться только после этого и закончило в 13:54. PUT, то есть запись новых объектов, вернулся последним.

AWS уже дробила сервисы на небольшие независимые части — ячейки (cells), чтобы уменьшить радиус поражения и иметь возможность проверить восстановление даже самой большой подсистемы. Индекс S3 собирались разбить дальше позже в 2017 году. После сбоя эту работу начали сразу.

Почему AWS два часа не могла обновить страницу статуса

С начала сбоя и до 11:37 AWS не могла менять статусы сервисов на своей панели Service Health Dashboard. Причина — та же: консоль, через которую панель обновляют, зависела от S3. Клиентам сообщали новости через Twitter и баннер на самой панели. После сбоя консоль перенесли так, чтобы она работала в нескольких регионах AWS.

Уроки для DevOps

1. Защита от неверного ввода — в самом инструменте

Разбор AWS не ищет виноватого: команду запускал авторизованный инженер по утверждённому плейбуку. Проблема названа прямо — инструмент позволил вывести слишком много ёмкости слишком быстро. Исправление тоже в инструменте: вывод ёмкости стал медленнее, и появилась проверка, которая не даёт опустить любую подсистему ниже минимально необходимого уровня. По словам AWS, это не даст неверному вводу вызвать похожий сбой.

Для своих плейбуков то же самое пишется в несколько строк:

- name: Вывести серверы из балансировщика
  hosts: "{{ target }}"
  serial: 1                # по одному серверу
  max_fail_percentage: 0   # первая ошибка останавливает прогон
  pre_tasks:
    - name: Не больше двух серверов за запуск
      ansible.builtin.assert:
        that: ansible_play_hosts_all | length <= 2
        fail_msg: "Цель {{ target }} — это {{ ansible_play_hosts_all | length }} хостов"
      run_once: true

Если вместо двух хостов в target попала вся группа, прогон остановится до первого изменения:

$ ansible-playbook drain.yml -e target=web
...
fatal: [web-01]: FAILED! => {"assertion": "ansible_play_hosts_all | length <= 2", "changed": false, "evaluated_to": false, "msg": "Цель web — это 12 хостов"}

В Kubernetes ту же роль играет PodDisruptionBudget: kubectl drain выселяет поды через Eviction API, а тот отказывает, если после выселения готовых реплик станет меньше, чем minAvailable. Drain в ответ ждёт и повторяет попытку:

error when evicting pods/"api-7d4b9c6f8-kx2lp" -n "prod" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

После сбоя AWS проверила и другие свои эксплуатационные инструменты на такие же защиты. У вас это скрипты вывода серверов, массовые изменения DNS, чистка ресурсов в облаке. Как выглядит скрипт удаления без такой защиты, хорошо видно на сбое Atlassian 2022 года.

2. Редкую операцию надо репетировать

Полный перезапуск индекса никто не делал годами, поэтому никто не знал, сколько он займёт на текущем масштабе. То же с бэкапами: у GitLab в 2017 году ни один механизм бэкапа не сработал, потому что восстановление никто не проверял. Холодный старт, восстановление из бэкапа, переключение на резерв — всё это надо регулярно прогонять и засекать время.

3. Радиус поражения ограничивают архитектурой

Одна подсистема индекса на весь регион означала, что её отказ — отказ всего региона. Ячейки ограничивают поломку частью клиентов и делают восстановление каждой части быстрее и предсказуемее. Тот же принцип у вас — отдельные кластеры, шарды, группы серверов, которые обновляются и ломаются независимо.

4. Страница статуса не должна зависеть от того, о чём сообщает

Панель здоровья AWS не могла сообщить о сбое S3, потому что сама от него зависела. Похожая история была у Cloudflare в 2019 году: дашборд и API шли через её же сеть. Страницу статуса, алертинг и чат дежурных держите в другом регионе или у другого провайдера.

5. Знайте, от чего зависит ваш сервис

Упал S3, а с ним запуск инстансов EC2, тома из снапшотов и Lambda. Если вы в us-east-1, ваш сервис мог упасть, даже не храня ничего в S3 напрямую. Карта зависимостей, включая зависимости облачных сервисов друг от друга, нужна до сбоя, а не во время.

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

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

Реши сам

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

  1. Панель отключили, чтобы не пугать клиентов
  2. Консоль администрирования панели зависела от S3 в том же регионе
  3. Все инженеры были заняты восстановлением
  4. Панель обновляется раз в сутки
Показать ответ

Верный ответ — 2. Инструмент оповещения зависел от того, что сломалось. AWS перенесла консоль так, чтобы она работала в нескольких регионах, а до этого сообщала новости через Twitter и баннер.

Вопрос 2. Инженер ввёл неверный параметр в команду из утверждённого плейбука. Какое изменение надёжнее всего защитит от повторения?

  1. Запретить запуск плейбуков в рабочее время
  2. Проверка внутри инструмента: выводить ёмкость постепенно и отказываться, если подсистема опустится ниже минимума
  3. Требовать от инженеров быть внимательнее
  4. Перенести команду в веб-интерфейс
Показать ответ

Верный ответ — 2. Так и сделала AWS. Люди ошибаются всегда, и «быть внимательнее» — не мера. Проверка в инструменте срабатывает каждый раз, кто бы и в каком состоянии ни запускал команду.

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

Сколько длился сбой AWS S3 в 2017 году? С 9:37 до 13:54 по тихоокеанскому времени 28 февраля, то есть 4 часа 17 минут. Чтение и удаление (GET, LIST, DELETE) начали возвращаться в 12:26, запись (PUT) — последней, после восстановления подсистемы размещения.

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

Какие сервисы пострадали? S3 в регионе us-east-1, а вместе с ним консоль S3, запуск новых инстансов EC2, тома EBS, которым нужны были данные из снапшотов S3, и AWS Lambda. Другим сервисам после восстановления понадобилось время, чтобы разобрать накопившиеся очереди.

Кого AWS назвала виноватым? Никого. В разборе сказано, что команду выполнил авторизованный сотрудник по утверждённому плейбуку, а проблема в том, что инструмент позволил вывести слишком много ёмкости слишком быстро. Такой подход и называют постмортемом без поиска виноватых.

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

В симуляторе DevOps KAI Lab этот разбор стоит в пятом месяце, посвящённом Ansible. После него коллега просит переделать плейбук обновления веб-серверов так, чтобы один прогон не мог положить их все сразу. А постмортем месяца — про прогон роли, который на девять минут уронил nginx на всех веб-серверах.

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

Источники

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