Управление хостами и Traefik

В нашей инфраструктуре есть неудобства. В отличие от доменов и поддоменов при разработке и тестировании мы используем маршрутизацию по портам. При тестировании мы используем домен gateway вместо localhost. Все поддомены нам приходится вписывать вручную. И из-за монополии на 80 и 443 порты кластера мы не можем задеплоить несколько проектов.

Сегодня мы всё это решим. И от Nginx и Certbot перейдём на декларативное управление доменными именами и проксированием с помощью Traefik с автополучением Let's Encrypt сертификатов. И как бонус вынесем прокси-сервер в отдельный репозиторий, чтобы можно было деплоить в один кластер сколько угодно проектов:

  • 00:01:32 Использование поддоменов localhost
  • 00:03:38 Подмена localhost в E2E тестах
  • 00:06:18 Замена адресов проекта
  • 00:11:19 Конфликт портов нескольких проектов
  • 00:13:54 Автоматизация через метки
  • 00:15:44 Сервис Traefik
  • 00:16:24 Использование в dev-окружении
  • 00:21:14 Выделенная сеть для проксирования
  • 00:25:20 Редирект с www
  • 00:27:42 Подмена для тестового окружения
  • 00:31:37 Перенос production с Lets Encrypt
  • 00:33:36 Редирект на https
  • 00:36:13 Дополнительные HTTP-заголовки
  • 00:38:07 Прямой проброс портов
  • 00:41:55 Смена версии Python в Ansible
  • 00:42:58 Удаление Certbot
  • 00:45:28 Вынесение Traefik для кластера
  • 00:49:02 Вынесение общих плейбуков
  • 00:50:23 Обзор результата
Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (48)
Arunas

Спасибо.

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

Спасибо!

Ответить
Александр Кулик

Спасибо. Давно хотел про traefik

Ответить
Евгений Горяев

Спасибо за видео! Хочется попросить Дмитрия что-то сделать с сессией. Вроде бы кука до 22 года но каждый раз когда захожу сюда приходится логиниться опять. Возможно это потому что смотрю по очереди с двух компов и сайт сбрасывает старый токен при заходе с другого устройства... Если это такая защита от чего-то - то в ущерб удобству юзеров, к тому же платных ) Прошу пофиксить хотя бы это, если других обновлений не планируется.

Ответить
Евгений Горяев

если это защита от того чтобы с одного аккаунта не смотрели разные люди как защита от пиратства и тд - то хотя бы разрешать несколько токенов в рамках одного айпишника например )

Ответить
fedot

Все изменения не бесплатны, время потраченное на них, задержит выпуск последующих эпизодов, а они и так не часто выходят, думаю лучше не тратить время Дмитрия на такое, у меня тоже 2 компа и такая же история, не удобно, но не критично.

Ответить
Евгений Горяев

пусть даст практическое задание ученикам )))

Ответить
Максим (@myks92)

Привет старым знакомым)

Да не критично вообще) Нам, программистам, приходится и не с такими костылями жить, а это мелочи) У меня и тоже самое с телефона и компа, но никогда не вызывало проблем. Сохрани пароль в браузерах да и заходи без проблем за 1 секунду!) Самое простое решение и не совсем костыльное…)

Что касается новых функций и идей, то согласен с комментатором выше. У Дмитрия их и так куча!) Лучше сосредоточится на контенте и так не частых выпусков. Это в наших же интересах ;)

Ответить
Альберт

Согласен, что выпуски выходят с задержкой.

Ответить
Дмитрий

Заходите через google и никаких паролей не надо

Ответить
Pavel N

Добрый день.
Подскажите пожалуйста.
Как правильно заменить имя хоста на переменную с учетом www и безы www. В зависимости от от ветки у нас собирается либо на production либо на staging.

- traefik.http.routers.frontend.rule=Host(${HOST_NAME}) || Host(`www.example.com`)
Ответить
Дмитрий Елисеев

Попробуйте:

Host(${HOST_NAME}) || Host(`www.${HOST_NAME}`)
Ответить
Konstantin

тут есть пример

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

Дмитрий, добрый день,

подскажите, пожалуйста, как настроить сборку, чтобы прокинуть доступ к сервисам по сети на нативные мобильные устройства для тестирования?

Спасибо заранее!

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

PS: использую Engine 20.10.8 (Docker Desktop for Mac 4.10), gateway проксирую пока через nginx без Traefik.

