Поиск по сайту:

Как использовать Traefik в качестве обратного прокси-сервера для контейнеров Docker в Ubuntu 16.04


Введение

Docker может быть эффективным способом запуска веб-приложений в рабочей среде, но вам может понадобиться запустить несколько приложений на одном хосте Docker. В этой ситуации вам нужно настроить обратный прокси-сервер, так как вы хотите открыть только порты 80 и 443 для остального мира.

Давайте зашифруем.

Предпосылки

Чтобы следовать этому руководству, вам понадобится следующее:

  • Один сервер Ubuntu 16.04, настроенный в соответствии с руководством по начальной настройке сервера Ubuntu 16.04, включая пользователя без полномочий root и брандмауэр.
  • Docker установлен на вашем сервере, что вы можете сделать, следуя инструкциям по установке и использованию Docker в Ubuntu 16.04.
  • Docker Compose устанавливается с помощью инструкций из раздела Как установить Docker Compose в Ubuntu 16.04.
  • Домен и три записи A, db-admin, blog и monitor, каждая из которых указывает на IP-адрес вашего сервера. Вы можете узнать, как указать домены на дроплеты DigitalOcean, прочитав документацию DigitalOcean по доменам и DNS. В этом руководстве замените свой домен на example.com в файлах конфигурации и примерах.

Шаг 1 — Настройка и запуск Traefik

У проекта Traefik есть официальный образ Docker, поэтому мы будем использовать его для запуска Traefik в контейнере Docker.

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

Мы будем использовать утилиту htpasswd для создания этого зашифрованного пароля. Сначала установите утилиту, входящую в пакет apache2-utils:

  1. sudo apt-get install apache2-utils

Затем сгенерируйте пароль с помощью htpasswd. Замените secure_password паролем, который вы хотите использовать для администратора Traefik:

  1. htpasswd -nb admin secure_password

Вывод из программы будет выглядеть так:

Output
admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

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

Чтобы настроить сервер Traefik, мы создадим новый файл конфигурации с именем traefik.toml, используя формат TOML. TOML — это язык конфигурации, похожий на файлы INI, но стандартизированный. Этот файл позволяет нам настроить сервер Traefik и различные интеграции или провайдеров, которые мы хотим использовать. В этом руководстве мы будем использовать три доступных провайдера Traefik: web, docker и acme, который используется для поддержки TLS с помощью Let's Encrypt. .

  1. nano traefik.toml

Во-первых, добавьте две именованные точки входа, http и https, к которым по умолчанию будут иметь доступ все серверные части:

defaultEntryPoints = ["http", "https"]

Точки входа http и https мы настроим позже в этом файле.

Затем настройте поставщика web, который предоставит вам доступ к интерфейсу панели инструментов. Сюда вы вставите вывод команды htpasswd:

...
[web]
address = ":8080"
  [web.auth.basic]
  users = ["admin:your_encrypted_password"]

Панель инструментов — это отдельное веб-приложение, которое будет работать в контейнере Traefik. Мы настроили панель инструментов для работы на порту 8080.

Раздел web.auth.basic настраивает базовую HTTP-аутентификацию для панели управления. Используйте выходные данные только что выполненной команды htpasswd для значения записи users. Вы можете указать дополнительные логины, разделив их запятыми.

Далее определяем точки входа. Раздел entryPoints настраивает адреса, которые могут прослушивать Traefik и прокси-контейнеры. Добавьте эти строки в файл:

...
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

Точка входа http обрабатывает порт 80, а точка входа https использует порт 443 для TLS/SSL. Мы автоматически перенаправляем весь трафик через порт 80 на точку входа https, чтобы обеспечить безопасное соединение для всех запросов.

Наконец, добавьте этот раздел, чтобы настроить поддержку сертификатов Let’s Encrypt для Traefik:

...
[acme]
email = "your_email@example.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false

Этот раздел называется acme, потому что ACME — это название протокола, используемого для связи с Let’s Encrypt для управления сертификатами. Чтобы Traefik генерировал сертификаты для наших хостов, мы устанавливаем ключ email на ваш адрес электронной почты. Затем мы указываем, что будем хранить информацию, которую получим от Let’s Encrypt, в файле JSON с именем acme.json. Ключ entryPoint должен указывать на точку входа, обрабатывающую порт 443, который в нашем случае является точкой входа https.

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

Сохраните файл и выйдите из редактора. Со всей этой конфигурацией мы можем запустить Traefik.

Шаг 2 — Запуск контейнера Traefik

Затем создайте сеть Docker, чтобы прокси-сервер мог совместно использовать контейнеры. Сеть Docker необходима, чтобы мы могли использовать ее с приложениями, которые запускаются с помощью Docker Compose. Назовем эту сеть proxy.

  1. docker network create proxy

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

Затем создайте пустой файл, в котором будет храниться наша информация Let’s Encrypt. Мы поместим это в контейнер, чтобы Traefik мог его использовать:

  1. touch acme.json

