Начав экспериментировать с Kubernetes, многие сталкиваются с одним из самых больших заблуждений: они считают в проде K8s будет работать так же, как и в среде разработки или тестирования.
Не будет.
Когда речь заходит о Kubernetes, и вообще о контейнерах и микросервисах, существует большая разница между запуском в «лабораторных» условиях и в полноценной эксплуатации. Такая же разница, как между просто запуском и запуском с обеспечением безопасности и надёжности.
В этом утверждении есть важный исходный постулат: это проблема не Kubernetes, а всего разнообразия контейнеров и микросервисов. Развернуть контейнер относительно «просто». А использовать и масштабировать контейнеры (и контейнеризированные микросервисы) в боевой среде уже значительно сложнее.
С оркестрацией контейнеров обычно та же ситуация. Например, компания The New Stack три года назад провела исследование и выяснила, что внедрение контейнеров подтолкнуло к внедрению Kubernetes, потому что компании искали мощную технологию, способную помочь им в решении сложных эксплуатационных задач. Хотя у Kubernetes есть альтернативы, однако он быстро стал синонимом оркестрации и стандартом де-факто. И может быть большая разница между запуском K8s в песочнице и в боевых условиях.
Когда ИТ-специалисты начинают работать с контейнерами и K8s в небольших объёмах, они могут столкнуться с резким подъёмом кривой обучения, переходя от «локальной настройки» к «выкатыванию в прод». Рекомендую развеять некоторые заблуждения, прежде чем вы окажетесь в такой ситуации. Об этом нужно думать заранее.
Миф первый: запуск Kubernetes в среде разработки или тестирования гарантирует, что ваши эксплуатационные потребности будут удовлетворены
В реальности: запуск Kubernetes в среде разработки или тестирования позволяет кое-что упростить или вообще не возиться с эксплуатационной нагрузкой, которая появится при выкатывании в прод. Соображения эксплуатации и безопасности — это главные сферы, в которых проявляется разница между запуском K8s в бою и в среде разработки или тестирования. Потому что если кластер упадёт в лабораторных условиях, то в этом ничего страшного нет.
Разницу между запуском в проде и запуском в одной из сред можно сравнить с разницей между гибкостью (agility) и гибкостью в сочетании с надёжностью и производительностью. И в последнем случае придётся поработать.
Разработчики используют контейнеры, чтобы добиться гибкости работы с приложениями при разработке, а также для тестирования новых приложений и кода. А эксплуатационщикам нужно обеспечивать надёжность, масштабирование, производительность и безопасность, которая требует применения устойчивой, проверенной временем платформы корпоративного уровня.
Повышается критичность автоматизации при использовании Kubernetes (и вообще контейнеров) в бою. Нужно автоматизировать развёртывание кластеров, чтобы обеспечить повторяемость процесса и гарантировать согласованность. Также это помогает при восстановлении работы системы.
Также для операций в проде критически важно версионирование. По мере возможности управлять версиями нужно везде, в том числе в конфигурации развёртывания сервисов, политиках и инфраструктуре (посредством подхода инфраструктура-как-код). Это обеспечивает повторяемость сред. Также обязательно версионируйте образы контейнеров, не нужно применять тэг «последний» для развёртывания в средах, так можно легко прийти к дрифту версий.
Миф второй: вы обеспечили надёжность и безопасность
В реальности: если вы используете Kubernetes только в небоевых средах, то скорее всего не обеспечили, по крайней мере пока. Но не расстраивайтесь, вы к этому придёте. Это лишь вопрос планирования и проработки архитектуры до выкатывания в прод.
Очевидно, что в боевых средах выше требования к производительности, масштабированию, доступности и безопасности. Важно закладывать эти требования в архитектуру и встраивать управление безопасностью и масштабированием в планы по развертыванию K8s, в Helm-чарты и т.д.
Как эксперименты в среде разработки или тестирования могут привести к ложной уверенности?
Это нормально, когда в непродуктивных средах открыты все сетевые подключения. Возможно, даже желательно убедиться, что любой сервис может обратиться к любому другому сервису. Открытые подключения — это настройка по умолчанию в Kubernetes. Но в боевой среде такой подход вряд ли будет разумным, потому что простои и увеличение атакуемых площадей представляют очень большую угрозу для бизнеса.
Когда речь идёт о контейнерах и микросервисах, нужно потратить немало усилий, чтобы создать высоконадёжную, высокодоступную систему. В этом нам помогает оркестрация, но она не волшебная палочка. Всё то же самое касается и безопасности.
Придётся много потрудиться, чтобы защитить Kubernetes и уменьшить поверхность атаки. Очень важно перейти к модели с минимальными привилегиями и принудительным использованием сетевых политик, оставив только те каналы связи, которые нужны сервисам.
Уязвимости образов контейнеров могут быстро превратиться в критическую проблему эксплуатационной среды, а в средах разработки и тестирования опасность может быть невелика или вообще отсутствовать.
Обращайте внимание, какие базовые образы вы используете для сборки контейнеров. По мере возможности используйте доверенные официальные образы, или раскатывайте собственные. В локальной среде может быть проще использовать неизвестные образы, но это создаёт риски для безопасности. Вряд ли вам захочется, чтобы ваш Kubernetes-кластер помогал кому-то майнить крипту.
Рекомендуется относиться к безопасности контейнеров как к десятиуровневой системе, охватывающей стек контейнеров (хост и реестры), а также вопросы, связанные с жизненным циклом контейнеров (например, управление API). Подробно об этих десяти уровнях и их связи с инструментами оркестрации вроде Kubernetes рассказывается в подкасте со специалистом по безопасности из Red Hat, а также в статье Ten Layers of Container Security.
Миф третий: оркестрация превращает масштабирование в пустяк
В реальности: хотя профессионалы обычно считают оркестраторы вроде Kubernetes совершенно необходимым инструментом для масштабирования контейнеров, будет заблуждением думать, что оркестрация сразу облегчит масштабирование в эксплуатационной среде. Объём данных там гораздо больше, и вашему мониторингу тоже потребуется масштабирование. С ростом объёмов всё меняется. Невозможно удостовериться в полноценной реализации интерфейсов всех компонентов K8s, пока не выкатишь их в прод. Не получится автоматически определять, что Kubernetes работает нормально, и что API-сервер и другие управляющие компоненты масштабировались в соответствии с вашими потребностями.
Повторюсь, в средах разработки и тестирования всё может выглядеть несколько проще. И со временем придётся поработать над тем, чтобы удовлетворить потребности и поддерживать это состояние. В локальных средах легко пропустить какие-то основы, например, прописывание правильных ресурсов и ограничений на запросы. А если не сделать этого в проде, то однажды у вас может всё рухнуть.
Масштабирование кластера в ту или другую сторону — основной пример, когда задача может выглядеть просто при локальных экспериментах, но явно усложняется в боевой среде.
Продуктивные кластеры масштабировать сложнее, чем кластеры для разработки или тестирования. Хотя в Kubernetes довольно просто масштабировать приложения горизонтально, но DevOps нужно помнить о некоторых нюансах, особенно когда речь идёт о поддержании работы сервисов при масштабировании инфраструктуры. Важно убедиться, что основные сервисы, а также системы оповещения об уязвимостях и нарушении безопасности, были распределены по узлам кластера и работали со stateful-томами, чтобы данные не терялись при масштабировании вниз.
Как и в случае с другими задачами, всё дело в правильном планировании и ресурсах. Вам нужно понимать свои потребности в масштабировании, планировать, а главное — тестировать. Ваша продуктивная среда должна выдерживать гораздо более высокие нагрузки.
Миф четвёртый: Kubernetes везде работает одинаково
В реальности: различия в работе в разных средах могут быть подобно тому, как различается запуск Kubernetes на ноутбуке разработчика и на боевом сервере. Многие считают, что если K8s работает локально, то он будет работать и в любой эксплуатационной среде. Хотя он обеспечивает согласованные среды, однако в зависимости от вендора могут быть серьёзные отличия.
Для ввода кластера в промышленную эксплуатацию нужны компоненты, которых в локальных средах обычно нет: мониторинг, журналирование, управление сертификатами и учётными данными. Вам нужно это учитывать, это одна из главных проблем, усиливающих разницу между боевыми средами и средами разработки и тестирования.
Впрочем, всё сказанное относится не столько к Kubernetes, сколько к контейнерам и микросервисам в целом, особенно в гибридных облачных и многооблачных средах.
Публично-приватные внедрения Kubernetes сложнее, чем кажется на бумаге, потому что многие необходимые сервисы являются проприетарными, например, балансировщики нагрузки и файрволы. Контейнер, который прекрасно работает в локальной среде, в облаке с другим набором инструментов может вообще не запуститься, или работать в незащищённом режиме. Поэтому технологии service mesh вроде Istio привлекают столько внимания. Они обеспечивают доступность сервисов приложений везде, где работает ваш контейнер, так что вам не нужно думать об инфраструктуре — а это главная фишка контейнеров.
alexesDev
А в меня каждый раз летят помидоры, когда я говорю, что проще писать docker-compose для дева и k8s.yml для прода. Контейнеры должны быть гибкими и одинаково просто запускаться в любой среде.
JetHabr Автор
Можно и так. Но все же нам кажется, что лучше иметь одинаковую платформу для dev и prod. Контейнер будет работать везде, но deploy в K8S на Docker Swarm вы не проверите.
saboteur_kiev
Можно и так. Но ведь кроме DEV есть еще SIT, UAT, Regression?
Дев может отличаться вплоть до того, что включены отладчики, дебаг логи и кучи других вещей, которые могут не только быть отключены, но даже и не включены в прод-кандидат пакет.
ramilexe
И как это противоречит тому, чтобы иметь k8s не только на проде?
OnYourLips
Для дева все равно лучше compose. Просто должны будь еще тестовые среды с k8s перед продом, настроенные аналогичным образом.
VolCh
Чем лучше?
OnYourLips
Тем, что не надо добавлять новую сущность, не будет дополнительных проблем/усилий. Сильно снижаются требования к разработчику, как минимум на начальных этапах. Практически нулевая сложность настройки и конфигурирования. Не нужно ставить виртуалку с k8s. Значительно проще отлаживать проект на условном PHP, сделав байнд маунт.
saboteur_kiev
Виртуалки уже созданы и в случае чего автоматом создаются скриптами или тулзами, которые написали/настроили «девопсы».
И вообще не обязательно виртуалки. Даже для билда могут подниматься временные облачные кубер ноды с нужными компиляторами, собирать, прогонять тесты на других временных виртуальных нодах, и деплоиться в более стабильный тестовый енвайрнмент. Все автоматом. все быстро, ибо нет лимитированного количества виртуалок. Все недорого, ибо все лишнее останавливается.
OnYourLips
Вы меня не совсем поняли. Я под девом имею ввиду именно среду выполнения при разработке (где процесс написания кода происходит с остановленным на брекпойнте отладчиком и мгновенным запуском), а не куда проект попадает уже после работы девелопера для QA.
Естественно для QA полноценная среда, близкая к проду со всем необходимым.
VolCh
Выглядит, что если на проде k8s, то docker-compose новая сущность. И поддерживать надо будет две системы оркестрации. А насчёт практически нулевой сложности… из коробки нет чего-то вроде ingress. Виртуалка для k8s нужна ровно там где нужна и для docker-compose. И примаунтить в k8s PHP ничто не мешает.
OnYourLips
Обычно docker-compose разработчики сами кладут и он самый
простой и примитивный. О k8s половина разрабов даже не задумывается и пользоваться не умеет. Ингресса и аналогов не нужно — запускают отдельный сервис, внешние вызовы из сервиса замоканы каким-нибудь wiremock, который описан в этом же docker-compose файле.
Расскажите, как zero-configuration прокинуть вольюм с ноутбука в под без дополнительных сущностей для настройки. Я просто таких способов не знаю.
VolCh
Если отдельные сервисы, да с моками остальных, то может и есть какой-то смысл. На моей практике все, от фронтендеров и QA до CTO хотят полную систему из 30+ контейнеров (без репликации по дефолту) локально запускать. И те же фронтендеры пускай базово, пускай копипастой пишут конфиги подов, сервисов и т. д.
В docker-compose вам тоже строчку в секции volumes сервиса надо написать, а то и не одну, а то и сторонний (?) драйвер ставить
OnYourLips
Но ведь это не возможно на типичном ноутбуке разработчика с 16-32гб оперативки, если в стеке компании есть джава или если количество сервисов переваливает за сотню.
Поэтому приходится запускать при разработке сервисы изолированно (а в случае провала проектирования в виде распределенного монолита хотя бы маленькими пачками).
Просто одна строчка с маунтом до кода.
Как можно подобное сделать с k8s? Не обязательно одной строчкой, но чтобы не пришлось очень сильно конфигурировать дополнительные сущности. Цель — чтобы при изменении кода в IDE открывалась обновленная страничка.
alexesDev
HostPath делает тоже самое, что и volumes.
Только прибить под нужно к ноде.
Чуть более сложный метод — local volumes.
OnYourLips
HostPath протыянет маунт только до k8s-хоста. А надо еще и наружу вывести до основного хоста (операционки ноутбука), например каким-нибудь конфигом вагранта (первое, о чем подумал). И что, это проще, чем базовый docker-compose?
alexesDev
Я не фанат куба на машинах штатных разработчиков, потому что это в общем сложно. Просто сказал, что конкретно эта пробелма — не проблема. В деве используется миникуб, там есть minikube mount $HOME:/host на хост машину.
VolCh
Вы про запуск k8s в виртуалке? Ну, можно, наверное. У нас запускался непосредственно на хосте. minikube --native или как-то так.
OnYourLips
Тогда получается, что разработчики жестко привязаны к линуксу, а ведь у многих не он.
VolCh
А с docker-composе не привязаны? Вообще тут мне сложно сказать что-то. С современными виртуалками не работал для подобных задач. Какие-то средства наверняка есть, но, наверное, они к инфраструктуре виртуализации относятся, а не к docker/k8s. Манифесты и т. п. не должны меняться от того, что кубер в виртуалках крутится
andreyverbin
Ещё проще, compose для дева и никаких k8s для прода. Должно сработать достаточно хорошо для 99.9% проектов.
VolCh
Контейнеры просто запускаются и через docker run. Сложности со связью контейнеров друг с другом и локализацией проблем