# Развёртывание в Kubernetes

## Требования

- Kubernetes 1.28+ (проверено на k0s 1.36.1)
- kubectl 1.28+
- Доступ к registry с образами backend и frontend

## Состав manifests

Все манифесты в `k8s/`. Порядок применения — по префиксу номера.

| Файл                    | Ресурсы                             |
|-------------------------|-------------------------------------|
| `00-namespace.yaml`     | Namespace `support-bot`              |
| `01-postgres.yaml`      | PV, PVC, Deployment, Service (postgres:16-alpine) |
| `02-redis.yaml`         | PV, PVC, Deployment, Service (redis:7-alpine)    |
| `03-qdrant.yaml`        | PV, PVC, Deployment, Service (qdrant/qdrant)     |
| `04-backend.yaml`       | Deployment, Service (FastAPI)        |
| `05-frontend.yaml`      | Deployment, Service (nginx SPA)      |
| `06-ingress.yaml`       | IngressRoute (Traefik CRD)           |
| `host-fix-pod.yaml`     | Debug pod для отладки узла          |

## 1. Подготовка

### 1.1 Создание namespace

```bash
kubectl apply -f k8s/00-namespace.yaml
```

### 1.2 Настройка Traefik (Ingress Controller)

```bash
# CRDs и RBAC (однократно)
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.3/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.3/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml

# Сам Traefik
kubectl apply -f k8s/traefik/01-core.yaml
```

Traefik запускается с `hostNetwork: true` на портах 80/443.

### 1.3 Настройка Private Registry (если необходимо)

```bash
kubectl create secret docker-registry regcred \
  --docker-server=<registry> \
  --docker-username=<user> \
  --docker-password=<pass> \
  -n support-bot
```

Secret `regcred` уже указан в `imagePullSecrets` у backend и frontend.

### 1.4 Secrets

Секрет `app-env` содержит переменные окружения для backend. Создаётся из `.env`:

```bash
kubectl create secret generic app-env \
  --from-env-file=.env \
  -n support-bot
```

Состав ключей в `app-env`:

| Ключ                         | Назначение                          |
|------------------------------|--------------------------------------|
| `OPENROUTER_API_KEY`         | API-ключ OpenRouter                  |
| `OPENROUTER_EMBEDDING_MODEL` | Модель эмбеддингов                   |
| `OPENROUTER_LLM_MODEL`       | Модель LLM                          |
| `JWT_SECRET`                 | Секрет для JWT                       |
| `PROXY_URL`                  | Адрес HTTP-прокси (опционально)      |
| `PROXY_LOGIN`                | Логин прокси (опционально)           |
| `PROXY_PASS`                 | Пароль прокси (опционально)          |

Переменные `DATABASE_URL`, `REDIS_URL`, `QDRANT_URL` заданы в Deployment статически (через container_name).

## 2. Развёртывание

### 2.1 Базы данных

```bash
kubectl apply -f k8s/01-postgres.yaml
kubectl apply -f k8s/02-redis.yaml
kubectl apply -f k8s/03-qdrant.yaml
```

Дождаться запуска:

```bash
kubectl wait --for=condition=ready pod -l app=postgres -n support-bot --timeout=120s
kubectl wait --for=condition=ready pod -l app=redis -n support-bot --timeout=60s
kubectl wait --for=condition=ready pod -l app=qdrant -n support-bot --timeout=60s
```

### 2.2 Backend

```bash
kubectl apply -f k8s/04-backend.yaml
kubectl rollout status deployment/backend -n support-bot
```

Проверка:

```bash
kubectl exec deploy/backend -n support-bot -- curl -s http://localhost:8000/api/health
# {"status":"ok"}
```

### 2.3 Frontend

```bash
kubectl apply -f k8s/05-frontend.yaml
kubectl rollout status deployment/frontend -n support-bot
```

### 2.4 Ingress

```bash
kubectl apply -f k8s/06-ingress.yaml
```

IngressRoute слушает порт 80 (entrypoint `web`), хост задаётся в манифесте.

## 3. Проверка

```bash
curl http://<node-ip>/api/health
# {"status":"ok"}

curl http://<node-ip>/
# HTML страница
```

## 4. Обновление backend

После изменения кода или `.env`:

```bash
# 1. Собрать образ
docker build -t <registry>/backend:latest ./backend
docker push <registry>/backend:latest

# 2. Обновить секрет (если менялся .env)
kubectl delete secret app-env -n support-bot
kubectl create secret generic app-env --from-env-file=.env -n support-bot

# 3. Перекатить под
kubectl rollout restart deployment/backend -n support-bot
kubectl rollout status deployment/backend -n support-bot
```

## 5. Persistent Volumes

| Компонент | Размер | Путь на ноде                |
|-----------|--------|-----------------------------|
| postgres  | 10Gi   | `/mnt/data/postgres`        |
| redis     | 5Gi    | `/mnt/data/redis`           |
| qdrant    | 20Gi   | `/mnt/data/qdrant`          |

PV привязаны к ноде через `nodeAffinity`. При смене воркера — заменить значение `hostnames` в манифестах.

## 6. Удаление

```bash
# Удалить всё, кроме PV
kubectl delete -f k8s/06-ingress.yaml
kubectl delete -f k8s/05-frontend.yaml
kubectl delete -f k8s/04-backend.yaml
kubectl delete -f k8s/03-qdrant.yaml
kubectl delete -f k8s/02-redis.yaml
kubectl delete -f k8s/01-postgres.yaml

# Секреты
kubectl delete secret app-env regcred -n support-bot

# Namespace (удалит всё, включая PV/PVC)
kubectl delete namespace support-bot
```
