Синхронизация развертывания
Представьте, что мы вносим существенные изменения как в интерфейс, так и в интерфейс, и оба они станут несовместимыми с предыдущими версиями.Таким образом, новые версии должны быть развернуты одновременно.
В нашей текущей настройке мы должны сначала развернуть бэкэнд (что сломает развернутый фронтенд), а затем развернуть новый фронтэнд, исправив производство, но с «down»period.
Я не пользователь portainer, но, может быть, вы могли бы положиться на какой-нибудь файл docker-compose.yml
или около того, собирая как версию бэкэнда, так и интерфейс?в этом случае они могут быть обновлены одновременно…
Действительно, в соответствии с portainer / portainer # 1963 и на этой странице документа , portainer, кажется, поддерживает оба docker-составлять и копить стеки.
Кроме того, Docker Swarm предоставляет некоторые функции для обновления службы без простоев, как описано в этом блоге , но я не знаю, в какой степени это можно настроитьв portainer.
Возможные решения
Я не уверен, что следует использовать для указания версий здесь: хеш коммита, тег git, ветвь, версия образа докера ...Последнее, возможно, избавляет от необходимости перестраивать и тестировать изображения, но я думаю, что имена и версии изображений зафиксированы в определении стеков Portainer, и их нелегко автоматически обновлять.
Хотя хэши фиксации являются точными идентификаторами, ониВероятно, недостаточно удобно для выявления несовместимых версий.Поэтому вы можете использовать семантическое управление версиями с использованием тегов (и / или ветвей) в своем репозитории Git backend.
Затем вы можете соответствующим образом пометить соответствующие изображения Docker, введя некоторые синонимные тегиесли нужно.Например, предполагая, что серверная часть была выпущена с версиями 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0, 1.2.1, 1.2.2
, стандартная практика заключается в маркировке образов Docker следующим образом:
project/backend:2.0.2
= project/backend:2.0
= project/backend:2
project/backend:2.0.1
project/backend:2.0.0
project/backend:1.1.1
= project/backend:1.1
= project/backend:1
project/backend:1.1.0
project/backend:1.0.1
= project/backend:1.0
project/backend:1.0.0
(удаление старых изображений при необходимости)
Бэкэнд-интеграционные тесты
В настоящее времябэкэнд не тестируется на внешнем интерфейсе (только наоборот).
ОК, но я думаю, что ваш подход довольно стандартный (внешний интерфейс зависит от бэкенда, а не наоборот).
В любом случае, я напомню, что даже если тестируемая система является интерфейсной, возможно, стоит реализовать модульные тесты (которые дешевле и дешевле разработать, чем интеграционные тесты), так что на первом этапеконвейер быстро запускает эти модульные тесты, прежде чем запускать необходимые интеграционные тесты.
Зависимость ветвления для тестовts
В нашей текущей настройке все коммиты во внешнем интерфейсе проверяются на развернутый бэкэнд (во избежание репликации бэкэнда в CI используется только адрес производственного API), что приводит к ложным результатам тестирования в таких случаях.
Это может быть недостаточно гибким: в общем случае CI / CD предполагает, что интеграционные тесты выполняются с использованием выделенного серверного экземпляра (сервер "dev" или сервер "pre-prod"), и если всеИнтеграционные тесты и системные тесты проходят, образ развертывается на сервере «prod» (и отслеживается и т. д.)
Я вижу из вашего поста, что вы используете GitLab CI, который имеет некоторый собственный Dockerподдержка , так что, возможно, это можно было бы легко реализовать.
Пара подсказок:
Предположим, что бэкэнд был изменен в версии, не совместимой с предыдущими,и соответствующий образ Docker доступен в реестре (например, в GitLab CI).Затем вы можете просто изменить спецификацию этого образа в конфигурации внешнего интерфейса (например, заменив project/backend:1
на project/backend:2
или около того в GitLab CI conffile).
Ваш бэкэнд, вероятно, реализован в виде веб-службы REST, и в этом случае вы также можете добавить префикс версии в свой URL, чтобы при переключении с project/backend:1
на project/backend:2
(с несовместимыми изменениями)при необходимости обе версии могут быть развернуты одновременно по URL-адресам https://example.com/api/v1/…
и https://example.com/api/v2/…
Кроме того, помимо решения иметь только два репозитория с CI / CD(бэкэнд протестирован отдельно, а веб-интерфейс протестирован с соответствующей версией бэкэнда), решение, которое вы предложили в первую очередь, также может быть рассмотрено:
Для проблемы синхронизации развертывания я подумал о создании другого репозиторияв нем будет только один файл с указанием версий для внешнего и внутреннего интерфейсов, которые должны быть развернуты.Фиксация в этом репозитории приведет к тому, что оба веб-подключения сервисов Portanier будут «свернуты» для обновления (backend и frontend).Это не гарантирует одновременное обновление (в Portainer может произойти сбой, и отката не будет), но это будет лучше, чем текущая настройка.
Вы можете немного изменить этот подход, чтобы избежать одного такогоошибка развертывания: вы можете добавить некоторые настройки CI к этому третьему репо, которые будут содержать только файл docker-compose.yml
или около того, и переместить интеграционные тесты из внешнего интерфейса CI в этот «составной» CI…
(FYIэтот подход аналогичен предложенному в этом руководстве по DigitalOcean , где интеграционное тестирование выполняется благодаря некоторому файлу docker-compose.test.yml
.)