Каких фич не хватает K8s по мнению юзеров Reddit: толковый менеджер пакетов и устранение болей с sidecar-контейнерами
Kubernetes — краеугольный камень современной инфраструктуры. Он включает в себя множество различных компонентов и функций, при этом их хватает не всем. Представьте, что у вас появилась возможность добавить фичу в Kubernetes или что-то в нём кардинально поменять. Что бы вы добавили или изменили? Похожие вопросы постоянно появляются на Reddit.
Мы проанализировали несколько веток и отобрали фичи, за которые высказалось большинство пользователей. К некоторым из них мы привели доводы, почему такой функции ещё нет или, может быть, она уже в планах. Предлагаем изучить их, а в комментариях написать, согласны ли вы с предложениями или у вас есть свои идеи.
Упрощение процесса обновления / семантическое версионирование K8s и компонентов
Многие высказались за упрощение процесса обновления Kubernetes и добавление готовых миграций. Эта тема активно обсуждается в среде разработчиков оркестратора, и некоторые сдвиги на этом направлении заметны. Так, в версию 1.31 должен войти KEP 4330, в котором появится флаг --emulation-version
для эмуляции возможностей (API, функций и прочего) опредёленной предыдущей версии Kubernetes. При этом любые фичи, которые появились после этой версии, будут недоступны. И наоборот, фичи, которые были удалены в последующих версиях, станут доступны.
Некоторые пользователи с такими пожеланиями не согласны:
Не согласен. Цель в том, чтобы упростить миграцию между кластерами, организовать что-то вроде простой федерации. Не нужно относиться к кластеру как к единственному питомцу (известная аналогия pets vs. cattle — питомцы vs. скот. — Прим. ред.). Кластеры должны быть «скотом», иначе они ничем не будут отличаться от предыдущих схем с долгоживущими виртуальными машинами или bare-metal-узлами.
Более продолжительная поддержка версий (LTS)
Некоторые пользователи высказались за более долгоживущие версии K8s. В частности, они жалуются на то, что многие компоненты не успевают за мейнстримным Kubernetes.
Сейчас уже вышла версия 1.29, а kubespray ещё даже не получил поддержку 1.28 (на момент публикации вышел K8s 1.30, kubespray поддерживает 1.29.3. — Прим. ред.). К тому моменту, когда она появится, останется совсем немного времени до того, как 1.27 станет EOL.
Дополнительные возможности по отладке
В dev-кластере нужны всевозможные хуки, пробы и прочее, настраиваемое до мелочей. Так легче проводить отладку: можно запускать кластер в любых режимах и смотреть, как он себя ведёт. А пока же при дебаге в основном приходится полагаться на собственные догадки и логи.
Больше встроенных стратегий развёртывания
Пользователи хотят видеть больше встроенных стратегий развёртывания, сине-зелёных или канареечных. Возможно, расширить CRDs Deployment«ов/Statefulset«ов таким образом, чтобы можно было использовать продвинутые стратегии без полного перехода на совершенно новые CRDs. Что-то вроде API HPA на кастомных метриках.
Настоящая федерация
Настоящая федерация кластеров, для которой не требуется кластер-оркестратор. Такая, чтобы можно было развернуть приложение в нескольких кластерах, маршрутизировать трафик между ними и управлять количеством реплик в каждом кластере с помощью одного и того же логического объекта, словно у тебя один кластер, а не много.
Изменение scope для kubectl -n namespace get all
При вызове команды kubectl -n namespace get all
должны выводиться все объекты, связанные с пространством имён.
Сейчас это невозможно, и для этого есть веские причины — в некоторых случаях ключ может иметь ни одно, ни два, а целых три различных значения. То есть результат команды будет вовсе не таким, какой ожидался.
Имя для кластера
Встроенный ресурс для простой идентификации кластера, который можно было использовать в качестве метаданных для событий или логов. Пример: вы отправляете логи в центральное хранилище. Добавив имя кластера в конфигурацию отправителя логов, получится различать кластеры при анализе/чтении логов.
Управление версиями CRD
Возможность использовать и разграничивать версии CRD, чтобы можно было запускать пересекающиеся операторы. Или сделать так, чтобы CRD были привязаны к пространствам имён. Не каждому пользователю следует быть администратором кластера, но нынешний механизм операторов требует именно этого.
Нативный ресурс «application»
Со встроенными спецификациями Service, Deployment и Ingress с адекватными значениями по умолчанию. Он покрыл бы большинство сценариев использования, предусматривающих развёртывание простого веб-приложения.
Полноценный Open Source GUI
Часть пользователей недовольна встроенным дашбордом. В то же время Open Source-версия Lens их не устраивает невозможностью просматривать логи или заходить (exec) в контейнер (справедливости ради, есть соответствующее расширение). K9s не нравится своей «терминальностью».
Нормальная система управления пакетами / встроенный менеджер пакетов вместо Helm
У пользователей огромное количество вопрос к Helm. Вот лишь некоторые из них:
Почему при написании Helm-чарта приходится считать отступы?
Почему у каждого чарта свои переменные для topologySpreadConstraints, tolerations, nodeAffinity, serviceMonitors? Всё это должно быть стандартизировано.
Почему во многих чартах нет CRD и приходится отдельно их ставить и управлять ими? (Эта «проблема» с CRD на самом деле является лучшей практикой. В идеальном мире все CRD должны управляться отдельно от приложения — жизненный цикл кастомных ресурсов не должен зависеть от контроллера. К примеру, обновление менеджера сертификатов не должно автоматически приводить к удалению всех сертификатов. — Прим. ред.)
Почему многие чарты дают невоспроизводимые результаты? Я не хочу, чтобы ваша таблица «услужливо» генерировала для меня случайные секреты или сертификаты. Я хочу, чтобы при заданном наборе входных значений и версии чарта всегда получался идентичный результат
helm template
.Почему мне приходится изучать Golang, чтобы расшифровать ошибки типа в values.yaml?
Почему Helm так сильно хочет быть инструментом развёртывания? Я не хочу отслеживать состояние развёртывания в самом кластере, потому что в случае DR-сценария (disaster recovery) это приведёт к куче проблем. И я не хочу использовать Helm в качестве инструмента развёртывания, потому что есть гораздо лучшие варианты. Helm должен просто сосредоточиться на том, что у него хорошо получается: преобразовывать конфигурацию чартов в YAML-ресурсы Kubernetes.
RBAC, который поддерживает лейблы
По мнению пользователей, это позволило бы более выборочно выдавать разрешения в полном соответствии с принципом наименьших привилегий.
Один из них приводит следующий пример:
Многим Ingress-контроллерам требуется доступ к секретам по всему кластеру, чтобы различные пространства имён могли предоставлять сертификаты для защиты своих хостов / конечных точек. Другим словами, нужно, чтобы Ingress-контроллеры могли получить доступ к любому секрету по всему кластеру — достаточно, чтобы у него был лейбл
owner: ingress
. В текущей реализации любой, кто найдёт способ проникнуть в под или извлечь его SA-токен, сможет получить доступ к КАЖДОМУ СЕКРЕТУ в кластере.
Оптимизация управления sidecar-контейнерами
Остановка sidecar-контейнеров и их запуск, которые не требуют кучи странных хаков и обходных маневров.
Предположим, прокси-контейнер используется для подключения к какому-либо сервису. В настоящее время он понятия не имеет о том, что делает процесс в главном поде. Поэтому sidecar-контейнер поддерживает работу пода, даже если его главному процессу посылается SIGTERM. Это совершенно не то, что нужно. Поэтому сегодня есть куча всевозможных мудрёных решений, которые позволяют главному контейнеру подавать SIGTERM на некий exit-эндпоинт sidecar«а, или bash-скрипты, которые реализуют ожидание с помощью циклов.
Та же проблема возникает и при запуске: sidecar-контейнеру может потребоваться некоторое время для подключения к сервису, но нынешняя реализация не предусматривает ожидания для основного пода. Тот может попытаться использовать sidecar-контейнер. Такая попытка завершится неудачей, что в результате приведёт к перезапуску пода.
Нативный способ указывать, что под А зависит от пода B до запуска
У нас есть Liveness/Readiness-пробы, но поды не могут их нативно использовать.
Я устал от костыля с initContainer, хотя достаточно добавить пару строк в YAML, чтобы под перед запуском дожидался готовности другого сервиса. Я знаю про приложение, которое должно «определять, когда сервис готов» и все такое, но в реальном мире мне просто нужен простой способ запускать кучу контейнеров. Нынешний способ — муторный.
Как отмечают другие пользователи, предложение довольно спорное:
Я бы сказал, что это антипаттерн в K8s, поскольку нарушает цикл самосогласования (reconciliation loop), который необходим для самовосстановления.
Правильное упорядочивание зависимостей между контейнерами в одном поде
Пользователи хотят иметь возможность управлять зависимостями контейнеров без нужды вносить какие-либо изменения в сами контейнеры. К примеру, есть под с несколькими контейнерами, один из которых — VPN-сервис. Требуется, чтобы трафик на все контейнеры шёл через этот VPN-контейнер, то есть они должны дождаться его запуска и готовности. Сейчас добиться этого без внесения специфических для приложения изменений невозможно.
Оптимизация отсчёта CrashLoopBackoff
Вопрос оптимизации отсчёта времени ожидания после сбоя (больше о том, что такое CrashLoopBackoff, можно узнать из нашей статьи) уже очень давно волнует сообщество пользователей Kubernetes. К слову, соответствующий Issue был открыт в далеком 2017 году.
Вот что по этому поводу пишет Тим Хокин:
«Текущий дизайн был разработан для того, чтобы сбалансировать потребности немногих (сбойных приложений) и многих (всех остальных). Постоянные сбои и перезапуски обычно указывают на то, что что-то не так. Но, очевидно, это справедливо не ВСЕГДА.
В этой теме было предложено много хороших идей. Вот некоторые из них с моими комментариями.
Пересмотреть кривую отката по умолчанию. Возможно, она слишком агрессивна и должна начинаться медленнее и достигать пика ниже. Например, можно начинать её с 250 мс, повышать до 4 с и останавливаться на этом. Или 16 с (всё равно намного меньше, чем 5 минут). Возможно, стоит использовать коэффициент 1,2 вместо 2. Или притормаживать на 4 с, а потом, скажем, после 100 перезапусков, опять повышать.
Не считать выход с 0 сбоем, что автоматически влечёт быстрый рестарт. Можно перезапускать такие поды незамедлительно или использовать для них совсем другую кривую отката.
Превратить предыдущую идею в инструмент — например, в этакий
restart-on-exit-0 -- mycommand -arg -arg -arg
. Не слишком приятное решение, которое вполне реализуемо.Сбрасывать crash-счётчик, когда приложение успешно проходит
startupProbe
илиreadinessProbe
(или три пробы readiness, или что-то ещё). Как вариант, можно уменьшать счётчик после каждой пройденной пробы (то есть если приложение проработало некоторое время, то перезапуск будет быстрым. А если оно постоянно падает, перезапуск будет откладываться).ПРИМЕЧАНИЕ. Все эти варианты не являются взаимоисключающими.
Хочу ещё раз подчеркнуть: это сделано для защиты системы от приложений, которые плохо себя ведут. Мы не хотим устранять эту защиту. По этой причине нежелательно добавлять в API явный механизм для её обхода. Лучше придумать умное решение, которое не затрагивает API. Например, что-то на базе пунктов 1, 2 и 4».
Возможность делать что-то вроде kubectl exec --user 0
В Docker флаг --user
в выражении вида docker exec --user 0
позволяет выполнить команду от лица другого пользователя (в данном случае — root). В Kubernetes такой возможности нет, и приходится придумывать обходные пути — например, запускать привилегированный sidecar-контейнер для дебага. Пользователи хотели бы, чтобы в kubectl был аналог этой функциональности — тогда можно было бы выполнять отдельные команды от лица root, не выдавая повышенные привилегии всем программам. Ознакомиться с конкретными сценариями использования этого флага можно в соответствующем Issue.
Разное
Перейти с YAML на HCL, получив единый язык для всего стека, который также лучше справляется с шаблонизацией, чем Helm, и лучше со слоями, чем Kustomize.
Переименовать ряд сущностей Kubernetes (вроде spec.template.spec).
Обеспечить полную прозрачность: каждый компонент кластера должен быть на дашборде, чтобы можно было посмотреть, что с ним происходит.
Заключение
Развитие Kubernetes во многом завязано на обратную связь от тех, кто с ним работает. Поэтому пользователи оркестратора постоянно делятся идеями о том, как удовлетворить свои потребности при работе с ним. И в этой статье мы представили малую часть предложений из сети. Такое количество идей отражает явный интерес к Kubernetes, благодаря чему в перспективе он должен стать более масштабируемым, безопасным и удобным.
Приведённые в этой статье предложения чаще всего упоминались среди пользователей Reddit в последнее время. Одни из предложенных фич уже находятся в планах на новые версии Kubernetes, а другие не могут быть реализованы по разным причинам. Но в любом случае подобные обсуждения в сообществе играют решающую роль в формировании будущего Kubernetes.
А что вы добавили бы в Kubernetes или изменили бы в нём? Давайте обсудим в комментариях.
P. S.
Читайте также в нашем блоге: