Бесшовный деплой с 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
Скрытый контент
Комментарии (15)
Руслан
2020-07-18 16:51

Спасибо!

Ответить
Arunas
2020-07-18 19:39

Спасибо.

Ответить
Андрей
2020-07-19 09:33

Очень круто!

Ответить
Yevhenii Lykholai
2020-07-19 11:37

Спасибо.

Ответить
Руслан
2020-07-20 16:18

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

Ответить
Дмитрий Елисеев
2020-07-27 09:31

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

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

Ответить
Paul
2020-08-02 22:06

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

Ответить
Дмитрий Елисеев
2020-08-04 06:29

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

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

Ответить
Павел
2020-08-09 15:27

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

Ответить
Дмитрий Елисеев
2020-08-13 15:42

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

Ответить
Alexey Antipin
2020-08-31 07:56

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

Ответить
Alexey Antipin
2020-09-02 04:42

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

Ответить
Дмитрий Елисеев
2020-09-03 08:58

Да, это специфика работы 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
2020-09-07 06:40

Победил !!! Вдруг кому то пригодится. Стек следующий 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
Ответить
Дмитрий
2020-09-08 07:30

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

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