Как мы провели «пересадку сердца» у бегущего марафон, миграция 50 000 АРМ с ALSE 1.7 на 1.8 через Ansible без простоя
Привет, Хабр. Я Александр Габидуллин, старший инженер внедрения в Группе Астра. Основная часть моей работы — автоматизация установки и разворачивания наших продуктов. Нередко заказчик ставит задачу, для которой нет готового «коробочного» решения — тогда я создаю своё.
Один из таких случаев — обновление парка из десятков тысяч рабочих станций с ALSE 1.7 на 1.8 без остановки бизнес-процессов.
Перед нами стояла задача: обеспечить бесшовное мажорное обновление десятков тысяч рабочих станций крупного промышленного холдинга с ALSE 1.7 на 1.8. Жёсткие требования исключали компромиссы: нулевой простой для пользователей, гарантированная сохранность кастомной экосистемы и усиление настроек безопасности в процессе.
В этой статье я расскажу, как мы создали Ansible-коллекцию, которая превратила рутинное обновление в промышленный процесс с 98.2% успешных запусков с первого раза.
1. Цель: не только обновить, а трансформировать
Мы обеспечивали ключевой этап цифровой трансформации, где мажорное обновление ОС было стратегическим шагом для повышения безопасности, стабильности и управляемости всей ИТ-инфраструктуры.
Ключевые требования:
-
Абсолютная бесшовность процесса для пользователей. Инженер в офисе или на месторождении не должен был столкнуться с внезапным «синим экраном», потерей данных или нерабочим ПО после мажорного обновления. Его рабочий день и бизнес-процессы не должны были прерваться ни на минуту. Фактически, мы должны были провести сложнейшую операцию, пока «пациент» продолжал работать.
-
Гарантированная сохранность всей кастомной экосистемы. Десятки специализированных пакетов, корпоративных сертификатов, уникальных конфигураций сетевых подключений и проприетарное ПО. Каждый такой элемент был критически важен для конкретного бизнес-процесса, и его потеря была недопустима.
-
Реальный нулевой простой бизнес-сервисов. В условиях круглосуточной работы предприятия простои означали прямые финансовые потери.
-
Усиление настроек безопасности. Требовалось гарантировать, что в процессе мажорного обновления ни одна из защитных мер (настройки ЗПС, блокировки интерпретаторов) не будет скомпрометирована.
2. Первые версии утилиты мажорного обновления: было сложно

Изначально за основу нашего процесса мы взяли штатные инструменты мажорного обновления — astra-full-upgrade (для графического режима) и astra-console-upgrade (для консоли). Их концепция элегантна и продумана: это полноценная установка новой ОС с последующим переносом данных и пользовательских настроек, а не просто «апдейт» пакетов поверх существующей системы.
Как это работало в первых версиях «из коробки»:
-
Предварительные проверки: Утилита проводила строгий аудит системы на соответствие требованиям: наличие свободного пространства, достаточного для создания резервных копий, проверка режима ЗПС, верификация пакетной базы на возможность переноса в целевую ОС .
-
Загрузка пакетов: Система скачивала все необходимые пакеты новой версии ОС (ALSE 1.8) в кеш и сторонние пакеты из внешних репозиториев, если стояло внешнее ПО, что позволяло провести установку впоследствии даже без доступа к сети.
-
Создание целевой системы: На месте исходной системы сначала создается образ (резервная копия), затем производиться загрузка с этого образа, разворачивание chroot-окружения с использованием исходной дисковой конфигурации и разворачивание целевой системы в этом chroot-окружении. Это обеспечивает отказоустойчивость на всем процессе проведения мажорного обновления. Ключевой особенностью было то, что разделы
/home,/bootи/boot/efiне копировались, а переиспользовались — это гарантировало сохранность пользовательских данных и загрузчика. -
Перенос пользовательских данных и конфигураций: После активации мажорного обновления при следующей перезагрузке происходил переход на новую систему. Старая ОС оставалась на диске в виде резервной копии, предоставляя возможность отката с помощью утилиты
astra-revert-upgrade.
Где мы столкнулись со стеной:
Утилита изначально разрабатывалась для работы в связке с системами управления конфигурациями и не содержала собственного механизма массового запуска. Масштабирование, контроль выполнения и оркестрация сознательно выносились на уровень инфраструктуры заказчика.
Такое разделение ответственности задало рамки дальнейшего внедрения. В ходе проекта мы столкнулись с рядом практических задач, связанных с интеграцией, расширяемостью и устойчивостью процесса обновления:
-
Масштабирование под парк рабочих станций
Изначально утилита была рассчитана на работу в связке со средствами управления конфигурациями, поэтому сама по себе не включала механизм массового запуска. На практике это оказалось вполне удобным: мы быстро интегрировали её с существующей у заказчика системой, благодаря чему централизованный запуск и контроль мажорного обновления заработали без необходимости добавлять в утилиту собственный сложный оркестратор.
-
Расширение конфигурации под нетипичные сценарии
Базовая конфигурация (upgrade.conf.yaml) специально сделана предсказуемой и безопасной по умолчанию — чтобы утилита надёжно работала в стандартных окружениях. В ходе проекта стало понятно, что заказчику требуется больше гибкости, и здесь встроенный механизм скриптов сыграл ключевую роль.Мы использовали возможность подключения пользовательских скриптов на разных этапах процесса, что позволило без изменения утилиты реализовать кастомные требования: от установки специфичных пакетов до интеграции нестандартных политик.
-
Адаптация под индивидуальные процессы заказчика
Во время внедрения выяснилось, что некоторые требования — например, взаимодействие с пользователем через GUI или интеграция с корпоративными системами заказчика — выходят за рамки типовых задач утилиты. Эти сценарии мы закрыли через внешние инструменты и расширения, сохранив при этом стабильность и чистоту базового функционала.
-
Дополнительные проверки и устойчивость к политике безопасности
Разнообразие настроек и политик на рабочих станциях требовало расширить перечень предварительных проверок. Мы оперативно добавили необходимые механизмы как в коллекцию, так и в саму утилиту, благодаря чему инструмент стал ещё устойчивее и надёжнее.
Пару примеров для понимания: Проверка umask, если на обновляемой машине выставлено umask 0027, то это затрагивало не только пакеты утилиты мажорного обновления.
Проверка включен или нет digsig ( ЗПС ), так как первые версии утилиты некорректно работали в режиме ЗПС.
3. Ansible в дело: Рождение коллекции и Push-модели
Так родилась идея создать собственную Ansible-коллекцию. На первом этапе мы реализовали push-модель, которая позволяла администратору централизованно и принудительно запускать мажорное обновление на группах хостов. Это был продуманный оркестратор всего процесса, а не просто набор скриптов.
Что это дало на практике:
— Единый контур управления для сотен машин через Ansible Inventory
— Сквозная идемпотентность — повторный запуск роли не ломал систему
— Расширенные предварительные проверки (prechecks), выходящие за рамки штатной утилиты:
Архитектурные особенности реализации
Код роли был разбит на теги и этапы, это обеспечивало гибкость, переиспользуемость и возможность пропускать шаги для оптимизации времени обновления:
# Основные этапы выполнения роли:
- precheck.yml # Базовая проверка готовности
- check_version_alse.yml # Проверка версии ОС
- preparation.yml # Установка зависимостей
- util_install.yml # Установка утилиты мажорного обновление
- full_update.yml # Минорное обновление с 1.7.x до 1.7.6
- force_migration.yml # мажорное обновление с 1.7.6 до 1.8.1
- rollback_migration.yml # Откат при необходимости
Ключевые технические инновации:
1. Графический интерфейс процесса — создание прогресс-баров и уведомлений на рабочем столе и экране блокировки через кастомные bash-скрипты, запускаемые через systemd:
- name: Run progress.sh
command: systemd-run /bin/bash "{{ migrate_tmp_dir }}/progress.sh"
2. Гибкая система тегов — возможность запускать отдельные этапы (только подготовку, только минорное обновление, только мажорное обновление):
ansible-playbook main.yml --tags "prepare"
ansible-playbook main.yml --tags "precheck"
ansible-playbook main.yml --tags "update"
3. Кастомизация через переменные — единый конфиг позволял выбирать режимы работы:
migrate_migration_status: true/false # Включить мажорное обновление
migrate_update_status: true/false # Включить минорное обновление
migrate_rollback_status: true/false # Включить откат обновления
migrate_digsig_status: true/false # Управление ЗПC
Результат: Мы получили не просто обертку вокруг штатной утилиты, а полноценную систему оркестрации, которая превращала сложный многоэтапный процесс в одну команду ansible-playbook, выполняемую для всего парка рабочих станций одновременно. Это был качественный скачок от ручного управления к промышленной автоматизации.
4. Тесты, тесты… и первые грабли

