Как использовать 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
:
- sudo apt-get install apache2-utils
Затем сгенерируйте пароль с помощью htpasswd
. Замените secure_password
паролем, который вы хотите использовать для администратора Traefik:
- htpasswd -nb admin secure_password
Вывод из программы будет выглядеть так:
Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
Вы будете использовать эти выходные данные в файле конфигурации Traefic для настройки базовой HTTP-аутентификации для панели мониторинга и проверки работоспособности Traefik. Скопируйте всю строку вывода, чтобы вы могли вставить ее позже.
Чтобы настроить сервер Traefik, мы создадим новый файл конфигурации с именем traefik.toml
, используя формат TOML. TOML — это язык конфигурации, похожий на файлы INI, но стандартизированный. Этот файл позволяет нам настроить сервер Traefik и различные интеграции или провайдеров, которые мы хотим использовать. В этом руководстве мы будем использовать три доступных провайдера Traefik: web
, docker
и acme
, который используется для поддержки TLS с помощью Let's Encrypt. .
- 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
.
- docker network create proxy
Когда контейнер Traefik запустится, мы добавим его в эту сеть. Затем мы можем добавить дополнительные контейнеры в эту сеть позже, чтобы Traefik мог использовать прокси.
Затем создайте пустой файл, в котором будет храниться наша информация Let’s Encrypt. Мы поместим это в контейнер, чтобы Traefik мог его использовать:
- touch acme.json
Traefik сможет использовать этот файл только в том случае, если пользователь root внутри контейнера имеет уникальный доступ для чтения и записи к нему. Для этого заблокируйте разрешения на acme.json
, чтобы только владелец файла имел разрешение на чтение и запись.
- chmod 600 acme.json
Как только файл будет передан в Docker, владелец автоматически изменится на пользователя root внутри контейнера.
Наконец, создайте контейнер Traefik с помощью этой команды:
- docker run -d \
- -v /var/run/docker.sock:/var/run/docker.sock \
- -v $PWD/traefik.toml:/traefik.toml \
- -v $PWD/acme.json:/acme.json \
- -p 80:80 \
- -p 443:443 \
- -l traefik.frontend.rule=Host:monitor.example.com \
- -l traefik.port=8080 \
- --network proxy \
- --name traefik \
- 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:
- Блог, использующий официальное изображение Wordpress.
- Сервер управления базой данных, использующий официальный образ администратора.
Мы будем управлять обоими этими приложениями с помощью Docker Compose, используя файл docker-compose.yml
:
- 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
, прежде чем запускать свои контейнеры:
- export WORDPRESS_DB_PASSWORD=secure_database_password
- export MYSQL_ROOT_PASSWORD=secure_database_password
Замените secure_database_password
на желаемый пароль базы данных.
Установив эти переменные, запустите контейнеры с помощью docker-compose
:
- 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.