Мастер Траэфик

Интегрируйте обратный прокси Traefik 2.1 со службами Docker Swarm

Динамически создавайте и предоставляйте правила маршрутизации для ваших служб без перезапуска или повторного развертывания обратного прокси-сервера.

Traefik - это Edge Router с открытым исходным кодом, который делает публикацию ваших сервисов увлекательной и простой. Он получает запросы от имени вашей системы и выясняет, какие компоненты отвечают за их обработку.

Https://docs.traefik.io/

Traefik поддерживает широкий спектр функций, включая обработку трафика TCP, сертификаты SSL и подключение промежуточного программного обеспечения к определенным маршрутам. Однако наиболее заметной особенностью является возможность автоматического обнаружения конфигураций прокси для определенных служб. Traefik постоянно проверяет инфраструктуру и собирает информацию, необходимую для определения прокси-маршрутов, сервисов и промежуточного программного обеспечения. Например, в случае кластеров Docker Swarm он проверяет службы роя и проверяет определенные метки для каждой из служб. Кроме того, он поддерживает большинство основных кластерных технологий, таких как Docker Swarm, Kubernetes, Mesos, Marathon и многие другие.

В этой статье мы собираемся изучить некоторые функции и возможности Traefik, создав и развернув Traefik в кластере Docker Swarm. Я буду использовать этот репозиторий Github для демонстрации возможностей Traefik. Вы можете начать с клонирования репозитория, используя следующую команду:

$> git clone [email protected]:wshihadeh/traefik_v2.git

Развертывание служб Swarm

Вышеупомянутый репозиторий содержит определение службы для стандартного приложения Rails. В этой статье мы будем управлять этими сервисами с помощью Traefik. В приведенных ниже фрагментах показано определение службы Swarm для приложения Rails:

Службы, определенные в указанном выше файле, можно развернуть локально, выполнив следующую команду в корневой папке репозитория:

$> DEPLOY_VERSION=v1 make deploy

После выполнения этой команды вы сможете проверить службу и контейнеры Docker. Однако вы не сможете получить доступ к веб-интерфейсу Rails, поскольку мы не открыли порты на хост-сервере.

Разверните Traefik с минимальными настройками

Чтобы иметь доступ к веб-интерфейсу приложения Rails, мы развернем Traefik с базовыми конфигурациями, необходимыми для предоставления сервиса. Для выполнения этой задачи нам необходимо добавить сервис Traefik в сервис Swarm со следующими базовыми конфигурациями:

  • provider.docker: Установите используемый провайдер Traefik, здесь можно выбрать пару опций.
  • entrypoint.web.address: Определите порт конечной веб-точки (внутренний порт).
  • providers.${item}: Определите конфигурации, зависящие от поставщика Docker, такие как Swarm-Mode, доменное имя по умолчанию, и следите за инфраструктурой.

В приведенном ниже фрагменте кода показана точная docker-compose служба, которую можно использовать для развертывания Traefik:

Затем нам нужно добавить следующие метки в службу приложения Rails:

  • traefik.enable: этот ярлык включает и отключает отображение службы в службе Traefik.
  • traefik.http.${service_name}.loadbalancer.server.port: Внутренний порт службы, на который Traefik будет пересылать ему запрос. Обратите внимание, что здесь необходимо изменить service_name.
  • traefik.http.routers.${router_name}.rule: Правило маршрутизации, которое будет использоваться Traefik для пересылки входящих запросов в службу Rails. Traefik поддерживает несколько типов правил маршрутизации, например Хост, Путь и Метод. Здесь вы можете узнать больше о поддерживаемых правилах. Для нашей службы мы собираемся использовать правило Host со следующим значением blog.local.me. Это означает, что Traefik будет перенаправлять входящий запрос с заданным значением host в службу rails_blog. .
  • traefik.http.routers.${router_name}.service: эта метка определяет службу, связанную с определенным маршрутизатором. Значение этой метки должно быть таким же, как ${service_name}.
  • traefik.http.routers.${router_name}.entrypoints: точки входа, к которым подключен маршрутизатор. Значение метки может быть списком всех подключенных конечных точек, разделенных запятыми.
  • traefik.docker.network: Эта метка определяет сеть, которая будет использоваться для доступа к сервисной форме Traefik.

Разверните новые изменения из предоставленного репозитория с помощью следующих команд:

$> make clean
$> DEPLOY_VERSION=v2 make deploy

Вам также необходимо добавить следующую строку в ваш /etc/hosts файл:

127.0.0.1 blog.local.me local.me

