Learning Platform
Глоссарий Troubleshooting
Урок 16.02 · 22 мин
Средний
Eventskubectl describekubectl eventsFailedSchedulingBackOffschedulerkubelet

Events и kubectl describe

Event — это полноценный объект Kubernetes API (apiVersion: v1, kind: Event или новый events.k8s.io/v1), не просто запись в логе. У него есть namespace, lifecycle, RBAC. Компоненты Kubernetes — scheduler, kubelet, controllers, admission webhooks — пишут события в etcd как способ сказать клиенту: «вот что произошло с твоим ресурсом». TTL — 1 час. Если ты не успел посмотреть, событие уйдёт навсегда.


journalctl: единый журнал systemd для всех сервисов

Что такое Event

apiVersion: v1
kind: Event
metadata:
  name: my-pod.16f7e2c5a3d9
  namespace: default
type: Warning
reason: FailedScheduling
message: "0/3 nodes are available: 3 Insufficient memory."
source:
  component: default-scheduler
involvedObject:
  apiVersion: v1
  kind: Pod
  name: my-pod
  namespace: default
  uid: ...
firstTimestamp: "2026-05-13T10:00:00Z"
lastTimestamp: "2026-05-13T10:03:21Z"
count: 4

Ключевые поля:

  • type: Normal (информация) или Warning (что-то пошло не так — обычно это и интересно).
  • reason: машино-читаемый код. Типовые: Scheduled, FailedScheduling, Pulled, Failed, Created, Started, Killing, BackOff, Unhealthy, FailedMount.
  • message: человеческое описание.
  • source: кто создал событие. scheduler, kubelet на ноде X, deployment-controller, и т.д.
  • involvedObject: на какой ресурс ссылается.
  • firstTimestamp / lastTimestamp / count: повторяющиеся события схлопываются в один объект с инкрементом count, чтобы не плодить тысячи дубликатов.
Кто создаёт Events в Kubernetes
schedulerkube-scheduler. Создаёт Scheduled (Pod привязан к ноде) и FailedScheduling (нет подходящих нод — указывает причины: insufficient memory, taints, affinity).
kubeletСамый плодовитый источник. Pulled / Failed (image pull), Created / Started / Killing (lifecycle контейнера), BackOff (CrashLoopBackOff retry), Unhealthy (probe failed), FailedMount (volume не подключился).
controllerskube-controller-manager: ReplicaSet создаёт Pod-ы (SuccessfulCreate), Deployment делает rolling update, Job tracks completions. Каждый controller пишет свои события.
admission webhooksValidatingAdmissionWebhook / MutatingAdmissionWebhook могут писать события для отчёта о принятых решениях. Например, OPA Gatekeeper пишет ConstraintViolation.

TTL: 1 час и что с этим делать

В apiserver есть флаг --event-ttl=1h (default). Через час Event удаляется из etcd навсегда. Это сделано специально:

  • Events часто и пишут много — у активного кластера тысячи событий в час.
  • Хранить их вечно — раздувать etcd.
  • Это transient signal, а не audit log. Для audit-а нужен apiserver --audit-log-path или внешний сборщик.

Для долгосрочной аналитики:

  • kube-state-metrics + Prometheus — конвертирует event reasons в metrics (например, счётчик kube_pod_status_reason{reason="ContainerCreating"}).
  • Logging stack (Loki / ELK) собирает events отдельным DaemonSet (например, через eventrouter).
  • Audit log на apiserver — пишет всё, что прошло через API, включая создание событий.
WARNING

Не полагайся на Events для post-mortem спустя сутки — они уже удалены. Сразу при инциденте делай kubectl get events -n <ns> -o yaml > events.yaml и копай оттуда.


kubectl get events vs kubectl events

Старый способ:

kubectl get events
kubectl get events -n production
kubectl get events --sort-by=.lastTimestamp        # хронологически
kubectl get events --field-selector type=Warning   # только warnings
kubectl get events --field-selector involvedObject.name=my-pod

Default-сортировка kubectl get events — по metadata.name (бесполезно). Всегда добавляй --sort-by=.lastTimestamp, иначе порядок случайный.

Новая команда — kubectl events (GA с v1.27, лучше UX):

kubectl events                    # уже отсортированы хронологически
kubectl events -n production
kubectl events --for pod/my-pod   # удобный filter на involvedObject
kubectl events --watch            # follow, как logs -f
kubectl events --types=Warning
TIP

kubectl events --watch — лучший способ смотреть, что происходит во время rolling update Deployment или при отладке scheduling issue.


kubectl describe: spec + status + Events в одном

describe — это не просто YAML-дамп. Это сформированный человеком вывод, где:

  • В верхней части — основные поля spec (labels, annotations, containers, volumes).
  • В середине — status (conditions, containerStatuses).
  • В нижнейEvents: секция, отфильтрованная по involvedObject.uid ресурса.

Именно эта Events-секция делает describe основным debug-tool:

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Normal   Scheduled         3m17s  default-scheduler  Successfully assigned default/my-pod to node-1
  Normal   Pulling           3m16s  kubelet            Pulling image "myapp:v2"
  Normal   Pulled            3m10s  kubelet            Successfully pulled image
  Normal   Created           3m10s  kubelet            Created container app
  Normal   Started           3m9s   kubelet            Started container app
  Warning  Unhealthy         2m45s  kubelet            Readiness probe failed: dial tcp 10.244.0.5:8080: connect: connection refused
  Warning  BackOff           1m30s  kubelet            Back-off restarting failed container