Первые прогоны в тестовом контуре выявили спектр непредвиденных сценариев. Казалось , мы предусмотрели все в prechecks, но реальность внесла свои коррективы.
С какими «граблями» мы столкнулись
-
Тонкости работы с ЗПС: Автоматическое отключение digsig через Ansible не всегда срабатывало предсказуемо. В некоторых конфигурациях требовалась дополнительная перезагрузка для полной выгрузки модулей безопасности из памяти ядра, иначе утилита обновления не запускалась. Поэтому команда разработки реализовала возможность мажорного обновления без отключения ЗПС.
-
Сетевые артефакты: В изолированных сегментах сети пакеты из локальных репозиториев могли «зависать» при параллельной загрузке на 100+ машин, вызывая таймауты apt. Но благодаря заложенной функциональности в утилиту мажорного обновления, имелась возможность делать тонкую настройку параметров загрузки.
-
Конфликты версий пакетов: Кастомные сборки ПО заказчика иногда требовали интерактивных ответов во время установки. Это выливалось в «тихие» сбои, когда обновление формально проходило успешно, но критичное бизнес‑приложение отсутствует в новой системе.
Как мы выстроили процесс тестирования
Мы создали пирамиду тестовых стендов
-
Базовый стенд — «чистая» ALSE 1.7.6 для отладки идеального сценария
-
Нагруженный стенд — системы с имитацией активной работы пользователей (открытые приложения, смонтированные сетевые диски)
-
Проблемный стенд — специально «сломанные» конфигурации: переполненные диски, сбитые настройки безопасности, частично удаленные пакеты
Каждый кейс мы фиксировали, дорабатывали коллекцию и писали дополнительные валидации. Например, добавили проверку на фрагментацию дискового пространства и создали отдельные task-файлы для восстановления «битых» систем перед мажорным обновлением.
Совместная работа как ключ к скорости
Отдельно стоит отметить слаженную работу команды специалистов со стороны заказчика. Их вклад стал одним из ключевых факторов успеха.
Коллеги не просто сообщали о возникающих проблемах, а проводили глубокий первичный анализ ошибок на своих стендах, структурировали логи и предоставляли нам четкие, воспроизводимые кейсы.
Это позволило нашей команде сосредоточиться не на расшифровке сырых данных, а сразу на поиске и внедрении решений. Такой подход значительно ускорил цикл обратной связи и повысил качество каждой новой версии как нашей Ansible-коллекции, так и базовой утилиты обновления.
Итеративный процесс оттачивания
Это был классический agile-подход в действии:
-
Утроенный понедельник: Прогон тестов на 10+ конфигурациях;
-
Вечерний разбор полетов: Анализ логов и выявление ошибок;
-
Ночной билд: Выпуск новой версии коллекции с исправлениями;
-
Утренний регресс: Проверка, что новое не сломало старое.
Особую ценность представляло тестирование откатов — мы убедились, что в любой точке процесса можно безопасно откатиться к предыдущей версии ОС без потери данных. Для этого мы создали отдельные сценарии принудительного прерывания мажорного обновления на каждом из этапов.
Результат: После трех недель интенсивного тестирования мы прошли путь от 40% успешных мажорных обновлений до стабильных 98%. Каждые грабли, на которые мы наступили на нашем пути, делали нас сильнее, а набор инструментов перерос из теоретического решения в боеспособный продукт.
Параллельно мы активно взаимодействовали с командой разработчиков утилиты. Сообщали о найденных багах или необходимых фичах в штатной утилите мажорного обновления, предлагали улучшения. Многие наши идеи и правки были оперативно внедрены в следующие сборки.
5. Pull-модель с GUI: как мы сделали обновления удобными
Одним из ключевых запросов от заказчика была минимизация влияния на пользователей при обновление, и чтобы пользователь минимально мешал обновлению. Так на свет появилась вторая роль коллекции — migrate_pull.
Ее фичи:
-
GUI-интерфейс для пользователя с возможностью выбора времени установки.
-
Автоматический опрос и логирование ответов.
-
Вывод прогресс-баров и уведомлений на рабочий стол и экран блокировки.
-
Возможность запуска кастомных post-install скриптов (например, для переноса прикладного ПО).
Финальным и самым сложным этапом была адаптация под продуктивный контур заказчика. Здесь мы столкнулись с:
-
Версионностью кастомных пакетов (требовалось жестко фиксировать версии в
upgrade.conf.yaml). -
Разными схемами установки корпоративного ПО.
-
Необходимостью тонкой настройки сценариев для сохранения работоспособности специализированного софта.
Наша коллекция доказала свою гибкость, позволив описать все эти нюансы в виде конфигурационных файлов и шаблонов.
6. В цифрах

