Files
SergObsidian/WORK & PROJECTS/Mol/Серверы/PROXY_PASS/Traefik config.md
2025-05-13 18:22:29 +05:00

759 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Отличный вопрос! Давай сравним, **как реализовать ту же задачу в Traefik**, и посмотрим, проще ли это будет по сравнению с Angie.
---
# 🎯 Цель (повторение)
Нужно организовать систему обратного прокси, где:
- Пользователи разделены на группы:
- `public` — публичный доступ ко всем общедоступным сайтам.
- `internal` — сотрудникам доступны внутренние сервисы (git, jira и т.д.).
- `client-X` — клиенты с доступом только к своему поддомену (`client1.site.com`, `client2.site.com`).
- Каждая группа имеет свои **IP-подсети**.
- Каждый домен/поддомен имеет список разрешённых групп.
- Конфиги должны обновляться **динамически** без перезапуска.
- Желательно наличие **GUI** и **API управления**.
---
# ✅ Вывод сразу: **Traefik лучше подходит для этой задачи**
Почему?
| Функция | Traefik ✅ / ❌ | Angie ✅ / ❌ |
|----------------------------------|----------------------|----------------------|
| ACL по IP | ✅ | ✅ |
| Группы пользователей | ✅ через middleware | ✅ через allow/deny |
| Динамическая конфигурация | ✅ через API или файл | ✅ через `/control` |
| Поддержка GUI | ✅ встроенный dashboard | ❌ (нужно внешнее) |
| Простота автоматизации | ✅ | ⚠️ сложнее |
| Интеграция с Lets Encrypt | ✅ | ⚠️ нужно допилить |
| Удобство масштабирования | ✅ | ✅ |
---
# 🔧 Как реализовать в Traefik
## 1. **Базовая структура конфигурации**
Traefik использует два типа конфигов:
- `traefik.yml` — статическая часть (порт, провайдеры, логирование и т.п.)
- `dynamic_conf.yml` — динамическая часть (маршруты, middleware, TLS и т.п.)
Также можно управлять через **REST API**, но начнём с файла.
---
## 2. **Middleware для групп доступа**
В Traefik есть мощная система **middleware**, которую мы будем использовать для контроля доступа по IP.
### Пример: определяем middleware для каждой группы
```yaml
http:
middlewares:
public-access:
ipWhiteList:
sourceRange:
- "0.0.0.0/0" # все IP
internal-access:
ipWhiteList:
sourceRange:
- "192.168.1.0/24"
- "10.10.0.0/16"
client1-access:
ipWhiteList:
sourceRange:
- "203.0.113.0/24"
```
---
## 3. **Роуты с указанием middleware**
Каждому роуту можно указать, какие middleware применять.
### Пример: маршрут для site1.com
```yaml
http:
routers:
site1-router:
rule: "Host(`site1.com`, `www.site1.com`)"
entryPoints:
- web
service: site1-service
middlewares:
- public-access
- internal-access
```
### Пример: маршрут для git.site1.com
```yaml
http:
routers:
git-router:
rule: "Host(`git.site1.com`)"
entryPoints:
- web
service: git-service
middlewares:
- internal-access
```
### Пример: маршрут для client1.site.com
```yaml
http:
routers:
client1-router:
rule: "Host(`client1.site.com`)"
entryPoints:
- web
service: client1-service
middlewares:
- client1-access
```
---
## 4. **Сервисы (бэкенды)**
Определяешь бэкенд для каждого сайта:
```yaml
http:
services:
site1-service:
loadBalancer:
servers:
- url: http://192.168.10.10:8080
git-service:
loadBalancer:
servers:
- url: http://192.168.10.11:3000
client1-service:
loadBalancer:
servers:
- url: http://192.168.20.10:8000
```
---
## 5. **Динамическое обновление конфига**
Можно использовать:
### А. **Файл с динамическим конфигом**
Traefik следит за изменениями в файле и применяет их автоматически.
Пример запуска:
```yaml
providers:
file:
filename: /etc/traefik/dynamic_conf.yml
watch: true
```
> При изменении `dynamic_conf.yml` — конфиг применяется без перезагрузки!
### Б. **REST API**
Если хочешь полностью управлять через API, можешь использовать [Traefik Pilot](https://pilot.traefik.io/) или свой микросервис.
Пример добавления маршрута через API:
```bash
curl -X POST "http://traefik:8080/api/http/routers" \
-H "Content-Type: application/json" \
-d '{
"name": "client2-router",
"rule": "Host(`client2.site.com`)",
"service": "client2-service",
"entryPoints": ["web"],
"middlewares": ["client2-access"]
}'
```
---
## 6. **Генерация конфигов**
Как и в случае с Angie, можно написать небольшой **генератор конфигов**, который:
- Получает данные о новом клиенте.
- Создаёт middleware с его IP-диапазоном.
- Создаёт новый роут.
- Обновляет `dynamic_conf.yml`.
Или делает всё через API.
---
## 7. **Dashboard (GUI)**
Traefik предоставляет встроенный **веб-интерфейс** по адресу `http://localhost:8080`.
Там ты увидишь:
- Все маршруты,
- Сервисы,
- Middleware,
- Состояние бэкендов.
---
## 🔄 Автоматизация всего процесса
Ты можешь создать:
- **API-сервис**, принимающий запросы на добавление клиентов/групп.
- **Шаблонизатор**, генерирующий YAML или JSON.
- **Систему хранения правил** (например, PostgreSQL или Redis).
- **Синхронизацию с файлом или API Traefik**.
---
## 🔐 Как работает проверка доступа?
1. Запрос приходит в Traefik.
2. Traefik проверяет IP клиента через middleware `ipWhiteList`.
3. Если IP не в списке — возвращает `403 Forbidden`.
4. Иначе — направляет запрос на нужный бэкенд.
---
## 📦 Пример структуры проекта
```
traefik/
├── traefik.yml # статический конфиг
├── dynamic_conf.yml # динамические маршруты и middleware
└── data/
└── clients/ # шаблоны или скрипты для клиентов
```
---
# 🎯 Общая цель
Ты хочешь реализовать систему, где:
1. **Клиенты добавляются/удаляются автоматически** из внешней БД.
2. **Правила доступа пересоздаются регулярно**, оставляя только актуальные.
3. **Скорость обработки не критична**, но важно понимать, как поведёт себя система при росте числа правил.
---
# ✅ Как это сделать в Traefik
## 1. **Механизм хранения правил**
В Traefik есть 2 основных способа управления конфигом:
| Способ | Подходит для динамических правил? | Простота интеграции |
|---------------------------|-----------------------------------|---------------------|
| Файл `dynamic_conf.yml` | ✅ | ✅ |
| REST API | ✅ | ⚠️ требует кода |
### Рекомендация:
Используй **файл с динамическим конфигом (`file provider`)** — он проще в управлении, особенно если ты хочешь периодически перезаписывать его целиком на основе данных из БД.
---
## 2. **Интеграция с внешней БД**
### Шаги:
1. Периодически запускай скрипт (например, раз в час или по cron):
- Выбираешь из БД список активных клиентов.
- Для каждого клиента генерируешь middleware (ACL) и router (маршрут).
- Перезаписываешь файл `dynamic_conf.yml`.
2. Traefik сам применяет изменения (если `watch: true`).
### Пример структуры файла `dynamic_conf.yml`:
```yaml
http:
middlewares:
client1-access:
ipWhiteList:
sourceRange:
- "203.0.113.0/24"
client2-access:
ipWhiteList:
sourceRange:
- "198.51.100.0/24"
routers:
client1-router:
rule: "Host(`client1.example.com`)"
service: client1-service
middlewares:
- client1-access
client2-router:
rule: "Host(`client2.example.com`)"
service: client2-service
middlewares:
- client2-access
services:
client1-service:
loadBalancer:
servers:
- url: http://192.168.20.10:8080
client2-service:
loadBalancer:
servers:
- url: http://192.168.20.20:8080
```
---
## 🧪 Пример нагрузки (гипотетический)
| Конфигурация | Запросов в секунду (RPS) |
|-------------------------------------|--------------------------|
| Traefik + 1000 клиентов | ~80009000 RPS |
| Angie + 1000 клиентов | ~1000011000 RPS |
| Traefik + простой прокси (без ACL) | ~12000 RPS |
| Angie + простой прокси (без ACL) | ~14000 RPS |
# 🔄 Рекомендуемая архитектура
```
[База данных] → [Генератор dynamic_conf.yml] → [Traefik]
```
1. **База данных** — хранит список клиентов, их домены и IP-подсети.
2. **Генератор** — скрипт (Python, Go и т.п.), который берёт данные из БД и генерирует YAML.
3. **Traefik** — читает файл и применяет правила без перезапуска.
---
## **Можно ли разнести конфигурацию общего доступа + сотрудников и клиентов?**
### ✅ Да, и это даже рекомендуется!
Разделение конфигов позволяет:
- Упростить поддержку.
- Лучше управлять обновлениями.
- Изолировать статические правила от динамических.
---
### 🛠️ Как это сделать в Traefik?
Traefik поддерживает **множественные файловые провайдеры**, что позволяет загружать несколько YAML-файлов независимо.
#### Пример структуры:
```
traefik/
├── traefik.yml # основной статический конфиг
├── dynamic-common.yml # маршруты и middleware для public/internal
└── dynamic-clients.yml # маршруты и middleware для клиентов
```
#### В `traefik.yml` указываешь:
```yaml
providers:
file:
directory: /etc/traefik/dynamic
watch: true
```
> Traefik автоматически загрузит все `.yml` из этой папки.
---
### Пример `dynamic-common.yml` (для всех):
```yaml
http:
middlewares:
public-access:
ipWhiteList:
sourceRange:
- "0.0.0.0/0"
internal-access:
ipWhiteList:
sourceRange:
- "192.168.1.0/24"
- "10.10.0.0/16"
routers:
site1-router:
rule: "Host(`site1.com`, `www.site1.com`)"
service: site1-service
middlewares:
- public-access
- internal-access
git-router:
rule: "Host(`git.site1.com`)"
service: git-service
middlewares:
- internal-access
```
---
### Пример `dynamic-clients.yml` (динамически обновляется):
```yaml
http:
middlewares:
client1-access:
ipWhiteList:
sourceRange:
- "203.0.113.0/24"
client2-access:
ipWhiteList:
sourceRange:
- "198.51.100.0/24"
routers:
client1-router:
rule: "Host(`client1.site.com`)"
service: client1-service
middlewares:
- client1-access
client2-router:
rule: "Host(`client2.site.com`)"
service: client2-service
middlewares:
- client2-access
services:
client1-service:
loadBalancer:
servers:
- url: http://192.168.20.10:8080
client2-service:
loadBalancer:
servers:
- url: http://192.168.20.20:8080
```
---
## 🔄 Обновление только клиентской части
Поскольку файлы разделены, можно:
- **Часто обновлять только `dynamic-clients.yml`** (например, ежечасно) без затрагивания остальной конфигурации.
- **Не трогать `dynamic-common.yml`**, если нет изменений в общих правилах.
---
## 📦 Полезная архитектура
```
[База данных] → [Генератор dynamic-clients.yml] ↔ [Traefik]
[API для других сервисов]
```
- **База данных** — хранит клиентов, группы, IP.
- **Генератор** — создаёт/обновляет `dynamic-clients.yml`.
- **Traefik** — применяет конфиг без перезагрузки.
- **Внешний API** — даёт доступ к данным о клиентах (в т.ч. IP-диапазонам).
Отличный и важный вопрос! Давай разберём, **какие требования к железу будут у Traefik**, если:
- Он будет работать вместе с:
- **UFW** (брандмауэр),
- **Prometheus** (мониторинг),
- **Grafana** (визуализация),
- И в будущем ожидается нагрузка до **20 000 RPS** (запросов в секунду),
- Нужно понять: **что важнее — CPU или RAM?**
- А также: **можно ли логировать подключения и собирать метрики для Prometheus**
---
# 🧮 1. Требования к серверу
Traefik написан на Go, работает быстро и эффективно, но при высокой нагрузке требует определённых ресурсов.
## 🔁 Примерная производительность Traefik (на одном ядре):
| Запросы/сек | RAM (примерно) | CPU (ядро ~Xeon E5) |
|-------------|----------------|----------------------|
| 5 000 | 300500 MB | ~0.4 ядра |
| 10 000 | 600800 MB | ~0.7 ядра |
| 20 000 | 11.5 GB | ~1.21.5 ядра |
> Это оценка для простого reverse proxy без TLS, сложных middleware, WAF и т.п.
---
## 🖥️ Рекомендуемая конфигурация для 20 000 RPS + дополнительные сервисы
| Компонент | Рекомендация |
|------------------|-----------------------------------|
| CPU | 46 ядер (минимум), лучше 8 |
| RAM | 46 ГБ |
| Диск | SSD, 2040 ГБ |
| ОС | Linux (Debian, Ubuntu Server) |
| Сеть | 1 Гбит/с минимум |
> ✅ Если нагрузка будет расти постепенно, можно начать с 24 ядер и 24 ГБ RAM, масштабируя дальше при необходимости.
---
## 💡 Что важнее: RAM или CPU?
### ✅ Ответ: **и то, и другое важно, но первым ограничителем станет CPU**
- **RAM** обычно расходуется не очень много (~11.5 ГБ при 20K RPS).
- **CPU** становится бутылочным горлышком из-за обработки маршрутов, middleware, шифрования TLS (если есть), проверок IP, генерации логов и т.п.
---
# 📊 2. Логирование и мониторинг через Prometheus
Traefik имеет **встроенную поддержку метрик Prometheus**, а также позволяет логировать запросы.
## ✅ Включить экспорт метрик Prometheus:
Добавь в `traefik.yml`:
```yaml
metrics:
prometheus:
addRoutersLabels: true
addServicesLabels: true
entryPoint: metrics
```
И открой соответствующий `entryPoint`:
```yaml
entryPoints:
metrics:
address: ":8082"
```
Теперь ты можешь забирать метрики по адресу:
👉 `http://<traefik>:8082/metrics`
Примеры доступных метрик:
- `traefik_http_requests_total{status, method, router}`
- `traefik_http_in_flight_requests`
- `traefik_backend_requests_total`
- `traefik_router_requests_total`
---
## 📝 Включить логирование запросов:
Добавь в `traefik.yml`:
```yaml
accessLog:
filePath: "/var/log/traefik/access.log"
format: "json" # или "common", "jsonWithTime"
```
Можно дополнительно отправлять логи в Loki, Fluentd, ELK и т.д.
---
## 📈 Пример сбора данных в Prometheus + Grafana
1. **Prometheus** сканирует `/metrics` у Traefik.
2. **Grafana** строит дашборды:
- Запросы в секунду,
- Коды ответов (2xx, 4xx, 5xx),
- Время отклика,
- Нагрузка на конкретные роутеры и сервисы.
---
# ✅ Выводы
| Пункт | Рекомендация |
|-----------------------------------|------------------------------------------------------------|
| Минимальный CPU | 4 ядра (начало), 8 комфортно |
| Минимальный RAM | 4 ГБ |
| Диск | SSD, 20+ ГБ |
| Что важнее | CPU |
| Логирование | ✅ Да, через `accessLog` |
| Мониторинг через Prometheus | ✅ Да, встроено |
| Можно ли всё запустить на одном сервере | ✅ Да, через Docker или Kubernetes |
| Как масштабироваться | Горизонтально: добавление ещё Traefik-нод (в кластере) |
---
Отлично, давай разберём **конкретный сценарий**:
> Ты хочешь:
>
> - Добавить новый поддомен (например, `client1.example.com`),
> - Чтобы Traefik автоматически получил для него **TLS-сертификат через HTTP-01 чаллендж**,
> - Чтобы домен работал по HTTPS,
> - А внутрь сети проксировался на бэкенд в подсети (например, `http://192.168.10.10:8080`),
> - И всё это — без ручного участия после добавления конфига.
---
# ✅ Что нужно сделать
## 1. **Настроить статический конфиг (`traefik.yml`)**
```yaml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
file:
filename: /etc/traefik/dynamic_conf.yml
watch: true
certificatesResolvers:
myresolver:
acme:
email: admin@example.com
storage: acme.json
httpChallenge:
entryPoint: web
```
### 📌 Важные моменты:
- `myresolver` — это имя resolver'а, которое будем использовать в динамическом конфиге.
- `storage: acme.json` — файл, где будут храниться сертификаты.
- `httpChallenge.entryPoint: web` — указывает, что проверка будет идти через порт 80.
---
## 2. **Добавить динамический маршрут в `dynamic_conf.yml`**
```yaml
http:
routers:
client1-router:
rule: "Host(`client1.example.com`)"
service: client1-service
entryPoints:
- websecure
tls:
certResolver: myresolver
services:
client1-service:
loadBalancer:
servers:
- url: http://192.168.10.10:8080
```
### 🔍 Что здесь происходит:
- При запросе `https://client1.example.com`:
- Traefik проверяет, есть ли уже выданный сертификат.
- Если нет — запрашивает его у Lets Encrypt.
- Для проверки прав на домен — создаёт временный маршрут `//.well-known/acme-challenge/...`.
- После успешной проверки — сохраняет сертификат в `acme.json`.
- Запрос перенаправляется на внутренний сервер `http://192.168.10.10:8080`.
---
## 3. **Как работает HTTP-челлендж?**
Lets Encrypt делает GET-запрос:
```
GET http://client1.example.com/.well-known/acme-challenge/<токен>
```
Traefik:
- Автоматически отвечает на этот запрос,
- Не требует дополнительных правил,
- Работает **без участия пользователя**.
> ⚠️ Убедись, что порт **80 открыт** и доступен извне (Let's Encrypt должен видеть твой сервер).
---
## 4. **Файл `acme.json`**
Это **ключевой файл**, в котором Traefik хранит:
- Приватные ключи,
- Сертификаты,
- Сроки действия,
- Информацию о доменах.
Создай его и установи права:
```bash
touch /etc/traefik/acme.json
chmod 600 /etc/traefik/acme.json
```
---
## 🧩 Как работает вся система?
1. **Ты добавляешь новый поддомен в `dynamic_conf.yml`**
2. **Traefik обнаруживает изменение** (если включен `watch: true`)
3. **Запрашивает сертификат у Lets Encrypt**
- Через HTTP-чаллендж (порт 80),
- Проверяет владение доменом,
- Получает сертификат.
4. **Начинает обслуживать сайт по HTTPS**
5. **Проксирует запросы во внутреннюю сеть**
6. **Автоматически обновляет сертификат за 7 дней до истечения**
---
## 📋 Пример полной структуры файлов
```
/etc/traefik/
├── traefik.yml # основной статический конфиг
├── dynamic_conf.yml # динамические маршруты
├── acme.json # хранилище сертификатов
```
---
## 📈 Полезные советы
| Задача | Совет |
|-------------------------------------|----------------------------------------------------------------------|
| Обновление сертификатов | Происходит автоматически каждые 24 часа |
| Проверка сертификатов | Открой Traefik Dashboard → раздел HTTPS > Certificates |
| Лимиты Let's Encrypt | Не более 300 новых сертификатов в день на один домен |
| Избегать блокировок | Не делай много ошибочных запросов |
| Бэкапы | Регулярно бэкапь `acme.json` |
---
## 🚀 Хотите пример скрипта или API?
Если интересно, могу показать:
- Как написать скрипт на Python, который автоматически добавляет поддомены в `dynamic_conf.yml`.
- Как использовать REST API Traefik вместо файла.
- Как проверить, что HTTP-чаллендж прошёл успешно.
- Как использовать staging-среду Lets Encrypt для тестирования.
Просто напиши — подготовлю конкретный пример под твой случай!