[Перевод] «Давайте использовать Kubernetes!»: как получить 8 проблем
Это перевод вводной статьи об использовании Kubernetes: «Let«s use Kubernetes!» Now you have 8 problems
Если вы используете Docker, то следующим логичным шагом будет Kubernetes, известный как K8s. Именно так вы обеспечиваете эксплуатацию своих продуктов, верно?
Ну, возможно. Решения, созданные для того, чтобы 500 программных инженеров одновременно работали над одним приложением, сильно отличаются от решений для 50 программных инженеров. И совсем другое дело — решения для команды из 5 человек
Если у вас маленькая команда, то Kubernetes, вероятно, не для вас: он влечёт за собой много сложностей и даёт очень мало преимуществ.
Давайте разберёмся с этим.
Все любят движущиеся детали
В Kubernetes куча движущихся деталей: концепции, подсистемы, процессы, машины, код. И это означает кучу проблем.
Многочисленные машины
Kubernetes является распределённой системой: здесь основная машина управляет рабочими — воркерами. Задачи распределяются по разным воркерам, и затем каждая машина выполняет в контейнерах свой объём работы.
То есть лишь для того, чтобы что-нибудь сделать, нужно две физических или виртуальных машины. И в результате вы получаете… одну машину. А если хотите масштабироваться (в этом весь смысл), то вам понадобится от 3–4 до 17 виртуальных машин.
Много, много, очень много кода
По состоянию на март 2020-го кодовая база Kubernetes состоит из более чем 580 000 строк на Go. Причём это актуальный код, без учёта комментариев, пустых строк и вендорских пакетов. Вот что говорится в одном из отчётов об информационной безопасности:
… кодовую базу Kubernetes можно во многом улучшить. Она велика и сложна, большие фрагменты кода содержат минимальную документацию и многочисленные зависимости, в том числе внешние по отношению к Kubernetes системы. В кодовой базе часто встречаются повторные логические реализации разной логики, которые можно централизовать во вспомогательных библиотеках, тем самым уменьшив сложность, облегчив установку патчей и снизив потребность в документировании разрозненных фрагментов кодовой базы.
Справедливости ради, то же самое можно сказать про многие большие проекты. Но вам придётся иметь дело со всем этим кодом, чтобы ваше приложение не сломалось.
Архитектурная сложность, эксплуатационная сложность, сложность конфигурирования и концептуальная сложность
Kubernetes — сложная система с многочисленными сервисами, системами и элементами.
Прежде чем вы сможете запустить одно приложение, вам потребуется создать очень упрощённую архитектуру (взято из документации Kubernetes):
Документация по концепциям в рамках общей документации содержит множество подобных обучающих материалов:
EndpointSlice содержит ссылки на набор сетевых конечных точек. Кjulf задан селектор, контроллер EndpointSlice автоматически создаёт EndpointSlice для сервиса Kubernetes. Эти EndpointSlice будут содержать ссылки на любые поды, соответствующие селектору сервиса. EndpointSlice группируют сетевые конечные точки по уникальной комбинации сервиса и порта.По умолчанию каждая из EndpointSlice, которой управляет контроллер EndpointSlice, может содержать не более 100 конечных точек. Ниже этой границы количество EndpointSlice должно соотноситься 1:1 с количеством конечных точек и сервисов и иметь ту же производительность.
В принципе, я понимаю, что тут написано, но обратите внимание на количество концепций: EndpointSlice, сервис, селектор, под, конечная точка.
И да, обычно вам не потребуется большинство этих возможностей. Но при этом большую часть времени вам вообще не нужен сам Kubernetes.
Вот ещё одна выдержка из документации:
По умолчанию трафик, который отправляется на ClusterIP или сервис NodePort, может маршрутизироваться на любой адрес бэкенда для этого сервиса. Начиная с Kubernetes 1.7 можно маршрутизировать «внешний» трафик к подам на ноду, принимающую трафик, но эта возможность не поддерживается для сервиса ClusterIP, а более сложные топологии, такие как зональная маршрутизация, невозможны. Функция Service Topology позволяет создателю сервиса определять на основе меток нод политику маршрутизации трафика для исходных и конечных нод.
Вот что говорится в вышеупомянутом отчёте об информационной безопасности:
Kubernetes — комплексная система с высокой сложностью эксплуатации. Группа экспертов по оценке сочла конфигурирование и развёртывание Kubernetes нетривиальной задачей. У некоторых компонентов запутанные настройки по умолчанию, не хватает средств управления эксплуатацией, а также неявно определены средства управления безопасностью.
Сложность разработки
Чем глубже вы погружаетесь в Kubernetes, тем сложнее заниматься нормальной разработкой: вам понадобится освоить множество разных концепций (поды, развёртывание, сервисы и т.д.), чтобы исполнять свой код. То есть вам потребуется запустить полноценную систему K8s, только чтобы что-то протестировать с помощью виртуальных машин или вложенных Docker-контейнеров.
А поскольку ваше приложение теперь гораздо труднее исполнять локально, разработка усложняется, и это приводит к различным решениям, от промежуточных сред до проксирования локальных процессов в кластер (несколько лет назад был написан для этого инструмент) или проксирования удалённых процессов на вашу локальную машину…
Есть много несовершенных решений. Проще и лучше всего не использовать Kubernetes.
Микросервисы (плохая идея)
Поскольку ваша система теперь позволяет запускать много сервисов, вы начинаете писать многочисленные сервисы. Это плохая идея.
Распределённые приложения трудно разрабатывать корректно. Очень трудно. Чем больше движущихся деталей, тем больше возникает проблем.
Распределённые приложения сложны в отладке. Вам потребуются новые виды инструментов и журналирования, чтобы понять, что они не так хороши, как логи монолитного приложения.
Микросервисы — это способ организационного масштабирования: когда у вас 500 разработчиков создают один живой сайт, то имеет смысл связываться с большой распределённой системой, которая позволит командам работать независимо друг от друга. Вы даёте каждой команде из 5 разработчиков отдельный микросервис, и команда притворяется, что остальные микросервисы являются внешними сервисами, которым они не могут доверять.
Но если команда из 5 человек ведёт 20 микросервисов и у вас нет очень веской причины использовать распределённую систему, то вы совершаете ошибку. Вместо 5 человек на сервис, как это делается в больших компаниях, у вас приходится 0,25 человека на сервис.
Но разве он не полезен?
Масштабирование
Kubernetes может быть полезен, если вам нужно сильно масштабироваться. Но давайте рассмотрим альтернативы:
- Вы можете взять облачные виртуальные машины с общим количество виртуальных процессоров до 416 шт и до 8 Тб памяти. Да, это будет дорого, но это будет просто.
- Можно легко масштабировать многие веб-приложения с помощью сервисов наподобие Heroku.
Конечно, предполагается, что добавление воркеров принесёт вам какую-то пользу:
- Большинству приложений не нужно очень сильно масштабироваться. Достаточно каких-то разумных оптимизаций.
- Обычно узким местом при масштабировании многих веб-приложений становится база данных, а не веб-воркеры.
Надёжность
Чем больше движущихся деталей, тем выше вероятность ошибки.
Средства Kubernetes для обеспечения надёжности (проверки состояния, rolling-развёртывания) можно реализовать гораздо проще, а во многих случаях это уже встроенные фичи. Например, nginx умеет проверять состояние воркер-процессов, а для их автоматического перезапуска можно использовать docker-autoheal или нечто подобное.
Если же вас беспокоит длительность простоев, то вашей первой мыслью не должно быть «как мне уменьшить простои с 1 секунды до 1 мс». Нет, нужно подумать «как мне сделать так, чтобы изменения схемы базы данных не мешали откатам, если я где-то накосячу».
А если вам нужны надёжные веб-воркеры без машины в виде единой точки отказа, то есть много способов реализовать это без Kubernetes.
Лучшие методики?
Не существует общепринятых лучших методик, есть лишь лучшие методики для конкретной ситуации. Если какой-то инструмент сегодня популярен, это не означает, что он подходит именно вам.
В определённых случаях Kubernetes — это отличная идея. А в других случаях он будет пожирать ваше время и не даст никаких преимуществ.
Если у вас нет настоящей потребности во всей этой сложности, то обратите внимание на широкий выбор инструментов, которые сделают для вас всё то же самое: Docker Compose на одной машине, Hashicorp Nomad для оркестрации, Heroku и подобные системы, Snakemake для вычислительных конвейеров, и многое другое.