После выполнения описанных выше шагов вы сможете получить доступ к приложению Rails на определенном Hostname.

Откройте панель администратора и конечную точку Ping

Traefik предоставляет панель администратора, которая помогает администраторам проверять и просматривать ресурсы Traefik, такие как маршрутизаторы, службы и промежуточное ПО. Эта панель мониторинга не отображается по умолчанию, поэтому нам нужно явно настроить трафик, чтобы раскрыть ее. Ниже приведены необходимые конфигурации для выполнения задачи:

  • api=true: Включите службу Traefik API.
  • api.insecure=true: включить небезопасный режим API.
  • api.dashboard: включить панель управления Traefik.

Кроме того, для включения конечной точки ping нам потребуются следующие конфигурации. Эту конечную точку можно использовать для проверки работоспособности службы Traefik с помощью служб мониторинга или балансировщиков нагрузки.

  • ping.entrypoint=web

Развертывание новых изменений может быть выполнено с помощью следующих команд.

$> make clean
$> DEPLOY_VERSION=v3 make deploy

После развертывания вы сможете получить доступ как к панели управления, так и к конечной точке ping, как показано на изображениях ниже:

Предоставьте доступ к конечной точке показателей и защитите ее с помощью учетных данных с базовой аутентификацией

Traefik поддерживает несколько серверных метрик, таких как Datadog и InfluxDB. Каждая из поддерживаемых серверных частей имеет свои собственные элементы конфигурации, но все они могут быть настроены одинаково.

В нашем примере мы настроим Traefik для предоставления метрик Prometheus и защиты конечной точки метрик с помощью basic-auth учетных данных. Вот краткое описание конфигураций Traefik, необходимых для включения конечной точки Prometheus:

  • entrypoint.metrics.address=:8082: Определите внутренний порт для службы метрик.
  • metrics.prometheus=true: включить службу Prometheus. Сервис будет доступен под следующим названием «prometheus @ internal».
  • metrics.prometheus.addEntryPointLabels=true: разрешить добавление меток точек входа к показанным метрикам.
  • metrics.prometheus.addServicesLabels=true: разрешить добавление ярлыков служб к показанным метрикам.
  • metrics.prometheus.manualrouting=true: Разрешить создание маршрутизаторов для Prometheus вручную. Эта опция необходима, потому что мы хотели бы добавить basic-auth промежуточное ПО для защиты конечной точки. Если вам не нужна basic-auth защита, вы можете оставить этот пункт.

С другой стороны, защита конечной точки метрик может быть выполнена путем определения меток в самой службе Traefik. Обычно метки инструктируют Traefik создать промежуточное программное обеспечение с базовой аутентификацией и связать его с маршрутизатором, используемым для доступа к конечной точке метрик. Они есть:

  • traefik.http.middlewares.${name}.basicauth.users: Определите промежуточное программное обеспечение basic-auth и назначьте учетные данные промежуточного программного обеспечения. Значение этой метки можно сгенерировать с помощью следующей команды.
$> echo $(htpasswd -nb ${user} ${password}) | sed -e s/\\$/\\$\\$/g
$> echo $(htpasswd -nb traefik traefik2020) | sed -e s/\\$/\\$\\$/g
  • traefik.http.services.prometheus.loadbalancer.port: эта метка определяет внутренний порт службы Prometheus.
  • traefik.http.routers.rule: Определите правило маршрутизатора для доступа к конечной точке метрик. мы сохраним простоту и воспользуемся правилом PathPrefix PathPrefix(`/metrics`).
  • traefik.http.routers.service: имя службы Prometheus. Значение этой метки должно быть «prometheus @ internal».
  • traefik.http.routers.entrypoint: определяет точку входа для маршрутизатора Prometheus.
  • traefik.http.routers.middleware: Определите связанное ПО промежуточного слоя к маршрутизатору Prometheus. В нашем случае оно будет таким же, как определенное выше промежуточное ПО.

Разверните новые изменения с помощью этих команд:

$> make clean
$> DEPLOY_VERSION=v4 make deploy

После развертывания новых изменений вы сможете получить доступ к конечной точке метрик на открытом порте 8082, как показано на изображениях ниже.

Добавление настраиваемых заголовков в запросы и ответы

Эту задачу легко решить, используя только метки Docker Swarm. Например, если мы хотим добавить X-REQUEST-SOURCE и X-RESPONSE-SOURCE к запросам и ответам приложения Rails, нам нужно добавить промежуточное программное обеспечение ниже и присоединить его к маршрутизатору службы.

Обработка запросов HTTPS

