Представляем библиотеку kubedog для слежения за ресурсами Kubernetes +28


Рады анонсировать новую Open Source-разработку компании «Флант» для DevOps-специалистов и не только — kubedog. Это написанная на Go библиотека и CLI на её основе для отслеживания событий ресурсов Kubernetes и сбора их логов.


На данный момент библиотека поддерживает слежение за следующими ресурсами: Pod (и Container), Job, Deployment, StatefulSet и DaemonSet. События и логи передаются через callback’и.

CLI в kubedog имеет два режима работы:

  • rollout track — слежение за ресурсом до достижения состояния Ready и выход в случае ошибки для удобного использования в CI/CD;
  • follow — печать событий и логов на экран без выхода, аналогично tail -f.

Проблема


Зачем мы стали писать новую библиотеку, если подобные проекты уже существуют (см. «Работу с логами» в этом обзоре)? Kubedog используется в нашей DevOps-утилите dapp для слежения за ходом выката Helm-чартов. Сам Helm не умеет следить за состоянием ресурсов, которые он же добавляет, а передача логов не предусмотрена на уровне GRPC-взаимодействия между Helm и tiller. По этому поводу есть наш issue 3481, в рамках которого нами же было реализовано отслеживание добавленных ресурсов… Однако проект Helm сейчас неохотно добавляет новые функции в Helm 2, поскольку все силы сосредоточены на новой версии Helm 3. По этой причине мы решили выделить kubedog в отдельный проект.

Что же нужно от библиотеки слежения за ресурсами?

  • Получать логи Pod’ов, которые принадлежат ресурсу — например, Deployment’у.
  • Реагировать на изменение состава Pod’ов, которые принадлежат ресурсу: добавлять получение логов от новых Pod’ов, отключать логи из Pod’ов старых ReplicaSet’ов.
  • Слежение за Event’ами, в которых приходят расшифровки разных ошибок. Например, Pod не удаётся создать из-за неизвестного образа или Pod создан, но указанной в шаблоне команды нет в образе.
  • И ещё одно требование — отслеживание перехода ресурса из режима rollout в режим ready. И у каждого ресурса свои условия для этого.

Как легко догадаться, в kubedog мы постарались учесть всё вышеперечисленное.

По-хорошему, в начале работы над чем-то новым проводят анализ существующих решений. Но оказалось, что хотя решений в виде CLI много, то Go-библиотеки попросту нет. Поэтому нам остаётся лишь привести небольшое сравнение основных особенностей существующих CLI-утилит для слежения за ресурсами Kubernetes.

Существующие решения


kubespy


> GitHub

  • Умеет следить только за Deployment и Service, реагирует на новые Pod’ы.
  • Есть режим слежения за описанием ресурса и его статусом и вывод изменений в виде json diff.
  • Есть цветное табличное представление изменений, где видно статус ReplicaSet’ов и conditions.
  • Не показывает логи Pod’ов.
  • Написан на Go, но в качестве библиотеки применить нельзя.

kubetail


> GitHub

  • Bash-скрипт, который вызывает kubectl.
  • Умеет показывать логи существующих Pod’ов.
  • Новые Pod’ы не обнаруживает, если происходит выкат, то kubetail нужно перезапускать.

stern


> GitHub

  • Показывает логи Pod’ов, отфильтрованных по pod-query.
  • Обнаруживает новые Pod’ы.
  • Строки логов раскрашиваются для лучшего восприятия.
  • Показывает события добавления и удаления Pod’ов с именами контейнеров в них.
  • Не следит за Events, поэтому не показывает причину ошибок Pod’ов.
  • Написан на Go, но в качестве библиотеки использовать не получится.

kail


> GitHub

  • Умеет показывать логи одновременно из разных пространств имён по разным ресурсам .
  • Не следит за Events, не показывает причины ошибок, например, для Deployment.
  • Не раскрашивает логи Pod’ов.
  • Написан на Go, но в качестве библиотеки использовать не получится.

k8stail


> GitHub

  • Выборка Pod’ов по namespace и лейблам.
  • Следит за появлением новых, за удалением.
  • Не следит за Events, не покажет ошибки.
  • На Go, но не библиотека.

kubedog


> GitHub

  • CLI работает в двух режимах: бесконечное слежение и слежение до перехода ресурса в статус READY.
  • Следит за одним ресурсом.
  • Реагирует на изменения ресурса, подписывается на логи новых Pod’ов.
  • Умеет следить за Deployment, StatefulSet, DaemonSet, Job или отдельным Pod’ом.
  • Написан на Go, можно использовать как библиотеку для добавления в свою программу слежения за статусом ресурсов и получения логов от контейнеров.

Если приглядеться, то можно сказать, что каждая утилита в чём-то обыгрывает своих соперников и нет однозначного победителя, который бы умел делать всё, что и остальные.

Итак, kubedog!


Суть работы kubedog в следующем: для указанного ресурса запустить Watcher’ы на Event’ы и на Pod’ы, принадлежащие ресурсу, а при появлении Pod’а запустить сборщик его логов. Всё, что происходит с ресурсом, транслируется клиенту с помощью вызова callback’ов.

