# SQS Operator — План для Sonnet (этап: сборка → деплой → тест) # Дата: 2026-04-07 # Подготовил: Claude Opus 4.6 # Исполнитель: Claude Sonnet --- ## Контекст SQS Operator переделан через Operator SDK v1.37.0. Код компилируется (`make build` OK). Нужно: docker build → push в registry → deploy в кластер → создать тестовый QueueService → убедиться что ElasticMQ pod поднялся. **Ветка**: `sqs-operator` **Последний коммит**: `66dcd99` — refactor через Operator SDK --- ## КРИТИЧЕСКИЕ ПРАВИЛА (прочитай ПОЛНОСТЬЮ перед работой) 1. **ВСЕ команды — ТОЛЬКО через SSH на VM**: ``` ssh -i /home/naeel/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 КОМАНДА ``` 2. **Файлы редактировать можно через VS Code** — папка `/home/naeel/remote_dev/sless` = mount VM `~/terra/sless/` 3. **НЕ запускать НИЧЕГО локально** — только SSH 4. **Всегда указывать timeout** в run_in_terminal 5. **Не делать без явной команды пользователя** — спрашивать, если непонятно 6. **kubeconfig протух** — перед kubectl нужно обновить. СПРОСИ ПОЛЬЗОВАТЕЛЯ как. 7. **Документировать каждый шаг** в doc/thinking/ и doc/progress.md --- ## Этап 1: Исправить Dockerfile **Проблема**: Scaffold Dockerfile копирует только `internal/controller/`, но наш код также в: - `internal/config/` — загрузка env конфига - `internal/elasticmq/` — HOCON генератор + credentials **Файл**: `sqs-operator/Dockerfile` **Что менять**: добавить строки COPY для недостающих пакетов. После строки: ``` COPY internal/controller/ internal/controller/ ``` Добавить: ``` COPY internal/config/ internal/config/ COPY internal/elasticmq/ internal/elasticmq/ ``` **Проверка**: `make docker-build IMG=pearlharbor.registryk8s.services.ngcloud.ru/naeel/sqs-operator:v0.1.0` --- ## Этап 2: Docker build + push ```bash cd ~/terra/sless/sqs-operator make docker-build IMG=pearlharbor.registryk8s.services.ngcloud.ru/naeel/sqs-operator:v0.1.0 make docker-push IMG=pearlharbor.registryk8s.services.ngcloud.ru/naeel/sqs-operator:v0.1.0 ``` Docker registry: `pearlharbor.registryk8s.services.ngcloud.ru` (уже залогинен - `docker login` возвращает OK). --- ## Этап 3: Обновить kubeconfig **Сейчас kubectl не работает** — `the server has asked for the client to provide credentials`. **СПРОСИ ПОЛЬЗОВАТЕЛЯ** как обновить kubeconfig. Не пытайся обойти самостоятельно. --- ## Этап 4: Установить CRD в кластер ```bash cd ~/terra/sless/sqs-operator make install ``` Это применит `config/crd/bases/sqs.kube5s.ru_queueservices.yaml` в кластер. **Проверка**: ```bash kubectl get crd queueservices.sqs.kube5s.ru ``` --- ## Этап 5: Deploy оператора ### 5a. Подготовить manager.yaml Kustomize namespace: `sqs-operator-system` (из `config/default/kustomization.yaml`). **Нужно проверить/настроить**: 1. IMAGE: заменить `controller:latest` на реальный registry image 2. ENV: добавить `SQS_EXTERNAL_HOST=sqs.kube5s.ru` в Deployment container env 3. ImagePullSecrets: если registry приватный, может понадобиться secret Команда деплоя через kustomize: ```bash cd ~/terra/sless/sqs-operator make deploy IMG=pearlharbor.registryk8s.services.ngcloud.ru/naeel/sqs-operator:v0.1.0 ``` ### 5b. Добавить env SQS_EXTERNAL_HOST **ВАЖНО**: manager.yaml не содержит env SQS_EXTERNAL_HOST. Оператор крашнется без него. Варианты: - **Вариант A** (рекомендуемый): Создать kustomize patch файл `config/manager/env_patch.yaml` - **Вариант B**: Отредактировать `config/manager/manager.yaml` напрямую — добавить env Добавить в containers[0].env: ```yaml env: - name: SQS_EXTERNAL_HOST value: "sqs.kube5s.ru" ``` ### 5c. ImagePullSecrets Registry `pearlharbor.registryk8s.services.ngcloud.ru` — приватный. В namespace `sqs-operator-system` нужен secret: ```bash kubectl create secret docker-registry pearlharbor-registry \ --namespace=sqs-operator-system \ --docker-server=pearlharbor.registryk8s.services.ngcloud.ru \ --docker-username=admin \ --docker-password= ``` Пароль для registry — проверь в `secrets/pearlharbor_registry.txt`. И добавить `imagePullSecrets` в manager.yaml. **Проверка**: ```bash kubectl -n sqs-operator-system get pods kubectl -n sqs-operator-system logs deployment/sqs-operator-controller-manager -c manager ``` Ожидаемый лог: `operator config loaded`, `starting manager`. --- ## Этап 6: Тестирование — создать QueueService ### 6a. Обновить sample CR Файл `config/samples/sqs_v1alpha1_queueservice.yaml` — сейчас пустой (scaffold). Заполнить: ```yaml apiVersion: sqs.kube5s.ru/v1alpha1 kind: QueueService metadata: name: test-tenant-001 namespace: sqs-operator-system spec: tenantId: "test001" memoryMB: 64 storageMB: 512 persistence: true ``` ### 6b. Применить ```bash kubectl apply -f config/samples/sqs_v1alpha1_queueservice.yaml ``` ### 6c. Наблюдение ```bash # CR статус kubectl get queueservices -A # Логи оператора kubectl -n sqs-operator-system logs deployment/sqs-operator-controller-manager -c manager -f # Ресурсы тенанта (должны появиться в sless-fn-test001) kubectl -n sless-fn-test001 get all,pvc,secret,ingress # ElasticMQ pod kubectl -n sless-fn-test001 get pods -w ``` **Ожидаемый результат**: - QueueService Phase: Pending → Provisioning → Ready - В `sless-fn-test001`: - Deployment `sqs-test001` — 1 pod Running - Service `sqs-svc-test001` — ClusterIP:9324 - Ingress `sqs-ing-test001` — sqs.kube5s.ru/sqs/test001 - Secret `sqs-creds-test001` — accessKey/secretKey - PVC `sqs-data-test001` - ConfigMap `sqs-cfg-test001` --- ## Этап 7: Smoke test SQS API ```bash # Получить credentials ACCESS_KEY=$(kubectl -n sless-fn-test001 get secret sqs-creds-test001 -o jsonpath={.data.accessKey} | base64 -d) SECRET_KEY=$(kubectl -n sless-fn-test001 get secret sqs-creds-test001 -o jsonpath={.data.secretKey} | base64 -d) # Создать очередь через curl (SQS API) curl -k "https://sqs.kube5s.ru/sqs/test001/?Action=CreateQueue&QueueName=my-test-queue&Version=2012-11-05" \ --user "$ACCESS_KEY:$SECRET_KEY" # Отправить сообщение curl -k "https://sqs.kube5s.ru/sqs/test001/?Action=SendMessage&MessageBody=hello-world&Version=2012-11-05" \ --user "$ACCESS_KEY:$SECRET_KEY" # Прочитать сообщение curl -k "https://sqs.kube5s.ru/sqs/test001/?Action=ReceiveMessage&Version=2012-11-05" \ --user "$ACCESS_KEY:$SECRET_KEY" ``` --- ## Этап 8: Коммит + пуш ```bash git add -A && git commit -m "feat(sqs-operator): docker build, deploy, tested QueueService" git push ``` --- ## Справочная информация ### Ключевые файлы | Файл | Назначение | |------|-----------| | `api/v1alpha1/queueservice_types.go` | CRD Spec/Status с kubebuilder маркерами | | `internal/controller/queueservice_controller.go` | Reconciler: provision, checkReady, handleDeletion | | `internal/elasticmq/elasticmq_config.go` | HOCON конфиг ElasticMQ для тенанта | | `internal/elasticmq/elasticmq_credentials.go` | Генератор accessKey/secretKey | | `internal/config/sqs_operator_config.go` | Env конфиг: SQS_EXTERNAL_HOST, SQS_ELASTICMQ_IMAGE | | `cmd/main.go` | Entry point (scaffold + config loading) | | `config/crd/bases/sqs.kube5s.ru_queueservices.yaml` | Автосгенерированный CRD YAML | | `config/rbac/role.yaml` | Автосгенерированный RBAC ClusterRole | | `Makefile` | Operator SDK toolchain: manifests, generate, build, docker-build, deploy | | `Dockerfile` | Multi-stage build (НУЖНО ИСПРАВИТЬ — см. этап 1) | ### Reconciler фазы ``` Pending → provision() → Provisioning → checkReady() → Ready ↑ Failed ← ensureHealthy() (pod down) recoverFromFailed() ←→ Ready ``` ### Env переменные оператора | Переменная | Обязательная | Default | Описание | |-----------|-------------|---------|----------| | SQS_EXTERNAL_HOST | ДА | — | Публичный хост: sqs.kube5s.ru | | SQS_ELASTICMQ_IMAGE | нет | softwaremill/elasticmq-native:1.7.1 | Docker образ ElasticMQ | | OPERATOR_NAMESPACE | нет | sless | Namespace оператора | ### SSH ``` ssh -i /home/naeel/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 ``` ### Docker registry ``` pearlharbor.registryk8s.services.ngcloud.ru/naeel/sqs-operator:v0.1.0 ``` Логин: admin, пароль в `secrets/pearlharbor_registry.txt` ### Toolchain версии - Go: 1.26.1 - operator-sdk: v1.37.0 - controller-gen: v0.17.0 - controller-runtime: v0.17.3 - Docker: 28.2.2