Бесшовный деплой с Docker Swarm

Перевод проекта с Docker Compose на Docker Swarm для кластера из виртуальных машин. Организация бесшовного деплоя. Управление размещением сервисов.

  • 00:00:46 - Проблема зависимостей запуска контейнеров
  • 00:04:05 - Удаление зависимостей Nginx
  • 00:09:32 - Вынос резолвера в сниппет
  • 00:11:21 - Проверка здоровья контейнера
  • 00:12:34 - Healt Check для Nginx
  • 00:19:12 - Проверки в Gateway
  • 00:20:55 - Проверка для Frontend
  • 00:23:01 - Healt Check для PHP-FPM
  • 00:34:42 - Доработка конфигурации docker-compose
  • 00:35:16 - Перенос миграций в сервис
  • 00:38:33 - Конфигурирование параметров деплоя
  • 00:41:37 - Конфигурирование размещения сервисов
  • 00:43:43 - Режим подключения к БД
  • 00:47:17 - Изменение команды деплоя
  • 00:54:05 - Деплой проекта
  • 00:55:53 - Смена хука для Certbot
  • 00:59:45 - Размещение сервисов по меткам
  • 01:03:54 - Простановка меток через Ansible
  • 01:16:59 - Обзор результата
  • 01:08:09 - Подключение к Docker по TLS
Скрытый контент
Комментарии (17)
Руслан

Спасибо!

Ответить
Arunas

Спасибо.

Ответить
Андрей

Очень круто!

Ответить
Yevhenii Lykholai

Спасибо.

Ответить
Руслан

Здравствуйте, подскажите, есть ли пример реализации паттерна сага на php?

Ответить
Дмитрий Елисеев

Сага обычно реализуется как обычный обработчик команды и слушатель событий. Хореографическая сага реализуется обычным вызовом наших сущностей из слушателей событий других сущностей. И даже сагу-оркестратор при необходимости хранить состояние можно оформить тоже как обычную Doctrine-сущность.

Мы здесь как раз все эти варианты рассмотрим.

Ответить
Paul

Дмитрий, а если я монтирую папку с файлами (файловое хранилище) через volume, но при этом хочу запустить несколько инстансов приложения, я столкнусь с проблемой о которой вы говорили про базу (что swarm будет создавать volume на разных хостах, а нам надо только на одном). Тоже самое произойдет, если я, например, хочу сохранять сессии на основной хост. Где-то в комментариях видел, что для хранения файлов будет использоваться s3 хранилище, но хотелось бы понять, как можно обойтись без этого.

Ответить
Дмитрий Елисеев

Вместо хранения сессий по умолчанию в файлах переходят на хранение в БД или в Redis. Для этого во многих фреймворках вместо HttpSession имеются классы DbSession или RedisSession.

А для хранения файлов у себя на нужном хосте можно через докер на нём поднять сервис хранилища. Потом из php-fpm загружать в него файлы по FTP и проксировать запросы из gateway.

Ответить
Павел

здравствуйте! спасибо за ваши труды. не могу только найти бесшовный деплой в условиях связанных сервисов. например, версия фронта может работать с определенной версией бека, поэтому обновлять по 1 сервису не вариант, так как запросы могу "перемешиваться" и будут возникать ошибки. поэтому нужен blue-green деплой сразу для нескольких сервисов, например объединенных одной сетью и переключать трафик между сетями. где то вроде у вас я видел такое видео или ошибаюсь?

Ответить
Дмитрий Елисеев

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

Ответить
Alexey Antipin

Доброго времени. Дмитрий подскажите, когда мы раворачиваем NGINX в докере получаем замену IP на бридж IP тоесть в логах NGINX мы больше не видим client ip, вместо этого видим Docker bridge ip, если ли рещения в вашем арсенале? Вынос из докера gateway тоже не самая удобная идея.

Ответить
Alexey Antipin

Проблема оказалась не в этом, Конфликты faerwalld iptables and nftables . Centos 8 в топку пока)

Ответить
Дмитрий Елисеев

Да, это специфика работы overlay-сети в Swarm. При балансировке между несколькими нодами на gateway передаётся не реальный клиентский запрос с реальным IP-адресом, а уже перенаправленный внутрь запрос из балансировщика Docker с IP-адресом этого балансировщика.

Так что если сильно нужен реальный IP и не хочется ставить внешний Nginx с простановкой X-Real-IP, то как компромисс можно привязывать порты gateway напрямую к портам виртуальной машины через режим mode:host вместо проброса через docker-балансировщик:

services:
    gateway:
        image: ${REGISTRY}/auction-gateway:${IMAGE_TAG}
        volumes:
            - /etc/letsencrypt:/etc/letsencrypt:ro
            - /var/www/html:/var/www/html:ro
        ports:
            - target: 80
              published: 80
              protocol: tcp
              mode: host
            - target: 443
              published: 443
              protocol: tcp
              mode: host
        deploy:
            placement:
                constraints: [node.role == manager]

Тогда входящий запрос будет отправляться в gateway напрямую. Но при таком прямом подключении портов в обход Swarm-а не получится запускать несколько реплик одновременно. Так что бесшовное обновление сделать не получится и gateway при каждой сборке будет отваливаться при обновлении.

Для бесшовного деплоя надо будет, например, присваивать и менять версию gateway вручную:

docker build --tag gateway:1.3 ...

и в продакшене в image указывать gateway:1.3. Тогда этот сервис не будет обновляться при каждой сборке. Но придётся вручную помнить, что нужно будет при изменении везде менять эту версию.

Либо можно присвоить дополнительно тег latest:

docker build --tag gateway:${IMAGE_TAG} --tag gateway:latest ...

и использовать в продакшене gateway:latest, чтобы Swarm его перезапускал только когда увидит изменения после pull. Но так мы не сможем сделать rollback.

Ответить
Alexey Antipin

Победил !!! Вдруг кому то пригодится. Стек следующий Debian 10 + iptables + fail2ban (v0.11), centos and ubuntu не работает.

2020/09/07 06:18:01 [error] 6#6: *2542 limiting requests, excess: 5.384 by zone "dynamic", client: 194.193.XX.XX, server: 27.50.xx.xx, request: "GET / HTTP/1.1",
возвращает коректный client ip

рисует конфиг от DDOS

[nginx-limit-req]
enabled = true
chain=DOCKER-USER
findtime = 600
bantime = 7200
Ответить
Дмитрий

Я делаю совсем другой проект (react ssr) , но твои уроки показали как сделать CI и автоматический деплой в кластер. Дима, спасибо огромное! Всё получилось! Супер!

Ответить
saudade

почему не кубернетис?

Ответить
Дмитрий Елисеев

Потому что на Swarm перейти проще. А K8s уже следующий продвинутый шаг.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий