Архитектурное руководство для DevOps и инфраструктурных команд
Содержание¶
- Обзор
- 1. Системные требования
- 1.1 Аппаратные требования
- 1.2 Программные требования
- 1.3 Сетевые порты
- 2. Docker Compose (разработка)
- 2.1 Структура файлов
- 2.2 docker-compose.yml
- 2.3 Переменные окружения (.env)
- 2.4 Запуск
- 3. Kubernetes (production)
- 3.1 Архитектура
- 3.2 Namespace и ConfigMap
- 3.3 Secrets
- 3.4 Deployment
- 3.5 Service и Ingress
- 3.6 HorizontalPodAutoscaler
- 3.7 NetworkPolicy
- 4. Изолированное развёртывание
- 4.1 Особенности изолированной среды
- 4.2 Конфигурация для изолированной среды
- 4.3 Подготовка артефактов для изолированной среды
- 4.4 Установка в изолированной среде
- 5. Безопасность развёртывания
- 5.1 TLS/SSL конфигурация
- 5.2 Pod Security Standards
- 5.3 Secrets Encryption
- 6. Мониторинг и наблюдаемость
- 6.1 Prometheus ServiceMonitor
- 6.2 Grafana Dashboard
- 6.3 Alertmanager правила
- 7. Резервное копирование и восстановление
- 7.1 Резервное копирование PostgreSQL
- 7.2 Резервное копирование DuckDB
- 7.3 Disaster Recovery
- 8. Миграция и обновление
- 8.1 Поэтапное обновление
- 8.2 Миграция базы данных
- Связанные документы
Обзор¶
CodeGraph поддерживает несколько режимов развёртывания для различных требований безопасности и масштабирования:
| Режим | Описание | Рекомендуется для |
|---|---|---|
| Docker Compose | Один узел, простая настройка | Разработка, тестирование |
| Kubernetes | Кластер, HA, автомасштабирование | Production |
| Изолированная среда | Изолированная сеть, локальный LLM | Режимные объекты |
1. Системные требования¶
1.1 Аппаратные требования¶
| Компонент | Минимум | Рекомендуется | Production |
|---|---|---|---|
| CPU | 4 ядра | 8 ядер | 16+ ядер |
| RAM | 8 GB | 16 GB | 32+ GB |
| SSD | 50 GB | 100 GB | 500+ GB |
| GPU | - | NVIDIA 8GB+ | NVIDIA 24GB+ |
Примечание: GPU требуется только для локального LLM (изолированный режим).
1.2 Программные требования¶
| Компонент | Версия | Назначение |
|---|---|---|
| Python | 3.11+ | Основная среда выполнения |
| PostgreSQL | 16+ | Хранение пользователей, сессий, аудита |
| DuckDB | 1.4.4+ | Хранение CPG графов (расширение DuckPGQ) |
| Go | 1.26+ | Генератор CPG GoCPG (требуется CGO) |
| Docker | 24+ | Контейнеризация (необязательно) |
| Kubernetes | 1.28+ | Оркестрация (production) |
Примечание: GoCPG используется для генерации CPG из исходного кода, генерируя вывод DuckDB напрямую. Требуется Go 1.26+ с включённым CGO для парсинга tree-sitter.
1.3 Сетевые порты¶
| Порт | Сервис | Протокол |
|---|---|---|
| 8000 | CodeGraph API | HTTP/HTTPS |
| 5432 | PostgreSQL | TCP |
| 514 | SIEM (Syslog) | UDP/TCP |
| 8200 | HashiCorp Vault | HTTP/HTTPS |
| 9090 | Prometheus | HTTP |
| 9093 | Alertmanager | HTTP |
| 3000 | Grafana | HTTP |
2. Docker Compose (разработка)¶
2.1 Структура файлов¶
codegraph/
├── docker-compose.yml
├── docker-compose.override.yml # Локальные настройки
├── .env # Переменные окружения
├── config.yaml # Конфигурация приложения
├── monitoring/
│ ├── prometheus.yml # Конфигурация Prometheus
│ ├── alertmanager.yml # Конфигурация Alertmanager
│ ├── rules/ # Правила алертов
│ ├── grafana-datasources.yml # Источники данных Grafana
│ └── grafana-dashboards.yml # Дашборды Grafana
└── data/
├── duckdb/ # Файлы DuckDB
└── projects/ # Рабочие области проектов
2.2 docker-compose.yml¶
Файл compose определяет 6 сервисов:
services:
# ==========================================================================
# CodeGraph API Server
# ==========================================================================
api:
build:
context: .
dockerfile: Dockerfile
target: production
image: codegraph:latest
container_name: codegraph-api
restart: unless-stopped
ports:
- "8000:8000"
environment:
# База данных
- DATABASE_URL=postgresql+asyncpg://codegraph:${POSTGRES_PASSWORD}@postgres:5432/codegraph
# Аутентификация
- API_JWT_SECRET=${API_JWT_SECRET}
- API_ADMIN_USERNAME=${API_ADMIN_USERNAME:-admin}
- API_ADMIN_PASSWORD=${API_ADMIN_PASSWORD}
# Yandex AI Studio LLM
- YANDEX_API_KEY=${YANDEX_API_KEY}
- YANDEX_FOLDER_ID=${YANDEX_FOLDER_ID}
# Окружение
- ENVIRONMENT=production
- LOG_LEVEL=${LOG_LEVEL:-INFO}
# Безопасность
- SECURITY_ENABLED=${SECURITY_ENABLED:-true}
- DLP_ENABLED=${DLP_ENABLED:-true}
# CORS (production)
- CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS:-}
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./data/projects:/app/data/projects
- ./data/duckdb:/app/data/duckdb
- ./logs:/app/logs
depends_on:
postgres:
condition: service_healthy
networks:
- codegraph-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
# Примечание: 1 worker Uvicorn (не api.workers из config.yaml) для когерентности кеша
deploy:
resources:
limits:
cpus: '4'
memory: 8G
reservations:
cpus: '2'
memory: 4G
# ==========================================================================
# PostgreSQL Database
# ==========================================================================
postgres:
image: postgres:17-alpine
container_name: codegraph-postgres
restart: unless-stopped
environment:
- POSTGRES_USER=codegraph
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=codegraph
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- codegraph-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U codegraph -d codegraph"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
deploy:
resources:
limits:
cpus: '2'
memory: 2G
# ==========================================================================
# Prometheus Monitoring
# ==========================================================================
prometheus:
image: prom/prometheus:v3.10.0
container_name: codegraph-prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./monitoring/rules:/etc/prometheus/rules:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
- '--storage.tsdb.retention.time=30d'
networks:
- codegraph-network
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:9090/-/healthy"]
interval: 30s
timeout: 10s
retries: 3
# ==========================================================================
# Alertmanager
# ==========================================================================
alertmanager:
image: prom/alertmanager:v0.31.1
container_name: codegraph-alertmanager
restart: unless-stopped
ports:
- "9093:9093"
environment:
- ALERTMANAGER_WEBHOOK_URL=${ALERTMANAGER_WEBHOOK_URL:-http://localhost:9095/alert}
volumes:
- ./monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
networks:
- codegraph-network
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:9093/-/healthy"]
interval: 30s
timeout: 10s
retries: 3
# ==========================================================================
# Grafana Dashboard
# ==========================================================================
grafana:
image: grafana/grafana:12.4.0
container_name: codegraph-grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=${GRAFANA_ROOT_URL:-http://localhost:3000}
volumes:
- grafana-data:/var/lib/grafana
- ./monitoring/grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml:ro
- ./monitoring/grafana-dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml:ro
depends_on:
- prometheus
networks:
- codegraph-network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost:3000/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
# ==========================================================================
# GoCPG - Code Property Graph Generator
# ==========================================================================
# Использование:
# docker compose run --rm gocpg parse --input=/src --output=/out/cpg.duckdb --lang=c
gocpg:
build:
context: ./gocpg
dockerfile: Dockerfile
image: gocpg:latest
container_name: codegraph-gocpg
volumes:
- ${GOCPG_SOURCE_PATH:-.}:/src:ro
- ./data/duckdb:/out
networks:
- codegraph-network
deploy:
resources:
limits:
memory: 4G
networks:
codegraph-network:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
volumes:
postgres-data:
driver: local
prometheus-data:
driver: local
grafana-data:
driver: local
2.3 Переменные окружения (.env)¶
# =============================================================================
# CodeGraph Environment Variables
# =============================================================================
# PostgreSQL
POSTGRES_PASSWORD=<secure-password-here>
# JWT Authentication
API_JWT_SECRET=<64-char-random-string>
API_ADMIN_USERNAME=admin
API_ADMIN_PASSWORD=<secure-admin-password>
# LLM Providers
# Yandex AI Studio
YANDEX_API_KEY=<your-yandex-api-key>
YANDEX_FOLDER_ID=<your-yandex-folder-id>
# GigaChat (Сбер) — альтернативный провайдер
# GIGACHAT_AUTH_KEY=<base64-encoded-credentials>
# Безопасность
SECURITY_ENABLED=true
DLP_ENABLED=true
# Grafana
GRAFANA_ADMIN_PASSWORD=<secure-grafana-password>
# Alertmanager webhook (необязательно)
# ALERTMANAGER_WEBHOOK_URL=http://localhost:9095/alert
2.4 Запуск¶
# Создание .env файла
cp .env.example .env
# Редактирование переменных
nano .env
# Запуск всех сервисов
docker compose up -d
# Проверка статуса
docker compose ps
# Просмотр логов
docker compose logs -f api
# Инициализация базы данных
docker compose exec api python -m alembic upgrade head
# Создание администратора
docker compose exec api python -m src.api.cli create-admin \
--username admin --password <secure-password>
3. Kubernetes (production)¶
3.1 Архитектура¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ KUBERNETES CLUSTER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ INGRESS CONTROLLER │ │
│ │ (nginx / traefik / istio) │ │
│ │ │ │
│ │ api.codegraph.company.com ────────────────► codegraph-api:8000 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ CODEGRAPH NAMESPACE │ │
│ │ │ │
│ │ ┌───────────────────┐ ┌───────────────────┐ ┌─────────────────┐ │ │
│ │ │ codegraph-api │ │ codegraph-api │ │ codegraph-api │ │ │
│ │ │ (replica 1) │ │ (replica 2) │ │ (replica 3) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ CPU: 2 │ │ CPU: 2 │ │ CPU: 2 │ │ │
│ │ │ RAM: 4Gi │ │ RAM: 4Gi │ │ RAM: 4Gi │ │ │
│ │ └───────────────────┘ └───────────────────┘ └─────────────────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────────┼──────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌───────────────────────────────────────────────────────────────┐ │ │
│ │ │ SERVICES │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │
│ │ │ │ PostgreSQL │ │ GoCPG │ │ HashiCorp Vault │ │ │ │
│ │ │ │ (StatefulSet)│ │ (StatefulSet)│ │ (External) │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ PVC: 100Gi │ │ PVC: 50Gi │ │ │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
3.2 Namespace и ConfigMap¶
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: codegraph
labels:
name: codegraph
istio-injection: enabled # Если используется Istio
pod-security.kubernetes.io/enforce: restricted
---
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: codegraph-config
namespace: codegraph
data:
config.yaml: |
domain:
name: postgresql
auto_activate: true
api:
host: "0.0.0.0"
port: 8000
workers: 1 # Один worker для когерентности кеша (TTLCache)
security:
enabled: true
dlp:
enabled: true
pre_request:
enabled: true
default_action: "WARN"
post_response:
enabled: true
default_action: "MASK"
siem:
enabled: true
syslog:
enabled: true
host: "siem-syslog.security.svc.cluster.local"
port: 514
vault:
enabled: true
url: "http://vault.vault.svc.cluster.local:8200"
auth_method: "kubernetes"
kubernetes:
role: "codegraph"
3.3 Secrets¶
# secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: codegraph-secrets
namespace: codegraph
type: Opaque
stringData:
DATABASE_URL: "postgresql+asyncpg://codegraph:password@postgres:5432/codegraph"
API_JWT_SECRET: "<64-char-random-string>"
YANDEX_API_KEY: "<your-yandex-api-key>"
YANDEX_FOLDER_ID: "<your-yandex-folder-id>"
---
# Для production используйте External Secrets Operator + Vault
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: codegraph-vault-secrets
namespace: codegraph
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: codegraph-secrets
data:
- secretKey: DATABASE_URL
remoteRef:
key: codegraph/database
property: url
- secretKey: API_JWT_SECRET
remoteRef:
key: codegraph/api
property: jwt_secret
- secretKey: YANDEX_API_KEY
remoteRef:
key: codegraph/llm
property: yandex_api_key
3.4 Deployment¶
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: codegraph-api
namespace: codegraph
labels:
app: codegraph
component: api
spec:
replicas: 3
selector:
matchLabels:
app: codegraph
component: api
template:
metadata:
labels:
app: codegraph
component: api
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8000"
prometheus.io/path: "/api/v1/metrics"
spec:
serviceAccountName: codegraph
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: api
image: codegraph:latest
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
envFrom:
- secretRef:
name: codegraph-secrets
env:
- name: SECURITY_ENABLED
value: "true"
- name: DLP_ENABLED
value: "true"
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
- name: duckdb-data
mountPath: /app/data/duckdb
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
livenessProbe:
httpGet:
path: /api/v1/health/live
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/v1/health/ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumes:
- name: config
configMap:
name: codegraph-config
- name: duckdb-data
persistentVolumeClaim:
claimName: codegraph-duckdb-pvc
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: codegraph
topologyKey: kubernetes.io/hostname
3.5 Service и Ingress¶
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: codegraph-api
namespace: codegraph
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: http
selector:
app: codegraph
component: api
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: codegraph-ingress
namespace: codegraph
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.codegraph.company.com
secretName: codegraph-tls
rules:
- host: api.codegraph.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: codegraph-api
port:
number: 8000
3.6 HorizontalPodAutoscaler¶
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: codegraph-api-hpa
namespace: codegraph
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: codegraph-api
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
3.7 NetworkPolicy¶
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: codegraph-network-policy
namespace: codegraph
spec:
podSelector:
matchLabels:
app: codegraph
policyTypes:
- Ingress
- Egress
ingress:
# Разрешить трафик от ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8000
# Разрешить трафик от Prometheus
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 8000
egress:
# PostgreSQL
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
# Vault
- to:
- namespaceSelector:
matchLabels:
name: vault
ports:
- protocol: TCP
port: 8200
# SIEM (Syslog)
- to:
- namespaceSelector:
matchLabels:
name: security
ports:
- protocol: UDP
port: 514
# LLM APIs (GigaChat, Yandex AI, OpenAI)
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
# DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
4. Изолированное развёртывание¶
4.1 Особенности изолированной среды¶
┌────────────────────────────────────────────────────────────────────────┐
│ ИЗОЛИРОВАННАЯ СРЕДА │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ БЕЗ ДОСТУПА К ИНТЕРНЕТУ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ CodeGraph │ │ Local LLM │ │ Local Container │ │ │
│ │ │ API │ │ (llama.cpp) │ │ Registry │ │ │
│ │ │ │──│ │ │ │ │ │
│ │ │ DLP: ON │ │ │ │ registry.local:5000 │ │ │
│ │ │ SIEM: ON │ │ │ │ │ │ │
│ │ │ Vault: ON │ │ │ │ │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ БЕЗ ВНЕШНИХ LLM API │
│ ВСЕ ДАННЫЕ ОСТАЮТСЯ ЛОКАЛЬНО │
│ │
└────────────────────────────────────────────────────────────────────────┘
4.2 Конфигурация для изолированной среды¶
# config.yaml для изолированной среды
llm:
# Использовать локальный LLM вместо GigaChat
provider: "local"
# Онлайн-режим: Qwen3-235B через Yandex AI Studio
yandex:
model: "qwen3-235b"
# Офлайн-режим: Локальная модель через переменную окружения QWEN3_MODEL_PATH
local:
# Путь к модели (перенесена на носителе или задана через QWEN3_MODEL_PATH)
model_path: "${QWEN3_MODEL_PATH:-/models/model.gguf}"
n_ctx: 8192
n_gpu_layers: -1 # Все слои на GPU
n_batch: 512
n_threads: 8
security:
enabled: true
# DLP работает локально
dlp:
enabled: true
webhook:
enabled: false # Нет внешних вебхуков
# SIEM — локальный сервер
siem:
enabled: true
syslog:
enabled: true
host: "siem.local"
port: 514
# Vault — локальный экземпляр
vault:
enabled: true
url: "http://vault.local:8200"
auth_method: "approle"
4.3 Подготовка артефактов для изолированной среды¶
#!/bin/bash
# prepare-airgapped.sh — запустить на машине с интернетом
# 1. Скачать Docker образы
docker pull codegraph:latest
docker pull postgres:17-alpine
docker pull gocpg:latest
docker pull hashicorp/vault:1.15
# 2. Сохранить образы в tar
docker save codegraph:latest postgres:17-alpine \
gocpg:latest hashicorp/vault:1.15 \
| gzip > codegraph-images.tar.gz
# 3. Скачать LLM модель
wget https://huggingface.co/...
# 4. Скачать Python зависимости
pip download -d ./packages -r requirements.txt
# 5. Упаковать всё
tar -czvf codegraph-airgapped-bundle.tar.gz \
codegraph-images.tar.gz \
model.gguf \
packages/ \
config/ \
scripts/
4.4 Установка в изолированной среде¶
#!/bin/bash
# install-airgapped.sh — запустить в изолированной среде
# 1. Распаковать бандл
tar -xzvf codegraph-airgapped-bundle.tar.gz
# 2. Загрузить Docker образы
gunzip -c codegraph-images.tar.gz | docker load
# 3. Установить Python зависимости из локального кеша
pip install --no-index --find-links=./packages -r requirements.txt
# 4. Скопировать модель
cp model.gguf /models/
# 5. Запустить сервисы
docker compose -f docker-compose.airgapped.yml up -d
5. Безопасность развёртывания¶
5.1 TLS/SSL конфигурация¶
# Nginx Ingress с TLS 1.3
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: codegraph-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.3"
nginx.ingress.kubernetes.io/ssl-ciphers: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
5.2 Pod Security Standards¶
Kubernetes 1.28+ использует Pod Security Admission (PSA) вместо устаревшего PodSecurityPolicy. Примените профиль безопасности restricted через метки namespace:
# namespace.yaml с Pod Security Standards
apiVersion: v1
kind: Namespace
metadata:
name: codegraph
labels:
name: codegraph
# Pod Security Admission (заменяет устаревший PodSecurityPolicy)
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Профиль restricted обеспечивает:
- runAsNonRoot: true
- allowPrivilegeEscalation: false
- Сброс ALL capabilities
- Файловая система только для чтения
- Без host network/PID/IPC
Эти параметры уже настроены в спецификации Deployment (раздел 3.4) через securityContext.
5.3 Secrets Encryption¶
# EncryptionConfiguration для etcd
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
6. Мониторинг и наблюдаемость¶
6.1 Prometheus ServiceMonitor¶
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: codegraph-monitor
namespace: codegraph
spec:
selector:
matchLabels:
app: codegraph
endpoints:
- port: http
path: /api/v1/metrics
interval: 30s
6.2 Grafana Dashboard¶
CodeGraph экспортирует метрики Prometheus с префиксом rag_ через /api/v1/metrics:
| Панель | Метрика | Описание |
|---|---|---|
| Активные запросы | rag_active_requests |
Запросы в обработке (gauge) |
| Всего запросов | rate(rag_total_requests[5m]) |
Запросы в секунду |
| Задержка P95 | histogram_quantile(0.95, rate(rag_scenario_duration_seconds_bucket[5m])) |
95-й перцентиль задержки |
| Задержка LLM | histogram_quantile(0.95, rate(rag_llm_latency_seconds_bucket[5m])) |
Задержка LLM API |
| Токены LLM | sum(rate(rag_llm_tokens_total[1h])) by (model) |
Использование токенов по модели |
| Ошибки LLM | rate(rag_llm_errors_total[5m]) |
Ошибки LLM API |
| Попадания в кеш | rate(rag_cache_hits_total[5m]) / (rate(rag_cache_hits_total[5m]) + rate(rag_cache_misses_total[5m])) |
Эффективность кеша |
6.3 Alertmanager правила¶
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: codegraph-alerts
namespace: codegraph
spec:
groups:
- name: codegraph
rules:
- alert: CodeGraphHighLatency
expr: histogram_quantile(0.95, rate(rag_scenario_duration_seconds_bucket[5m])) > 30
for: 5m
labels:
severity: critical
annotations:
summary: "High P95 latency on CodeGraph API"
- alert: CodeGraphLLMErrors
expr: rate(rag_llm_errors_total[5m]) > 0.1
for: 10m
labels:
severity: warning
annotations:
summary: "Elevated LLM API error rate"
- alert: CodeGraphPodNotReady
expr: kube_pod_status_ready{namespace="codegraph", condition="true"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "CodeGraph pod not ready"
7. Резервное копирование и восстановление¶
7.1 Резервное копирование PostgreSQL¶
#!/bin/bash
# backup-postgres.sh
BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
NAMESPACE="codegraph"
# Создать резервную копию
kubectl exec -n $NAMESPACE postgres-0 -- \
pg_dump -U codegraph codegraph | gzip > $BACKUP_DIR/codegraph_$DATE.sql.gz
# Удалить старые резервные копии (старше 30 дней)
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
7.2 Резервное копирование DuckDB¶
#!/bin/bash
# backup-duckdb.sh
BACKUP_DIR="/backups/duckdb"
DATE=$(date +%Y%m%d_%H%M%S)
# Копировать файлы DuckDB
kubectl cp codegraph/codegraph-api-0:/app/data/duckdb $BACKUP_DIR/duckdb_$DATE
# Сжать
tar -czvf $BACKUP_DIR/duckdb_$DATE.tar.gz -C $BACKUP_DIR duckdb_$DATE
rm -rf $BACKUP_DIR/duckdb_$DATE
7.3 Disaster Recovery¶
| RPO | RTO | Стратегия |
|---|---|---|
| 1 час | 4 часа | Ежечасные снапшоты, запасной кластер |
| 24 часа | 24 часа | Ежедневное резервное копирование, ручное восстановление |
| 1 неделя | 72 часа | Еженедельное резервное копирование, cold standby |
8. Миграция и обновление¶
8.1 Поэтапное обновление¶
# Обновление образа с нулевым простоем
kubectl set image deployment/codegraph-api \
api=codegraph:v2.0.0 \
-n codegraph
# Мониторинг rollout
kubectl rollout status deployment/codegraph-api -n codegraph
# Откат при проблемах
kubectl rollout undo deployment/codegraph-api -n codegraph
8.2 Миграция базы данных¶
# Запуск миграций Alembic
kubectl exec -n codegraph deployment/codegraph-api -- \
python -m alembic upgrade head
# Проверка текущей версии
kubectl exec -n codegraph deployment/codegraph-api -- \
python -m alembic current
Связанные документы¶
- Enterprise Security Brief — Обзор безопасности
- RBAC Authorization — Контроль доступа
- SIEM Integration — Интеграция с SIEM
- LLM Security — Защита LLM-взаимодействий
Версия: 1.2 | Март 2026