From 9ca6b107ab72d8f2799ab6a7b02846e71b3bf475 Mon Sep 17 00:00:00 2001 From: TheSt1tch Date: Sun, 21 Apr 2024 03:12:50 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20Traefik=20install?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docker/traefik/index.md | 104 ++++++++++++++++++++--------------- mkdocs.yml | 1 + 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/docs/docker/traefik/index.md b/docs/docker/traefik/index.md index 86cc651..663bce1 100755 --- a/docs/docker/traefik/index.md +++ b/docs/docker/traefik/index.md @@ -1,16 +1,22 @@ -Traefik — это обратный прокси-сервер с открытым исходным кодом, обеспечивающий простую работу с микросервисами и/или просто контейнерами с вашими приложениями. +# Traefik -Обратный прокси-сервер (reverse proxy, реверс-прокси) служит для ретрансляции запросов из внешней сети к каким-либо серверам/сервисам внутренней сети (например веб-сервера, БД или файловые хранилища) и позволяет: -- обеспечить сокрытие структуры внутренней сети и подробностей о находящейся в ней сервисах; -- осуществлять балансировку нагрузки (load balancing) между экземплярами одного и того же сервиса или серверами с одинаковыми задачами; -- обеспечить зашифрованное (HTTPS) соединение между клиентом и любым сервисом, в таком случае SSL сессия создается между клиентом и прокси, а между прокси и сервисом во внутренней сети устанавливается незашифрованное HTTP соединение, если сервис поддерживает HTTPS то можно организовать зашифрованное соединение и во внутренней сети; -- организовать контроль доступа к сервисам (аутентификацию клиента), а также установить файрвол (брандмауэр). +**Traefik** — это обратный прокси-сервер с открытым исходным кодом, обеспечивающий простую работу с микросервисами и/или просто контейнерами с вашими приложениями. + +!!! tip + Обратный прокси-сервер (reverse proxy, реверс-прокси) служит для ретрансляции запросов из внешней сети к каким-либо серверам/сервисам внутренней сети (например веб-сервера, БД или файловые хранилища) и позволяет: + + - обеспечить сокрытие структуры внутренней сети и подробностей о находящейся в ней сервисах + - осуществлять балансировку нагрузки (load balancing) между экземплярами одного и того же сервиса или серверами с одинаковыми задачами + - обеспечить зашифрованное (HTTPS) соединение между клиентом и любым сервисом, в таком случае SSL сессия создается между клиентом и прокси, а между прокси и сервисом во внутренней сети устанавливается незашифрованное HTTP соединение, если сервис поддерживает HTTPS то можно организовать зашифрованное соединение и во внутренней сети + - организовать контроль доступа к сервисам (аутентификацию клиента), а также установить файрвол (брандмауэр). В статье будет описываться использование Traefik в Docker в качестве реверс-прокси для других контейнеров Docker, а также не контейнеризированных сервисов. ## Введение -Traefik позиционируется разработчиками как “Edge Router”, то есть можно направить его непосредственно в глобальную сеть одной стороной и во внутреннюю другой. Если у читателя создалось впечатление что таким образом создается единая точка отказа всей системы, то так и есть, но есть несколько моментов: -- во-первых, **Traefik** имеет развитый функционал для автоматического восстановления при сбоях; + +**Traefik** позиционируется разработчиками как "Edge Router", то есть можно направить его непосредственно в глобальную сеть одной стороной и во внутреннюю другой. Если у читателя создалось впечатление что таким образом создается единая точка отказа всей системы, то так и есть, но есть несколько моментов: + +- во-первых, **Traefik** имеет развитый функционал для автоматического восстановления при сбоях - во-вторых, существует **Traefik EE** — платная версия, в которой помимо прочих преимуществ имеется HA (Hight Availability, Высокая доступность), что подразумевает распределение нагрузки между несколькими экземплярами сервиса (узлами), таким образом при отказе одного его задачи перераспределяются на другие узлы, а отказавший узел отключается и затем немедленно вводится обратно в эксплуатацию. > В качестве примечания отметим, что в статье будет рассматриваться бесплатная версия Traefik. @@ -19,23 +25,23 @@ Traefik позиционируется разработчиками как “Ed Список основных провайдеров: - Docker +- File - Kubernetes - Consul Catalog - Marathon - Rancher -- File -В рамках этой статьи будут рассмотрены первый и последний провайдеры из этого списка. +В рамках этой статьи будут рассмотрены первый и второй провайдеры из этого списка. -Вероятно, не знакомому с темой читателю будет не понятно, чем является провайдер с именем — “File”, это некоторый файл (или папка с файлами), в котором описана конфигурация какого-либо сервиса, не связанного с другими провайдерами, но который должен быть скрыт за реверс-прокси. Остальные же провайдеры являются различными системами оркестрации контейнеров. +Вероятно, не знакомому с темой читателю будет не понятно, чем является провайдер с именем — *File*, это некоторый файл (или папка с файлами), в котором описана конфигурация какого-либо сервиса, не связанного с другими провайдерами, но который должен быть скрыт за реверс-прокси. Остальные же провайдеры являются различными системами оркестрации контейнеров. -Файл конфигурации Traefik, а также файлы для провайдера “File” могут быть написаны на TOML либо YAML, в статье будут приведены примеры на YAML так как этот синтаксис больше нравится автору, а какой-либо функциональной разницы между ними нет, а также не составляет трудности переписать файлы на другой формат конфигурации. Traefik будет развернут в Docker. Для развертывания будет использоваться docker-compose, для обеспечения простоты повторного развертывания. +Файл конфигурации **Traefik**, а также файлы для провайдера *File* могут быть написаны на TOML либо YAML, в статье будут приведены примеры на YAML так как этот синтаксис больше нравится автору, а какой-либо функциональной разницы между ними нет, а также не составляет трудности переписать файлы на другой формат конфигурации. Traefik будет развернут в Docker. Для развертывания будет использоваться `docker-compose`, для обеспечения простоты повторного развертывания. -> В статье будут приведены команды для ОС Linux. +> В статье будут приведены команды для ОС Ubuntu. ## Деплой Traefik -Предполагается что у читателя установлены и настроены `docker` и `docker-compose`, их установка выходит за рамки этой статьи. +Предполагается, что у читателя установлены и настроены `docker` и `docker-compose`. Установить можно [тут](../install.md) Создадим в домашней папке пользователя папку `traefik`, в которой будем хранить всю конфигурацию, и перейдем в эту папку @@ -49,7 +55,7 @@ cd ~/traefik version: '3.9' services: traefik: - image: traefik:v2.10 + image: traefik:v2.10 # Лучше не использовать тег latest container_name: traefik restart: unless-stopped security_opt: @@ -58,9 +64,9 @@ services: - 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 + - /etc/localtime:/etc/localtime:ro # for localtime + - /var/run/docker.sock:/var/run/docker.sock:ro # Docker Socket + - ./data/traefik.yml:/traefik.yml:ro # static config ``` Во внешний мир будут смотреть порты 80 и 443 для HTTP и HTTPS соответственно. Также пробросим в контейнер сокет демона Docker для работы механизма автоматической конфигурации. Конфигурацию Traefik будем описывать в файле `traefik.yml` находящемся в папке `data` в текущей директории. @@ -70,6 +76,7 @@ services: Создадим и будем постепенно наполнять этот файл. Для начала опишем точки входа в наш прокси (те самые порты, которые смотрят во внешний мир): + ```yaml entryPoints: http: @@ -89,7 +96,7 @@ providers: exposedByDefault: false ``` -Параметром указываем что Traefik не должен брать все контейнеры подряд, далее будет объяснено каким образом мы будем сообщать какие контейнеры нас интересуют. Также здесь видно зачем мы пробрасывали сокет в контейнер — именно через него Traefik будет получать сведения о запускаемых контейнерах на этом хосте (можно подключиться и к демону на другом хосте). +Параметром `exposedByDefault` указываем, что Traefik не должен брать все контейнеры подряд, далее будет объяснено каким образом мы будем сообщать какие контейнеры нас интересуют. Также здесь видно зачем мы пробрасывали сокет в контейнер — именно через него Traefik будет получать сведения о запускаемых контейнерах на этом хосте (можно подключиться и к демону на другом хосте). Следующим шагом развернем весь HTTP трафик в HTTPS (почему это было сделано именно таким образом будет описано дальше): @@ -117,10 +124,10 @@ Traefik может проксировать не только HTTP трафик, Рассмотрим на примере описанного выше роутера: -- `http-catchall` — имя роутера, может быть любым, но обязано быть уникальным в рамках блока `http` всей конфигурации Traefik; -- `rule:` — правило, описывает какой трафик попадает в этот роутер, в данном случае описывается `HostRegexp`, то есть поле `Host` запроса должно попадать под регулярное выражение `.+` (то есть любое), здесь мы видим специфику регулярных выражений в Traefik — оно должно быть заключено в фигурные скобки и иметь наименование (`host` в данном случае), то есть синтаксис имеем вид `{name:reg_exp}`; -- `entrypoints` — массив описанных ранее точек входа, которые будут использоваться этим роутером, в нашем случае используем только `http`; -- `middlewares` — массив промежуточных обработчиков, куда попадает трафик перед передачей к сервису (сервисы будут рассмотрены позднее). +- `http-catchall` — имя роутера, может быть любым, но обязано быть уникальным в рамках блока `http` всей конфигурации **Traefik** +- `rule` — правило, описывает какой трафик попадает в этот роутер, в данном случае описывается `HostRegexp`, то есть поле `Host` запроса должно попадать под регулярное выражение `.+` (то есть любое). Синтаксис имеет вид `{name:reg_exp}` +- `entrypoints` — массив описанных ранее точек входа, которые будут использоваться этим роутером, в нашем случае используем только `http` +- `middlewares` — массив промежуточных обработчиков, куда попадает трафик перед передачей к сервису (сервисы будут рассмотрены позднее) Подробнее о различных видах правил можно прочитать в [документации](https://docs.traefik.io/routing/routers/#rule). @@ -133,6 +140,8 @@ Traefik может проксировать не только HTTP трафик, Подробнее о различных обработчиках можно прочитать в [документации](https://docs.traefik.io/middlewares/overview/) (дальше в статье будет описан ещё один обработчик — BasicAuth). +## Файл конфиурации + ??? note "Полностью файл traefik.yml" ```yaml entryPoints: @@ -159,15 +168,17 @@ Traefik может проксировать не только HTTP трафик, permanent: false ``` -Таким образом мы получим первую рабочую конфигурацию. Выполняем +Таким образом мы получим первую рабочую конфигурацию. Выполняем: + ```bash sudo docker-compose up -d ``` + И прокси должен подняться, можно почитать логи (`sudo docker-compose logs -f`) и убедиться, что всё работает. ## Let’s Encrypt -Поскольку мы хотим использовать HTTPS нам нужно где-то взять SSL сертификаты для сервисов, есть возможность использовать свои сертификаты, но мы настроем автоматическое получение бесплатных сертификатов от Let’s Encrypt. +Поскольку мы хотим использовать HTTPS, нам нужно где-то взять SSL сертификаты для сервисов. У нас есть возможность использовать свои сертификаты, но мы настроем автоматическое получение бесплатных сертификатов от **Let’s Encrypt**. Добавим в конфигурацию (`traefik.yml`) новый блок: @@ -181,17 +192,17 @@ certificatesResolvers: httpChallenge: entryPoint: http ``` - Здесь: -- `letsEncrypt` — это просто имя резолвера; -- `acme` — тип резолвера (других типов в общем-то и нет); -- `storage` — файл, в котором хранятся сведения о полученных сертификатах; -- `httpChallenge` — тип acme-челенжа, дополнительно указываем параметр — точку входа; + +- `letsEncrypt` — это просто имя резолвера +- `acme` — тип резолвера (других типов в общем-то и нет) +- `storage` — файл, в котором хранятся сведения о полученных сертификатах +- `httpChallenge` — тип acme-челенжа, дополнительно указываем параметр — точку входа - `caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"` — позволяет использовать не основной сервер Let’s Encrypt в тестовых целях, так как основной имеет строгие лимиты API (можно закомментировать, когда наладите получение сертификатов). Также дополним пункт `volumes` в файле `docker-compose.yml`, чтобы сохранять сертификаты при перезапуске контейнера (предварительно создав файл `data/acme.json`): -```yaml +```yaml hl_lines="5" volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro @@ -215,20 +226,21 @@ HTTPS настроен, пришло время поднять первый се - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888" ``` Разберем построчно: + - `traefik.enable=true` — указываем что Traefik должен обеспечить - доступ к этому контейнеру, необходимо для всего остального; + доступ к этому контейнеру, необходимо для всего остального - `traefik.http.routers.traefik.entrypoints=https` — создаем новый - роутер с точной входа `https`; + роутер с точной входа `https` - `traefik.http.routers.traefik.rule=Host(`traefik.example.com`)` — - роутер будет жить по адресу traefik.example.com; + роутер будет жить по адресу traefik.example.com - `traefik.http.routers.traefik.tls=true` — указываем что используется - TLS; + TLS - `traefik.http.routers.traefik.tls.certresolver=letsEncrypt` — - указываем через какой резолвер получать сертификат; + указываем через какой резолвер получать сертификат - `traefik.http.routers.traefik.service=api@internal` — указываем, что сервер за этим роутером — `api@internal`, это специальный сервис, созданный по умолчанию, это как раз и есть дашбоард который мы хотели - увидеть; + увидеть - `traefik.http.services.traefik-traefik.loadbalancer.server.port=888` — издержки интерфейса, без этого не заработает, но можно написать абсолютно любую цифру. @@ -248,25 +260,26 @@ sudo docker-compose down && sudo docker-compose up -d Когда всё поднимется можно перейти на `traefik.example.com` (тут на самом деле должен быть ваш домен, который направлен на хост с Traefik) и увидеть дашборд. -Дашбоард это хорошо, но мы не хотим, чтобы все пользователи интернета имели к нему доступ, закроем его от внешнего мира с помощью BasicAuth, для это в Traefik есть специальный middleware. +Дашбоард это хорошо, но мы не хотим, чтобы все пользователи интернета имели к нему доступ, закроем его от внешнего мира с помощью BasicAuth, для это в Traefik есть специальный *middleware*. -Для начала сгенерируем для нас строку с логином и паролем (admin/password)^ +Для начала сгенерируем для нас строку с логином и паролем (admin/password): ```bash $ htpasswd -nb admin password admin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1 ``` - Теперь добавим в наш `docker-compose.yml` новые строчки: + ```yaml - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1" - "traefik.http.routers.traefik.middlewares=traefik-auth" ``` Заметим, что символы `$` из полученной строки мы должны заменить на `$$`. -- `traefik.http.middlewares.traefik-auth.basicauth.users=...` — создаем middleware типа `basicauth` с параметром `users`; -- `traefik.http.routers.traefik.middlewares=traefik-auth` — указываем что роутер `traefik` использует только что-то созданный middleware. + +- `traefik.http.middlewares.traefik-auth.basicauth.users=...` — создаем middleware типа `basicauth` с параметром `users` +- `traefik.http.routers.traefik.middlewares=traefik-auth` — указываем что роутер `traefik` использует только что-то созданный middleware ??? note "Весь docker-compose.yml" ```yaml @@ -294,6 +307,8 @@ admin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1 - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888" + - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1" + - "traefik.http.routers.traefik.middlewares=traefik-auth" ``` Теперь при попытке доступа к дашборду у нас спросят логин и пароль. @@ -318,7 +333,7 @@ admin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1 Добавим в `docker-compose.yml` ещё один `volume`: -```yaml +```yaml hl_lines="5" volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro @@ -333,7 +348,6 @@ admin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1 ```yaml providers: -... file: directory: /custom watch: true @@ -370,7 +384,7 @@ http: loadBalancer: servers: - хосты для балансировки нагрузки - - ... + #- ... ``` Дополнительно мы указываем параметр `passHostHeader: true` чтобы тот хост думал, что он на самом деле смотрит в сеть и прокси нет. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 3233000..350a9e6 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -145,6 +145,7 @@ nav: - Траблшутинг: hardware/tsd/troubleshooting.md - Synology: - HPE Microserver Gen10: hardware/synology/install-hpe-ms-gen10.md + - Update CA root Cert: hardware/synology/update-ca-root-cert.md - HPE iLo: hardware/hpe-ilo.md - Proxmox: - Proxmox VE: