Инженерная практика Межотраслевые

Чужой парк из 12 VDS: аудит за 6 часов, порядок за месяц

Веб-студия передала нам 12 VDS, где «раз-два в неделю что-нибудь стабильно падает». Аудит за 6 часов, обновление парка за 1,75 ч вместо шести, wiki на каждый сервер и мониторинг в чате.

Выполнено
Аудит чужого парка из 12 VDS за 6 часов — кейс бюро

Самое опасное в чужом парке серверов — не то, что в нём сломано. Сломанное видно. Опасно то, о чём никто не помнит: правило фаервола, добавленное «на ходу» и не сохранённое, swap, вписанный в fstab с ошибкой, самописный конфиг nginx, который живёт только в голове ушедшего админа. Поэтому приём парка мы начинаем не с починки, а с описи — и только потом трогаем боевое.

Этот кейс — про первый месяц такой работы: как незнакомые 12 VDS со стабильным фоном аварий стали парком, где у каждого сервера есть страница в wiki, у каждой работы согласованное окно, а у мониторинга — человек, который на него отвечает.

Снапшот

Отрасль конечного клиента digital-агентство, разработка интернет-магазинов на Битрикс
Конечный клиент веб-студия «Медиастудия», Россия
Формат сотрудничества прямой контракт ИП↔ИП: 3 месяца с пролонгацией, подписан по ЭДО
Тип проекта приём парка на поддержку: аудит, первая волна наведения порядка, постановка процесса
Объём работ 12 VDS, из них 4 под внутренние сервисы студии (GitLab, облако, бэкапы, мониторинг)
Дата проекта 4 июн 2024 – 26 июл 2024 (53 дня)
Трудозатраты 11,25 ч по пяти задачам трекера
Команда 3 специалиста (руководитель проекта · инженер-сисадмин · инженер)
Технологический стек CentOS 7 / Ubuntu · ISPmanager · MariaDB 10.4 · nginx · Apache httpd · Zabbix 6.4 · fail2ban
Сдано аудит всех 12 VDS с wiki-описаниями, обновлённый парк, мониторинг в общем чате, регулярный цикл обновлений как процесс

Постановка задачи

К нам пришла веб-студия: Битрикс, немного Laravel, десятки клиентских сайтов и 12 VDS у одного хостера. Прежний админ ушёл, документации нет. Запрос техлид сформулировал честно: «Условно раз или два в неделю что-нибудь стабильно падает или ломается. То база решит сама перезапуститься по какому-то там своему таймеру, то озу закончится, то боты на сайт придут». Свой Zabbix у студии был и выдавал от 1 до 12 алертов в день.

Хотели четыре вещи, и мы приводим их в формулировке клиента: наладить стабильность, оперативнее реагировать на проблемы, регулярно ставить обновления безопасности, выполнять серверные работы по запросу. Выбирали из трёх компаний. Решение дозрело ещё до договора: у студии упала сеть на железном сервере, и мы откликнулись за минуты. Клиент успел починить сам, поправив MAC-адрес, и написал в чат: «можно мне к вам лучше?» Через неделю договор ушёл по ЭДО.

У техлида студии при такой передаче два страха, и оба обоснованны. Первый: подрядчик начнёт «наводить порядок» широкими мазками и уронит боевые магазины, которые годами работали на недокументированных костылях. Второй, противоположный: подрядчик утонет в аудите и месяцами не сделает ничего осязаемого. Балансировать пришлось на живом парке, где каждая перезагрузка по определению лотерея: никто ещё не знает, что именно на этом сервере не переживёт ребут.

Как мы это сделали

1. Аудит со счётчиком времени, а не «исследование». Прошли все серверы по списку: примерно 30 минут на машину, 6 часов на парк. Оценку скорректировали публично, прямо по ходу работ: после шести описанных серверов стало ясно, что в исходные 4 часа не уложимся. На каждый сервер завели страницу в wiki, на выходе собрали документ рекомендаций: swap, единый лог, fail2ban, бэкапы. Дальше клиент сам нарезал из этого документа задачи в трекере — каждая ссылается на аудит, ничего не делается «по памяти».

2. Чужой мониторинг вместо своего. У студии уже был Zabbix: строить параллельный означало бы потратить часы и получить два источника правды. Вместо этого бот клиента подключили в общий рабочий чат и сразу договорились об алерт-гигиене: только важные и критические триггеры, и только по серверам, а не по каждому сайту. Иначе один упавший сервер с полусотней сайтов засыпает чат полусотней сообщений. «Ок, давайте пока критические». С этого дня аварии и реакции на них видят обе стороны, в одном месте, с отметками времени.

3. Обновление парка как процедура, а не подвиг. Клиент исходил из получаса на сервер и предлагал резать парк на группы: иначе 6 часов, весь месячный бюджет. Мы предложили другое: согласованное окно, на связи дежурный с доступом к консоли хостера («при обновлении всегда есть шанс, что сервер не вернётся из ребута») и весь парк за один заход. Десять серверов из согласованного списка обновили за 1,75 часа; облако сознательно не трогали до переноса, а GitLab обновлял другой инженер в рамках отдельной задачи. В задачу легли выгрузки обновлённых пакетов по каждому серверу: MariaDB, zabbix-agent, ядро. Заодно обновление вскрыло на центральном сервере PHP 7.2 с истёкшим сроком поддержки (с ноября 2020). Риск зафиксировали письменно.

