Российский рынок частных облаков последние несколько лет активно смещается в сторону OpenStack — как альтернативы ушедшим вендорам и как основы для построения отечественных платформ. OpenStack давно перестал быть экзотикой для узкого круга энтузиастов, ведь на нём сегодня строятся частные облака у операторов, банков и промышленных компаний, которым нужен контроль над инфраструктурой без привязки к одному вендору. Но у этого перехода есть обратная сторона, о которой на старте проекта задумываются реже, чем стоило бы: облако на OpenStack нужно не только развернуть, но и потом годами обновлять, своевременно реагируя на выявленные бреши в безопасности, устанавливая новые релизы компонентов и удовлетворяя требования регуляторов. И если сам факт перехода на OpenStack давно перестал быть новостью, то вопрос «а как это облако вообще обновлять, когда придёт время» у большинства эксплуатирующих команд до сих пор упирается в ручной труд, дефицитную экспертизу и риск простоя. То есть проблема не в том, чтобы просто поднять OpenStack, а в том, чтобы удерживать его в рабочем и безопасном состоянии на протяжении всего жизненного цикла. Разберёмся, почему обновление OpenStack остаётся сложной инженерной задачей, какие этапы этого процесса можно автоматизировать и какие ограничения необходимо заложить в механизм обновления, чтобы автоматизация сама не стала источником риска.

Проблема, о которую спотыкается почти каждый оператор облака

OpenStack принято хвалить за гибкость и открытость, но за кулисами этой гибкости стоит один из самых болезненных процессов в жизненном цикле облачной платформы — обновление. В отличие от монолитных систем, OpenStack — это фреймворк из полутора-двух десятков взаимозависимых сервисов (Keystone, Nova, Neutron, Cinder, Glance, Placement и т. д.), каждый со своей базой данных, своими миграциями схемы, своим порядком запуска и своими требованиями к совместимости версий API. Обновить такую систему не значит «поставить новую версию пакета». Это значит провести десятки взаимосвязанных операций в строго определённой последовательности, не нарушив по пути ни одну зависимость.

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

Что именно усложняет обновление OpenStack

Если разложить проблему на составляющие, получится примерно такой список (и он актуален независимо от того, разворачивается ли OpenStack «руками», через Ansible-плейбуки или через Kubernetes-операторы):

Порядок и зависимости сервисов. Часть компонентов должна обновляться раньше других — например, Keystone и Placement обычно идут в начале цепочки, а сервисы, зависящие от их API, следом. Ошибка в порядке приводит к рассинхронизации версий API между сервисами и падению запросов.

Миграции баз данных. Каждое обновление тянет за собой миграции схем в базах Nova, Neutron, Cinder и других сервисов. Некоторые миграции требуют «миграции данных без остановки» ещё на текущей версии — если этот шаг пропущен, обновление может завершиться с повреждением данных.

Простой сервисов управления и, в худшем случае, сетей и вычислительных ресурсов пользователей. Даже при аккуратном планировании слой управления обычно недоступен часть времени обновления. Плохо спроектированный процесс способен зацепить и вычислительные ресурсы пользователей — то есть повлиять на уже работающие виртуальные машины и пространство пользователей.

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

Человеческий фактор и разрыв компетенций. Классический процесс обновления — это последовательность команд в CLI, правка YAML-файлов инвентаря и конфигурации, запуск плейбуков с нужными флагами в нужном порядке. Уровень экспертизы, который для этого требуется, есть далеко не в каждой команде эксплуатации, а дефицит сертифицированных OpenStack-инженеров на рынке — известная проблема.

Долгий цикл патчинга безопасности. Когда обновление — это рискованный процесс и многочасовая процедура, а не «нажал кнопку и забыл», критические обновления безопасности откладываются дольше, чем следовало бы. Разрыв между выходом патча и его применением в продуктиве — это прямой риск для периметра.

Дрейф конфигурации между средами. В компаниях с несколькими окружениями (dev/test/prod) ручные обновления быстро приводят к тому, что конфигурации расходятся, и то, что сработало на тесте, ломается в проде именно из-за незамеченного отличия.

Как эти проблемы решаются (или не решаются) в разных реализациях OpenStack

Здесь стоит сразу отметить: экосистема способов развернуть OpenStack довольно широкая, и подход к обновлению принципиально различается в зависимости от выбранного инструментария.