Этот хронологический trace отвечает на 80% вопросов отладки. Видно: image pull прошёл, container запущен, потом readiness FAIL, потом restart loop.


Типовая CKAD-задача: Pod в Pending

Дано: kubectl get pod my-pod показывает Pending. Диагностика:

# 1. Что говорит Pod о себе
kubectl describe pod my-pod

# 2. Events секция в конце вывода — главное
# Возможные сценарии:

# 2a. FailedScheduling: "0/3 nodes are available: 3 Insufficient cpu"
#     → cpu requests > доступной ёмкости нод. Уменьшить requests или добавить ноды.

# 2b. FailedScheduling: "node(s) had untolerated taint {dedicated: gpu}"
#     → Pod должен иметь tolerations для taint-а.

# 2c. FailedScheduling: "node(s) didn't match Pod's node affinity"
#     → spec.affinity не находит matching ноды.

# 2d. Нет ни одного FailedScheduling, Pod просто Pending
#     → PVC bound? kubectl describe pvc <name>. Если Pending — нет PV или StorageClass.

# 3. Если Pod привязан к ноде но container не стартует:
kubectl describe pod my-pod | tail -30
# Ищем: ImagePullBackOff, ErrImagePull, CreateContainerConfigError, etc.

# 4. Если уже Running но restart loop:
kubectl logs my-pod --previous
kubectl describe pod my-pod | grep -A 10 'Last State'
WARNING

Pending без событий через 30+ секунд — обычно проблема с PVC: storage не выделился. kubectl describe pvc <name> покажет, ждёт ли он provisioner-а или StorageClass отсутствует.


Field selectors на events

Events не поддерживают label selectors (на них нет labels), но field selectors — да:

# Все events для конкретного Pod-а
kubectl get events --field-selector involvedObject.name=my-pod

# Все Warning-events в namespace
kubectl get events --field-selector type=Warning -n production

# Events от kubelet конкретной ноды
kubectl get events --field-selector source.component=kubelet,source.host=node-1

Killer-моменты

  • Events живут 1 час. Никаких post-mortem спустя сутки.
  • --sort-by=.lastTimestamp обязателен в kubectl get events, иначе порядок случайный. У kubectl events сортировка по умолчанию.
  • kubectl describe Events section — первое место смотреть при любых проблемах с Pod. CKAD-задача «Pod не работает» в 80% случаев решается через describe.
  • Events схлопываются по involvedObject + reason. Поле count показывает, сколько раз произошло; firstTimestamp / lastTimestamp — окно.
  • FailedScheduling message содержит причины — читай внимательно, scheduler перечисляет все predicates, которые failed на каждом узле.

Проверка знанийKnowledge check
kubectl get pod показывает Pending уже 5 минут. Какая первая команда для диагностики и что искать в выводе?
ОтветAnswer
kubectl describe pod <name>. Смотреть в самый низ — секция Events. Если есть FailedScheduling с reason — читать message: 'Insufficient cpu/memory' (ресурсы), 'untolerated taint' (нужны tolerations), 'didn't match node affinity' (selector/affinity не нашёл нод), 'pod has unbound immediate PersistentVolumeClaims' (PVC ждёт provisioner-а). Если нет ни одного FailedScheduling и Pod просто висит — почти всегда PVC issue: kubectl describe pvc.
Проверка знанийKnowledge check
Почему kubectl get events без --sort-by=.lastTimestamp бесполезен для отладки?
ОтветAnswer
Default сортировка — по metadata.name. Имена событий — это автогенерированные строки вида my-pod.16f7e2c5a3d9 (timestamp в hex + random suffix), и упорядочиваются они лексикографически, что НЕ совпадает с временем создания. В итоге события вперемешку. --sort-by=.lastTimestamp сортирует по времени последнего появления (учитывает count). Альтернатива — kubectl events (GA c v1.27), у которого хронологическая сортировка default.
Проверка знанийKnowledge check
После рестарта inсидента через 3 часа ты смотришь kubectl get events — там нет ничего интересного. Что произошло и как это предотвратить в будущем?
ОтветAnswer
Events удалены apiserver-ом: TTL = 1 час по умолчанию (--event-ttl на apiserver). Это сделано специально, чтобы не раздувать etcd. Для долгосрочного хранения нужно: (1) Audit log на apiserver, (2) eventrouter DaemonSet, отправляющий events в Elasticsearch/Loki/CloudWatch, (3) kube-state-metrics + Prometheus конвертирует reasons в counters. На случай уже произошедшего инцидента — kubectl logs предыдущих контейнеров и логи на нодах могут дать частичный picture.
Проверка знанийKnowledge check
Чем reason=BackOff отличается от reason=Failed в событиях kubelet?
ОтветAnswer
Failed — container завершился с non-zero exit code (или OOMKilled, или liveness fail убил его). BackOff — kubelet не пытается стартовать container ПРЯМО СЕЙЧАС, потому что предыдущая попытка failed; kubelet ждёт exponential backoff (10s, 20s, 40s, ..., max 5min). BackOff обычно следует за Failed. Если видишь BackOff но не видишь Failed в текущем окне — Failed уже схлопнулся или произошёл больше часа назад (TTL!), а BackOff продолжает retry-иться.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Какой TTL у Events в Kubernetes по умолчанию и почему это значимо для post-mortem анализа?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5