1) host.docker.internal не работает

2) пробовал использовать адрес сети из CLI

ipconfig getifaddr en0 && ipconfig getifaddr en1

отдельно фронт и бэк открываются через соответствующий порт gateway (8080, 8081), но их общение не работает (н-р oauth2 аутентификация), .env обновлял

Может кто подсказать как настроить docker-compose.yml для полноценного доступа к приложению с внешних устройств внутри одной сети?

Спасибо.

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

С мобильными устройствами не работал, так что не подскажу.

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

Понял, тестирую пока через bowserstack. Спасибо, ждем продолжения!)

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

Дмитрий, подскажите, пожалуйста, как в Traefik добавить готовые SSL сертификаты, а не генерировать новые? Спасибо!

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

Спасибо большое!

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

Добрый день,

пожалуйста, подскажите, как настроить Traefik/docker-compose.yml/hosts, чтобы запросы к api.localhost проходили из контейнера? Насколько понял, сейчас отрабатывают только по названию контейнера/сервиса (api).

Спасибо.

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

Также, как мы подменили localhost в E2E тестах через network_mode.

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

Дима, как раз с этим и проблема, при make init получаю на уровне cucumber-yarn-install ошибку:

Error response from daemon: network service:traefik not found

Возможно что-то упустил в настройках сети, или какая особенность докер-демона для MacOS?

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

Что-то упустили. Точно это вписали в network_mode, а не в простом network?

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

Ошибка возникает постоянно как пробую поднять текущий репозитарий аукциона как есть без правок, настройки докер-демона сбросил по-умолчанию, попробовал на разных OS BigSur (Intel) и Monterey(M1) - без изменений (( Может будут какие идеи?

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

Попробуйте в панели управления Docker в настройках отключить эксперименальные фичи и запустите init снова.

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

Дима, спасибо за время, уже сбросил Docker по-умолчанию, экспериментальные фичи отключены, перезапустил, результат тот-же, уже прям отчаялся с Traefik, пробую дальше локализовать проблему

Ответить
Aёct'ann

Может уже и не актуально, но оставлю заметку)

Данная ошибка возникает при использовании docker-compose v2. Руслан ниже писал, что добавил в networks в cucumber-node-cli запись, это может и исправляет проблему с "traefik not found", но появляется другая проблема: при запуске e2e тестов cucumber-node-cli не будет в одной сети с трафиком и не сможет переходить по адресам http//localhost или http//api.localhost

Поэтому, временно нужно переключить docker-compose на v1. На Windows это делается через приложение docker-desktop в настройках. На v1 все работает корректно, сервисы все поднимаются, e2e тесты проходят

Upd: также можно остаться на docker-compose v2, но придется внести некоторые корректировки в dockecr-compose.yml

К контейнеру с traefik добавляем container_name

  traefik:
    container_name: traefik

К контейнеру cucumber-node-cli меняем формат network_mode и добавляем depends_on от traefik, а то можно нарваться на ошибку cannot join network of a non running container: traefik

  cucumber-node-cli:
    build:
      context: cucumber/docker/development/node
    volumes:
      - ./cucumber:/app
    depends_on:
      - traefik
    network_mode: container:traefik

Enjoy!

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

Спасибо за решения, попробую вариант с container_name.

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

Удалось запустить на MacOS добавив networks в cucumber-node-cli:

    networks:
        - traefik-public
Ответить
Konstantin

а как настроить проксирование соединения WS в React, если ws обращается в порт 3000?

Ответить
Konstantin

дополню... не могу настроить соединение для react app - ws://example.localhost:3000/ws. frontend-node по умолчанию работает на 3000 порту. порт недоступн снаружи. редирект в frontend, из 3000 пути /ws, настроить нельзя, т.к. порт 3000 недоступен для frontend, для него доступен только 80 и он расшраен в traefik. расшарить в traefik порт 3000 не получится, т.к. этот порт уже занят frontend-node. как быть в такой ситуации. вижу только одно решение - настроить запросы на 80 порт, а не 3000 - ws://example.com:80/ws. но возможно ли это. как быть в такой ситуации?

Ответить
Konstantin

сам же отвечу ) изменить порт и адрес для ws можно через env переменные WDS_SOCKET_PORT: 3000, WDS_SOCKET_PATH: "sockjs-node".

указал WDS_SOCKET_PORT: 0 в frontend-node и все ок - запросы ws идут на 80 порт

Ответить
Konstantin

