Сервисы инфраструктуры
Дата: 2026-01-23
1. CallBox — Веб-приложение
1.1 Backend (FastAPI)
Расположение: web-1, web-2 (Docker контейнеры)
| Параметр | Значение |
|---|---|
| Технология | FastAPI + SQLAlchemy + Pydantic |
| Python | 3.12 |
| Порт | 8000 |
| Контейнер | callbox-backend |
| Точка входа | uvicorn app.main:app |
Основные компоненты:
- app/main.py — точка входа FastAPI
- app/config.py — конфигурация из переменных окружения
- app/database.py — подключение к PostgreSQL
- app/models/ — SQLAlchemy модели
- app/schemas/ — Pydantic схемы валидации
- app/routes/ — API endpoints
- app/services/ — бизнес-логика (asterisk_sync, tts_service)
API Endpoints:
/organizations — CRUD организаций
/operators — CRUD операторов
/queues — CRUD очередей
/endpoints — CRUD SIP терминалов
/incoming-routes — CRUD входящих маршрутов
/working-hours — Графики работы очередей
/statistics — Статистика звонков
/monitoring — Онлайн мониторинг
/recordings — Записи разговоров
/auth — Аутентификация
Переменные окружения:
DATABASE_URL=postgresql://asterisk:***@db-1:5432/asterisk
SECRET_KEY=***
AMI_HOST=10.10.19.51
AMI_PORT=5038
AMI_USERNAME=webadmin
AMI_SECRET=***
ASTERISK_CONFIG_MODE=remote
ASTERISK_SSH_HOST=10.10.19.51
ASTERISK_SSH_USER=sysadmin
REDIS_URL=redis://:***@redis-1:6379/0
1.2 Frontend (React)
Расположение: web-1, web-2 (Docker контейнеры)
| Параметр | Значение |
|---|---|
| Технология | React 19 + TypeScript + Vite |
| Порт | 3000 (nginx) |
| Контейнер | callbox-frontend |
| Сборка | npm run build → nginx |
Основные компоненты:
- src/pages/admin/ — Административный портал
- src/pages/client/ — Клиентский портал
- src/components/ — Переиспользуемые компоненты
- src/services/ — API клиенты (axios + TanStack Query)
- src/schemas/ — Zod схемы валидации
Порталы:
- /admin/* — Управление организациями, очередями, операторами
- /client/:tenantId/* — Статистика, мониторинг, расписания
2. PostgreSQL кластер
2.1 Архитектура
┌─────────────────┐ Streaming ┌─────────────────┐
│ db-1 │ Replication │ db-2 │
│ 10.10.19.31 │ ──────────────────►│ 10.10.19.32 │
│ PRIMARY │ │ REPLICA │
│ PostgreSQL │ │ PostgreSQL │
│ 16.11 │ │ 16.11 │
└────────┬────────┘ └────────┬────────┘
│ │
│ Patroni HA │
│ │
▼ ▼
┌─────────────────────────────────────────────────────────┐
│ etcd cluster │
│ db-1:2379 ◄────────► db-2:2379 ◄────────► mon-1:2379│
└─────────────────────────────────────────────────────────┘
2.2 PostgreSQL Primary (db-1)
| Параметр | Значение |
|---|---|
| Версия | PostgreSQL 16.11 |
| Порт | 5432 |
| База данных | asterisk |
| Пользователь | asterisk |
| Роль | Primary (pg_is_in_recovery = false) |
Конфигурация Patroni:
scope: callbox-cluster
name: db-1
restapi:
listen: 0.0.0.0:8008
connect_address: 10.10.19.31:8008
etcd3:
hosts:
- 10.10.19.31:2379
- 10.10.19.32:2379
- 10.10.19.60:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
use_slots: true
postgresql:
listen: 0.0.0.0:5432
connect_address: 10.10.19.31:5432
data_dir: /var/lib/postgresql/16/main
authentication:
superuser:
username: postgres
replication:
username: replicator
Основные таблицы:
- organizations — Организации (тенанты)
- operators — Операторы
- queues — Очереди
- ps_endpoints — PJSIP endpoints
- ps_auths, ps_aors — PJSIP аутентификация
- incoming_routes — Входящие маршруты
- working_hours — Графики работы
- call_detail_records — CDR (записи звонков)
- users, staff_users — Пользователи системы
2.3 PostgreSQL Replica (db-2)
| Параметр | Значение |
|---|---|
| Версия | PostgreSQL 16.11 |
| Порт | 5432 |
| Роль | Replica (pg_is_in_recovery = true) |
| Репликация | Streaming от db-1 |
Использование: - Только для чтения (read-only queries) - Hot standby для failover - Автоматический failover через Patroni
2.4 etcd кластер
| Нода | IP | Порты |
|---|---|---|
| db-1 | 10.10.19.31 | 2379, 2380 |
| db-2 | 10.10.19.32 | 2379, 2380 |
| mon-1 | 10.10.19.60 | 2379, 2380 |
Назначение: - Distributed consensus для Patroni - Leader election для PostgreSQL - Хранение состояния кластера
3. Redis
3.1 Redis Master (redis-1)
| Параметр | Значение |
|---|---|
| Версия | Redis 7.0.15 |
| Порт | 6379 |
| Sentinel порт | 26379 |
| Аутентификация | Включена (requirepass) |
Конфигурация Sentinel:
sentinel monitor callbox-redis 10.10.19.40 6379 2
sentinel down-after-milliseconds callbox-redis 5000
sentinel failover-timeout callbox-redis 60000
Sentinel nodes: - redis-1:26379 - web-1:26379 - web-2:26379
Использование: - Кэширование сессий - Кэширование API запросов - Pub/Sub для real-time событий - Rate limiting
4. Asterisk
4.1 Asterisk Primary (voip-1)
| Параметр | Значение |
|---|---|
| Версия | Asterisk 20.17.0 |
| Порт SIP | 5060/UDP |
| Порт AMI | 5038/TCP |
| Порт RTP | 10000-20000/UDP |
| Realtime | ODBC → PostgreSQL |
Конфигурационные файлы:
/etc/asterisk/
├── pjsip.conf # SIP endpoints (генерируется из БД)
├── queues.conf # Очереди (генерируется из БД)
├── queues_generated.conf # Автогенерируемый файл очередей
├── extensions.conf # Dialplan
├── func_odbc.conf # ODBC функции для CDR
├── res_odbc.conf # ODBC подключение к PostgreSQL
├── manager.conf # AMI пользователи
└── modules.conf # Загружаемые модули
PJSIP Realtime:
- Endpoints загружаются из таблицы ps_endpoints
- Auths загружаются из таблицы ps_auths
- AORs загружаются из таблицы ps_aors
AMI пользователи:
[webadmin]
secret = ***
read = all
write = all
Dialplan контексты:
- [incoming] — Входящие звонки
- [internal] — Внутренние звонки
- [outbound] — Исходящие звонки
- [cdr-init] — Инициализация CDR
- [operator-login] — Вход операторов в очереди
4.2 Asterisk Secondary (voip-2)
| Параметр | Значение |
|---|---|
| Версия | Asterisk 20.17.0 |
| Порт SIP | 5060/UDP |
| Статус | Hot standby |
Назначение: - Резервный сервер - Ручное переключение при отказе voip-1
4.3 Синхронизация конфигурации
Автоматическая синхронизация (asterisk_sync.py):
1. При изменении очередей через API
2. Генерация queues_generated.conf из БД
3. SSH копирование на voip-1
4. Команда asterisk -rx "queue reload all"
Ручная синхронизация:
# На web-1 или web-2
python -c "from app.services.asterisk_sync import sync_queues_to_asterisk; sync_queues_to_asterisk()"
5. Nginx / Load Balancing
5.1 lb-1 (Primary Load Balancer)
Nginx конфигурация:
# Upstream для API
upstream backend {
least_conn;
server 10.10.19.21:8000;
server 10.10.19.22:8000;
}
# Upstream для Frontend
upstream frontend {
least_conn;
server 10.10.19.21:3000;
server 10.10.19.22:3000;
}
# HTTPS сервер
server {
listen 443 ssl http2;
server_name b2g.kz;
ssl_certificate /etc/letsencrypt/live/b2g.kz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/b2g.kz/privkey.pem;
location /api/ {
proxy_pass http://backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://frontend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# HTTP → HTTPS redirect
server {
listen 80;
server_name b2g.kz;
return 301 https://$server_name$request_uri;
}
5.2 lb-2 (Secondary Load Balancer)
- Аналогичная конфигурация nginx
- Резервный публичный IP: 92.47.181.152
- Используется при отказе lb-1
5.3 SIP/RTP NAT
iptables правила на lb-1/lb-2:
# DNAT SIP на voip-1
iptables -t nat -A PREROUTING -p udp --dport 5060 -j DNAT --to 10.10.19.51:5060
# DNAT RTP на voip-1
iptables -t nat -A PREROUTING -p udp --dport 10000:20000 -j DNAT --to 10.10.19.51
# MASQUERADE для ответов
iptables -t nat -A POSTROUTING -s 10.10.19.0/24 -j MASQUERADE
6. Мониторинг
6.1 Prometheus (mon-1)
| Параметр | Значение |
|---|---|
| Порт | 9090 |
| Retention | 15 дней |
| Scrape interval | 15 секунд |
Targets (prometheus.yml):
scrape_configs:
- job_name: 'node'
static_configs:
- targets:
- 10.10.19.10:9100 # lb-1
- 10.10.19.11:9100 # lb-2
- 10.10.19.21:9100 # web-1
- 10.10.19.22:9100 # web-2
- 10.10.19.31:9100 # db-1
- 10.10.19.32:9100 # db-2
- 10.10.19.40:9100 # redis-1
- 10.10.19.51:9100 # voip-1
- 10.10.19.52:9100 # voip-2
- 10.10.19.60:9100 # mon-1
Собираемые метрики: - CPU, Memory, Disk, Network (node_exporter) - PostgreSQL метрики (postgres_exporter) - Redis метрики (redis_exporter) - Docker метрики (cadvisor)
6.2 Grafana (mon-1)
| Параметр | Значение |
|---|---|
| Версия | 12.3.1 |
| Порт | 3000 |
| Доступ | https://mon.b2g.kz |
Dashboards: - Node Exporter Full — Системные метрики - PostgreSQL Overview — Метрики БД - Redis Dashboard — Метрики Redis - Docker Containers — Метрики контейнеров
6.3 node_exporter
Установлен на всех серверах:
# Системный сервис
/usr/bin/node_exporter --web.listen-address=:9100
Порт: 9100/TCP
7. Docker
7.1 Docker на web-1/web-2
docker-compose.yml:
version: '3.8'
services:
backend:
container_name: callbox-backend
build: ./backend
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://asterisk:***@db-1:5432/asterisk
- REDIS_URL=redis://:***@redis-1:6379/0
volumes:
- /var/lib/callbox:/var/lib/callbox
- /root/.ssh:/root/.ssh:ro
restart: always
frontend:
container_name: callbox-frontend
build: ./frontend
ports:
- "3000:80"
restart: always
networks:
default:
driver: bridge
Volumes:
- /var/lib/callbox — Данные приложения (скриншоты, загрузки)
- /root/.ssh — SSH ключи для подключения к voip-1
7.2 Docker на mon-1
Контейнеры:
- prometheus — Сбор метрик
- grafana — Визуализация
- node-exporter — Метрики хоста
8. Системные сервисы
8.1 systemd сервисы
| Сервер | Сервисы |
|---|---|
| lb-1, lb-2 | nginx, node_exporter |
| web-1, web-2 | docker, node_exporter |
| db-1, db-2 | postgresql, patroni, etcd, node_exporter |
| redis-1 | redis-server, redis-sentinel, node_exporter |
| voip-1, voip-2 | asterisk, node_exporter |
| mon-1 | docker (prometheus, grafana), etcd, node_exporter |
8.2 Управление сервисами
# Проверка статуса
systemctl status <service>
# Перезапуск
systemctl restart <service>
# Логи
journalctl -u <service> -f
# Docker контейнеры
docker ps
docker logs <container>
docker-compose restart
9. Интеграции
9.1 CallBox ↔ PostgreSQL
web-1/web-2 (SQLAlchemy)
│
│ TCP:5432
│ postgresql://asterisk:***@db-1:5432/asterisk
▼
db-1 (Primary)
9.2 CallBox ↔ Asterisk
web-1/web-2
│
├── TCP:5038 (AMI) ─────────────────► voip-1
│ - Мониторинг очередей
│ - Статус endpoints
│
└── TCP:22 (SSH) ───────────────────► voip-1
- Синхронизация конфигурации
- Reload команды
9.3 Asterisk ↔ PostgreSQL
voip-1/voip-2 (ODBC Realtime)
│
│ TCP:5432
│ ODBC: asterisk-connector
▼
db-1
│
├── Чтение: ps_endpoints, ps_auths, ps_aors
└── Запись: call_detail_records
9.4 CallBox ↔ Redis
web-1/web-2
│
│ TCP:6379
│ redis://:***@redis-1:6379/0
▼
redis-1
│
├── Кэш сессий
├── Кэш API
└── Rate limiting
10. Безопасность сервисов
10.1 Аутентификация
| Сервис | Метод |
|---|---|
| PostgreSQL | scram-sha-256 |
| Redis | requirepass |
| AMI | secret в manager.conf |
| API | JWT tokens |
| SSH | Key-based |
10.2 Шифрование
| Соединение | Шифрование |
|---|---|
| HTTPS | TLS 1.2/1.3 (Let's Encrypt) |
| PostgreSQL | Без шифрования (внутренняя сеть) |
| Redis | Без шифрования (внутренняя сеть) |
| SIP | Без шифрования (NAT через LB) |
10.3 Firewall
Все сервисы защищены iptables: - Внешний доступ только через lb-1/lb-2 - Внутренние сервисы доступны только из 10.10.19.0/24 - SSH только с админских IP через lb-1