Рады представить свой новый 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.
Читайте также в нашем блоге:
- «Представляем shell-operator: создавать операторы для Kubernetes стало ещё проще»;
- «Расширяем и дополняем Kubernetes (обзор и видео доклада)»;
- «Мониторинг и Kubernetes (обзор и видео доклада)»;
- «werf — наш инструмент для CI/CD в Kubernetes (обзор и видео доклада)».
Автор: Андрей Климентьев