Лучше Docker Составить производственные настройки? - PullRequest
0 голосов
/ 17 января 2020

У меня действительно простое веб-приложение, содержащее эти контейнеры:

  • Веб-сайт внешнего интерфейса (Nuxt. js - приложение узла)
  • API внутреннего интерфейса (PHP, Symfony )
  • MySQL

У каждого контейнера есть собственный Dockerfile, и я могу запустить его с помощью Docker Создать вместе. Это действительно приятно, и мне нравится простота.

На моем сервере есть сценарий развертывания. Он клонирует GIT monorepo и запускает docker -составьте:

DIR=$(dirname $(readlink -f $0))
rm -rf $DIR/app
git clone git@bitbucket.org:adam/myproject.git $DIR/app
cd $DIR/app && \
   docker-compose down --remove-orphans && \
   docker-compose up --build -d

Но это решение действительно медленное и его время простоя составляет ~ 3 минуты. Для этого проекта я могу принять несколько секунд простоя, это не смертельно. Мне не нужно действительно нулевое время простоя. Но 3 минуты недопустимы.

Самым трудоемким является "npm build" внутри контейнеров. Это то, что должно выполняться после каждого изменения.

Что я могу сделать лучше? Является ли Swarm или Kubernetes действительно единственным решением? Могу ли я создавать контейнеры, пока старое приложение еще работает? А после сборки просто остановить старое и запустить новое?

Спасибо!

Ответы [ 4 ]

1 голос
/ 17 января 2020

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

Я бы рекомендовал использовать уникальный тег для ваших изображений. Штамп с датой работает хорошо; Вы упоминаете, что у вас есть монорепо, поэтому вы можете использовать идентификатор фиксации в этом репо и для своего тега изображения. В вашем docker-compose.yml файле используйте переменную окружения для имен изображений

version: '3'
services:
  frontend:
    image: myname/frontend:${TAG:-latest}
    ports: [...]
  et: cetera

Не не используйте volumes: для перезаписи кода в ваших изображениях. Сделайте так, чтобы ваша система CI проверила ваши изображения как встроенные, запустив именно тот образ, который вы собираетесь развернуть; нет привязных креплений или дополнительного искусственного тестового кода. В вопросе упоминается "npm build внутри контейнеров"; выполните все эти шаги сборки на этапе docker build и укажите их в своем Dockerfile, чтобы вам не нужно было запускать их во время развертывания.

Если у вас есть новый коммит в вашем репо, постройте новый картинки. Это может произойти в отдельной системе; это может происходить параллельно с вашей работающей системой. Если вы используете уникальный тег для каждого изображения, становится более очевидным, что вы создаете новое изображение, отличное от рабочего изображения. (В принципе, вы можете использовать один тег ...:latest, но я бы не рекомендовал его.)

# Choose a tag; let's pick something based on a timestamp
export TAG=20200117.01

# Build the images
docker-compose build

# Push the images to a repository
# (Recommended; required if you're building somewhere
# other than the deployment system)
docker-compose push

Теперь вы находитесь в точке, где вы создали новые изображения , но вы все еще используете контейнеры на основе старых изображений. Вы можете сказать Docker Составить, чтобы обновить вещи сейчас. Если вы docker-compose pull изображения заранее (или если вы создали их в той же системе), то это просто остановка существующих контейнеров и запуск новых. Это единственная точка простоя.

# Name the tag you want to deploy (same as above)
export TAG=20200117.01

# Pre-pull the images
docker-compose pull

# ==> During every step up to this point the existing system
# ==> is running undisturbed

# Ask Compose to replace the existing containers
# ==> This command is the only one that has any downtime
docker-compose up -d

(Почему важен уникальный тег? Скажите, что произошла ошибка, и сборка 20200117.02 имеет критическую ошибку. Очень легко вернуть тег к более раннему 20200117.01 и перезапустите развертывание, поэтому выполните откат развернутой системы, не выполняя git revert и не перестраивая код. Если вы смотрите на менеджеры кластеров, такие как Kubernetes, то значение измененного тега является сигналом для объекта развертывания Kubernetes, что что-то обновило , так что это вызывает автоматическое c перераспределение.)

0 голосов
/ 17 января 2020

Единственная проблема действительно была docker-compose down до docker-compose build. Я удалил команду down, и время простоя составляет несколько секунд. Я думал, build отключает запущенные контейнеры перед автоматическим построением. Я не знаю почему. Спасибо Ноэ за идею! Я идиот.

0 голосов
/ 17 января 2020

Хотя я думаю, что переключение на Kubernetes (или, может быть, Docker Swarm, с которым у меня нет опыта) было бы лучшим вариантом, ДА, вы можете создать свои docker изображения и затем перезапустить.

Вам просто нужно запустить команду docker-compose build. Смотрите ниже:

DIR=$(dirname $(readlink -f $0))
rm -rf $DIR/app
git clone git@bitbucket.org:adam/myproject.git $DIR/app
cd $DIR/app && \
   docker-compose build && \
   docker-compose down --remove-orphans && \
   docker-compose up -d
0 голосов
/ 17 января 2020

Это длительное время может происходить из-за нескольких вещей:

  • Ваше приложение игнорирует сигнал остановки, docker - составляет ожидание их завершения, прежде чем убить их. Убедитесь, что ваш контейнер успешно завершен, не дожидаясь сигнала уничтожения.
  • Ваш файл Docker неправильно заказан. Docker имеет встроенный кеш для каждого шага, но если предыдущий шаг был изменен, он будет делать каждый шаг снова. Я рекомендую вам быть осторожным, когда копируете файлы, часто это нарушает кеш.
  • Запустите docker-compose build перед тем, как класть контейнеры Будьте осторожны с подключенными томами, если docker не может получить контекст, произойдет сбой
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...