Я Дмитрий Лазаренко, руковожу командой, создающей и внедряющей собственный Kubernetes aaS на платформе Mail.ru Cloud Solutions. Давно работая с внедрением Kubernetes, мы часто сталкиваемся с недопониманием нюансов этой технологии. Хочу рассказать о типичных стратегических просчетах при внедрении Kubernetes в крупных проектах.
Большинство проблем с внедрением Kubernetes в конечном счете растут из сложности самой технологии. Есть неочевидные трудности и нюансы внедрения и эксплуатации, есть преимущества, которые недоиспользуют и в итоге теряют деньги. И есть глобальный дефицит экспертизы в Kubernetes, потому что научиться правильно готовить технологию по книжке сложно, трудно нанять квалифицированных специалистов. На эту сложность накладывается известный хайп, который усложняет рациональное принятие решений о внедрении Kubernetes. Как ни странно, Kubernetes нередко внедряют достаточно формально, чтобы был, потому что он как-то сделает лучше.
Я надеюсь, что моя заметка поможет вам сориентироваться и сделать выбор, о котором впоследствии вы будете вспоминать с гордостью (а не жалеть, не проклинать себя и не пытаться собрать машину времени, чтобы отменить свое решение).
Итак, добро пожаловать в мир факапов внедрения Kubernetes уровня PRO. И как на самом деле в каждом случае получить пресловутый меджик: снижение Time-to-Market, ускорение релизов и бесперебойную работу приложений.
Ошибка 1. Не подготовиться к работе со Stateful-приложениями
Kubernetes изначально разработали для Stateless-приложений, которые обрабатывают данные, но ничего не хранят, — тех же веб-приложений.
Для развертывания хранящих данных Stateful-приложений на Kubernetes можно задействовать Persistent Volumes (PV) — хранилища данных, которые связаны с подами. С точки зрения приложения PV подключается внутрь контейнера как локальная директория, что позволяет не менять логику работы с данными. При этом благодаря Kubernetes хранилище доступно для приложения на любой ноде кластера. Для организации PV понадобится организовать СХД и настроить Kubernetes для работы с ним.
Как альтернатива — можно переработать само приложение, чтобы оно хранило данные не под собой, а в отдельных базах данных или объектных хранилищах, которые можно развернуть самостоятельно, а можно получить в виде готовых сервисов (aaS).
При организации работы этих Stateful-хранилищ нужно решить задачи их резервирования. Это сложная задача, которую тяжело решить самостоятельно, и трудно поддерживать такую систему. Но в нашем Kubernetes aaS уже «из коробки» есть интегрированные PV на базе блочного хранилища CEPH, виртуального файлового хранилища или SSD/NVME-дисков, подключенных по iSCSI к каждому вычислительному серверу. Также есть возможность запустить объектное хранилище или базы данных на той же платформе в формате aaS.
Без доработки архитектуры под Stateful случаются разные казусы. Типичный кейс: в компании вместе с Kubernetes не внедряют распределенную систему хранения, потому что на первых порах на проекте запускают только Stateless-приложения. Потом выясняется, что какие-то данные хранить все-таки нужно, где-то рядом на сервере поднимают NFS, куда ходят приложения на Kubernetes. Сначала это служебные приложения вроде мониторинга, информацию из которых потерять не страшно. Но потом в ненадежный и медленный NFS начинают обращаться продакшен и core-сервисы, хранят там данные. Эта ситуация уже чревата большими проблемами, которые на ходу решить гораздо сложнее, чем если сразу все продумать. Интегрировать высокопроизводительные хранилища в инфраструктуру нужно сразу вместе с Kubernetes.
Ошибка 2. Не адаптировать архитектуру монолитных приложений к работе в Kubernetes
Речь о приземлении Kubernetes на монолитный проект без адаптации инфраструктуры, принципов ее эксплуатации и управления.
Kubernetes оптимален для приложений в слабосвязной архитектуре микросервисов — четкими границами модульности, независимым деплоем, разработкой и масштабированием. Такие приложения удобно упаковать в контейнеры и управлять через оркестратор. Соответственно, Kubernetes не стоит использовать в монолитной архитектуре и нагрузках с большим числом зависимостей. Одно лишь обновление таких приложений занимает часы.
Какие ключевые моменты адаптации приложений?
Во-первых, монолиты любят хранить данные под собой. И, как мы уже обсудили, монолит придется научить работать со Stateful-хранилищами.
Во-вторых, монолит придется научить работать в несколько инстансов:
-
Инстансы должны уметь работать с данными, хранящимися отдельно от монолита, и получать к ним доступ.
-
Для кэшей в монолите обычно рядом с приложением поднят Memcached или Redis, в которые приложение обращается локально. При размещении приложения в Kubernetes нужен отдельный кластер Redis, а приложение должно уметь работать с ним именно как с кластером, чего классические монолиты не умеют.
-
В Kubernetes отказоустойчивость, балансировка, Self-Healing достигаются за счет того, что инстансы приложений легко переезжают на другие ноды. С монолитом иначе: даже если он работает в несколько инстансов, клиентские приложения обычно умеют продолжать работу только с тем же инстансом, с которым начали, и переезд на другую ноду сбрасывает сессию. Поэтому приложение должно научиться обрабатывать такие переключения либо же на балансировщике нужно реализовать Sticky Session.
Наконец, народная мудрость гласит, что для адаптации к Kubernetes монолитное приложение надо разбивать. Цель разбиения — получить слабосвязную архитектуру, где каждая функциональность разбита на отдельные сервисы и упакована в контейнеры вместе с зависимостями. Без этого приложение превращается в распределенный сетевой монолит, набор сильно связанных «микромонолитов», которые можно развернуть только вместе, в одном контейнере, и это не решает исходную проблему громоздких и рискованных развертываний. Не стоит рассчитывать, что удастся переиспользовать код монолитного приложения: дизайн архитектуры и сам код придется существенно переработать.
Есть кейсы, в которых часть логики уже удалось перевести на микросервисы, а часть еще монолитна. Перевести в Kubernetes все, включая монолитную часть — плохая идея. Хорошим решением тут будет оставить монолитную часть за пределами Kubernetes, а микросервисы разворачивать в нем.
Ошибка 3. Пытаться полностью перейти на Kubernetes
Для многих компаний Kubernetes — способ унификации работы с серверами на одной платформе, отсюда возникает стремление единообразно всем управлять. Контейнер в Kubernetes запустить легче, чем настроить приложение или базу данных на виртуальной машине. Это шаткий путь искушения, и продакшен быстро расставит все на свои места и покажет, что не учли при переносе.
К примеру, перенести базу данных в Kubernetes обычно можно, но гораздо реже нужно. И если уж вы задались целью это сделать, учитывайте, что из-за подвижности Kubernetes нужен кластер СУБД, в котором переключение с Master на Slave должно происходить автоматически. Кроме того, под базой данных в Kubernetes будет лежать сетевое хранилище, а это не то же самое, что локальное: нужно учесть, что увеличатся задержки.
Если в вашей системе есть компоненты, про которые вы не понимаете, как изменится их поведение после переезда на Kubernetes, дайте себе время на то, чтобы оценить последствия.
Ошибка 4. Не подготовить команду к внедрению Kubernetes
Работа с Kubernetes подсвечивает нехватку экспертности. Если администраторы, которые занимаются установкой и поддержкой Kubernetes, не понимают концепций технологии, на выходе мы получаем не Cloud-Native-систему, а архитектуру с ручными операциями, без адаптации к задачам конкретной компании, без использования реальных возможностей кластера.
Для работы с Kubernetes нужны администраторы, понимающие в разработке, с опытом работы с этим инструментом. Kubernetes — не отдельный исполняемый файл на отдельной виртуальной машине, а экосистема компонентов. И развернуть кластер, а потом поддерживать в производственной среде с запущенным программным обеспечением внутри надо уметь. Конкретно надо знать, из чего состоит Kubernetes, как работает, как дебажить, какие Best Practices по запуску приложений.
Если в команде сисадминов с Kubernetes не знакомы, вряд ли получится с первого раза работать на проде. Придется учить, отправлять на курсы, давать время на эксперименты, приготовиться к тому, что сначала будут сюрпризы в продакшене. Если специалистов нанимать, то надо проверить, могут ли они развернуть Kubernetes самостоятельно и администрировать его эксплуатацию: многие умеют только кнопку нажать на платформах вроде Rancher, с таким опытом тоже не выйдет своими силами администрировать кластер.
Зато если вы найдете экспертов для управления инфраструктурой приложения в Kubernetes, их понадобится меньше, чем нужно было админов до переезда приложения в контейнеры. Еще один плюс — Kubernetes как технология сильно стандартизирован, поэтому любые новые сотрудники с нужным опытом, которые приходят в проект на Kubernetes, могут быстро включиться в задачи. Когда вместо Kubernetes в компании используют для автоматизации разработки самописные решения, все происходит гораздо сложнее.
Ошибка 5. Не подготовить процессы к внедрению Kubernetes
Разработку надо адаптировать под Kubernetes, сначала внедрить процессы DevOps, которые затрагивают всю разработку кода. А компании, внедряя Kubernetes, часто оставляют старые способы работы. Разработчики пишут код как раньше.
При этом внедрение Kubernetes меняет распределение ролей и ответственности в команде и подсвечивает все культурные проблемы. Если у разработчиков нет желания внедрять DevOps, есть сопротивление к этой методологии, ее инструменты бесполезны, включая Kubernetes.
В идеологии DevOps администраторы поддерживают инфраструктуру. А разработчики поддерживают приложение от планирования и написания кода до этапа запуска, внедрения, мониторинга и работы в производственной среде. Разработчики теперь не могут не разбираться в инфраструктуре, они должны понимать, как работает код в контексте всех этих процессов.
Однако часто возникают такие ситуации: команда решает разбить монолит на микросервисы, тратит на это много времени, останавливает всю бизнес-разработку. После разделения монолита собираются управлять приложением с помощью Kubernetes. Но разработчиков не подготовили к тому, что им придется внедрять Docker и CI. Это создает сопротивление. В итоге Kubernetes и микросервисы появились для галочки, и это никак не сказалось на приложении.
Почему ничего не улучшится, если не изменить подход к разработке? Потому что происходит следующее:
-
Если разработчики не разбираются в Docker, то Docker-файлы для них пишет DevOps-инженер. При этом как работает приложение, его версии и зависимости, знает именно разработчик. Он мог бы легко сам написать Docker-файл (если бы умел) и контролировать инфраструктуру своего приложения. Когда же Docker-файл пишет DevOps-инженер, он может учесть не все детали, плюс ему надо разбираться в приложении — времени уходит больше.
-
Иногда DevOps-инженеры пишут за разработчиков и манифесты Kubernetes, хотя технология опять же дает разработчику возможность самому контролировать запуск приложения, ресурсы, health checks. Когда этим занимаются девопсы, они снова тратят больше времени.
-
Наконец, DevOps-инженеров в любой команде гораздо меньше, чем разработчиков. Если 100 разработчиков генерируют микросервисы, а 5–10 девопсов пытаются написать под все это манифесты, выкатки замыкаются на них и выстраиваются в очередь. Процессы не ускоряются, а замедляются.
Что конкретно может вызывать сопротивление? Разработчикам приходится ознакомиться с концепцией Docker Way. Это включает изучение Docker, манифестов Kubernetes, внедрение health checks, указание ресурсов к приложению. При ошибках в этих моментах приложение может не запускаться, и разработчику нужно в этом разбираться. Иногда команде разработки непонятно, почему она должна брать на себя эти традиционно админские задачи.
В действительности новый подход в конечном итоге приносит пользу самим разработчикам, и это несложно донести до команды. К примеру, раньше ты писал код, делал задачу в Jira на получение инфраструктуры. Потом задача висит там месяц. С Kubernetes разработка получает полный контроль над выкатками. Из опыта: когда разработчики это действительно понимают и осваивают, им это начинает нравиться.
Kubernetes сильно упрощает жизнь разработчика за счет декларативности — все конфигурации инфраструктуры описываются в файлах. Для сравнения: в более старом императивном подходе, например при использовании Ansible, для управления конфигурациями приходится вручную прописывать конкретные задачи, которые нужны, чтобы выкатить приложение.
В декларативном подходе, который реализует Kubernetes, описывают не задачи, которые нужно выполнить, а состояние, к которому нужно прийти. Он в разы уменьшает необходимость разбираться в том, что как работает и что как сделать. Не надо учитывать, в каком состоянии система сейчас. Для управления конфигурациями в Kubernetes используют удобочитаемые YAML-манифесты, прозрачные шаблоны, инструменты IaC (инфраструктура как код), которые описывают, что, где, как будет запущено и с какими параметрами.
По мере развития этого подхода в команде появляются общие пайплайны доставки ПО на серверы, общие шаблоны CI/CD и манифестов Kubernetes внутри группы разработки, что сильно ускоряет процессы. Разработчик уже не придумывает каждый раз заново, как что-то подключить, а просто подключает готовые шаблоны CI/CD-задач к CI-файлам. Шаблоны манифестов Kubernetes помогают не писать их заново каждый раз — девопсы дают инструменты для подготовки единых шаблонов, разработчики только указывают параметры, которые отличают конкретный кейс от шаблона.
Когда все в команде понимают, какие преимущества получают, перейти к DevOps-практикам намного проще.
Ошибка 6. Не использовать технологии и подходы, дополняющие Kubernetes
Первый подход — это тестирование новых версий самого Kubernetes. Ведь он — приложение со своим жизненным циклом, для которого нужно решать проблемы настройки, обновления, соединения с сервисами. Можно провести аналогию со стандартной операционной системой: здесь возникают те же проблемы, только Kubernetes сложнее, чем ОС на отдельном сервере. Соответственно, обновления Kubernetes могут создавать проблемы для работы приложений. Поэтому стоит завести тестовую среду для их проверки.
Второе — Kubernetes нужно прокачивать. В его экосистеме пара сотен продуктов, которые легко интегрируются с ним через API: SDN, Ingress, Prometheus, Fluentd, СХД, авторизация и так далее. Не стоит полагать, что все это работает вместе из коробки, это надо настраивать.
Вот перечень базовых направлений, на которые стоит обратить внимание:
-
хранение данных приложений: Ceph, GlusterFS, Minio;
-
мониторинг: Prometheus, Influx + Telegraph;
-
сбор и хранение логов: Fluentd, Elasticsearch, Loki;
-
автомасштабирование: Metrics Server, Prometheus Adapter;
-
настройки безопасности: Dex, Keycloak, Open Policy Agent;
-
инструменты CI/CD: Gitlab, Jenkins, Argo CD, Teamcity;
-
Docker Registry: Harbor, Nexus, Official Docker Registry;
-
сети: Calico, Weave net, Cilium;
-
инструменты для хранения и обработки функции Serverless: Kubeless, OpenFaaS, Fission;
-
Service Mesh для контроля потока данных в приложении без изменения кода: Istio, Linkerd, Consul.
В компании могут поставить Kubernetes, но не учесть, что мониторинга из коробки там нет. После установки выясняется, что нужен и мониторинг самого кластера, и мониторинг приложений в нем. Причем специфический мониторинг, для которого не подходит тот же Zabbix. Нельзя, как раньше, просто прописать IP-адреса серверов, нужно запускать Prometheus или Telegraph.
Аналогично с логами. Кластер «из коробки» предоставляет историю логов, но они хранятся только для приложений, которые сейчас запущены. При передеплое история пропадает. С монолитом можно было ходить по серверам и собирать логи вручную, с Kubernetes это не работает.
Для надежного доступа в кластер нужен отказоустойчивый балансер: MetalLB или просто VirtualIP. Такие инструменты могут быть «из коробки» только в Managed-решениях, например, в нашем K8s aaS балансировщики уже встроены.
Ошибка 7. Не задействовать автоматизацию решений типовых задач
Прелесть Kubernetes для разработки раскрывается в возможности уйти от рутинных операций за счет шаблонизации. Часто продолжают делать манифесты вручную.
Использование шаблонов манифестов не только убирает большую часть ручной работы, но и помогает внедрять лучшие практики централизованно. Помимо шаблонов, есть операторы, которые автоматизируют выполнение рутинных действий над объектами кластера при определенных условиях. Оператор выполняется внутри кластера и может, к примеру, создать Redis без описания всех манифестов, деплоймента, PV и так далее. Он создает объекты в конфигурации уже существующих, с нужными донастройками. Здесь можно посмотреть список операторов.
По сравнению с шаблоном манифеста Kubernetes у операторов больше возможностей, так как это отдельное приложение: они могут считать настройки и не просто создавать манифесты, а параллельно выполнять логику работы приложения, взаимодействовать с другими системами, регистрироваться в системе Auto-Discovery, создавать дашборды в Grafana.
Наконец, в части управления инфраструктурой незаменимы IaC-инструменты (Infrastructure as Code), такие как Terraform.
Ошибка 8. Думать, что Kubernetes в облаке можно запустить и забыть
В облаке можно развернуть кластер за 10 минут. Провайдеры K8s aaS стремятся реализовать большинство надстроек, нужных для самого Kubernetes и приложений в нем: автоматизация обновлений и масштабирования, балансировка, сети, мониторинг. Формат as a Service снимает часть головной боли по настройке и управлению кластерами. Но это не означает, что облачный кластер достаточно запустить и забыть.
Ни один провайдер K8s aaS не дает 100% гарантии доступности сервиса. SLA 99,95% означает простой не более 5 часов в год — и эти 5 часов простоя в год провайдер может допустить. Если нужна высокая доступность, нужно обеспечить ее за счет балансировки нагрузки и репликации. И если провайдер позволяет запускать кластер на несколько зон доступности, стоит этим пользоваться.
Кроме того, провайдер отвечает только за свою часть инфраструктуры K8s aaS. Он несет ответственность за доступность предоставляемых сервисов, которая зависит от работы оборудования, платформы виртуализации, компонентов IaaS и PaaS. Ответственность за анализ рабочей нагрузки, трафика и производительности всегда лежит на клиенте. Сотрудники компании отвечают за настройку запросов, планирование утилизации мощностей и настройку логики автомасштабирования, аварийное восстановление — если не использует сервис аварийного восстановления от провайдера, настройки безопасности и доступов пользователей, работу с базами данных, конфигурирование сети.
Облако снимает большую часть задач администрирования и управления инфраструктурой, но не полностью, при подключении K8s aaS стоит разобраться в том, чем компании придется заниматься самой.
Ошибка 9. Запустить кластер в K8s aaS, но не использовать другие сервисы выбранной платформы
О получении сервисов DBaaS, объектных и других Stateful-хранилищ мы уже рассказывали выше. Теперь хочу выделить синергию Kubernetes с другими сервисами платформ в контексте машинного обучения и обработки больших данных. С помощью него можно получить мощности для обучения нейросетей, эффективно использовать ресурсы и проводить все вычисления внутри кластера. Kubernetes в целом отлично подходит для Data Science и работы с большими данными, аналитикам проще выстраивать пайплайны для работы с Big Data, чтобы использовать данные для автоматизации принятия решения и других задач.
Kubernetes позволяет быстро получить столько инфраструктуры для машинного обучения, сколько нужно. Автомасштабирование позволяет кластеру быстро реагировать на увеличение нагрузки. Для машинного обучения бывает нужно много мощностей в моменте — автомасштабирование дает возможность сразу их получить, когда нужно, и отключить, как только они становятся не нужны.
Кроме того, есть огромное количество решений для машинного обучения, заточенных под Kubernetes, например Kubeflow — их также можно использовать вместе с K8s aaS, запуская самостоятельно.
Ошибка 10. Думать, что Kubernetes безопасен «из коробки»
Нельзя думать, что кластер, приложения и данные автоматически защищены, если оставлены дефолтные настройки.
Сталкивались с тем, что служба безопасности клиента не ориентируется в Kubernetes и не учитывает, что это такая же часть инфраструктуры, как и все остальное. Администраторы не думают про безопасность, а ИБ уверены, что достаточно антивируса. Kubernetes в дефолтной конфигурации создает дыру в безопасности. Так, из-за незакрытых уязвимостей в кластер разработчиков видеоплеера JW Player однажды проник майнер и использовал его для добычи криптовалюты.
Проблема решается через внедрение DevOps, когда все отделы компании начинают использовать единые инструменты для достижения общих целей. В процесс DevOps надо включить службу ИБ, организовать процессы DevSecOps, автоматизированный контроль безопасности, когда безопасники внедряют инструменты контроля ИБ в пайплайны.
Базовые практики безопасности:
-
RBAC,
-
Pod Security Policy,
-
сетевые политики,
-
мониторинг,
-
авторизация пользователей,
-
ограничение привилегий.
Ошибка 11. Внедрять Kubernetes любой ценой, даже когда он не нужен
Не любой крупной компании, которая занимается разработкой, Kubernetes действительно нужен. Он показан, когда разработка идет постоянно, планируется поддержка новых релизов, нужно выполнять требования, которые диктует HighLoad.
Если же проект по разработке небольшой, внедрение Kubernetes приведет лишь к необходимости разворачивать громоздкую архитектуру только ради того, чтобы заработал простой код. Если внедряете Kubernetes, оцените, в каких проектах компании он правда нужен и принесет пользу.
При всей пользе Kubernetes это сложная технология. И все проблемы, которые я описал, в конечном итоге растут из этого. Перед тем как его внедрить, стоит подготовить архитектуру, убедиться, что в команде есть люди, которые разбираются в инструменте, и правильно оценить, на каких проектах и как Kubernetes даст свой профит. А если вы уверены в своем выборе, но хотите внедрить технологию максимально быстро, мы поможем и поддержим в настройке и использовании нашего облачного Kubernetes aaS.
Пользуясь случаем, даю линк на свою предыдущую статью про наш Kubernetes aaS на платформе Mail.ru Cloud Solutions. О том, как он устроен, что у него под капотом и что в него еще входит, кроме собственно Kubernetes.
Что еще почитать по теме:
Автор: Дмитрий Лазаренко