Как мониторить логи и управлять ресурсами в Kubernetes
Что проверяют
Понимаете ли вы, куда девается вывод вашего Python-сервиса в кластере и чем requests отличаются от limits. Следом обычно дают ситуацию: под перезапускается с кодом 137 или тормозит под нагрузкой, что будете смотреть.
Как отвечать
Логи. Контейнер пишет в stdout и stderr, среда исполнения складывает это в файлы на узле, kubectl logs их читает: -f для потока, -c для конкретного контейнера, --previous для упавшего экземпляра. После удаления пода логи пропадают, поэтому в проде нужен сбор: агент в виде DaemonSet (Fluent Bit, Vector, Grafana Alloy) отправляет всё в Loki или OpenSearch. Со стороны Python: пишите в stdout, а не в файл, в JSON (structlog, python-json-logger), с request_id или trace id, и выставьте PYTHONUNBUFFERED=1, иначе строки приходят с задержкой.
Метрики. kubectl top работает через metrics-server. Для мониторинга ставят Prometheus с kube-state-metrics и node-exporter, дашборды в Grafana, метрики приложения через prometheus_client. kubectl describe pod и kubectl get events покажут OOMKilled и проваленные пробы.
Ресурсы:
- requests: сколько резервирует планировщик, от них HPA считает процент загрузки CPU;
- limits: потолок в cgroups. Превышение по CPU даёт троттлинг, по памяти убийство процесса с кодом 137;
- QoS:
Guaranteedпри равных requests и limits,Burstable,BestEffortбез ресурсов, такие поды вытесняются первыми; - namespace:
LimitRangeзадаёт значения по умолчанию,ResourceQuotaобщий потолок.
Для Python важно, что os.cpu_count() видит ядра узла, а не лимит контейнера, поэтому число воркеров gunicorn задают явно.
Где спотыкаются
Не ставят requests вовсе. Под получает BestEffort, вылетает первым при нехватке памяти, а HPA не может посчитать утилизацию.
Ставят низкий CPU limit и удивляются росту задержек: процесс не падает, его троттлят, и видно это только по метрике container_cpu_cfs_throttled_periods_total.
Считают kubectl logs системой логирования. Пересозданный под уносит историю с собой, и разбирать инцидент уже не по чему.