разделил проекты на api, frontend и traefik. сделал деплой api и traefik с внешней сетью traefik-public. но запрос curl GET по домену api выдает 443 - "Failed to connect to api.домен.ru port 443: В соединении отказано". почему-то нет логов traefik - команда docker service logs -f <service> показывает пустоту. то же самое с nginx в api.

traefik - https://i.imgur.com/2miMHcN.png https://i.imgur.com/jB8t4hF.png
api - https://i.imgur.com/4eptLom.png https://i.imgur.com/ndznwby.png

может уже сталкивался с этим? или как сделать чтобы логи были.

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

Весьма странно. Если "Failed to connect", то значит сам traefik не запустился.

Ответить
Konstantin

нешл ошибку, волюм указал как путь /traefik-certs:... ))) удалось протолкнуть, но почему то траефик ругается level=error msg="middleware \"secure-headers@docker\" does not exist"

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

Приветствую, подскажите плз как вам удалось разрешить ошибку:

middleware \"secure-headers@docker\" does not exist
Ответить
Дмитрий Ориховский

Всем привет. Кто не смог запустить на MacOS network_mode: service:gateway вот мое решение.

1) добавляем названия контейнера container_name: gateway

gateway:
        container_name: gateway
        build:
            context: gateway/docker
            dockerfile: development/nginx/Dockerfile
        ports:
            - "8080:8080"
            - "8081:8081"
            - "8082:8082"
            - "8083:8083"

2) меняем network_mode на container:gateway

cucumber-node-cli:
        build:
            context: cucumber/docker/development/node
        volumes:
            - ./cucumber:/app
        network_mode: container:gateway
Ответить
Сергей

Добрй день! Все бы ничего но у меня не работает api-php-fpm на локалке гуд но в продакшене не запускается сервис с php. Не могу понять в чем ошибка? из контейнера api не могу достучаться до php пишет curl: (6) Could not resolve host: api-php-fpm

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

Попробуйте зайти на сервер, посмотреть список сервисов:

docker service ls

и вывести логи api-php-fpm:

docker service logs ...
Ответить
Сергей

Спасибо уже решил. Была ошибка в секции deploy в лейбах

Ответить
Максим (@myks92)

Дмитрий, скажите, пожалуйста, как у вас константа DB_PASSWORD_FILE переходит в DB_PASSWORD при использовании secrets: db_password в docker-compose.yaml. На удалённой машине с помощью Jenkins я понял как это делается. А как делать это в режиме разработки на dev окружении? Судя по всему как-то через entrypoint.sh, но у меня на Mac os ругается что нет DB_PASSWORD

Ответить
Максим (@myks92)

Я разобрался и понял что вы сделали это env.php через который получаете данные из файла. А как такое же сделать в yaml файлах на Symfony? Там есть отдельное использование из файлов. Но хотелось бы как у вас.

Ответить
Максим (@myks92)

Кажется и тут нашёл ответ))

Ответить
Сергеев Василий

Объясните пожалуйста, какая есть веская причина отказа от nginx в сторону traefik. Задумался над критичностью использования traefik. Правильно понимаю, что всё это можно было сделать используя nginx?

"В нашей инфраструктуре есть неудобства. В отличие от доменов и поддоменов при разработке и тестировании мы используем маршрутизацию по портам. При тестировании мы используем домен gateway вместо localhost. Все поддомены нам приходится вписывать вручную. И из-за монополии на 80 и 443 порты кластера мы не можем задеплоить несколько проектов."

В чём киллер-фича(и)?

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

Основная киллер-фича Traefik в том, что он автоматически подхватывает настройки из всех сервисов.

В кластер с одним общим Traefik можно задеплоить сколько угодно проектов на любых доменах или поддоменах, и они автоматически получат Let's Encrypt сертификаты и заработают.

А при использовании Nginx+Certbot нужно все конфигурации и домены для каждого сайта прописывать в них вручную.

Ответить
Дмитрий

В видео сказано, что мы используем 1 копию traefik, вместо gateway, где использовали 2 копии для бесшовного деплоя. А если нам нужно будет обновить версию traefik? В этом случае получается не будет бесшовного деплоя?

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

Да, в случае обновления traefik будет пауза. Но если он задеплоен отдельно, то обновлять его мы будем редко. Например, захотим обновить какой-нибудь ночью через месяц.

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

Или войти через:

Yandex
MailRu
GitHub
Google