Логи:
Kubernetes сам ничего не агрегирует. Kubelet складывает stdout и stderr контейнера в файл на ноде и ротирует его (по умолчанию 10Mi на файл, 5 файлов, настраивается через containerLogMaxSize и containerLogMaxFiles в конфиге kubelet). Отсюда два следствия. Первое: приложение должно писать в stdout, а не в файлы внутри контейнера. Второе: удалили под, логи уехали вместе с ним.
Код: Выделить всё
kubectl logs deploy/api -n shop --tail=100 -f
kubectl logs api-7d4b9c-x2k4f --previous # лог упавшего контейнера до рестарта
kubectl logs -l app=api -n shop --all-containers --prefix --since=15m
kubectl logs api-7d4b9c-x2k4f -c init-migrate # конкретный контейнер подаМетрики:
kubectl top показывает текущее потребление CPU и памяти, но требует metrics-server (мы ставили его в главе 17 для HPA):
Код: Выделить всё
minikube addons enable metrics-server
# для kind придется добавить --kubelet-insecure-tls в args деплоймента metrics-server
kubectl top nodes
kubectl top pods -n shop --containersСобытия:
Events, это записи о том, что кластер делал с вашими объектами: запланировал под, стянул образ, убил по OOM, не смог смонтировать том.
Код: Выделить всё
kubectl get events -n shop --sort-by=.lastTimestamp
kubectl events --for deploy/api -n shop --types=WarningPrometheus и Grafana:
Стандарт де-факто. Prometheus работает по pull-модели: сам обходит поды и снимает метрики с HTTP-эндпоинта /metrics. Собирать стек по частям не надо, helm-чарт kube-prometheus-stack привозит Prometheus, Alertmanager, Grafana, node-exporter и kube-state-metrics с готовыми дашбордами:
Код: Выделить всё
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack \
-n monitoring --create-namespace \
--set prometheus.prometheusSpec.retention=15d
kubectl -n monitoring port-forward svc/monitoring-grafana 3000:80
# логин admin, пароль лежит в секрете monitoring-grafanaПара PromQL-запросов, с которых все начинают:
Код: Выделить всё
# CPU по подам неймспейса за последние 5 минут
sum(rate(container_cpu_usage_seconds_total{namespace="shop", container!=""}[5m])) by (pod)
# кто рестартовал за последний час
increase(kube_pod_container_status_restarts_total[1h]) > 0
# реальная память (именно по ней прилетает OOM kill)
container_memory_working_set_bytes{namespace="shop", container!=""}Prometheus без PVC: переехал под, вся история метрик обнулилась. Задайте storageSpec в values чарта. Вторые грабли, кардинальность: не вешайте в лейблы метрик user_id или request_id, миллион временных рядов положит Prometheus быстрее, чем любая нагрузка. Третьи: на дашборде container_memory_usage_bytes вместо working_set, и вы паникуете из-за page cache, который ядро и так отдаст. И классика: смотреть kubectl logs у пода в CrashLoopBackOff без --previous и удивляться, что лог пустой.
Итог:
Логи отвечают на вопрос "что случилось", метрики на "как себя чувствует система", events на "что кластер делал с объектами". kubectl logs, top и events закрывают быструю диагностику руками, kube-prometheus-stack дает историю, дашборды и алерты. В следующей главе вернемся к безопасности всерьез: securityContext, Pod Security Standards, NetworkPolicy и шифрование секретов.