Traefik сможет использовать этот файл только в том случае, если пользователь root внутри контейнера имеет уникальный доступ для чтения и записи к нему. Для этого заблокируйте разрешения на acme.json, чтобы только владелец файла имел разрешение на чтение и запись.

  1. chmod 600 acme.json

Как только файл будет передан в Docker, владелец автоматически изменится на пользователя root внутри контейнера.

Наконец, создайте контейнер Traefik с помощью этой команды:

  1. docker run -d \
  2. -v /var/run/docker.sock:/var/run/docker.sock \
  3. -v $PWD/traefik.toml:/traefik.toml \
  4. -v $PWD/acme.json:/acme.json \
  5. -p 80:80 \
  6. -p 443:443 \
  7. -l traefik.frontend.rule=Host:monitor.example.com \
  8. -l traefik.port=8080 \
  9. --network proxy \
  10. --name traefik \
  11. traefik:1.3.6-alpine --docker

Команда немного длинная, поэтому давайте разберем ее.

Мы используем флаг -d для запуска контейнера в фоновом режиме в качестве демона. Затем мы делимся нашим файлом docker.sock с контейнером, чтобы процесс Traefik мог прослушивать изменения в контейнерах. Мы также совместно используем файл конфигурации traefik.toml и файл acme.json, который мы создали в контейнере.

Затем мы сопоставляем порты :80 и :443 нашего хоста Docker с теми же портами в контейнере Traefik, чтобы Traefik получал весь HTTP- и HTTPS-трафик на сервер.

Затем мы настраиваем две метки Docker, которые указывают Traefik направлять трафик на имя хоста monitor.example.com на порт :8080 внутри контейнера Traefik. , открывая панель мониторинга.

Мы устанавливаем сеть контейнера на proxy и называем контейнер traefik.

Наконец, мы используем образ traefik:1.3.6-alpine для этого контейнера, потому что он маленький.

ENTRYPOINT образа Docker — это команда, которая всегда запускается при создании контейнера из образа. В этом случае команда представляет собой двоичный файл traefik внутри контейнера. Вы можете передать дополнительные аргументы этой команде при запуске контейнера. В нашем случае мы передаем аргумент --docker в ENTRYPOINT, что гарантирует, что провайдер docker зарегистрирован с настройками по умолчанию. Поставщик docker позволяет Traefik выступать в качестве прокси-сервера перед контейнерами Docker. Конфигурация поставщика Docker по умолчанию нам подходит, поэтому нам не нужно настраивать ее в нашем traefik.toml.

Когда контейнер запущен, у вас теперь есть панель мониторинга, к которой вы можете получить доступ, чтобы увидеть состояние своих контейнеров. Вы также можете использовать эту панель управления для визуализации внешних и внутренних интерфейсов, зарегистрированных Traefik. Получите доступ к панели мониторинга, указав в браузере https://monitor.example.com. Вам будет предложено ввести имя пользователя и пароль, которые являются admin и паролем, который вы настроили на шаге 1.

После входа в систему. вы увидите интерфейс, похожий на этот:

Пока не на что смотреть, но оставьте это окно открытым, и вы увидите, как содержимое меняется, когда вы добавляете контейнеры для работы с Traefik.

Теперь у нас запущен прокси-сервер Traefik, он настроен для работы с Docker и готов отслеживать другие контейнеры Docker. Давайте запустим несколько контейнеров, для которых Traefik будет выступать в качестве прокси.

Шаг 3 — Регистрация контейнеров в Traefik

Запустив контейнер Traefik, вы готовы запускать приложения за ним. Давайте запустим следующие контейнеры позади Traefik:

  1. Блог, использующий официальное изображение Wordpress.
  2. Сервер управления базой данных, использующий официальный образ администратора.

Мы будем управлять обоими этими приложениями с помощью Docker Compose, используя файл docker-compose.yml:

  1. nano docker-compose.yml

Добавьте следующие строки в файл, чтобы указать версию и сети, которые мы будем использовать:

version: "3"

networks:
  proxy:
    external: true
  internal:
    external: false

Мы используем Docker Compose версии 3, поскольку это новейшая основная версия формата файла Compose.

Чтобы Traefik распознал наши приложения, они должны быть частью одной сети, а так как мы создали сеть вручную, мы подтягиваем ее, указав сетевое имя proxy и установив external на true. Затем мы определяем другую сеть, чтобы мы могли подключить наши открытые контейнеры к контейнеру базы данных, который мы не будем раскрывать через Traefik. Мы назовем эту сеть internal.

Далее мы определим каждый из наших сервисов по одному. Начнем с контейнера blog, в основе которого лежит официальный образ WordPress. Добавьте эту конфигурацию в файл:

version: "3"
...

services:
  blog:
    image: wordpress:4.7.5-apache
    environment:
      WORDPRESS_DB_PASSWORD:
    labels:
      - traefik.backend=blog
      - traefik.frontend.rule=Host:blog.example.com
      - traefik.docker.network=proxy
      - traefik.port=80
    networks:
      - internal
      - proxy
    depends_on:
      - mysql