Traefik также можно настроить для обработки запросов HTTPS. Эту задачу можно выполнить с помощью следующих элементов конфигурации как в службе Traefik, так и в службе приложений Rails.

Ярлыки Traefik:

  • entrypoint.websecure.address: Определите внутренний порт, который будет использоваться для обработки запросов HTTPS. Здесь также можно настроить имя точки входа, и вы можете выбрать для нее любое имя, кроме «websecure».

Ярлыки приложений Rails:

  • traefik.http.routers.${router_name}.tls=true: включить соединение TLS для приложения Rails.
  • traefik.http.routers.${router_name}.entrypoints=websecure: использовать конечную точку TLS для обработки веб-запросов приложения Rails.

Развертывание новых изменений выполняется с помощью следующих команд:

$> make clean
$> DEPLOY_VERSION=v6 make deploy

После развертывания новых изменений вы можете получить доступ к приложению Rails по протоколу HTTPS, как показано на изображении ниже. Однако, поскольку у нас нет действующего сертификата TLS для размещенного домена, веб-браузер запросит подтверждение доступа к странице и покажет, что это небезопасная страница.

Используйте действительный сертификат TLS

Traefik поддерживает несколько вариантов обработки сертификатов TLS. В зависимости от ваших потребностей вы можете выбрать один из этих вариантов. Например, если у вас уже есть действующие файлы сертификатов TLS, вы можете настроить Traefik, указав путь к ключу сертификата и файлу сертификата, как описано здесь.

Traefik также поддерживает создание сертификатов TLS с помощью Let's Encrypt. Я продемонстрирую, как настроить Traefik для генерации подстановочного сертификата TLS с помощью Let's Encrypt и сервиса AWS route53.

Примечание. Предварительным условием для этого шага является наличие действующей учетной записи и домена AWS.

Чтобы переключиться с внутреннего домена, использованного выше, на действительный домен с действующим сертификатом TLS, нам необходимо выполнить следующие действия как в Traefik, так и в приложении Rails.

Добавьте или измените следующие аргументы команды Traefik:

  • provider.docker.defaultRule: Обновите эту метку, указав зарегистрированное доменное имя.
  • certificateresolvers.route53.acme.dnschallange: добавьте новый преобразователь сертификатов с именем route53 (его можно назвать как угодно) и включите запрос DNS.
  • certificateresolvers.route53.acme.dnschallange.provider: установите для поставщика преобразователей DNS значение route53 .
  • certificateresolvers.route53.acme.email: Определите адрес электронной почты, который будет использоваться для сертификата TLS.
  • certificateresolvers.route53.acme.storage: Определите путь к файлу ACME. этот файл будет содержать информацию о сертификате TLS, и вам может потребоваться указать путь к файлу вне контейнера.

Добавьте учетные данные AWS: ключ и секрет AWS необходимы для обработки запроса DNS. Учетные данные необходимо передать в качестве переменных среды в службу Traefik.

Добавьте метки Traefik для создания подстановочных сертификатов. Нам нужны следующие метки, чтобы добавить подстановочный знак (имя может быть любым) маршрутизатора и дать Traefik команду сгенерировать подстановочный сертификат для настроенного домена.

  • traefik.http.routers.wildcard.tls: включить поддержку TLS для маршрутизатора с подстановочными знаками.
  • traefik.http.routers.wildcard.certresolver: выберите преобразователи сертификатов. Traefik поддерживает несколько предложений для решения проблемы DNS. В нашем случае мы будем использовать route53 для обработки запроса DNS.
  • traefik.http.routers.wildcard.domain[0].main: Определите основной домен сертификата TLS.
  • traefik.http.routers.wildcard.domain[0].sans: Определите другие домены, включенные в сертификат TLS.

Обновите метку приложения Rails:

  • traefik.http.routers.${router_name}.rule: нам нужно обновить имя хоста службы, чтобы оно было действительным blog.wshihadeh.cloud.

Развертывание новых изменений:

$> make clean
$> DEPLOY_VERSION=v7 make deploy

Перенаправить входящие HTTP-запросы на HTTPS

Перенаправление HTTP-трафика на HTTPS на веб-сайтах - обычная практика. Traefik поддерживает эту функцию через промежуточное программное обеспечение перенаправления. Вот краткое описание элементов конфигурации, необходимых для выполнения этой задачи.

  • traefik.http.middlewares.${name}.redirectscheme.scheme: Определите промежуточное программное обеспечение схемы перенаправления. Значение этой метки должно быть https.
  • traefik.http.middlewares.${name}.redirectscheme.permanent: включить постоянное перенаправление для определенного промежуточного программного обеспечения.
  • traefik.http.routers.${router_name}.rule: Определите маршрутизатор для всех входящих HTTP-запросов. Значение этой метки должно быть подстановочным знаком, чтобы включать все запросы.
  • traefik.http.routers.${router_name}.entrypoints: Установите маршрутизатор для связи с точкой входа «Интернет».
  • traefik.http.routers.${router_name}.middlewares: Свяжите определенное промежуточное ПО с маршрутизатором HTTP.

