Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Обновление сервера без простоя

Обновления сервера без простоя: от unattended-upgrades до rolling-подхода

Как обновлять сервер и не ронять сервис: unattended-upgrades для безопасности, maintenance windows, порядок обновлений, проверки после и rolling-обновление парка серверов.

Прямой ответ

«Сервер не обновлялся 400 дней» и «обновил — всё легло» — две стороны одной ошибки: обновления делаются нерегулярно и без процесса. Рабочая схема из трёх слоёв: безопасность — автоматически (unattended-upgrades ставит security-патчи сам: незакрытая CVE в nginx/OpenSSH — больший риск, чем автоматическое обновление — SSH-hardening); остальное — по расписанию (maintenance-окно раз в месяц: полный apt upgrade, чтение changelog'ов мажорных пакетов, проверка сервисов после — healthcheck-привычка); парк — последовательно (rolling-подход: обновляем по одному серверу, каждый выходит из обновления проверенным до начала следующего — стратегии деплоя — та же логика, что для приложений). Обязательная страховка — бэкап перед окном (снапшот VPS или pgBackRest для базы) и порядок: зависимости и рантаймы раньше приложений, ядро — с плановым ребут-окном (живой сервер без ребута месяцами работает на старом ядре — needrestart показывает, какие сервисы ждут перезапуска). Дистрибутивный релиз (22.04 → 24.04) — отдельный проект с тестовым прогоном, не «apt dist-upgrade в пятницу».

Автоматика безопасности: unattended-upgrades

Настройка (Ubuntu/Debian): apt install unattended-upgrades, dpkg-reconfigure -plow unattended-upgrades — дефолт: security-репозиторий применяется автоматически ежедневно. Уточнения в /etc/apt/apt.conf.d/50unattended-upgrades: Unattended-Upgrade::Automatic-Reboot "false" (ребут — только в плановом окне: автоматический ребут в 6 утра без предупреждения — классика неприятных сюрпризов; true с Automatic-Reboot-Time — для одиночных некритичных серверов); Package-Blacklist — исключения для чувствительных пакетов (Postgres-мажор не должен обновляться сам); Unattended-Upgrade::Remove-Unused-Dependencies. Контроль: /var/log/unattended-upgrades/ (что ставилось), apt list --upgradable (что накопилось вне security), алерт при ошибках прогона (timer-юнит падает молча — лог-чек в мониторинг). Что автоматика не закрывает: мажорные версии (переход PostgreSQL 15→16 — ручная миграция с дампом), конфигурационные конфликты (conffile-промпты — в неинтерактивном режиме дефолт «оставить свой», изменения дистрибутива копятся — читать при плановых окнах), и EOL-релизы (автопатчи кончаются вместе с поддержкой — календарь EOL дистрибутива в задачах).

Maintenance-окно: регулярный ручной проход

Ежемесячный ритуал (30–60 минут на сервер): (1) бэкап/снапшот до начала — откат вместо героизма; (2) apt update && apt list --upgradable — взгляд на список: мажорные скачки (nginx 1.22→1.26, python-пакеты) — glance на changelog/release notes (сломанные конфиги, дефолты); (3) apt upgrade — conffile-вопросы решаются осознанно (diff показан — смотреть, что меняется); (4) needrestart -r l — какие демоны работают со старыми библиотеками в памяти и ждут рестарта; рестарт сервисов — по одному с проверкой (systemd: restart + healthcheck + взгляд в лог); (5) проверки после: ключевые эндпоинты отвечают, метрики в норме (дашборд), логи без новых ошибок — диагностика при аномалии; (6) ядро обновилось — запланировать ребут-окно (до ребута работает старое ядро — уязвимость ядра остаётся актуальной: livepatch-сервисы (Canonical Livepatch) закрывают критичные CVE без ребута — опция для критичных контуров). Фиксация: окно в календаре, чек-лист в ansible-ранбуке — процесс переживает смену сопровождающего.

Rolling-обновление парка и инфраструктура как код

Несколько серверов — обновление последовательно с проверками: сервер 1 — вывод из балансировки (healthcheck-флап или DNS-снятие), обновление, прогрев, возврат, наблюдение 15 минут, сервер 2... (ровно blue-green/rolling-логика, применённая к ОС); ошибка на первом — стоп и разбор, остальные не тронуты. Автоматизация: ansible-плейбук serial: 1 + пост-проверки (тест эндпоинта) — парк обновляется прогоном с человеческим надзором (ansible-основа). Альтернатива для облачного парка — immutable-подход: сервер не обновляется вовсе — новый образ с актуальной базой разворачивается рядом, трафик переключается, старый уничтожается (обновление = деплой: воспроизводимо и откатно; цена — инфраструктура под образы/Packer, оправдана от десятка серверов). Особый случай — база данных: rolling не применим (одна инстанция), обновление БД — в отдельном окне с пре-бэкапом и планом отката (PITR-страховка), мажоры — через pg_upgrade/dump-restore с тестом на копии заранее.

Практический сценарий: релиз Ubuntu LTS и год рутины

Годовая рутина: security-патчи ежедневно автоматически; первое воскресенье месяца — окно: снапшот, upgrade (в среднем 10–30 пакетов), needrestart-рестарты, проверки — 40 минут, ноль простоей за год (единственный инцидент — обновление библиотеки сбросило соединения с БД: рестарт приложения в окне это переживает, клиенты — переподключение — graceful-практики окупились). Отдельный проект — релиз LTS 22.04 → 24.04 (поддержка старой кончается): (1) клон сервера из снапшота в песочнице — do-release-upgrade на клоне — ловим сломанные конфиги и пакеты (нашли: старый PHP-репозиторий, конфликт nginx-конфига); (2) правки в ansible/конфигах, повторный прогон на клоне до чистого результата; (3) прод — в расширенном окне: снапшот, upgrade (~40 минут), полный прогон смоук-тестов, сутки наблюдения со снапшотом-страховкой; (4) откат не понадобился, но был возможен за 15 минут (снапшот → замена диска/instance). Вывод: рутина сделала мажорный релиз скучным — накопленные «страшные» обновления не сложились в один неподъёмный скачок.

FAQ

Правда ли, что автообновления ломают прод? Ломают реже, чем незакрытые CVE (инциденты эксплуатации известных уязвимостей массовы и автоматизированы); риск автообновлений снижается black-листом чувствительных пакетов, reboot=false и мониторингом после прогона. Статистика лично у каждого своя, но «не обновлять» — гарантированное накопление риска.

Нужен ли livepatch для ядра? Для одиночного сервера — обычно нет (плановый ребут в окне покрывает); для критичных контуров с жёстким SLA — да: критичные CVE ядра закрываются без ребута, стоимость — подписка/сервис дистрибутора.

Как обновлять Docker-хост с запущенными контейнерами? Обновление пакетов — как обычно; ребут хоста перезапускает контейнеры (restart-политики + graceful-обработка сигналов — healthcheck-статья); сами образы приложений обновляются отдельно от ОС (image pull + recreate — деплой, не OS-патчинг); Docker-мажоры — читать release notes (изменения storage-драйверов/runtime редки, но болезненны).

Что делать, если обновление всё же сломало сервис? Порядок: диагностика (лог сервиса, dpkg -l против списка установленных в окне — что изменилось), быстрый откат пакета (apt install pkg=старая_версия — при известной версии) или восстановление из снапшота (полный откат окна); постмортем — пакет-виновник в black-лист/пин, сценарий — в чек-лист окна.

Источники: Debian UnattendedUpgrades wiki, документация Ubuntu, Ansible — ссылки в шапке.