# Развёртывание audio-pipeline в k3s Пошаговая инструкция для однонодового k3s. Все сервисы из `docker-compose.yml` переносятся в namespace `audio-pipeline`. ## Архитектура в кластере ``` namespace: audio-pipeline ├── rabbit (Service :5672, :15672) ├── postgres (Service :5432, PVC local-path) ├── PVC audio-storage → hostPath /var/lib/audio-pipeline/storage ├── watcher ├── transcribe (+ ConfigMap prompts.json) ├── tagging └── analyse ``` DNS внутри кластера: `rabbit`, `postgres` — те же хосты, что в `.env` для Docker Compose. ## Требования - Linux-сервер с k3s - `kubectl` (обычно `/usr/local/bin/kubectl` или `k3s kubectl`) - Docker (для сборки образов) или свой container registry ## 1. Установка k3s ```bash curl -sfL https://get.k3s.io | sh - sudo k3s kubectl get nodes ``` Для доступа без `sudo`: ```bash mkdir -p ~/.kube sudo k3s kubectl config view --raw > ~/.kube/config chmod 600 ~/.kube/config ``` ## 2. Подготовка секретов ```bash cd audio-pipeline # из корневого .env ./k8s/prepare-secret.sh # или вручную cp k8s/secret.env.example k8s/secret.env # отредактируйте ключи Nexara / Yandex ``` Файл `k8s/secret.env` в git не коммитится. Проверьте URL в секрете: ```env RABBITMQ_URL=amqp://admin:secret123@rabbit:5672/ DATABASE_URL=postgres://pipeline:pipeline_secret@postgres:5432/pipeline?sslmode=disable ``` ## 3. Сборка и загрузка образов ### Вариант A — локальный k3s (без registry) ```bash chmod +x k8s/build-images.sh ./k8s/build-images.sh ``` Скрипт собирает 4 образа и импортирует их в containerd k3s. ### Вариант B — через registry ```bash REGISTRY=registry.example.com/audio-pipeline TAG=v1 docker build -t $REGISTRY/watcher:$TAG ./watcher docker build -t $REGISTRY/transcribe:$TAG ./workers/transcribe docker build -t $REGISTRY/tagging:$TAG ./workers/tagging docker build -t $REGISTRY/analyse:$TAG ./workers/analyse docker push $REGISTRY/watcher:$TAG # ... остальные # в k8s/watcher.yaml и др. замените image: на $REGISTRY/... ``` ## 4. Хранилище аудио По умолчанию используется **hostPath** на ноде: ``` /var/lib/audio-pipeline/storage/ ├── incoming/ ├── processing/ └── failed/ ``` Создайте каталоги на ноде k3s: ```bash sudo mkdir -p /var/lib/audio-pipeline/storage/{incoming,processing,failed} sudo chmod -R 777 /var/lib/audio-pipeline/storage # или нужный uid подов ``` > **Важно:** `ReadWriteMany` + hostPath работает, пока все поды на **одной** ноде. Для multi-node кластера подключите NFS или Longhorn с RWX. ## 5. Деплой ```bash kubectl apply -k k8s/ ``` Проверка: ```bash kubectl -n audio-pipeline get pods kubectl -n audio-pipeline get pvc kubectl -n audio-pipeline logs -f deploy/watcher ``` Ожидаемый порядок старта: `rabbit` + `postgres` → воркеры (сами ждут RabbitMQ/Postgres при старте). ## 6. Загрузка тестового файла На ноде k3s: ```bash sudo cp recording.wav /var/lib/audio-pipeline/storage/incoming/ ``` Или с машины разработчика (замените `NODE` на IP сервера): ```bash scp recording.wav user@NODE:/tmp/ ssh user@NODE 'sudo cp /tmp/recording.wav /var/lib/audio-pipeline/storage/incoming/' ``` ## 7. Мониторинг ```bash # логи воркеров kubectl -n audio-pipeline logs -f deploy/transcribe kubectl -n audio-pipeline logs -f deploy/analyse kubectl -n audio-pipeline logs -f deploy/tagging # RabbitMQ Management UI (port-forward) kubectl -n audio-pipeline port-forward svc/rabbit 15672:15672 # http://localhost:15672 (логин из secret.env) # Postgres kubectl -n audio-pipeline exec -it deploy/postgres -- \ psql -U pipeline -d pipeline -c "SELECT task_id, status, updated_at FROM results ORDER BY updated_at DESC LIMIT 5;" ``` ## 8. Обновление После изменения кода: ```bash ./k8s/build-images.sh kubectl -n audio-pipeline rollout restart deploy/watcher deploy/transcribe deploy/tagging deploy/analyse ``` После смены `YANDEX_API_KEY` / `NEXARA_API_KEY`: ```bash ./k8s/prepare-secret.sh kubectl apply -k k8s/ kubectl -n audio-pipeline rollout restart deploy/tagging deploy/analyse ``` После смены `prompts.json`: ```bash kubectl apply -k k8s/ kubectl -n audio-pipeline rollout restart deploy/transcribe ``` ## 9. Удаление ```bash kubectl delete -k k8s/ # данные postgres (PVC) и hostPath останутся — удалите вручную при необходимости ``` ## Отличия от Docker Compose | Compose | k3s | |---------|-----| | `env_file: .env` | ConfigMap + Secret | | volume `./storage` | PVC `audio-storage` (hostPath) | | `DOTENV_PATH` mount для hot-reload | переменные из Secret; после смены — `rollout restart` | | `docker compose up --build` | `build-images.sh` + `kubectl apply -k` | | порты 5672/5432 на хосте | только внутри кластера; снаружи — `port-forward` или Ingress | ## Опционально: NodePort для RabbitMQ UI Добавьте в `k8s/rabbitmq.yaml` в Service: ```yaml type: NodePort # ports: # - name: management # port: 15672 # nodePort: 31672 ``` ## Troubleshooting | Симптом | Решение | |---------|---------| | `ImagePullBackOff` | Запустите `./k8s/build-images.sh` или укажите registry | | PVC `audio-storage` Pending | Создайте PV hostPath (`storage.yaml`) и каталог на ноде | | watcher не видит файлы | Проверьте mount `/data/storage` и права на hostPath | | tagging/analyse `YANDEX_API_KEY is required` | Проверьте `secret.env` и `kubectl apply -k k8s/` | | postgres CrashLoop | Удалите PVC и передеплойте (init.sql только при первом старте) |