182 lines
5.8 KiB
Markdown
182 lines
5.8 KiB
Markdown
# Развёртывание в 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
|
||
```
|