# Развёртывание в 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= \ --docker-username= \ --docker-password= \ -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:///api/health # {"status":"ok"} curl http:/// # HTML страница ``` ## 4. Обновление backend После изменения кода или `.env`: ```bash # 1. Собрать образ docker build -t /backend:latest ./backend docker push /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 ```