Расскажите пример сложного инцидента в Kubernetes и как вы его решили.
Один из типичных сложных инцидентов (реалистичный сценарий), который часто вызывает серьёзные сбои в кластере — перегрузка etcd из-за «взрыва» количества объектов (ConfigMap/Secret/CR) в результате багнутого CI/оператора. Ниже — хронология, как это диагностируют и устраняют, точные команды и пост-инцидентные меры.
Симптомы и обнаружение
-
Вечером начали приходить алерты: etcd DiskUsage близок к 100%, apiserver latency (request duration p95/p99) резко выросла, контроллеры (Deployment/ReplicaSet) не успевали reconcile, kubectl часто возвращал 504/etcdserver: request timed out.
-
Приложения начали сообщать о таймаутах, новые Pod’ы оставались в Pending, rollout’ы зависали.
Быстрая проверка (команды для triage)
kubectl get --raw='/metrics' | grep apiserver_request_latencies_summary
etcdctl --endpoints=$ETCD_ENDPOINTS endpoint status --write-out=table
kubectl get events --all-namespaces --sort-by=.lastTimestamp | tail -n 50
kubectl get configmap -A --no-headers | wc -l
kubectl top nodes
journalctl -u kube-apiserver -n 200
Мы увидели: резкий рост числа ConfigMap в namespace ci (тысячи новых объектов за минуту), высокая частота операций create в apiserver и большая задержка ответов etcd.
Триаж и ограниченная «тушилка»
-
Остановить источник шторма. Немедленно приостановили CI-pipeline/робота, который генерировал ConfigMap (в админке CI выключили job). Это снижает входящую нагрузку.
-
Ограниченное удаление мусора: нельзя удалять тысячи объектов одномоментно (ещё больше нагружает API). Удаляли порциями:
kubectl get cm -n ci -l ci-build=true -o name | split -l 200 - cm_batch_
for f in cm_batch_\*; do kubectl delete -f $f & sleep 2; done
- Снижение нагрузки на etcd: уменьшили apiserver concurrency (если есть возможность) или временно ограничили внешние интеграции, чтобы дать etcd «остыть».
Восстановление состояния etcd (если compaction/defrag требуется)
- Проверили метрики compaction/DB size:
etcdctl --endpoints=$ETCD_ENDPOINTS endpoint status --write-out=table
etcdctl --endpoints=$ETCD_ENDPOINTS snapshot status /backups/snap.db
- Запустили ручную компактацию по последнему ревизионному номеру (вне пикового времени, после уменьшения записей):
REV=$(etcdctl --endpoints=$ETCD_ENDPOINTS endpoint status --write-out=json | jq '.\[0\].Status.header.revision')
etcdctl --endpoints=$ETCD_ENDPOINTS compact $REV
etcdctl --endpoints=$ETCD_ENDPOINTS defrag
Компактация + дефрагментация освободили место и снизили IO.
Коррекция control-plane и нагрузки
-
Увеличили временно IOPS/диск для etcd (в cloud) и масштабировали Prometheus scrape interval (если он делал heavy write/label cardinality).
-
Включили авто-throttling у CI (rate limits), чтобы избежать повторного шторма.
Root cause
- Выяснилось, что CI job создавал per-build ConfigMap (уникальные имена) и не удалял их при завершении из-за бага в скрипте. Через сутки накопилось огромное количество мелких объектов, что привело к экспоненциальному росту размера etcd и к нагрузке на диск/IOPS.
Пост-инцидентные меры (конкретные изменения)
- ResourceQuota в namespace CI, чтобы ограничить число ConfigMap:
apiVersion: v1
kind: ResourceQuota
metadata: { name: cm-quota, namespace: ci }
spec:
hard:
count/configmaps: "100"
-
CI fix: переписать job — переиспользовать один ConfigMap или обеспечивать корректный cleanup, добавить retry/backoff и проверку успешного удаления.
-
Alerting: добавить алерты на рост etcd DB size, rate of object creations (apiserver_admission_*), и на резкий рост count of objects per namespace.
-
Admission guard: выставили OPA/Gatekeeper правило, запрещающее создание ConfigMap с определёнными шаблонами имен или/и ограничивающее creation rate: временный fail-open в тестовой среде, затем enforce.
-
Etcd ops: настроили автоматическую компактацию и дефрагментирование по расписанию, мониторинг IOPS/latency, резервные снапшоты.
-
Throttling apiserver: при повторении проблемы можно скорректировать --max-requests-inflight и --max-mutating-requests-inflight у kube-apiserver, чтобы нагрузка не вывела его из строя.
Что проверяли после исправлений
- Наблюдали за p99 latency apiserver, скоростью создания/удаления объектов, размером etcd, количеством ConfigMap в namespace. Тестировали прогон CI в контролируемом режиме (ограниченный rate).
Пост-мортемные артефакты (что оставили)
-
Runbook: шаги остановки источника, batch-удаление, компактация etcd, масштабирование storage.
-
Автотест для CI: проверка cleanup шагов перед merge.
-
Регулярный rehearsal restore etcd + тесты восстановления.
Этот сценарий показывает, как баг в прикладном коде (CI) может превратиться в кластерный инцидент из-за ограничений etcd; ключевые элементы успешного реагирования — быстрое отключение источника нагрузки, аккуратная порционная очистка, оптимизация etcd (compaction/defrag) и внедрение guardrails (quota, admission rules, alerting).