Ключ environment позволяет указать переменные среды, которые будут установлены внутри контейнера. Не устанавливая значение для WORDPRESS_DB_PASSWORD, мы сообщаем Docker Compose, что нужно получить значение из нашей оболочки и передать его при создании контейнера. Мы определим эту переменную среды в нашей оболочке перед запуском контейнеров. Таким образом, мы не прописываем пароли в конфигурационный файл.

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

  • traefik.backend указывает имя серверной службы в Traefik (которое указывает на фактический контейнер blog).
  • traefik.frontend.rule=Host:blog.example.com указывает Traefik проверить запрошенный хост и проверить, соответствует ли он шаблону блога.< mark>example.com он должен направлять трафик в контейнер blog.
  • traefik.docker.network=proxy указывает, в какой сети следует искать Traefik, чтобы найти внутренний IP-адрес для этого контейнера. Поскольку у нашего контейнера Traefik есть доступ ко всей информации Docker, он потенциально может использовать IP-адрес для внутренней сети, если мы не укажем это.
  • traefik.port указывает открытый порт, который Traefik должен использовать для маршрутизации трафика в этот контейнер.

При такой конфигурации весь трафик, отправляемый на порт 80 нашего хоста Docker, будет направляться в контейнер blog.

Мы назначаем этот контейнер двум разным сетям, чтобы Traefik мог найти его через сеть proxy и мог взаимодействовать с контейнером базы данных через сеть internal.

Наконец, ключ depends_on сообщает Docker Compose, что этот контейнер необходимо запустить после выполнения его зависимостей. Поскольку для работы WordPress требуется база данных, мы должны запустить наш контейнер mysql перед запуском нашего контейнера blog.

Затем настройте службу MySQL, добавив эту конфигурацию в свой файл:

services:
...
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD:
    networks:
      - internal
    labels:
      - traefik.enable=false

Мы используем официальный образ MySQL 5.7 для этого контейнера. Вы заметите, что мы снова используем элемент environment без значения. Для переменных MYSQL_ROOT_PASSWORD и WORDPRESS_DB_PASSWORD необходимо установить одно и то же значение, чтобы убедиться, что наш контейнер WordPress может взаимодействовать с MySQL. Мы не хотим предоставлять контейнер mysql для Traefik или внешнего мира, поэтому мы назначаем этот контейнер только для внутренней сети. Поскольку у Traefik есть доступ к сокету Docker, процесс по-прежнему будет предоставлять внешний интерфейс для контейнера mysql по умолчанию, поэтому мы добавим метку traefik.enable=false в укажите, что Traefik не должен предоставлять доступ к этому контейнеру.

Наконец, добавьте эту конфигурацию, чтобы определить контейнер администратора:

services:
...

  adminer:
    image: adminer:4.3.1-standalone
    labels:
      - traefik.backend=adminer
      - traefik.frontend.rule=Host:db-admin.example.com
      - traefik.docker.network=proxy
      - traefik.port=8080
    networks:
      - internal
      - proxy
    depends_on:
      - mysql

Этот контейнер основан на официальном образе администратора. Конфигурация network и depends_on для этого контейнера точно соответствует тому, что мы используем для контейнера blog.

Однако, поскольку мы направляем весь трафик на порт 80 на нашем хосте Docker непосредственно в контейнер blog, нам нужно настроить этот контейнер по-другому, чтобы трафик сделайте это в нашем контейнере adminer. Строка traefik.frontend.rule=Host:db-admin.example.com указывает Traefik проверить запрошенный хост. Если он соответствует шаблону db-admin.example.com, Traefik направит трафик в контейнер adminer.

Сохраните файл и выйдите из текстового редактора.

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

  1. export WORDPRESS_DB_PASSWORD=secure_database_password
  2. export MYSQL_ROOT_PASSWORD=secure_database_password

Замените secure_database_password на желаемый пароль базы данных.

Установив эти переменные, запустите контейнеры с помощью docker-compose:

  1. docker-compose up -d

Теперь еще раз взгляните на панель администратора Traefik. Вы увидите, что теперь есть backend и frontend для двух открытых серверов:

Перейдите к blog.example.com, заменив example.com своим доменом. Вы будете перенаправлены на соединение TLS и теперь можете завершить настройку Wordpress:

Теперь войдите в Администратор, посетив db-admin.example.com в своем браузере, снова заменив example.com своим доменом. Контейнер mysql не открыт для внешнего мира, но контейнер adminer имеет к нему доступ через внутреннюю сеть Docker, которую они совместно используют с помощью имя контейнера mysql в качестве имени хоста.

На экране входа администратора используйте имя пользователя root, используйте mysql для сервера и используйте значение, которое вы установили для MYSQL_ROOT_PASSWORD в качестве пароля. После входа в систему вы увидите пользовательский интерфейс администратора:

Оба сайта теперь работают, и вы можете использовать панель управления на странице monitor.example.com, чтобы следить за своими приложениями.

Заключение

В этом руководстве вы настроили Traefik для прокси-запросов к другим приложениям в контейнерах Docker.

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

Чтобы узнать больше о том, что вы можете делать с Traefik, перейдите к официальной документации Traefik.