Самое опасное в чужом парке серверов — не то, что в нём сломано. Сломанное видно. Опасно то, о чём никто не помнит: правило фаервола, добавленное «на ходу» и не сохранённое, 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 — руководитель проекта
Если вам достался парк серверов без документации и без прежнего админа — пришлите список машин и то, что о них известно. Мы посмотрим, выделим узкие места и вернёмся с фиксированной оценкой в часах. Аудит парка бесплатный.