fbpx
Перейти к содержимому

Traefik 2 — установка, настройка, примеры

В данной статье вы найдете всю необходимую информация по настройке, установке и примерах использования обратного прокси-сервера (реверс-прокси) Traefik.

Reverse proxy служит для ретрансляции запросов из внешней сети к каким-либо сервервисам либо серверам внутренней сети.

Реверс-прокси используется для:

  • Сокрытия структуры внутренней сети и сервисах которые в ней находятся
  • Балансировать нагрузку между серверами либо сервисами выполняемые одинаковые задачи
  • Организовать контроль доступа к сервисам в виде дополнительной авторизации либо файрвола

Мы разберем установка Traefik 2 в Docker в качестве реверс-прокси. Реверс-прокси будет использоваться как для сервисов которые будут установлены в Docker контейнере так им для сторонних сервисов располагаемых на удаленных серверах.

Установка Traefik 2 в Docker

Предполагается, что перед началом установки Traefik 2 у вас уже установлен docker и docker-compose, если нет то краткую инструкцию по установки вы можете найти в данной статье.

Создадим папку в которой будут находиться файлы конфигурации traefik

mkdir traefik
cd traefik

Создадим файл docker-compose.ymlсо следующим содержимым

version: '3'
services:
  traefik:
    image: traefik:v2.8
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./ssl:/ssl

В данной конфигурации у нас будут доступны два порта 80 и 443 для HTTP и HTTPS. Последней строкой мы подключаем файл конфигурации который будет находится в подпапке data и называться traefik.yml. Создадим директорию data и создадим в ней файл traefik.yml

mkdir data
cd data
touch traefik.yml

Откроем файл traefik.yml в редакторе и внесем в него базовую конфигурацию

nano traefik.yml
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

http:
  routers:
    http-catchall:
      rule: hostregexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  letsEncrypt:
    acme:
      email: [email protected]
      storage: /ssl/acme.json
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: http

В entryPoints описываются все доступные входящие порты, у нас это 80 и 433 порт, название портов может быть любым, для простоты восприятия я дал портам название http и https.

В providers мы указываем нашего первого провайдера Docker и указываем, что Traefik не должен подгружать все доступные контейнеры.

Код который указан ниже отвечает за перенаправление всего http трафика в https

http:
  routers:
    http-catchall:
      rule: HostRegexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

В конфиг файле у нас есть отдельный блок который отвечает за получение сертификата Let’s Encrypt. В поле caServer указан тестовый сервер для того чтобы не получить лимит обращений к основному серверу. После того как вы все настроите необходимо будет закомментировать данную строку.

certificatesResolvers:
  letsEncrypt:
    acme:
      email: [email protected]
      storage: /ssl/acme.json
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: http

Таким образом у нас полностью готов файл конфигурации traefik.yml и файл docker-compose.yml и мы можем приступать к установки Traefik. Вернемся в директорию traefik и выполним следующую команду

sudo docker-compose up -d

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

sudo docker-compose logs -f

На этом установка и запуск Traefik завершена и можно переходить к настройке

Настройка Traefik 2 и добавление провайдеров

Для описания конфигурации в Docker Traefik использует метки контейнеров(labels) . Отредактируем файл docker-compose.yml и добавим в него следующий текст

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"

Подробнее разберем каждую из добавленных строк.

traefik.enable=true — сообщает что Traefik должен обеспечить доступ к этому контейнеру

traefik.http.routers.traefik.entrypoints=https — создаем новый роутер с точной входа https
traefik.http.routers.traefik.rule=Host(traefik.yourdomain.com) — роутеру назначен адрес traefik.yourdomain.com
traefik.http.routers.traefik.tls=true — указываем что будет использоваться TLS
traefik.http.routers.traefik.tls.certresolver=letsEncrypt — указывает что будет получаться сертификат через letsEncrypt
traefik.http.routers.traefik.service=api@internal — указываем, что сервер за этим роутером — api@internal, это специальный сервис, созданный по умолчанию, это наш дашборд который у нас и будет доступен по адресу traefik.yourdomain.com
traefik.http.services.traefik-traefik.loadbalancer.server.port=888 — порт на котором будет вебинтерфейс

Для того чтобы активировать дашборд необходимо в конфиг файл traefik.yml добавить

api:
  dashboard: true

Таким образом наш полный файл docker-compose.yml будет иметь следующий вид

version: '3'
services:
  traefik:
    image: traefik:v2.8
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./ssl:/ssl
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"

А файл traefik.yml

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

http:
  routers:
    http-catchall:
      rule: hostregexp(`{host:.+}`)
      entrypoints:
      - http
      middlewares:
      - redirect-to-https
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https
        permanent: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  letsEncrypt:
    acme:
      email: [email protected]
      storage: /ssl/acme.json
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
      entryPoint: http
api:
  dashboard: true

Теперь чтобы все наши правки применились нам необходимо пересоздать контейнер

sudo docker-compose down && sudo docker-compose up -d

И теперь после перехода по адресу который мы указали выше в конфиге в моем случаи это traefik.yourdomain.com мы попадаем в панель управления Traefik.

Базовая защита с BasicAuth

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

Для генерации зашифрованного пароля в терминале выполним команду

htpasswd -nb unixhost password

В качестве ответа мы получим строку которую будет содержать имя пользователя и зашифрованный пароль.

unixhost:$apr1$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/

Теперь отредактируем файл docker-compose.yml и добавим в labels следующий текст заменив значение auth.basicauth.users на строку которую мы получили ранее и дополнительно продублируем каждый символ $ . Вместо $apr1$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/ мы должны указать $$apr1$$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/

      - "traefik.http.middlewares.traefik-auth.basicauth.users=unixhost:$$apr1$$vqyMX723$6nZ1lC3/2JN6QJyeEhJB8/"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"

И теперь после пересоздания контейнера при переходе по адресу traefik.yourdomain.com у нас запросит логин и пароль для доступа в панели.

Добавление File провайдеров в Traefik 2

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

Допустим, нам необходимо добавить службу мониторинга Grafana которая находится на сервере с IP 192.168.100.100, порт который использует сервис 3000. Доступ к данному сервису необходимо сделать через HTTPS. О том как установить Grafana мы подробно разбирали в данной статье.

Отредактируем файл docker-compose.yml в volumes добавим следующее

      - ./data/custom/:/custom/:ro

Создадим новую директорию custom в директории data. А в файл конфигурации traefik.yml в providers добавим следующее

providers:
  file:
    directory: /custom
    watch: true

watch: true говорит о том, что traefik будет следить за изменением в данной директории и после внесения добавления новых файлов с конфигурациями они автоматически будет применены.

Секция providers в конфигурационном файле traefik.yml в рамках данной статьи у нас будет выглядеть следующим образом

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    directory: /custom
    watch: true

Пересоздадим контейнер, создадим файл grafana.yml в директории custom и добавим в него первый провайдер

http:
  routers:
    grafana:
      entryPoints: 
      - https
      service: grafana-host
      rule: Host(`grafana.yourdomain.com`) 
      tls:
        certResolver: letsEncrypt
  services:
    grafana-host:  
      loadBalancer:
        servers:
        - url: http://192.168.100.100:3000/
        passHostHeader: true 

И теперь если мы перейдем по адресу grafana.yourdomain.com у нас откроется система мониторинга Grafana.
Подобным образом вы можете добавлять новые сервисы.