Kolla-Ansible (в том числе на связке с Docker или Podman) разворачивает сервисы в контейнерах и обновляет их через Ansible-плейбуки (kolla-ansible upgrade). Классически это CLI-процедура: инженер вручную правит globals.yml, инвентарь, версии тегов образов и запускает плейбук, понимая, что происходит на каждом шаге. Вынос процесса в CI/CD позволяет сделать обновление воспроизводимым и версионируемым, а также сократить количество ручных операций. Но сам по себе CI/CD не снимает требования к квалификации специалиста. Кто-то по-прежнему должен понимать структуру пайплайна, интерпретировать результаты выполнения отдельных стадий и принимать решение при ошибках. Поэтому автоматизация исполнения и автоматизация принятия решений при обновлении — это разные задачи.

OpenStack-Ansible (OSA) концептуально близок к Kolla-Ansible, но использует LXC-контейнеры или venv вместо Docker/Podman-образов. Процесс обновления так же построен на плейбуках и так же требует ручного сопровождения и экспертизы.

TripleO / director-based установки (классический подход Red Hat OpenStack Platform до недавних версий) добавляют ещё один слой сложности — undercloud и overcloud обновляются отдельно, а сам процесс исторически считался одним из самых трудоёмких в экосистеме.

Charmed OpenStack от Canonical на базе Juju ближе всего к идее «графического» управления жизненным циклом: Juju GUI позволяет визуально управлять обновлением charms, что снижает порог входа по сравнению с чистым CLI, хотя полноценной автоматизации «в один клик» с предварительными проверками и остановкой на проблемном шаге это тоже не даёт из коробки.

MicroStack / Sunbeam (тоже Canonical, snap-based) упрощают обновления до команды snap refresh, но это решение ориентировано на небольшие и edge-инсталляции, а не на полномасштабные продуктивные облака.

Kubernetes-нативные подходы (OpenStack-Helm, Airship, а также коммерческий Mirantis OpenStack for Kubernetes) выигрывают за счёт того, что опираются на нативные механизмы Kubernetes — поэтапное обновление, readiness/liveness probes, helm rollback. Именно в этом сегменте чаще всего встречаются продукты с полноценным веб-интерфейсом управления обновлениями, потому что Kubernetes-примитивы изначально спроектированы для автоматизации подобных процессов.

Общий вывод, к которому подводит этот обзор, хочется сформулировать следующим образом. Проблема «обновление зависит от инженера с CLI» и проблема «обновление недоступно как самообслуживаемая операция» — это два разных уровня, и решаются они не одним и тем же шагом. Вынос процесса в CI/CD (как в случае с GitLab у связки Kolla-Ansible/Podman) решает первую: обновление становится воспроизводимым, версионируемым и не требует ручных команд в терминале. Но оно не решает вторую — запустить и проконтролировать пайплайн по-прежнему может только тот, кто ориентируется в GitLab, а не в продукте, которым он управляет. Поэтому интерфейс с кнопкой запуска сам по себе ещё не делает обновление автоматизированным. Существеннее то, какие проверки выполняются до старта, как система учитывает зависимости компонентов, может ли она остановить процесс при ошибке и насколько подробно сообщает администратору о состоянии инфраструктуры. Именно эти механизмы определяют, можно ли передать часть решений от инженера автоматике.

Что должно скрываться за кнопкой автоматического обновления

Автоматизация обновления OpenStack не сводится к переносу последовательности команд из CLI в CI/CD. Пайплайн может выполнять подготовленные операции, фиксировать стадии и сохранять результаты их выполнения. Но сам по себе он не определяет, какие действия допустимы в текущем состоянии инфраструктуры, в какой последовательности их выполнять и когда процесс необходимо остановить.

Поэтому поверх исполнительного слоя нужна логика, которая учитывает зависимости сервисов OpenStack, совместимость версий, состояние узлов и результаты проверок после каждого этапа. Иначе автоматизируется только запуск команд, а принятие решений по-прежнему остается на инженере.

При этом важно разделять два разных процесса: обновление хостовой операционной системы и переход на новую версию самого OpenStack. Внешне они похожи, но предъявляют разные требования к последовательности операций и допустимому уровню параллелизма.

Патчинг хостовой ОС: ротация узлов

При установке пакетов и обновлений безопасности на контроллерах и гипервизорах можно использовать принцип последовательной ротации.

