Где будет работать ваше приложение? Сервер, контейнер, serverless или edge
Вы собрали приложение. Оно работает на вашем ноутбуке. Теперь нужно разместить его так, чтобы им могли пользоваться другие. Простой вопрос — «где будет жить это приложение?» — определяет всё: как вы собираете, тестируете и доставляете код.
Ответ редко бывает однозначным. Возможно, приложение работает на физическом сервере в подсобке офиса. Может быть, на виртуальной машине в облаке. Или упаковано в контейнер под управлением Kubernetes. А может, это serverless-функция, которая существует только когда её кто-то вызывает. Или ему нужно работать на границе сети, рядом с пользователем, на IoT-устройстве или сетевом узле.
Каждая из этих целей меняет то, как вы проектируете пайплайн CI/CD. Инструменты важны, но главный вопрос — что ваш пайплайн должен уметь обрабатывать. Давайте пройдёмся по каждой цели и посмотрим, что меняется.
Развёртывание на серверах: физических или виртуальных
Когда вы развёртываете напрямую на сервер, ваш пайплайн должен работать со всем стеком целиком. Вы не просто доставляете код. Вы доставляете приложение, которому нужны конкретная операционная система, конкретное промежуточное ПО, конкретные версии библиотек и определённые конфигурационные файлы.
Процесс сборки обычно создаёт бинарник, пакет или набор файлов. Пайплайн переносит эти файлы на сервер, устанавливает их и перезапускает приложение. Откат означает замену файлов или возврат к предыдущей версии на той же машине.
Пайплайн для серверных развёртываний обычно длиннее. Вам нужны шаги для подготовки сервера, установки зависимостей, настройки окружения и проверки, что всё работает вместе. Если вы управляете несколькими серверами, нужно также координировать обновления между ними.
Преимущество — контроль. Вы решаете, что именно работает на машине. Недостаток — каждый сервер становится уникальным «снежинкой». Мелкие различия между окружениями — чуть другая версия библиотеки, вручную отредактированный конфиг — могут вызывать проблемы, которые трудно воспроизвести.
Развёртывание в контейнерах
Контейнеры меняют правила игры. Ваше приложение и все его зависимости упаковываются в образ. Этот образ собирается один раз и развёртывается везде. Окружение внутри контейнера одинаково на этапах разработки, тестирования и продакшена.
Фокус пайплайна смещается. Вместо управления конфигурацией сервера вы сосредотачиваетесь на сборке образа, его хранении в реестре и развёртывании на платформе оркестрации вроде Kubernetes. Откат становится проще: просто указываете на предыдущую версию образа.
Но появляются новые задачи. Нужно обеспечить безопасность образа. Управлять версиями и тегами образов. Обновлять работающие контейнеры без прерывания трафика. А также обрабатывать компоненты с состоянием, например базы данных, которые плохо вписываются в модель контейнеров.
Контейнеры дают согласованность и переносимость. Но требуют понимания сред выполнения контейнеров, оркестрации и сетей. Вашей команде нужно научиться отлаживать проблемы, возникающие внутри контейнера, а не только на сервере.
Развёртывание в serverless
Serverless поднимает абстракцию ещё выше. Вы вообще не думаете о серверах. Вы пишете функцию, загружаете её на платформу, а платформа занимается выполнением, масштабированием и доступностью.
Ваш пайплайн в чём-то упрощается. Нужно только упаковать код функции и развернуть его. Нет сервера для подготовки, нет операционной системы для настройки, нет контейнера для управления.
Но проблемы переходят в другие области. Как управлять версиями функций? Как настраивать переменные окружения и секреты? Как тестировать функцию, если среда выполнения не полностью под вашим контролем? Как бороться с холодным стартом, когда функция отвечает дольше, потому что её давно не вызывали?
Serverless хорошо подходит для событийно-ориентированных нагрузок, API с переменным трафиком и задач, которые выполняются время от времени. Он снижает операционные издержки, но ограничивает контроль над средой выполнения.
Развёртывание на границе сети (edge)
Edge-развёртывание добавляет другой вид сложности. Ваше приложение должно работать во многих местах, часто с ограниченными ресурсами. Представьте IoT-устройства, роутеры, узлы CDN или кассовые терминалы в магазинах.
Ваш пайплайн должен обрабатывать распространение обновлений на тысячи или миллионы устройств. Некоторые устройства могут быть офлайн, когда вы отправляете обновление. У некоторых может быть нестабильное сетевое соединение. Некоторые могут работать на оборудовании, которое нельзя легко заменить.
Откат на границе сети — сложная задача. Нельзя просто щёлкнуть выключателем и откатить все устройства сразу. Нужны стратегии для постепенных развёртываний, для обработки устройств, пропустивших обновление, и для восстановления устройств, которые вышли из строя после обновления.
Edge-развёртывание — это не только про софт. Это про логистику. Как гарантировать, что устройство в удалённом месте получит правильную версию? Как мониторить устройства, которые не всегда на связи? Как работать с устройствами, у которых закончилось место на диске или память?
Цель не навсегда
Вот в чём дело: ваша цель развёртывания — не окончательное решение. Одно и то же приложение может перемещаться между целями со временем. Вы можете начать с физического сервера, перейти на виртуальную машину, затем на контейнеры, а позже выделить части приложения в serverless-функции.
Каждое перемещение меняет ваш пайплайн. Меняется процесс сборки. Меняется стратегия развёртывания. Меняется механизм отката. Меняются требования к мониторингу и наблюдаемости.
Ключ в том, чтобы понимать, что каждая цель требует от вашего пайплайна, а не просто какие инструменты использовать. Когда вы знаете последствия, вы можете спроектировать пайплайн, который соответствует вашим реальным потребностям, а не просто последнему тренду.
Практический чеклист для выбора цели развёртывания
Прежде чем остановиться на какой-то цели, ответьте на эти вопросы:
Следующая блок-схема поможет визуализировать, как ваши ответы на эти вопросы приводят к цели развёртывания.
- Где у вашей команды больше всего опыта? Команда, хорошо знающая серверы, будет меньше страдать при серверном развёртывании, чем при работе с Kubernetes.
- Насколько вам нужен контроль над средой выполнения? Больше контроля — больше сложность пайплайна.
- Как вы будете делать откат? Некоторые цели делают откат лёгким (контейнеры), другие — болезненным (edge-устройства).
- Как вы будете тестировать развёртывание? Serverless и edge-окружения сложнее воспроизвести локально.
- Каков ваш паттерн трафика? Стабильный трафик — контейнеры или серверы. Всплески трафика — serverless.
- Сколько экземпляров нужно управлять? Несколько серверов — управляемо. Тысячи edge-устройств требуют другого подхода.
Что важнее всего
Цель развёртывания определяет форму вашего пайплайна. Она решает, что производит сборка, как выполняются тесты, как обновления доходят до пользователей и как вы восстанавливаетесь после сбоев.
Выбирайте, исходя из потребностей вашего приложения, возможностей команды и операционной реальности. Не потому, что контейнеры популярны или serverless — это будущее. Правильная цель — та, которую вы можете надёжно эксплуатировать, безопасно обновлять и эффективно отлаживать, когда что-то идёт не так.
Ваш пайплайн должен отражать этот выбор, а не бороться с ним.