- doc/progress.md: обновлена версия до operator v0.1.18 / provider v0.1.11, добавлен блок source_dir + fix destroy cleanup (2026-03-09), уточнены комментарии к контроллерам и trigger_resource - doc/errors/log.md: добавлены две записи — source_dir/hashicorp/archive, destroy route cleanup bug (три причины + решения) - .gitignore: добавлены examples/*/dist/ и terraform.tfstate.*.backup - examples/: удалены dist/ zip и tfstate.*.backup из трекинга
143 lines
7.9 KiB
Markdown
143 lines
7.9 KiB
Markdown
# Bug Report: HTTP route is not removed after Terraform destroy
|
||
|
||
## Summary
|
||
|
||
При удалении примера `hello-node` через Terraform команда `terraform destroy` завершается успешно, но публичный HTTP endpoint не удаляется.
|
||
|
||
Фактическое поведение после `destroy` такое:
|
||
|
||
1. Сразу после удаления endpoint ещё некоторое время отвечает `HTTP 200` и возвращает корректный ответ функции.
|
||
2. Затем backend функции действительно исчезает, но публичный маршрут остаётся опубликованным и начинает отвечать `HTTP 502 function unreachable`.
|
||
3. Даже через 120 секунд endpoint не исчезает.
|
||
|
||
Это выглядит как баг cleanup в platform/backend/provider lifecycle для HTTP trigger/route.
|
||
|
||
## Affected Example
|
||
|
||
- Example: `hello-node`
|
||
- Terraform files: `hello-node/main.tf`, `hello-node/http.tf`, `hello-node/job.tf`
|
||
- Public URL: `https://sless-api.kube5s.ru/fn/default/hello-http`
|
||
- Function name: `hello-http`
|
||
- Trigger name: `hello-http-trigger`
|
||
|
||
## Reproduction
|
||
|
||
Использовался репозиторий examples и скрипт:
|
||
|
||
- Script: `./run_terraform_examples.sh`
|
||
|
||
Шаги воспроизведения:
|
||
|
||
1. Выполнить `terraform init` в `hello-node`
|
||
2. Выполнить `terraform apply`
|
||
3. Убедиться, что endpoint живой
|
||
4. Выполнить `terraform destroy`
|
||
5. Проверять публичный URL после destroy
|
||
|
||
Логика проверки встроена в `run_terraform_examples.sh`:
|
||
|
||
1. После `apply` endpoint обязан отвечать `200`
|
||
2. После `destroy` endpoint должен исчезнуть
|
||
3. Скрипт ждёт до 120 секунд и перепроверяет endpoint каждые 5 секунд
|
||
|
||
## Expected Result
|
||
|
||
После успешного `terraform destroy`:
|
||
|
||
1. Публичный URL должен перестать существовать
|
||
2. Запрос на URL должен вернуть `404` или другой явный признак отсутствия маршрута
|
||
3. Provider не должен возвращать успешный destroy раньше, чем cleanup HTTP route завершён
|
||
|
||
## Actual Result
|
||
|
||
После успешного `terraform destroy`:
|
||
|
||
1. Terraform сообщает `Destroy complete! Resources: 4 destroyed.`
|
||
2. Endpoint `https://sless-api.kube5s.ru/fn/default/hello-http` продолжает отвечать `200`
|
||
3. Через некоторое время тот же endpoint начинает отвечать `502`
|
||
4. Тело ответа на `502`:
|
||
|
||
```json
|
||
{"error":"function unreachable: Post \"http://hello-http.sless-fn-default.svc.cluster.local:8080\": dial tcp 10.106.128.167:8080: connect: operation not permitted"}
|
||
```
|
||
|
||
Это означает:
|
||
|
||
1. внешний HTTP маршрут всё ещё существует;
|
||
2. запрос по нему всё ещё направляется внутрь платформы;
|
||
3. backend функции уже удалён или недоступен;
|
||
4. cleanup маршрута не завершён.
|
||
|
||
## Timeline From Real Run
|
||
|
||
Подтверждённая последовательность из фактического прогона:
|
||
|
||
1. `terraform destroy` завершился успешно
|
||
2. первые проверки после destroy возвращали `HTTP 200`
|
||
3. затем проверки начали возвращать `HTTP 502 function unreachable`
|
||
4. в течение всех 24 проверок по 5 секунд endpoint не исчез
|
||
5. итоговое время ожидания: 120 секунд
|
||
|
||
Итоговый summary из скрипта:
|
||
|
||
```text
|
||
ERROR SUMMARY
|
||
example: hello-node
|
||
step: endpoint cleanup after clean destroy
|
||
reason: route cleanup bug: public endpoint still exists but backend is already gone (HTTP 502 function unreachable); endpoint was still published after 120s
|
||
```
|
||
|
||
## Why This Is A Real Platform Bug
|
||
|
||
Это не похоже на проблему тестового скрипта или Terraform CLI по следующим причинам:
|
||
|
||
1. `terraform destroy` завершается без ошибки
|
||
2. state Terraform очищается как ожидалось
|
||
3. сначала endpoint отвечает `200`, значит маршрут реально жив после destroy
|
||
4. потом endpoint отвечает `502 function unreachable`, значит backend уже исчез, но route ещё остался
|
||
5. скрипт ждёт 120 секунд, то есть это не мгновенная eventual consistency на 1-2 секунды
|
||
|
||
Иными словами: удаление backend и удаление публичного маршрута расходятся по времени, а route cleanup либо не выполняется, либо не дожидается завершения.
|
||
|
||
## Most Likely Broken Layer
|
||
|
||
Наиболее вероятные точки проблемы:
|
||
|
||
1. API/backend destroy trigger возвращает success до фактического удаления HTTP route
|
||
2. Controller удаляет function workload, но не удаляет route/ingress/virtualservice/gateway mapping
|
||
3. Удаление route запускается асинхронно, но его результат не awaited
|
||
4. В системе остаётся запись маршрута на имя функции, хотя service/backend уже удалён
|
||
|
||
## What To Check In The Development Repo
|
||
|
||
Нужно проверить destroy flow именно для HTTP trigger:
|
||
|
||
1. Удаляется ли объект trigger только в metadata/storage или реально удаляется и внешний маршрут
|
||
2. Какие Kubernetes/ingress объекты создаются для HTTP trigger и все ли они удаляются
|
||
3. Есть ли race condition между удалением function/service и удалением route
|
||
4. Не возвращает ли provider success раньше, чем backend подтверждает полное удаление маршрута
|
||
5. Есть ли финальный polling/wait на исчезновение route перед возвратом успешного destroy
|
||
|
||
Если архитектура использует отдельные сущности route/service/function, то destroy должен идти в таком порядке:
|
||
|
||
1. disable/remove public routing
|
||
2. дождаться, что endpoint больше не публикуется снаружи
|
||
3. удалить backend/service/workload
|
||
4. завершить destroy success
|
||
|
||
Сейчас по фактическому поведению порядок либо обратный, либо неполный.
|
||
|
||
## Minimal Acceptance Criteria For Fix
|
||
|
||
Исправление можно считать рабочим, если после `terraform destroy` для `hello-node` выполняются все условия:
|
||
|
||
1. URL `https://sless-api.kube5s.ru/fn/default/hello-http` перестаёт отвечать как живой маршрут
|
||
2. URL не возвращает `502 function unreachable`
|
||
3. URL исчезает в разумное время после destroy
|
||
4. `./run_terraform_examples.sh` проходит шаг `endpoint cleanup after clean destroy`
|
||
|
||
## Current Status
|
||
|
||
На данный момент массовый прогон examples корректно останавливается на `hello-node`, потому что это первый воспроизводимый failure.
|
||
|
||
Дальше прогонять остальные примеры без исправления destroy cleanup смысла нет: тест уже доказал platform bug на базовом HTTP сценарии. |