На изображениях ниже показана разница в поведении Traefik до и после внедрения изменений. Как видите, без изменений Traefik ответит ошибкой 404 - после развертывания он ответит 308, что является перенаправлением на HTTPS.

Перенаправить входящие запросы на страницу регистрации

Здесь я хотел бы продемонстрировать, как мы можем настроить более сложные правила переадресации для определенных служб. Маршрутизатор приложения Rails обрабатывает только входящий запрос с хостом blog.wshihadeh.cloud. С помощью приведенной ниже конфигурации мы можем расширить маршрутизаторы, чтобы они имели следующее поведение:

  • Обрабатывает входящие запросы для wshihadeh.cloud, www.wshihadeh.cloud и blog.wshihadeh.cloud.
  • Перенаправьте входящий запрос на www.wshihadeh.cloud на blog.wshihadeh.cloud/users/sign_up
  • Защитите страницу регистрации с помощью базовых учетных данных.

На изображениях ниже показана разница в поведении Traefik до и после развертывания версии 9.

Обработка сертификата клиента TLS

В этом разделе я покажу, как мы можем настроить Traefik для обработки клиентских сертификатов TLS и как передать сертификаты в приложение Rails для дальнейшей обработки.

Настройте Traefik для запроса сертификата клиента. К сожалению, мне не удалось найти способ настроить сертификат клиента TLS с помощью поставщика Docker. Однако этого можно достичь с помощью поставщика файлов. В приведенном ниже фрагменте показана необходимая конфигурация для запроса сертификата клиента для TLS-соединений:

[tls.options]
  [tls.options.my-tls-opt]
    [tls.options.my-tls-opt.clientAuth]
      caFiles = ["/run/secrets/trusted_ca"]
      clientAuthType = "RequestClientCert"

Чтобы настроить наш экземпляр Traefik с этими конфигурациями, нам необходимо выполнить следующее действие:

  • provider.file.filename: определите поставщика файлов и свяжите его с файлом, содержащим конфигурации.
  • Прикрепите файл конфигурации как том к сервису Traefik.
  • Прикрепите сертификат CA, используемый для проверки клиентских сертификатов, в качестве секрета к службе Traefik.

Настройте маршрутизатор приложения Rails для передачи сертификата клиента службе. Эту задачу можно выполнить, добавив в маршрутизатор приложений Rails следующее промежуточное ПО:

После развертывания последних изменений в версии 10 вы увидите маршрутизатор приложений Rails на панели инструментов Traefik со всем подключенным промежуточным программным обеспечением, как показано на изображении ниже.

Ограничение источников конфигураций Traefik

В некоторых случаях необходимо определить несколько экземпляров Traefik для обработки различных наборов служб, возможно, из-за риска для безопасности, связанного с открытием внутренних служб на том же обратном прокси-сервере, что и общедоступные службы. В результате необходимо настроить экземпляры Traefik таким образом, чтобы они включали только частные или общедоступные службы, но не оба сразу. Этого можно добиться, просто добавив следующие конфигурации и метки.

  • Аргумент команды Traefik. Конфигурация ниже ограничит использование Traefik только теми сервисами, которые имеют метку traefik.tags со значением public.
--providers.docker.constraints=Label(`traefik.tags`,`public`)’
  • Ярлыки служб. Приведенную ниже метку необходимо добавить к каждой службе, которой должен управлять экземпляр Traefik, включая саму службу Traefik.
- traefik.tags=public

В приведенном ниже файле docker-compose показан полный стек со всеми функциями, обсуждаемыми в этой статье:

Наконец, вы можете развернуть последнюю версию со всеми реализованными функциями, используя следующую команду:

$> make clean
$> DEPLOY_VERSION=v11 make deploy

Заключение

Traefik - отличный инструмент и обратный прокси. Он поддерживает широкий спектр функций и, что наиболее важно, его можно динамически настраивать с помощью меток Docker Swarm - нет необходимости перезапускать или перезагружать Traefik, чтобы применить новые изменения.

Все функции, реализованные в этом посте, можно найти в этом репозитории.