А зачем мы собирали статистику? Казалось бы, ответ очевиден — для руководства, но на самом деле она нужна была самой команде.
Мы делаем изменения, их становиться все больше, появляются новые проверки и новые версии утилиты, и нам самим хотелось увидеть, к чему приводят наши старания.
На момент написания статьи успешно мигрировано более 10870 ( пока статья получала общее согласование, счетчик перевалил за 50.000 успех обновлений ) рабочих станций по всей стране. Процесс продолжается в плановом режиме.
Операционные показатели успеха:
-
Среднее время мажорного обновления одного рабочего места: менее 2 часов
-
Процент успешных обновлений с первого раза: 98.2%
Что означают эти цифры для бизнеса:
-
Снижение операционных рисков за счет перехода на актуальную, поддерживаемую версию ОС
-
Повышение производительности сотрудников благодаря современным функциям в ALSE 1.8
-
Сокращение будущих затрат на техническую поддержку благодаря единообразию окружения
-
Масштабируемость решения — отработанный процесс легко тиражировать на другие проекты
7. Уроки, которые мы вынесли для будущих проектов
Этот проект в очередной раз доказал простую истину: самые сложные технологические вызовы покоряются там, где сочетаются три ключевых элемента:
-
Сильная межфункциональная команда, где разработчики, инженеры и архитекторы работают как единый организм
-
Гибкость и готовность слышать заказчика, превращая его требования в технологические решения
-
Итеративный подход к решению задач, где каждый провал становится шагом к будущему успеху
Главный урок: автоматизация — это не про замену людей, а про умножение их возможностей. Наша Ansible-коллекция не исключила специалистов из процесса, а позволила им сосредоточиться на сложных кейсах, передав рутину машинам.
P.S. Если вам интересны технические детали реализации Ansible-коллекции — отпишитесь в комментариях. Возможно, темой для следующей статьи будет именно глубокий разбор ее устройства.
А если вы руководитель проекта, задумывающийся о подобной трансформации — будем рады поделиться опытом и метриками, которые помогут обосновать подобные инициативы в вашей компании.
Автор: MikeyTide

