Представляем k8s-image-availability-exporter для обнаружения пропавших образов в Kubernetes

Рады представить свой новый Open Source-проект. На этот раз мы сделали совсем небольшую, казалось бы, утилиту, но столь полезную буквально для любой инсталляции Kubernetes. В чем же её суть? K8s-image-availability-exporter — это Prometheus exporter, позволяющий проактивно предупредить пользователя об образах, которые прописаны в объектах Kubernetes (например, поле image в Deployment), но отсутствуют в реестре контейнеров (Docker Registry и т.п.).
Введение
Kubernetes — крайне динамическая система. Оперируя инфраструктурой в K8s-кластере, мы предполагаем, что в любой момент времени pod’ы — да что там pod'ы: целые узлы! — могут быть удалены. Чтобы убедиться в этом, мы применяем различные подходы chaos engineering, в основном убивая случайные узлы Kubernetes с тем, чтобы увидеть, готовы ли клиентские приложения к пересозданию pod’ов.
Для корректной работы приложения в таких динамических условиях Kubernetes надо соблюдать минимальные правила: создание PodDisruptionBudgets, деплой сразу нескольких реплик приложения, корректная конфигурация podAffinity, nodeAffinity и т.д.
Однако, несмотря на такие очевидные политики, мы не всегда можем повлиять на их применение. Реальность же такова, что нам пришлось (и не один раз!) встретиться с проблемами, когда у клиента по какой-то причине приложение запущено в единственной реплике. Оно работает так месяцами и почти не деплоится. Его редкие выкаты проводятся без нашего участия и, конечно, без werf (эта утилита смогла бы сделать всё сама). В то же время реестр настроен на автоматическое удаление всех старых образов.И вот однажды, когда по какой-то причине потребуется пересоздать pod, случится непоправимое.
Недавно — после того, как типовая операция перезаказа узла K8s привела к часовому простою, поскольку искали человека, который вообще сможет собрать приложение, — мы и решили написать k8s-image-availability-exporter. Идея утилиты — в автоматизации, позволяющей предотвратить последствия подобных ситуаций вне зависимости от соблюдения организационных политик и других «случайных» факторов.
Реализация
Общий алгоритм реализации сводится к следующему:
- Запускаем 5 информеров. Таким образом, в памяти держится копия состояния всех следующих объектов кластера: Deployment, StatefulSet, DaemonSet, CronJobs и Secrets.
- Все образы в PodTemplate’ах группируем и размещаем в очередь (priority queue).
- Каждые 15 секунд (настраивается через опцию
--check-period) достаём из очереди порцию наиболее старых образов и проверяем их наличие в registry. Количество образов динамически варьируется так, чтобы за 10 минут проверить все возможные образы кластера.- Если в
PodSpecприсутствуетimagePullSecrets, достаём нужные нам Secrets. - С полученными Secrets (если есть
imagePullSecrets) или без них заходим в реестр образов (container registry) и проверяем, есть ли там нужный образ.
- Если в
В результате проделанной работы экспортируются следующие виды метрик (под ТИП подразумевается deployment, statefulset, daemonset и cronjob):
-
k8s_image_availability_exporter_ТИП_available— ненулевое значение говорит об успешной проверке образа; -
k8s_image_availability_exporter_ТИП_bad_image_format— ненулевое значение указывает на некорректный формат поляimage; -
k8s_image_availability_exporter_ТИП_absent— ненулевое значение говорит об отсутствии манифеста образа в реестре контейнеров; -
k8s_image_availability_exporter_ТИП_registry_unavailable— ненулевое значение показывает на общую недоступность реестра (возможно, из-за сетевых проблем); -
k8s_image_availability_exporter_deployment_registry_v1_api_not_supported— ненулевое значение указывает на первую версию Docker Registry API (такие образы лучше игнорировать с помощью аргумента--ignored-images); -
k8s_image_availability_exporter_ТИП_authentication_failure— ненулевое значение свидетельствует об ошибке аутентификации в реестре контейнеров (проверьтеimagePullSecrets); -
k8s_image_availability_exporter_ТИП_authentication_failure— ненулевое значение свидетельствует об ошибке авторизации в реестре контейнеров (проверьтеimagePullSecrets); -
k8s_image_availability_exporter_ТИП_unknown_error— ненулевое значение говорит об ошибке, не поддающейся встроенной классификации (получите дополнительную информацию в логах экспортера); -
k8s_image_availability_exporter_completed_rechecks_total— инкрементируется в каждом цикле проверки наличия образов в реестре.
Последний штрих — предусмотрен настраиваемый список образов, которые нужно игнорировать при этом мониторинге (--ignored-images).
Код написан на Go, распространяется на условиях свободной лицензии Apache 2.0 и доступен на GitHub. Если есть предложения по его улучшению или замечания по использованию утилиты — будем рады!
Мы уже внедрили утилиту на десятках Kubernetes-кластеров и результатами её использования очень довольны. Однако формально текущий статус разработки — альфа-версия, поэтому применяйте её на свой страх и риск.
Как начать пользоваться?
Достаточно трёх шагов:
-
git pull https://github.com/flant/k8s-image-availability-exporter.git -
kubectl apply -f deploy/ - Настроить интеграцию с Prometheus: scraping и alerting rules.
Подробнее (включая примеры готовых конфигураций для Prometheus) — см. в README.
Итоги
Теперь — с k8s-image-availability-exporter — мы получаем алерты о том, что у каких-либо из запущенных Kubernetes-контроллеров пропал(и) образ(ы) контейнеров в registry. Это позволяет решить проблему до того, как она себя проявит.
Альтернативный путь решения — не чистить registry вообще или же повсеместно использовать утилиты, в которых эта проблема уже решена системно (как это сделано в werf).
P.S.
Читайте также в нашем блоге:
