Хабрахабр

[Перевод] Kafka на Kubernetes — это хорошо?

Приветствуем вас, Хабр!

В частности, нам показалась интересной тема взаимодействия Kafka и Kubernetes. В свое время мы первыми вывели на российский рынок тему Kafka и продолжаем следить за ее развитием. Сегодня же мы хотим обратить ваше внимание на более свежую, апрельскую статью Йоханна Гайгера (Johann Gyger), который, хотя и не обошелся без вопросительного знака в названии, рассматривает тему в более предметном ключе, сопровождая текст интересными ссылками. Обзорная (и довольно осторожная) статья на эту тему выходила в блоге компании Confluent еще в октябре прошлого года под авторством Гвен Шапиры. Простите нам пожалуйста вольный перевод «chaos monkey», если сможете!

image

Введение

Kubernetes предназначен для работы с нагрузками, не сохраняющими состояние. Как правило, такие рабочие нагрузки представлены в форме микросервисной архитектуры, они легковесны, хорошо поддаются горизонтальному масштабированию, подчиняются принципам 12-факторных приложений, позволяют работать с автоматическими выключателями (circuit breaker) и мартышками-ломашками (chaos monkeys).

Таким образом, при работе вам приходится иметь дело с состоянием, а оно гораздо тяжеловеснее микросервиса. Kafka, расположенный с другой стороны, в сущности, выступает в роли распределенной базы данных. Kubernetes поддерживает нагрузки с сохранением состояния, но, как указывает Келси Хайтауэр в двух своих твитах, с ними следует обращаться осторожно:

Это не так. Некоторым кажется, что, если накатить Kubernetes на нагрузку с сохранением состояния, он превращается в полностью управляемую базу данных, способную соперничать с RDS. Может быть, если достаточно потрудиться, прикрутить дополнительные компоненты и привлечь команду SRE-инженеров, то удастся обустроить RDS поверх Kubernetes.

Большинство из тех, кто интересуется, «смогу ли я запускать на Kubernetes нагрузки с сохранением состояния» не обладают достаточным опытом в работе с Kubernetes, а зачастую – и с той нагрузкой, о которой спрашивают. Всегда всем рекомендую проявлять исключительную осторожность, запуская нагрузки с сохранением состояния на Kubernetes.

Итак, следует ли запускать Kafka на Kubernetes? Встречный вопрос: а будет ли Kafka лучше работать без Kubernetes? Вот почему я хочу подчеркнуть в этой статье, как Kafka и Kubernetes дополняют друг друга, и какие подводные камни могут попасться при их сочетании.

Время исполнения

Давайте поговорим о базовой вещи — среде времени исполнения как таковой

Процесс

TLS может привнести некоторые издержки. Брокеры Kafka удобны при работе с CPU. При этом, клиенты Kafka могут сильнее нагружать CPU, если используют шифрование, но это не влияет на брокеров.

Память

Размер кучи JVM обычно модно ограничить 4–5 Гб, но вам также понадобится много системной памяти, поскольку Kafka очень активно использует страничный кэш. Брокеры Kafka отжирают память. В Kubernetes соответствующим образом задавайте пределы контейнера на ресурсы и запросы.

Хранилище данных

Для данных Kafka можно использовать том emptyDir, и эффект будет аналогичным: данные вашего брокера будут утеряны после завершения. Хранилище данных в контейнерах является эфемерным – данные теряются при перезапуске. Поэтому, после перезапуска отказавший брокер должен первым делом реплицировать все данные, а на этот процесс может потребоваться немало времени. Ваши сообщения все равно могут сохраниться на других брокерах в качестве реплик.

Пусть это будет нелокальное долговременное хранилище с файловой системой XFS или, точнее, ext4. Вот почему следует использовать долговременное хранилище данных. Я предупредил. Не используйте NFS. Короче говоря, брокер Kafka завершится, если не сможет удалить каталог с данными из-за проблемы с «глупыми переименованиями», актуальной в NFS. NFS версий v3 или v4 работать не будет. Хранилище данных должно быть нелокальным, чтобы Kubernetes мог более гибко выбирать новый узел после перезапуска или релокации. Если я вас до сих пор не убедил, очень внимательно прочтите эту статью.

Сеть

Не пытайтесь разместить все брокеры на одном и том же узле, так как в результате уменьшится доступность. Как и в случае с большинством распределенных систем, производительность Kafka очень сильно зависит от того, чтобы задержки в сети были минимальными, а ширина полосы – максимальной. Также не рассредоточивайте кластер Kafka по целым датацентрам. Если откажет узел Kubernetes, то откажет и весь кластер Kafka. Хороший компромисс в данном случае – выбрать разные зоны доступности. То же касается кластера Kubernetes.

Конфигурация

Обычные манифесты

Поскольку ZooKeeper входит в состав Kafka, именно с этого удобно начинать знакомиться с тем, какие концепции Kubernetes здесь применимы. На сайте Kubernetes есть очень хорошее руководство о том, как настроить ZooKeeper при помощи манифестов. Разобравшись с этим, вы сможете задействовать те же концепции и с кластером Kafka.

  • Под: под – это минимальная развертываемая единица в Kubernetes. В поде содержится ваша рабочая нагрузка, а сам под соответствует процессу у вас в кластере. В поде содержится один или более контейнеров. Каждый сервер ZooKeeper в ансамбле и каждый брокер в кластере Kafka будут работать в отдельном поде.
  • StatefulSet: StatefulSet – это объект Kubernetes, работающий со множественными рабочими нагрузками, сохраняющими состояниями, а такие нагрузки требуют координации. StatefulSet предоставляют гарантии относительно упорядочения подов и их уникальности.
  • Headless-сервисы: Сервисы позволяют откреплять поды от клиентов при помощи логического имени. Kubernetes в данном случае отвечает за балансировку нагрузки. Однако, при операциях с рабочими нагрузками, сохраняющими состояние, как в случае с ZooKeeper и Kafka, клиентам необходимо обмениваться информацией с конкретным инстансом. Именно здесь вам и пригодятся headless-сервисы: в таком случае у клиента все равно будет логическое имя, но напрямую к поду можно будет не обращаться.
  • Том для долговременного хранения: такие тома нужны для конфигурации нелокального блочного долговременного хранилища, которое упоминалось выше.

На Yolean предоставляется исчерпывающий набор манифестов, при помощи которых удобно начать работу с Kafka на Kubernetes.

Helm-диаграммы

С его помощью удобно устанавливать заранее определенные программные пакеты, описанные в диаграммах Helm. Helm – это менеджер пакетов для a Kubernetes, который можно сравнить с менеджерами пакетов для ОС, такими как yum, apt, Homebrew или Chocolatey. Есть несколько диаграмм Kafka: официальная находится в инкубаторном состоянии, есть одна от Confluent, еще одна – от Bitnami. Хорошо подобранная диаграмма Helm облегчает сложную задачу: как правильно сконфигурировать все параметры для использования Kafka на Kubernetes.

Операторы

Оператор не просто упаковывает софт для Kubernetes, но и позволяет вам развертывать такой софт, а также управлять им. Поскольку Helm свойственны определенные недостатки, немалую популярность приобретает еще одно средство: операторы Kubernetes.

Один из них — Strimzi. В списке потрясающих операторов упоминаются два оператора для Kafka. Практически никакой конфигурации вносить не требуется, кроме того, сам оператор предоставляет кое-какие приятные возможности, например, шифрование TLS вида «точка-точка» внутри кластера. При помощи Strimzi не составляет никакого труда поднять кластер Kafka за считанные минуты. Confluent также предоставляет собственный оператор.

Производительность

Такие тесты помогут вам обнаружить потенциальные узкие места, пока не начались проблемы. Очень важно тестировать производительность, снабжая установленный у вас экземпляр Kafka контрольными точками. Активно пользуйтесь ими. К счастью, в Kafka уже предоставляется два инструмента для тестирования производительности: kafka-producer-perf-test.sh и kafka-consumer-perf-test.sh. Для справки можете сверяться с результатами, описанными в этом посте Джеем Крепсом, либо ориентироваться на этот обзор Amazon MSK от Stéphane Maarek.

Операции

Мониторинг

Сегодня имеется солидный инструментарий, обеспечивающий мониторинг на основе метрик в стиле cloud native. Прозрачность в системе очень важна – иначе вы не поймете, что в ней происходит. Prometheus может собирать метрики со всех процессов Java (Kafka, Zookeeper, Kafka Connect) при помощи экспортера JMX – самым простым образом. Два популярных инструмента для этой цели — Prometheus и Grafana. Если присовокупить метрики cAdvisor, то можно будет полнее представлять, как в Kubernetes используются ресурсы.

Он визуализирует ключевые метрики, например, о недореплицированных секторах или о тех, что находятся оффлайн. У Strimzi есть очень удобный пример дашборда Grafana для Kafka. Эти метрики дополняются сведениями об использовании ресурсов и производительности, а также индикаторами стабильности. Там все очень понятно. Таким образом, вы получаете базовый мониторинг кластера Kafka за просто так!

Источник: strimzi.io/docs/master/#kafka_dashboard

Все это неплохо было бы дополнить мониторингом клиентов (метрики по консьюмерам и продьюсерам), а также мониторингом запаздывания (для этого есть Burrow) и сквозным мониторингом – для этого используйте Kafka Monitor.

Логирование

Убедитесь, что все контейнеры в вашей установке Kafka логируются в stdout и stderr, а также позаботьтесь о том, чтобы ваш кластер Kubernetes агрегировал все логи в центральной журнальной инфраструктуре, например, в Elasticsearch. Логирование – еще одна важнейшая задача.

Проверка работоспособности

Если проверка на живость не удается, Kubernetes остановит этот контейнер, а затем автоматически перезапустит его, если политика перезапуска установлена соответствующим образом. Kubernetes использует зонды «живости» (liveness) и готовности (readiness) чтобы проверить, нормально ли работают ваши поды. Таким образом, в подобных случаях больше вообще не требуется вмешательства вручную, а это большой плюс. Если не удается проверка на готовность, то Kubernetes изолирует этот под от обслуживания запросов.

Выкатывание обновлений

Таким образом можно свести длительность простоев к нулю. StatefulSet поддерживают автоматические обновления: при выборе стратегии RollingUpdate каждый под Kafka будет обновляться по очереди.

Масштабирование

Однако, в Kubernetes очень просто масштабировать поды до определенного количества реплик, а это значит, что вы сможете декларативно определить столько брокеров Kafka, сколько захотите. Масштабирование кластера Kafka – непростая задача. Опять же, с этой задачей вам поможет Kubernetes. Самое сложное в данном случае – переприсваивание секторов после масштабирования вверх или перед масштабированием вниз.

Администрирование

Однако, такое решение не слишком красивое. Задачи, связанные с администрированием вашего кластера Kafka, в частности, создание топиков и переприсваивание секторов можно сделать при помощи имеющихся шелл-скриптов, открывая интерфейс командной строки в ваших подах. Здесь есть что дорабатывать. Strimzi поддерживает управление топиками при помощи другого оператора.

Резервное копирование и восстановление

Если у вас упадет кластер Kubernetes, то в худшем случае упадет и кластер Kafka. Теперь доступность Kafka у нас будет зависеть и от доступности Kubernetes. Чтобы снизить риск такого рода, хорошо проработайте концепцию резервного копирования. По закону Мёрфи это обязательно произойдет, и вы потеряете данные. Можно воспользоваться MirrorMaker, другой вариант – задействовать для этого S3, как описано в этом посте от Zalando.

Заключение

При работе с небольшими или средними кластерами Kafka определенно целесообразно использовать Kubernetes, поскольку он обеспечивает дополнительную гибкость и упрощает работу с операторами. Если перед вами стоят очень серьезные нефункциональные требования, касающиеся задержки и/или пропускной способности, то, возможно, лучше рассмотреть какой-нибудь другой вариант развертывания.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть