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

_ Автор выбрал Girls Who Code, чтобы получить пожертвование в рамках программы Write for DOnations ._

Вступление

https://www.docker.com [Docker] может быть эффективным способом запуска веб-приложений в рабочей среде, но вы можете запустить несколько приложений на одном хосте Docker. В этой ситуации вам потребуется настроить обратный прокси, поскольку вы хотите открыть порты + 80 + и + 443 + для остального мира.

https://traefik.io [Traefik] - обратный прокси-сервер с поддержкой Docker, включающий собственную панель мониторинга. В этом руководстве вы будете использовать Traefik для маршрутизации запросов в два разных контейнера веб-приложения: контейнер http://wordpress.org [Wordpress] и контейнер Adminer, каждый из которых говорит в базу данных MySQL. Вы настроите Traefik для обслуживания всего через HTTPS, используя Let’s Encrypt.

Предпосылки

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

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

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

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

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

sudo apt-get install apache2-utils

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

htpasswd -nb admin

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

Outputadmin:

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

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

Откройте ваш новый файл в + nano + или в вашем любимом текстовом редакторе:

nano traefik.toml

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

traefik.toml

defaultEntryPoints = ["http", "https"]

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

Затем настройте провайдера + api, который дает вам доступ к интерфейсу панели мониторинга. Здесь вы вставите вывод команды + htpasswd +:

traefik.toml

...
[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]

[api]
entrypoint="dashboard"

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

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

Мы определили наш первый + entryPoint +, но нам нужно определить другие для стандартной коммуникации HTTP и HTTPS, которая не направлена ​​на поставщика + api +. Раздел + entryPoints + настраивает адреса, которые могут прослушивать Traefik и прокси-контейнеры. Добавьте эти строки в файл под заголовком + entryPoints +:

traefik.toml

...
 [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 Encrypt для Traefik:

traefik.toml

...
[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

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

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

Раздел + acme.httpChallenge + позволяет нам указать, как Let Encrypt может проверить, должен ли быть сгенерирован сертификат. Мы настраиваем его на обслуживание файла как часть задачи через точку входа + http +.

Наконец, давайте настроим провайдера + docker +, добавив в файл следующие строки:

traefik.toml

...
[docker]
domain = ""
watch = true
network = "web"

Поставщик + docker + позволяет Traefik выступать в качестве прокси-сервера перед контейнерами Docker. Мы настроили провайдера на «+ watch» для новых контейнеров в сети «+ web» (которые мы скоро создадим) и выставляем их в качестве поддоменов «++».

На этом этапе + traefik.toml + должно иметь следующее содержимое:

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

[docker]
domain = ""
watch = true
network = "web"

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

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

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

docker network create

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

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

touch

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

chmod 600

Как только файл будет передан в 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. \
 -l traefik.port=8080 \
 --network web \
 --name traefik \
 traefik:1.7.2-alpine

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

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

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

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

Мы устанавливаем для сети контейнера значение + web + и называем контейнер + traefik +.

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

Docker image + ENTRYPOINT - это команда, которая всегда выполняется, когда из образа создается контейнер. В этом случае команда является двоичным файлом + traefik + внутри контейнера. Вы можете передать дополнительные аргументы этой команде при запуске контейнера, но мы настроили все наши настройки в файле + traefik.toml +.

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

После входа вы увидите интерфейс, подобный следующему:

изображение: http: //assets.digitalocean.com/articles/63957_Traefik/Empty_Traefik_dashboard.png [Пустая панель инструментов Traefik]

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

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

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

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

  1. Блог с использованием official Wordpress image.

  2. Сервер управления базой данных с использованием official Adminer image.

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

nano docker-compose.yml

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

докер-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

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

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

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

докер-compose.yml

version: "3"
...

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

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

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

  • + traefik.backend + указывает имя бэкэнд-сервиса в Traefik (которое указывает на фактический контейнер + blog +).

  • + traefik.frontend.rule = Host: blog. + говорит Traefik проверить запрошенный хост и, если он соответствует шаблону + blog. +, он должен направить трафик в контейнер + blog +.

  • + traefik.docker.network = web + указывает, в какой сети искать Traefik для поиска внутреннего IP-адреса для этого контейнера. Поскольку наш контейнер Traefik имеет доступ ко всей информации Docker, он потенциально может получить IP для сети «+ internal +», если мы не укажем это.

  • + traefik.port + указывает открытый порт, который Traefik должен использовать для маршрутизации трафика в этот контейнер.

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

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

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

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

докер-compose.yml

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 не должен предоставлять этот контейнер. ,

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

докер-compose.yml

services:
...
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

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

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

На этом этапе + docker-compose.yml + должен иметь следующее содержимое:

докер-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

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

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

export WORDPRESS_DB_PASSWORD=
export MYSQL_ROOT_PASSWORD=

Замените ++ на ваш желаемый пароль базы данных. Не забудьте использовать один и тот же пароль для + WORDPRESS_DB_PASSWORD + и + MYSQL_ROOT_PASSWORD +.

С этими установленными переменными запустите контейнеры, используя + docker-compose +:

docker-compose up -d

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

изображение: http: //assets.digitalocean.com/articles/63957_Traefik/Populated_Traefik_dashboard.png [Заполненная панель инструментов Traefik]

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

изображение: http: //assets.digitalocean.com/articles/63957_Traefik/WordPress_setup_screen.png [экран настройки WordPress]

Теперь зайдите в Adminer, посетив + db-admin. + В вашем браузере, снова заменив + your_domain + вашим доменом. Контейнер + mysql + не доступен внешнему миру, но контейнер + adminer + имеет к нему доступ через сеть Docker + internal +, которую они используют совместно, используя имя контейнера + mysql + в качестве имени хоста.

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

изображение: http: //assets.digitalocean.com/articles/63957_Traefik/adminer-mysql-database/Adminer_MySQL_database.png [Администратор подключен к базе данных MySQL]

Оба сайта теперь работают, и вы можете использовать панель мониторинга в + monitor. +, Чтобы следить за вашими приложениями.

Заключение

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

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

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

Related