Traefik — реверспрокси, предназначенный для работы с Docker. Он позволяет очень просто и декларативно проксировать сервисы в контейнерах. Сначала вас могут отпугнуть лейблы, но вы привыкнете :)
В нескольких примерах постараюсь показать, как просто запроксировать сайты и api, автоматизировать получение сертификатов и даже навесить несколько middleware (например для добавления хедеров).
Для начала стоит создать конфиг траефика:
# traefik.yml
# ...
providers:
docker:
network: traefik
exposedbydefault: false
# добавляем file провайдер, который будет подтягивать данные из
# директории external
file:
directory: ./external
# ...
Для проксирования сервисов в локальной сети требуется добавить docker-host сервис, так как localhost внутри контейнера укажет на сеть самого контейнера, а не на локальную сеть машины.
# docker-compose.yml
version: "3.8"
services:
# ...
traefik:
# ...
networks:
- traefik
# добавляем общую для докерхоста и траефика сеть
- local
docker-host:
image: qoomon/docker-host
cap_add: [ "NET_ADMIN", "NET_RAW" ]
restart: always
networks:
- local
# ...
networks:
traefik:
external:
name: traefik
local:
# Dockerfile
FROM traefik:v2.5.2
WORKDIR /traefik
COPY ./traefik.yml ./traefik.yml
CMD ["traefik"]
# docker-compose.yml
version: "3.8"
services:
traefik:
build: .
container_name: traefik
restart: always
ports:
# открываем порты для http, https, и дашборда траефика,
# последним не стоит светить за пределы локальной сети
# к нему мы будем стучаться через ssh (об этом ниже)
- 80:80
- 443:443
- 127.0.0.1:8080:8080
volumes:
# траефику нужен доступ к docker.sock, чтобы мониторить контейнеры
- /var/run/docker.sock:/var/run/docker.sock:ro
# а вот и вольюм для сертификатов
- /data/letsencrypt:/letsencrypt
networks:
- traefik
# для примера подключим whoami - простенький сервис, который показывает
# инфу о запросе в текстовом виде
whoami:
image: "traefik/whoami"
restart: always
labels:
# включаем траефик для этого контейнера
- traefik.enable=true
# задаем сеть траефика
- traefik.docker.network=traefik
# самое интересное: добавляем роутер и правило для него
# в нашем случае роутер будет назваться whoami
# и будет доступен по домену example.com
# обязательно добавьте название роутера, оно должно
# быть уникальным, в нашем случаем это whoami (идет после
# traefik.http.routers.)
- traefik.http.routers.whoami.rule=Host(`example.com`)
# Задаем через какой энтрипоинт будет доступен роутер
- traefik.http.routers.whoami.entrypoints=https
# задаем certresolver
- traefik.http.routers.whoami.tls.certresolver=simple-resolver
# на самом деле порт не обязательно указывать явно
# traefik в состоянии сам определить, какой порт слушает сервис,
# но может так случиться, что один контейнер слушает сразу несколько
# портов (к примеру так делает rabbitMq), тогда надо будет создавать
# несколько роутеров и явно прописывать несколько портов
- traefik.http.services.whoami.loadbalancer.server.port=80
networks:
- traefik
# ну и собственно сети
networks:
traefik:
external:
name: traefik
Всё, теперь можно запускать и радоваться Если хотите потыкать в dashboard, то это можно сделать, зафорвардив порты через ssh…
ssh -L 8080:localhost:8080 root@example.com
…и открыть в браузере localhost:8080
Проксирование внешних сервисов
Traefik можно использовать не только для сервисов в Docker, но и для внешних. Из коробки поддерживает балансировку нагрузки, т.е. если у вас реплицирован сервис, то просто указываете все хосты и траефик возьмет на себя всю остальную работу.
Для проксирования внешних сервисов (вне докер сети) надо добавить провайдер в traefik.yml
# traefik.yml
# ...
providers:
docker:
network: traefik
exposedbydefault: false
# добавляем file провайдер, который будет подтягивать данные из
# директории external
file:
directory: ./external
# ...
Для проксирования сервисов в локальной сети требуется добавить docker-host сервис, так как localhost внутри контейнера укажет на сеть самого контейнера, а не на локальную сеть машины.
# docker-compose.yml
version: "3.8"
services:
# ...
traefik:
# ...
networks:
- traefik
# добавляем общую для докерхоста и траефика сеть
- local
docker-host:
image: qoomon/docker-host
cap_add: [ "NET_ADMIN", "NET_RAW" ]
restart: always
networks:
- local
# ...
networks:
traefik:
external:
name: traefik
local:
# Dockerfile
FROM traefik:v2.5.2
WORKDIR /traefik
COPY ./traefik.yml ./traefik.yml
# копируем папку с конфигами внешних сервисов
COPY ./external ./external
CMD ["traefik"]
И сам конфиг внешнего сервиса. Все конфиги кидаем в директорию external.
# external/example.yml
http:
services:
example-api:
loadBalancer:
servers:
# если сервис расположен на внешнем хосте,
# то просто пишем ip или домен
- url: "http://123.456.789.123:4716"
example-web-client:
loadBalancer:
servers:
# если на localhost, то docker-host
- url: "http://docker-host:8132"
routers:
example-web-client:
entryPoints:
- https
# вебклиент будет доступен по любым путям на домене # web.example.com
rule: "Host(`site.example.com`)"
service: example-web-client
tls:
certResolver: simple-resolver
example-api:
entryPoints:
- https
# апи будет доступно только на site.example.com/api(.*)
# при этом для вебклиента не надо прописывать дополнительные
# правила, траефик сам будет роутить запросы на /api,
# это работает примерно как специфичность в css
rule: "Host(`site.example.com`) && PathPrefix(`/api`)"
service: example-api
tls:
certResolver: simple-resolver
Wildcard сертификаты
Traefik умеет и работать с Wildcard сертификатами! Перепишем docker-compose.yml так, чтобы whoami был доступен по *.example.com
Для начала надо добавить wildcard-resolver в конфиг Traefik.
# traefik.yml
certificatesResolvers:
# ...
wildcard-resolver:
acme:
dnschallenge:
# указываем dns провайдера, в этом примере будет godaddy,
# но траефик умеет работать и с другими:
# https://doc.traefik.io/traefik/https/acme/#dnschallenge
provider: godaddy
email: me@example.com
storage: /letsencrypt/acme.jso
# docker-compose.yml
version: "3.8"
services:
traefik:
build: ./proxy
container_name: traefik
restart: always
environment:
# указываем api ключи нашего провайдера из переменных окружения
- GODADDY_API_KEY=${GODADDY_API_KEY}
- GODADDY_API_SECRET=${GODADDY_API_SECRET}
- GODADDY_POLLING_INTERVAL=10
- GODADDY_PROPAGATION_TIMEOUT=300
ports:
- 80:80
- 443:443
- 127.0.0.1:8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /data/letsencrypt:/letsencrypt
labels:
- traefik.enable=true
- traefik.http.routers.api.entrypoints=http
networks:
- local
- traefik
whoami:
image: "traefik/whoami"
restart: always
labels:
- traefik.enable=true
- traefik.docker.network=traefik
# меняем правила для роутера
- traefik.http.routers.whoami.rule="Host(`example.com`) || HostRegexp(`{subdomain:.+}.example.com`)"
- traefik.http.routers.whoami.entrypoints=https
# задаём wildcard-resolver
- traefik.http.routers.whoami.tls.certresolver=wildcard-resolver
# домены, на которые ресолвер будет получать серты
- traefik.http.routers.whoami.tls.domains[1].main=example.com
- traefik.http.routers.whoami.tls.domains[1].sans=*.example.com
- traefik.http.services.whoami.loadbalancer.server.port=80
networks:
- traefik
# ...
Middlewares
Traefik позволяет создавать Middleware и навешивать их на роутеры и даже энтри поинты!
К примеру, еслинадо убрать какой-нибудь сервис из поисковой выдачи, то всегда можно просто навесить на него хедер X-Robots-Tag: noindex, nofollow
Middleware можно вешать не только на роутеры, но и на целые энтри поинты. В таком случае все равно создаем middleware в лейблах, можно это сделать на самом Traefik.
Оставьте заявку — мы созвонимся и познакомимся с проектом. Бесплатно составим первичные требования, порекомендуем технологии и дадим оценку по стоимости.
Комментарии