186 lines
11 KiB
Markdown
186 lines
11 KiB
Markdown
# Запуск Telemt API Gateway (Docker)
|
||
|
||
Оглавление:
|
||
|
||
1. [Назначение](#назначение)
|
||
2. [Требования](#требования)
|
||
3. [Минимальная конфигурация](#минимальная-конфигурация)
|
||
4. [Переменные окружения](#переменные-окружения)
|
||
5. [Готовый образ из registry](#готовый-образ-из-registry)
|
||
6. [Локальная сборка образа](#локальная-сборка-образа)
|
||
7. [Запуск через Docker CLI](#запуск-через-docker-cli)
|
||
8. [Запуск через Docker Compose](#запуск-через-docker-compose)
|
||
9. [Проверка](#проверка)
|
||
10. [Обновление и CI/CD](#обновление-и-cicd)
|
||
11. [Устранение неполадок](#устранение-неполадок)
|
||
|
||
## Назначение
|
||
|
||
Шлюз — это один HTTP‑вход для нескольких экземпляров [Telemt Control API](API.md):
|
||
|
||
- **Белый список IP** (CIDR): кто может обращаться к шлюзу (кроме `GET /health`, см. ниже).
|
||
- **Маршрутизация по alias**: клиент вызывает `GET /api/{alias}/health`, шлюз проксирует на `{base_url}/v1/health` у соответствующего сервера.
|
||
- **Метрики Prometheus**: `GET /metrics` (под тем же правилом whitelist, что и API).
|
||
- **Доверенные прокси**: если прямой TCP‑peer входит в `trusted_proxies`, для проверки whitelist берётся первый адрес из `X-Forwarded-For` или `X-Real-IP`.
|
||
|
||
Эндпоинты и контракт ответов бэкенда описаны в [API.md](API.md).
|
||
|
||
## Требования
|
||
|
||
- Установленные [Docker](https://docs.docker.com/get-docker/) и при необходимости [Docker Compose](https://docs.docker.com/compose/) v2.
|
||
- Для локальной сборки из исходников: [Go 1.22+](https://go.dev/dl/) (опционально, если не используете только готовый образ из registry).
|
||
|
||
## Минимальная конфигурация
|
||
|
||
Скопируйте [config.example.yaml](../config.example.yaml) в свой `config.yaml` и отредактируйте.
|
||
|
||
Минимальный рабочий фрагмент для **разработки** (без проверки IP):
|
||
|
||
```yaml
|
||
listen: ":8080"
|
||
allow_all: true
|
||
servers:
|
||
- alias: main_srv
|
||
base_url: http://127.0.0.1:9091
|
||
```
|
||
|
||
Минимальный фрагмент для **продакшена** (только перечисленные сети/хосты):
|
||
|
||
```yaml
|
||
listen: ":8080"
|
||
allow_all: false
|
||
whitelist_cidrs:
|
||
- "203.0.113.10/32"
|
||
- "10.0.0.0/8"
|
||
servers:
|
||
- alias: main_srv
|
||
base_url: http://telemt-internal:9091
|
||
```
|
||
|
||
Правила:
|
||
|
||
- При `allow_all: false` и **пустом** `whitelist_cidrs` доступ будет **закрыт для всех** (кроме `GET /health`).
|
||
- В `whitelist_cidrs` и `trusted_proxies` допустимы **CIDR** (`10.0.0.0/8`) и **одиночный IPv4/IPv6** без маски (`87.103.241.8` эквивалентно `87.103.241.8/32`).
|
||
- `GET /health` на шлюзе **не** проверяется по whitelist — так проще настроить Docker `HEALTHCHECK` и оркестраторы.
|
||
- Поле `path_prefix` по умолчанию равно `/v1` (префикс Telemt Control API).
|
||
|
||
Опционально для бэкенда с включённым `auth_header` в Telemt задайте в конфиге имя переменной окружения, значение которой будет отправлено как заголовок `Authorization` на этот upstream:
|
||
|
||
```yaml
|
||
servers:
|
||
- alias: main_srv
|
||
base_url: http://telemt:9091
|
||
authorization_env: TELEMT_API_AUTH
|
||
```
|
||
|
||
Значение должно **точно** совпадать с настроенным в Telemt `auth_header` (см. [API.md](API.md)).
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | Описание |
|
||
|----------------|----------|
|
||
| `CONFIG_PATH` | Путь к YAML внутри контейнера. По умолчанию: `/etc/telemt-gateway/config.yaml`. |
|
||
| `TELEMT_API_AUTH` | Пример: секрет для `authorization_env` в конфиге (имя может быть любым). |
|
||
|
||
## Готовый образ из registry
|
||
|
||
CI публикует образ в Container Registry Gitea. Для репозитория `denozord/telemt-api` на `git.shts.su` стабильный тег:
|
||
|
||
```bash
|
||
docker pull git.shts.su/denozord/telemt-api:latest
|
||
```
|
||
|
||
Если registry **не публичный**, сначала войдите (логин — пользователь Gitea, пароль — personal access token с правом **`read:package`**):
|
||
|
||
```bash
|
||
docker login git.shts.su
|
||
```
|
||
|
||
Другие полезные теги из того же workflow: имя ветки (с `/` заменённым на `-`) и `sha-<12 символов коммита>` — см. раздел [Обновление и CI/CD](#обновление-и-cicd).
|
||
|
||
## Локальная сборка образа
|
||
|
||
Если нужно собрать образ самостоятельно из клона репозитория:
|
||
|
||
```bash
|
||
docker build -t telemt-api-gateway:local .
|
||
```
|
||
|
||
В командах `docker run` ниже вместо имени из registry подставьте `telemt-api-gateway:local`.
|
||
|
||
## Запуск через Docker CLI
|
||
|
||
Пример для Linux (подставьте путь к `config.yaml`; ниже — файл из текущего каталога). Используется **готовый** образ:
|
||
|
||
```bash
|
||
docker run -d --name telemt-gateway \
|
||
-p 8080:8080 \
|
||
-v "$(pwd)/config.yaml:/etc/telemt-gateway/config.yaml:ro" \
|
||
-e CONFIG_PATH=/etc/telemt-gateway/config.yaml \
|
||
git.shts.su/denozord/telemt-api:latest
|
||
```
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
curl -sS -i http://127.0.0.1:8080/health
|
||
curl -sS -i http://127.0.0.1:8080/api/main_srv/health
|
||
```
|
||
|
||
Второй запрос проксируется на `{base_url}/v1/health` для alias `main_srv`.
|
||
|
||
Остановка и удаление:
|
||
|
||
```bash
|
||
docker stop telemt-gateway
|
||
docker rm telemt-gateway
|
||
```
|
||
|
||
## Запуск через Docker Compose
|
||
|
||
В репозитории есть [docker-compose.yml](../docker-compose.yml) и пример [config.compose.yaml](../config.compose.yaml) с `allow_all: true` и `base_url: http://host.docker.internal:9091` (Telemt на хосте; на Docker Desktop для Linux это обычно работает из коробки). Образ по умолчанию **скачивается** из registry, локальная сборка не требуется.
|
||
|
||
```bash
|
||
docker compose pull
|
||
docker compose up -d
|
||
docker compose logs -f gateway
|
||
docker compose down
|
||
```
|
||
|
||
Чтобы пересобрать образ из исходников вместо pull, в [docker-compose.yml](../docker-compose.yml) временно замените блок `image:` на `build: .` (и нужный тег при необходимости).
|
||
|
||
На Linux без `host.docker.internal` сделайте одно из:
|
||
|
||
- в `docker-compose.yml` для сервиса `gateway` добавьте `extra_hosts: ["host.docker.internal:host-gateway"]` (Docker Engine 20.10+);
|
||
- либо замените в `config.compose.yaml` значение `base_url` на IP хоста в docker‑bridge (часто `172.17.0.1`) или на имя сервиса Telemt в той же сети compose.
|
||
|
||
## Проверка
|
||
|
||
| Сценарий | Ожидание |
|
||
|----------|----------|
|
||
| `GET /health` | `200`, JSON `{"status":"ok"}` |
|
||
| Разрешённый IP, корректный alias | ответ бэкенда (например `200` для `/v1/health`) |
|
||
| IP не в whitelist | `403`, JSON с `code: forbidden` |
|
||
| Неизвестный alias | `404`, JSON с `code: not_found` |
|
||
| Бэкенд недоступен | `502`, JSON с `code: bad_gateway` |
|
||
| `GET /metrics` | текст метрик Prometheus (при разрешённом IP) |
|
||
|
||
## Обновление и CI/CD
|
||
|
||
- **Образ**: подтяните свежий тег (`docker pull git.shts.su/denozord/telemt-api:latest` или `docker compose pull`), пересоздайте контейнер (`docker compose up -d` или новый `docker run` с тем же volume конфига). Локальная пересборка нужна только если вы меняете Dockerfile/код и не пользуетесь CI.
|
||
- **Конфиг**: отредактируйте файл на хосте и перезапустите контейнер (шлюз не перечитывает конфиг на лету).
|
||
- **Gitea Actions**: workflow [.gitea/workflows/docker.yaml](../.gitea/workflows/docker.yaml) сначала выполняет `go mod tidy && go test ./...`, затем собирает образ через Buildx и пушит в Container Registry Gitea.
|
||
|
||
- В репозитории должен быть secret **`ACTIONS_PAT`** — personal access token пользователя с правом **`write:package`** (и при необходимости `read:package`), как для обычного `docker login` к registry.
|
||
- Логин в registry: пользователь **`gitea.actor`** (кто запустил workflow), пароль — этот PAT.
|
||
- Хост registry задаётся в workflow в `env.REGISTRY` (по умолчанию `git.shts.su`); при другом инстансе Gitea измените значение в `.gitea/workflows/docker.yaml`.
|
||
- Теги образа: `latest`, имя ветки/тега (с `/` заменённым на `-`), и `sha-<первые 12 символов коммита>`. Полный путь: `{REGISTRY}/{gitea.repository}:<тег>`.
|
||
|
||
## Устранение неполадок
|
||
|
||
- **`docker pull`: `unauthorized` / `denied`**: выполните `docker login git.shts.su` с учётной записью Gitea и PAT с **`read:package`**.
|
||
- **`403 forbidden` с хоста при `allow_all: false`**: добавьте CIDR клиента в `whitelist_cidrs`. Запросы из контейнера к самому себе идут с `127.0.0.1` — при необходимости добавьте `127.0.0.1/32`.
|
||
- **За reverse proxy**: укажите CIDR прокси в `trusted_proxies`, иначе whitelist видит IP прокси, а не клиента.
|
||
- **`502 bad_gateway`**: проверьте `base_url`, DNS в Docker‑сети и то, что Telemt слушает API (`[server.api].enabled=true` и корректный `listen`).
|
||
- **Сборка Go без Docker**: в корне репозитория выполните `go mod tidy && go test ./...`.
|