Работает, потому что на сервере так настроено
Конфигурация живёт только в продакшене: правки в php.ini, расширения, cron и системные пакеты. Воспроизвести стенд невозможно, а переезд на новую машину превращается в проект.
Выберите тему — соберём контекст
Переносим приложение в контейнеры, разворачиваем кластер, описываем выкат декларативно и включаем автомасштабирование. Отдельно занимаемся stateful-сервисами и бэкапами — там, где кластеры чаще всего ломаются.
Или сразу: +7 (962) 368-39-51 Telegram
Знакомый набор: сервер настроен руками, версии на машинах расходятся, а данные в volumes никто не проверял на восстановление.
Конфигурация живёт только в продакшене: правки в php.ini, расширения, cron и системные пакеты. Воспроизвести стенд невозможно, а переезд на новую машину превращается в проект.
Один узел на PHP 8.1, второй на 8.3, расширения отличаются. Ошибки, которые воспроизводятся только на одном из серверов, съедают дни на отладку.
Файлы раскладываются по серверам вручную, кэш и очереди перезапускаются в полуручном режиме. Каждый релиз — короткий, но реальный простой для пользователей.
У сервисов нет requests и limits по памяти и CPU. Разросшаяся очередь или тяжёлый отчёт выедают память узла, и падает всё, что на нём работает.
Сетевых политик нет, секреты лежат в ConfigMap в base64, сервисные учётки имеют полные права. Компрометация одного пода открывает доступ ко всему окружению.
Базы и Redis живут в PersistentVolume, но резервные копии снимаются дампом на тот же диск, а восстановление никто не пробовал. Реальная проверка происходит во время аварии.
От Dockerfile до политик сети и бэкапов: контейнеризация без оркестрации и оркестрация без работы с данными одинаково неполны.
Собираем образ так, чтобы он одинаково вёл себя локально, на стенде и в продакшене, и не тянул за собой лишние пакеты.
Разворачиваем кластер — управляемый или собственный — и сразу закрываем типовые дыры: избыточные права, открытую внутреннюю сеть, секреты в открытом виде.
Состояние кластера описывается в git, изменения проходят ревью, а расхождение между репозиторием и кластером видно сразу.
Самая недооценённая часть миграции. Проектируем хранение данных и проверяем восстановление до того, как оно понадобится в бою.
Сначала контейнеры и предсказуемая сборка, затем кластер. Переезд идёт с работающим продакшеном, без «большого взрыва» в выходные.
Находим точки хранения состояния: загруженные файлы, сессии, кэш, cron, локальные очереди. Решаем, что выносится из контейнера, а что остаётся.
Пишем Dockerfile, docker-compose для локального запуска, выносим конфигурацию в переменные окружения. Добиваемся, чтобы вся команда поднимала проект одной командой.
Разворачиваем кластер, описываем чарты, подключаем Argo CD, настраиваем сети, ресурсы, автомасштабирование и сбор метрик с подов.
Переносим трафик частями, проверяем отказоустойчивость и восстановление данных, обучаем команду работе с кластером и передаём runbook.
Типичная ошибка первого переезда — перенести в образ весь сервер: cron, nginx, php-fpm и базу данных в одном контейнере с супервизором. Такой контейнер теряет главные свойства: он не масштабируется частями, не имеет внятного жизненного цикла и ломается при обновлении любой из частей.
Контейнер решает одну задачу: приложение пишет логи в stdout, конфигурацию получает из переменных окружения, состояние хранит вне себя, а фоновые задачи вынесены в отдельный процесс, который можно масштабировать независимо. Web-процессы, воркеры очередей, планировщик и сборщик фронтенда — это разные контейнеры из одного образа, каждый со своим масштабом и своими ресурсами.
Кластер отлично управляет stateless-сервисами: их можно перезапускать, дублировать и перемещать между узлами без последствий. С базами данных всё иначе: цена ошибки в конфигурации хранилища или в политике репликации — потерянные данные, а не пара минут недоступности.
Мы исходим из того, что команде выгоднее не эксплуатировать базу самостоятельно, если есть управляемый сервис с репликацией, бэкапами и восстановлением на момент времени. Если требования — размещение данных в вашем контуре, отсутствие управляемых сервисов у провайдера или особая конфигурация — разворачиваем StatefulSet с оператором, но обязательно с проверенным восстановлением и учениями по отказу узла. Утверждение «бэкапы делаются» без проверки восстановления мы не принимаем как готовность.
Kubernetes — это не только узлы и управляющая панель. Это обновление версий каждые несколько месяцев, сопровождение чартов, разбор сетевых проблем, обновление операторов, дежурство и обучение новых инженеров. Для парка из трёх-четырёх сервисов такая инфраструктура часто дороже, чем пара виртуальных машин с контейнерами под systemd.
Кластер окупается, когда сервисов и окружений много, нужны частые релизы, изоляция команд, автомасштабирование под пиковую нагрузку и единый способ описывать выкат. В остальных случаях мы честно говорим об этом и предлагаем более простой вариант, оставляя путь к кластеру открытым: контейнеры и декларативные описания, подготовленные сейчас, переносятся в Kubernetes почти без изменений.
Обычно нет. Для одного-двух приложений достаточно контейнеров на двух-трёх виртуальных машинах с балансировщиком и декларативным выкатом: это даёт воспроизводимость, отсутствие простоя и откат, но не требует сопровождения кластера, обновления его версий и отдельного дежурства. Кластер стоит разворачивать, когда растёт число сервисов и окружений или нужны автомасштабирование и изоляция команд.
Управляемый вариант снимает с команды работу с управляющей панелью, её обновления и отказоустойчивость — платите за узлы и, как правило, за панель. Собственный кластер имеет смысл, когда есть требования размещать всё в своём контуре, когда нужна нестандартная конфигурация сети или когда у команды уже есть опыт эксплуатации kubeadm-кластеров и дежурства. Мы разворачиваем оба варианта и помогаем посчитать совокупную стоимость владения, включая часы инженеров.
Мы оцениваем три варианта: оставить базу на отдельной виртуальной машине, перейти на управляемый сервис провайдера или развернуть её в кластере через оператор. Выбор зависит от требований к размещению данных, нагрузке и наличию компетенций. В любом случае до переезда настраиваем резервное копирование с восстановлением на момент времени и проверяем восстановление на отдельном контуре — вслепую такую миграцию делать нельзя.
Технически это readiness-пробы, корректная стратегия rolling update, lifecycles для аккуратного завершения обработки запросов, Pod Disruption Budget и достаточное число реплик. Для критичных релизов добавляем blue-green или canary с автоматическим откатом по метрике ошибок. Важное условие — совместимые миграции базы данных по схеме expand/contract, иначе простой возникает не из-за кластера, а из-за изменения схемы.
Смежные задачи, которые обычно решаются в одном проекте с этой.
Опишите приложение и текущую инфраструктуру — предложим этапы миграции без остановки продукта.
Cookie и аналитика
Мы используем необходимые cookie для работы сайта и форм. Аналитические cookie (Яндекс.Метрика, включая запись сессий) подключаем только с вашего согласия — от него можно отказаться. Подробнее: Политика использования cookie и обработка персональных данных.