Рассмотрим на примере DaemonSet, что доступно для кода, использующего библиотеку. Интерфейс callback’ов для Deployment, StatefulSet и DaemonSet одинаков* — это ControllerFeed:

type ControllerFeed interface {
    Added(ready bool) error
    Ready() error
    Failed(reason string) error
    EventMsg(msg string) error
    AddedReplicaSet(ReplicaSet) error
    AddedPod(ReplicaSetPod) error
    PodLogChunk(*ReplicaSetPodLogChunk) error
    PodError(ReplicaSetPodError) error
}

* Исключение составляет AddedReplicaSet, который имеет смысл только для Deployment (для слежения за DaemonsSet можно не определять этот метод).

Пояснения к другим методам интерфейса:

  • Added соответствует событию watch.Added наблюдателя за выбранным ресурсом;
  • Ready вызывается, когда ресурс перешёл в состояние Ready (например, для DaemonSet это момент, когда количество обновлённых и доступных Pod’ов совпало с «желаемым» количеством Pod’ов);
  • Failed — этот метод вызывается в случае удаления ресурса или в случае получения Event’а с причиной и описанием ошибки (например, FailedCreate);
  • EventMsg вызывается для каждого полученного Event’а от ресурса или его Pod’ов: это события о создании ресурса, о закачке образа и т.д. В том числе и сообщения об ошибке;
  • AddedPod — метод, которым можно ловить моменты создания новых Pod’ов;
  • PodLogChunk вызывается, когда от Kubernetes API приходит очередной кусок логов;
  • PodError будет вызван в случае ошибки Pod’а.

Каждый callback может вернуть ошибку типа StopTrack и слежение будет завершено. Так, например, сделано в rollout tracker — Ready возвращает StopTrack и CLI завершает свою работу.

Для облегчения определения callback’ов есть структура ControllerFeedProto, при создании объекта которой можно определить нужный callback метод.

Вот так, например, будет выглядеть бесконечный вывод логов DaemonSet’а без дополнительной информации о событиях и состоянии:

// kubedog может подключаться как снаружи Kubernetes'а, так и внутри
// см. https://github.com/flant/kubedog/blob/master/pkg/kube/kube.go
kubeClient, err := kubernetes.NewForConfig(config)
if err != nil {
  return err
}

feed := &tracker.ControllerFeedProto{
  PodLogChunkFunc: func(chunk *tracker.ReplicaSetPodLogChunk) error {
    for _, line := range chunk.LogLines {
     fmt.Printf(">> po/%s %s: %s\n", chunk.PodName, chunk.ContainerName, line)
    }
    return nil
  },
}

// Опциями можно задать timeout ответа от API сервера и время, начиная с которого показывать логи. Если время пусто, то логи будут выведены все, начиная от старта Pod'а.
opts := tracker.Options{
  Timeout:      time.Second * time.Duration(300),
  LogsFromTime: time.Now(),
}

tracker.TrackDaemonSet(dsName, dsNamespace, kubeClient, feed, opts)

Последний вызов — блокирующий: он запускает бесконечный цикл получения событий от Kubernetes и вызов соответствующих callback’ов. Программно прервать этот цикл можно с помощью возврата StopTrack из callback’а.

Примеры применения


Применение kubedog в качестве библиотеки можно увидеть в утилите dapp. Здесь запускаются готовые rollout Tracker’ы для проверки ресурсов, которые создаёт или обновляет Helm.

Kubedog CLI способен помочь с выкатом в системе CI/CD, причём вне зависимости от того, что используется: kubectl, Helm или что-то другое. Ведь можно запустить kubectl apply, а следом — kubedog rollout track, и в логах выката будет видно ошибку, если с ресурсом что-то не то. Такое применение kubedog поможет сократить время на диагностику проблем с выкатом.

Что дальше?


В наших планах развивать библиотеку в сторону поддержки большего количества ресурсов — например, очень хочется следить за Service и Ingress. Помимо этого предполагается провести работу по классификации reason в Event’ах, чтобы точнее определять момент, когда можно считать, что выкат ресурса не удался. Ещё один вектор развития библиотеки — слежение за несколькими ресурсами сразу, например, по labelSelector или по имени namespace. Также хочется поддерживать разные аннотации, которые могут изменять характер слежения, например, за хукам Helm’а, но это пока больше актуально для dapp.

В ближайшем будущем фокус будет именно на библиотеке, но и для CLI планируются улучшения: более удобные команды и флаги, раскраска логов, сообщения про удаление Pod’ов, как в stern. Также мы рассматриваем возможность создания интерактивного режима с таблицей состояния Deployment и событиями в одном окне и с логами — в другом.

Как попробовать?


Сборки kubedog CLI под Linux и macOS доступны на bintray.

Очень ждём ваших отзывов и issues в GitHub!

P.S.


Читайте также в нашем блоге:




К сожалению, не доступен сервер mySQL