Контроллер выводится в режим обслуживания, получает обновления, при необходимости перезагружается и возвращается в кластер. Только после проверки его состояния процесс переходит к следующему узлу. Пока один контроллер обслуживается, остальные продолжают обрабатывать запросы, что позволяет сохранить доступность управляющего слоя.

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

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

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

Обновление версии OpenStack: почему поэтапность не всегда означает меньший риск

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

Отдельный вопрос — порядок обновления контроллеров. Интуитивно безопасной кажется последовательная схема, при которой узлы переводятся на новую версию один за другим. Однако для конкретной архитектуры такой подход необходимо проверять с учетом совместимости API и компонентов. Если часть сервисов уже работает на новой версии, а часть остается на старой, может возникнуть период, когда управляющий слой работает в несогласованном состоянии.

Поэтому последовательность операций должна определяться не универсальным принципом «обновлять по одному», а особенностями конкретного релиза и архитектуры развертывания.

Не менее важен контроль состояния системы во время перехода. До старта должны выполняться системные проверки. После критических операций необходимо проверять работоспособность компонентов. Если очередная проверка не пройдена, дальнейшие действия следует остановить и зафиксировать этап, на котором возникла ошибка.

Для OpenStack такой сценарий зачастую безопаснее попытки автоматически вернуть всю систему в исходное состояние. Если часть схем баз данных уже мигрирована, а некоторые компоненты обновлены, полноценный откат может оказаться отдельной сложной и рискованной процедурой. Поэтому от механизма автоматизации требуется прежде всего контролируемая остановка и точная диагностика.

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

Что именно нужно автоматизировать

При оценке механизма обновления OpenStack важно смотреть не только на инструмент, который исполняет команды. Ansible, CI/CD или Kubernetes позволяют автоматизировать значительную часть технических операций, но сами по себе не определяют, можно ли выполнять конкретное обновление в текущем состоянии инфраструктуры.

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

Именно поэтому перенос команд из терминала в пайплайн решает только часть задачи. Он делает процесс воспроизводимым и версионируемым, но не заменяет механизм управления жизненным циклом облачной платформы.

Что должен видеть администратор

Способ запуска обновления вторичен. Это может быть CLI, CI/CD или графический интерфейс. Гораздо важнее, какую информацию получает администратор до начала процесса и во время его выполнения.

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

Задача интерфейса в данном случае не в том, чтобы скрыть сложность OpenStack за одной кнопкой. Он должен дать администратору понятную точку управления процессом, тогда как правила последовательности, совместимости и безопасной остановки должны соблюдаться автоматически.

От чего зависит длительность обновления

Продолжительность обновления нельзя свести к одному нормативному значению. Она зависит от числа узлов, состава компонентов, объема миграций, пользовательской нагрузки и расстояния между исходным и целевым релизами.

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

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

Почему обновление нужно тестировать заранее

Автоматизация не отменяет предварительной подготовки обновления. Для каждого поддерживаемого перехода необходимо проверить совместимость компонентов, миграции баз данных, последовательность операций и работу основных сценариев после установки новой версии.

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

Для эксплуатации это означает, что маршрут обновления должен быть заранее определен и протестирован. Автоматический механизм затем воспроизводит уже проверенную последовательность, контролируя состояние системы на каждом критическом этапе.

Когда обновление OpenStack действительно можно считать автоматизированным

Кнопка запуска сама по себе еще не делает обновление автоматическим. За ней может находиться тот же набор команд, который раньше инженер последовательно выполнял вручную.

Более зрелый подход начинается с автоматизации не только исполнения, но и части решений. Система проверяет состояние инфраструктуры до старта, учитывает совместимость версий и зависимости компонентов, ограничивает потенциально опасный параллелизм, контролирует результат отдельных операций и прекращает дальнейшие действия, если состояние системы отклоняется от ожидаемого.

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

Поэтому зрелость механизма обновления определяется не количеством операций, сведенных к одному нажатию, а тем, насколько предсказуемо система проходит штатный сценарий и насколько управляемо ведет себя при возникновении ошибки. По мере роста OpenStack-инфраструктуры такая автоматизация становится частью управления ее жизненным циклом, поскольку без нее увеличиваются трудозатраты на эксплуатацию и зависимость от ручных операций.

Кирилл Острогожский, архитектор компании ITKey