Перейти к содержанию

Инструкция дежурного

Инструкция написана для человека, которого разбудили. Никакого вступления: что проверить, чем это лечится, чего не делать.

Первые три команды в любом случае:

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl -n metroskop get pods
kubectl -n metroskop get rollout metroskop

Дашборды: цели по качеству, сеть и обращения.


Бюджет ошибок прожигается

Оповещение: MetroskopErrorBudgetBurningFast

Сервис отвечает ошибками сервера в десятки раз чаще допустимого. Посетители это уже видят.

  1. Посмотреть, все ли поды затронуты:
kubectl -n metroskop get pods -o wide

Если ошибки только на одном поде — почти наверняка идёт канареечный релиз, и виновата новая версия. Проверить:

kubectl -n metroskop get rollout metroskop -o jsonpath='{.status.phase} {.status.message}{"\n"}'

Контроллер должен отклонить её сам. Если он ещё в паузе, а ошибки очевидны:

kubectl argo rollouts abort metroskop -n metroskop
  1. Найти сами ошибки в логах — по метке уровня, а не поиском по тексту:
{namespace="metroskop", level="ERROR"} | json
  1. Взять traceId из любой записи и открыть трейс в Tempo: он покажет, на каком шаге запрос разваливается — в базе, в расчёте, в сериализации.

  2. Частая причина — недоступная база. Проверить:

kubectl -n metroskop get pod postgres-0
kubectl -n metroskop logs postgres-0 --tail=50

Чего не делать. Не перезапускать поды до того, как в логах найдена причина. Перезапуск уберёт симптом и вместе с ним — единственные улики.


Поезда двигаются рывками

Оповещение: MetroskopTickLagHigh

Такт рассылки опаздывает: кадры уходят не раз в секунду, а как получится.

  1. Посмотреть на график «Куча и сборка мусора». Если доля времени в сборке мусора выше 15 %, причина в паузах сборщика.
  2. Проверить, не включён ли сценарий отказа:
curl -s https://api.metroskop.petproj.ru/api/status | python3 -m json.tool

Поле chaos.memoryLeak со значением true объясняет всё. Сценарий выключится сам, но можно и сразу:

curl -X POST https://api.metroskop.petproj.ru/api/chaos/reset
  1. Если сценарии выключены, а куча полна — это настоящая утечка. Снять картину кучи до перезапуска, иначе разбираться будет нечем:
kubectl -n metroskop exec deploy/metroskop -- jcmd 1 GC.heap_info
  1. Если узлу не хватает памяти целиком (MetroskopNodeMemoryLow), проверить подкачку: free -m. Занятая подкачка при нехватке памяти означает, что поды вытесняются на диск, и медленно становится всему.

Карта замерла

Оповещение: MetroskopStreamStalled

Сервис отвечает на запросы, но кадры не рассылаются. Для посетителя схема выглядит застывшей.

  1. Проверить, живы ли подписки:
curl -s https://api.metroskop.petproj.ru/actuator/prometheus | grep metroskop_stream_subscribers
  1. Посмотреть последние записи планировщика:
{namespace="metroskop"} |= "tick"
  1. Если планировщик не выполняет такт, а поток исполнения занят — это блокировка в расчёте. Снять срез потоков:
kubectl -n metroskop exec deploy/metroskop -- jcmd 1 Thread.print > /tmp/threads.txt
  1. Перезапуск помогает, но без среза потоков причина будет утеряна:
kubectl -n metroskop rollout restart rollout/metroskop

Под не запускается

Признак: CrashLoopBackOff или Error в списке подов.

Порядок ровно такой, и он выстрадан — см. разбор инцидента:

  1. Прочитать журнал упавшего контейнера до любых гипотез:
kubectl -n metroskop logs <под> --previous --tail=80
  1. Посмотреть причину завершения. OOMKilled — превышен лимит памяти, Error с кодом — приложение не смогло стартовать:
kubectl -n metroskop describe pod <под> | grep -A5 "Last State"
  1. Если ошибка про отсутствующий класс, файл или каталог — смотреть содержимое образа, а не пересобирать его наугад:
buildah run localhost/metroskop/app:<тег> -- ls -l /app
  1. Если приложение не может подключиться к базе — проверить секрет и доступность службы:
kubectl -n metroskop get secret postgres-credentials -o jsonpath='{.data}' | head -c 80
kubectl -n metroskop exec deploy/web -- nc -z postgres 5432 && echo доступна

Чего не делать. Не пересобирать образ, пока не прочитан журнал. Ошибка почти всегда сказана прямым текстом.


Обращения уходят в просрочку

Оповещение: MetroskopIncidentsOverdue

Очередь обращений разбирается медленнее, чем растёт. На дашборде это видно как расхождение двух линий: поступление и закрытие.

  1. Проверить, справляется ли база:
kubectl -n metroskop logs postgres-0 --tail=100 | grep -i "slow\|error"
  1. Проверить пул соединений: если он исчерпан, обработка встала не из-за базы, а из-за незакрытых соединений. Метрика — hikaricp_connections_pending.
  2. На стенде поток обращений синтетический, и всплеск может быть просто всплеском. В настоящем сервисе на этом месте был бы разговор о людях, разбирающих очередь, а не о технике.

Сертификат не обновился

Оповещение: MetroskopCertificateExpiringSoon

kubectl get certificate -A
kubectl -n metroskop describe certificate metroskop-tls | tail -30
kubectl -n cert-manager logs deploy/cert-manager --tail=100

Типовые причины: закрытый снаружи 80-й порт (проверка HTTP-01 требует именно его), исчерпанный предел запросов Let's Encrypt, изменившаяся запись DNS. Проверить доступность проверки:

curl -sI http://metroskop.petproj.ru/.well-known/acme-challenge/test

Пока старый сертификат жив, срочности нет: у автоматики есть тридцать дней запаса. Но исправлять надо до того, как они кончатся.


Узлу не хватает памяти

Оповещение: MetroskopNodeMemoryLow, MetroskopSwapHeavilyUsed

free -m
kubectl top pods -A --sort-by=memory | head -15

Порядок действий по возрастанию неприятности:

  1. Выключить сценарии отказов, если включены.
  2. Сократить хранение метрик в Prometheus (в переменных Terraform) — обычно это самый крупный потребитель.
  3. Снять генератор нагрузки: он нужен для показа, а не для работы сервиса.
kubectl -n metroskop scale deploy/loadgen --replicas=0
  1. Не увеличивать число реплик приложения. На узле с 4 ГБ это ухудшит положение, а не улучшит.

Полное восстановление стенда

Если узел потерян целиком, порядок такой:

# 1. Узел: подкачка, параметры ядра, файрвол, k3s
ansible-playbook -i ansible/inventory.ini ansible/site.yml

# 2. Платформа: cert-manager, наблюдаемость, Argo Rollouts
cd terraform && terraform init && terraform apply

# 3. Приложение, база, публикация, правила, дашборды
cd .. && scripts/deploy.sh

Обращения жителей при этом теряются: они синтетические и наберутся заново за минуту. Всё остальное состояние описано кодом.