4. Первая волна порядка — точечно, по рекомендациям аудита. Swap добавили везде, где его не было, и везде одинаково, по одному и тому же пути. А вот от переразметки в отдельный раздел отказались вместе с клиентом: это VDS, загрузиться с live-cd не выйдет, и файла достаточно. На всех серверах с панелью собрали единый access-лог nginx, сохранив логи пользователей по их сайтам: теперь ботов и DDoS видно одним tail. Самое благодарное — магазин, где БД раньше падала «по два-три раза в день»: нашёлся swap, вписанный в fstab с ошибкой и не подключавшийся после ребута, буфер MySQL срезали с 4 до 3 ГБ под реальную базу около 3 ГБ, а наполовину настроенный nginx-кэш довели и поставили TTL в одну минуту: «тут задача именно всплески сгладить, а не всё закэшировать». Девять дней наблюдения, ни одного падения — задачу закрыли.

5. Процесс — с первого месяца, по живым прецедентам. Правила не писали заранее — их фиксировали после первого же столкновения. Низкоприоритетная задача съела часы, нужные на обновления? Договорились: работы идут строго по приоритету клиента или по согласованию, а сделанное вне плана можно перенести в следующий счёт. Redmine неудобен для обсуждений? Чат — для обсуждения, трекер — для фиксации факта, оценки и часов; задачи после обсуждения заводим мы, с пометкой клиента «согласовано». Антивирусный скан клиентского пользователя 20 минут грузил CPU всем соседям? Предложили внести в договор право убивать процессы, мешающие другим клиентам: эту практику принесли с собственного хостинга. К концу июля клиент попросил главное: «чтобы мне не нужно было самому вспоминать, что нам нужно обновить серваки». Завели регулярную ежемесячную задачу — с тех пор обновления идут циклами, без напоминаний.

Что пошло не так

Без этого раздела кейс был бы неправдой. При настройке единого лога инженер затёр правленные вручную nginx-конфиги с проксированием, и статика одного сервиса начала отдавать 404. Клиент заметил минут через десять, ещё примерно столько же ушло на починку. Дальше — работа над причиной, а не над симптомом: эти конфиги внесли в wiki, проверили, что панель бэкапит весь /etc (полностью раз в неделю, изменения ежедневно). Второй эпизод поймал сам мониторинг: после ребута один сервер пропал из Zabbix на 7 минут. Правило фаервола на порт агента когда-то добавили «на ходу» и не сохранили — перезагрузка его стёрла. Оба случая — ровно те мины, ради которых чужой парк сначала описывают и только потом перезагружают.

Был и эпизод подлиннее: вечером после обновления центральный сервер держал LA выше 10, и около двух часов обе команды вместе искали виновника. Им оказался «призрачный» node-процесс давно удалённого с диска проекта: он жил в памяти до ребута, а после перезагрузки пытался стартовать заново и грузил CPU. Попутно базе подняли innodb_buffer_pool с 1 до 1,5 ГБ, а клиент сделал свой вывод: разносить проекты по разным пользователям.

Результаты

Метрика Значение
Аудит парка 12 VDS, ~30 мин на сервер, 6 ч по трекеру, wiki-страница на каждый сервер
Обновление парка 10 серверов за 1,75 ч — против 6 ч, которые закладывал клиент из расчёта 0,5 ч/сервер
Вскрытые риски PHP 7.2 на центральном сервере (поддержка кончилась в 2020) — зафиксирован письменно
БД проблемного магазина падала «по два-три раза в день» → 0 падений за 9 дней наблюдения, задача закрыта
Мониторинг алерты Zabbix в общий чат: важные + критические, посерверно
Процесс регулярная ежемесячная задача на обновления + правило приоритетов + право убивать процессы-вредители в договоре
Трудозатраты периода 11,25 ч по трекеру

Если коротко: за первый месяц незнакомый парк стал описанным, обновлённым и наблюдаемым. Фон «раз-два в неделю что-нибудь стабильно падает» не исчез по волшебству (боты никуда не делись, впереди ещё были переносы и миграции), но каждое падение теперь видели бот и инженер, а не клиент по жалобе конечного заказчика. И главное, у обновлений, перезагрузок и правок конфигов появился ритуал: окно, дежурный, отчёт.

Процесс

Фаза Длительность Результат
Знакомство и договор 07.05 – 03.06 выбор из трёх подрядчиков, договор ИП↔ИП на 3 месяца с пролонгацией, ЭДО
Аудит и мониторинг 04.06 – 06.06 12 VDS описаны в wiki, документ рекомендаций, Zabbix-бот в общем чате
Первая волна порядка 10.06 – 20.06 парк обновлён за один заход, swap и единый лог везде, БД магазина стабилизирована
Постановка процесса 14.06 – 26.07 правило приоритетов, фиксация задач в трекере, регулярная задача на ежемесячные обновления

Фазы перекрываются: правила процесса рождались из инцидентов первой волны, а договорённость о регулярных обновлениях созрела к концу июля, поэтому сумма фаз не равна календарю.

Команда

  • Инженер-сисадмин (бюро) — аудит, обновление парка, swap, единый лог, стабилизация БД
  • Инженер (бюро) — аудит, оценки, постановка процесса
  • Антон Херсун, Xaver Pro — руководитель проекта

Если вам достался парк серверов без документации и без прежнего админа — пришлите список машин и то, что о них известно. Мы посмотрим, выделим узкие места и вернёмся с фиксированной оценкой в часах. Аудит парка бесплатный.

Прислать список серверов →

Прокрутить вверх