Есть колоссальная разница между тем, чтобы поднять на коленке небольшой кластерок Kubernetes на 5 воркеров для небольшого отдела разработчиков и внедрить его в виде полноценной платформы в большой компании. В домашней лаборатории или небольшом отделе вы почти не сталкиваетесь с вынужденно тяжеловесными бизнес-процессами и необходимостью заставить корректно работать вместе не только ПО разных версий, но и множество людей.
Когда мы в Газпромбанке ввязались в цифровую трансформацию, то сразу почувствовали, что в финале это будет даже близко не «Кубером с аутентификацией», как кажется многим с опытом небольших внедрений.
Если вы тоже поняли, что большие монолиты и сложные релизы не дают вам меняться с нужной скоростью, то наша история может оказаться полезной. Я попробую рассказать, на каком стеке мы выстраивали нашу платформу, про боль и унижение Open Source и о том, как работали с командой.
Меня зовут Олег, вместе с моим коллегой Иваном мы техлидили этот проект.
Статья больше направлена на лидеров команд, которые делают первый подход к вопросу постройки платформы на базе Kubernetes, в ней не будет технического хардкора и готовых рецептов.
Жирные релизы причиняют боль
Как было раньше? Организация у нас крупная, и долгое время ИТ жило в парадигме классических больших автоматизированных систем со множеством относительно независимых команд.
Работали все по стандартной Waterfall-методологии. Да, это та самая традиционная схема, когда мы вначале долго собираем требования, потом месяцами проектируем, внедряем и радуемся. Или понимаем, что продукт уже устарел на 3 месяца, так как конкурент давно выкатил в релиз что-то более интересное. В нашем случае это стало особенно болезненно, так как у нас была огромная автоматизированная система, включавшая в себя множество банковских продуктов. Команды тянули процесс разработки месяцами, убирая фичи в бэклог, а затем выкатывая все изменения одним большим куском.
Естественно, что в условиях текущей конкуренции бизнес такой подход совершенно не устраивает. Когда тебе надо ответить на банковский продукт конкурентов, бизнес не готов ждать два месяца, бизнесу нужно еще вчера. И вот на этом этапе приходит понимание, что крупные монолиты нужно распиливать, ручные процессы автоматизировать, а вместо масштабных релизов тысячелетия — переходить к быстрой протестированной доставке небольших патчей и новой функциональности старых продуктов.
Как мы распиливали монолит
Переход от длинных релизов к быстрой и качественной доставке атомарных изменений автоматически тащил за собой внедрение DevOps-методологии, подготовку полноценного CICD и разбор огромного монолитного монстра, которого мы заботливо поддерживали много лет. Ключевое отличие от стартапов тут в том, что в банковской сфере, где многие процессы живут десятки лет, просто нельзя взять и выбросить все наработки и начать с нуля.
Что мы сделали:
Крупные автоматизированные системы распадаются на небольшие банковские продукты.
Все продукты договариваются о едином интерфейсе для взаимодействия между собой.
Продукты попадают в небольшие команды, которые самостоятельно занимаются их разработкой и поддержкой. Все DevOps‑практики и CICD они строят самостоятельно, соблюдая договорённости о внешних интерфейсах.
Помимо довольно сложных организационных изменений и разбиения на отдельные команды, нужно было организовать и технологическую платформу для всего процесса. Классическое распиливание монолита на микросервисы практически автоматом тащит за собой Kubernetes, который уже давно стал основным отраслевым стандартом. Как только мы подошли к технической стороне трансформации, нам сразу пришлось объяснять бизнесу, что он не серебряная пуля, которая магическим образом решает все ваши проблемы. Из коробки оно просто не работает в масштабах банка с его сложными процессами и требованиями.
Kubernetes даже не умеет запускать контейнеры
Первый и ключевой тезис — Kubernetes из коробки — не готовая платформа, а скорее заготовка для создания платформ.
Чтобы понять, насколько это всё похоже на конструктор, давайте просто пробежимся по общей архитектуре на изображении выше.
Распределённый state — это не Kubernetes. Несмотря на то, что это ключевой элемент, который благодаря raft-протоколу обеспечивает непротиворечивое key-value-хранение, работает он на базе ETCD. Да, пока что концепция pluggable storage backends — это только проект, но уже попадаются отдельные эксперименты, которые позволяют использовать для этого различные СУБД.
Если же говорить про среду исполнения, то Kubernetes сам по себе даже не умеет запускать контейнеры. Он полагается на CRI (Container Runtime Interface), которые через CRI plugin уже дёргают существующую имплементацию, которая поддерживается на данной ОС. Главное, чтобы она соблюдала спецификации CRI API. Поэтому в бэкенде у нас может быть как минимум Docker, containerd или CRI-O.
Kubernetes в первую очередь даёт набор задокументированных API и ряд базовых сервисов, которые обеспечивают жизненный цикл сущностей внутри кластера. Подобная гибкость — это одновременно прекрасно и больно. Когда мы внедряем Kubernetes в больших масштабах, нам нужно прорабатывать и собирать весь этот конструктор с нуля, учитывая все особенности нашей инфраструктуры, сроки поддержки каждого структурного элемента и вообще её наличие.
А давайте возьмём вендора?
Когда крупный бизнес видит зоопарк из независимых технологий, которые нужно слепить в единую надёжную конструкцию, то он сразу задаёт вопрос про вендора, который будет это внедрять и сопровождать в течение всего жизненного цикла. Поверьте, попытки устранить обычную уязвимость в каком-то подключаемом плагине сложного продукта могут стать серьёзной головной болью ИБ и инфраструктурного подразделения. Нужно пересобрать весь конструктор, убедиться, что нигде нет конфликта между структурными элементами, а заботливо вставленные костыли модули собственной разработки продолжают работать.
Так как все серверы работают на RHEL, то вполне логично не связываться со сборкой конструктора, а взять сразу готовое и протестированное решение. Все проблемы — это проблемы вендора — закрытие багов, обеспечение совместимости, поддержку обеспечивает он. У них как раз есть OpenShift, который предлагает коробочную версию Kubernetes в видении Red Hat.
Выполнил ли он наши ожидания? И да и нет. С одной стороны, это полноценная платформа, которая позволяет гораздо быстрее запуститься по сравнению с ванильным Kubernetes. С другой, она всё-таки довольно монолитна и представляет из себя классический вендор-лок, где без привлечения вендора невозможно решить многие проблемы.
Классический пример — свой собственный проприетарный CNI-плагин на OpenShift не поддерживает eBPF. Собственно, как мой коллега Иван писал про eBPF ранее, он является идеологическим наследником древнего Berkeley Packet Filter, реализуя современные подходы в реализации сетевого стека. В результате на очень высоких нагрузках сетевая подсистема OpenShift не справлялась и ограничивала всю архитектуру целиком. Возможно, сейчас это уже поправили, но таких проблем может быть множество. Всё красиво работает на презентациях при умеренных нагрузках и до тех пор, пока ты не пытаешься шагнуть немного в сторону.
Кроме этого, вполне очевидной проблемой стал чёрный лебедь, больно ударивший по доступности множества внедрённых продуктов. OpenShift стал недоступен. В результате того, что перед нами встала проблема замещения ушедших вендоров, мы стали смотреть в сторону других продуктов с Kubernetes. Одним из первых мы рассмотрели открытый опенсорсный вариант OpenShift — OKD. На первый взгляд, он лучше всего ложился на уже существующую инфраструктуру и с минимальными доработками заменял то, что уже было внедрено.
В реальности, как и OpenShift, OKD оказалась очень сильно завязана на систему private registry QUAY и репозитории Red Hat. Тут сразу всплыл ряд проблем с тем, что не очень понятно, как самим собирать из исходных кодов OKD, всё это контейнеризировать и складывать во внутренний репозиторий. И вторая, самая ключевая проблема, — это ОС. OpenShift и OKD завязаны на операционную систему. Жёсткая привязка OKD к Fedora CoreOS оказалась для нас неприемлемым риском.
Мы поняли, что придётся всё-таки строить и развивать свою платформу.
Строим свою платформу
Сразу озвучу ключевые тезисы, которые мы осознали после этого весьма непростого пути:
Создание своей платформы — это далеко не то же самое, что Kubernetes с аутентификацией на 1–2 команды.
-
Если инфраструктура изначально не заточена под эту платформу, готовьтесь к большому количеству внутренних тикетов и обращений. К действительно БОЛЬШОМУ количеству.
Для начала — мы совершили классическую ошибку недооценки сложности и слишком оптимистично оценили планы по внедрению. Если вы планируете подобное, сразу умножайте свои пессимистичные прогнозы как минимум на π. Это эмпирическое правило поможет чуть приблизиться к реальной оценке.
У нас было несколько ключевых проблем, которые нужно было решить:
Как обеспечить потребности бизнеса? Мы можем собрать сколь угодно красивую архитектуру, но она будет иметь смысл только в том случае, если будет решать задачи бизнеса. Просто радовать инженеров осознанием круто решённых проблем бессмысленно.
Обеспечение безопасности. Крайне сложная задача, которая в больших компаниях ложится на крайне непростые регламенты жизненного цикла секретов и жёсткими требованиями со стороны регуляторов. Вы когда-нибудь видели бумажный журнал ознакомления с особо критичными паролями? В крупных компаниях это может быть встроено в бизнес-процессы.
Как правильно организовать взаимодействие платформы с остальной инфраструктурой.
Декомпозиция задач и проработка архитектуры. Тут можно закопаться очень надолго только на одних согласованиях всех деталей с ИБ и другими командами.
Руководители сильно недооценивают сложность подобных внедрений, начитавшись восторженных релизов про то, как стало хорошо с Kubernetes. Реальность очень быстро бьёт по голове осознанием того, что Kubespray в небольшом офисе — это совсем не то, что придётся строить в большой компании.
Выстраиваем нашу «пирамиду Маслоу»
На этапе планирования мы выстроили отдельные кирпичики в виде «пирамиды», чтобы сразу обозначить иерархичность и вопросы, решаемые на каждом слое.
Нижний уровень
Базовый уровень — это фундамент, который обеспечивает безопасность на уровне доступа к кластеру и ресурсам. На нём держится всё остальное.
Kubernetes. Тут всё более или менее понятно — тот самый кластер, который следит за запуском контейнеров и их жизненным циклом.
Teleport — это система ролевого доступа класса PAM — Privileged Access Management. Без адекватной ролевой модели в компаниях среднего и большого размера всё очень быстро превратится в бардак и околорутовые права у случайных людей. У нас этот продукт обеспечивает безопасный доступ к ресурсам компании. Он опенсорсный, написан на Go и прекрасно реализует модели доступа.
Cilium — это CNI (Container Network Interface) плагин. Cilium использует механизм ядра eBPF, что позволяет использовать NetworkPolicy и функционал EgressIP без ущерба производительности. Так же Cilium из коробки бесплатно предоставляет средства мониторинга сетевой активности — Hubble. Ну и вишенкой на торте является интеграция с Istio Service Mesh.
Средний уровень
Следующий уровень — это уровень эксплуатации со стороны поддержки самого Kubernetes. На этом уровне решаются уже потребности поддержки Kubernetes. В первую очередь — это мониторинг, работа с логами. И во вторую очередь — это поддержание конфигураций в актуальном состоянии, обеспечение эксплуатационной конфигурации. Здесь вы нарезаете tenant’ы и эксплуатируете саму платформу.
Argo CD — обеспечивает доставку изменений в полном соответствии с парадигмой GitOps.
ELK-стек — реализует мониторинг самой инфраструктуры, хранение и анализ логов.
Верхний уровень
Самый верхний уровень — это то, ради чего это всё затевалось. Это уровень потребностей бизнеса, пользователей вашей платформы. И на самом деле потребности бизнес-пользователей и DevOps-инженеров более или менее пересекаются. У них также есть потребность в мониторинге, в контроле управления конфигурациями и потребность работать с логами.
Добавляем людей
С техническим стеком мы определились, теперь надо начинать есть слона по кусочкам.
Нижний уровень у нас описывается в классическом подходе Infrastructure-as-a-code. Фундаментальный базис самый «холодный», так как меняется очень редко в процессе эксплуатации. Ansible оказался для нас максимально подходящей технологией, которая позволила сделать всё максимально идемпотентно и самодокументируемо. При необходимости мы сможем быстро тиражировать всю эту инфру.
На среднем уровне мы решили пойти по методологии GitOps. Методология в первую очередь не про то, что вы всё засунули в репозиторий и радуетесь. Её важнейшее свойство — reconciliation, которое говорит о том, что вы всегда можете быть уверены в том, что состояние, декларативно описанное в коде, соответствует реальному состоянию системы. То есть процесс построен именно так, что мимо никак не пройти. Залез, поменял что-то руками, а реконсиляция всё поотменяла и привела к описанному в коде состоянию. В основу этого слоя отлично лёг ArgoCD.
На верхнем уровне самые горячие, «красные» конфиги пользователей. Пользователи постоянно их изменяют в процессе эксплуатации вашей платформы. Тут уже всё довольно просто — это веб-интерфейсы программных продуктов, какие-то операторы, Grafana в tenant и прочее.
Когда мы всё это нарезали на слои, мы начали думать, какая же команда и какого уровня нужна для этого? Мы пришли к выводу, что нужна команда «единорогов», с высоким уровнем софт-скилов. Кто не в курсе, единорогами в HR называют специалистов широкого профиля, которые имеют хард-скилы в большей части ИТ. В процессе развития этого проекта мы поняли ещё один важный момент — крутым чувакам с хорошими софт-скилами нужно непрерывно подкидывать интересные задачи, иначе они заскучают. Для таких специалистов скука и рутина — это ключевой триггер к смене работы. Поэтому, если вы не продумали стратегию на несколько лет вперёд, то после первых сложных этапов и начала рутинной эксплуатации эта команда у вас разбежится.
Локализуем
В банковской сфере сборка Open Source — это история про боль и унижение. По соображениям банальной безопасности вы просто не можете взять начать развёртывать рандомный пакет из репозитория условного vasyaxx22. Можно сколько угодно негодовать по поводу бюрократии со стороны ИБ, но с современными проектами быстро начинаешь видеть насколько глубока кроличья нора на самом деле.
Особенно это стало ощущаться после того, как адекватные мейнтенеры стали не нужны разработчикам дали удобные инструменты контейнеризации. Мы как-то вытащили проект, чтобы изучить, а там происходит сборка размером в 7 гигабайт. Внутри что-то страшное и плохо подходящее для аудита. Или множество других проектов, которые сильно завязаны через git submodules на другие проекты в GitHub. То есть в итоге надо клонировать в безопасный периметр ещё больший объём зависимостей и всё подвергать аудиту.
Мы подключились к рабочей группе компаний, которые решали, как дальше жить с импортозамещённым стеком и активно в этом поучаствовали. В итоге пришли к выводу, что RedOS оптимально покроет наши потребности. Как минимум часть компонентов мы сможем не собирать самостоятельно, а брать готовыми из пакетов RedOS.
Кроме этого, если в вас есть аналогичные требования регулятора как к критической инфраструктуре с необходимостью регистрироваться в Минцифре, обязательно рекомендую пройти по этой ссылке и посмотреть на типичные случаи отказов в регистрации в Минцифры. Там, например, есть варианты, когда компания выбрала OracleDB для хранения данных пользователей, так как работала с ней очень давно. В итоге — отказ из-за несоответствия требованиям.
Краткие итоги
В первую очередь определитесь, какие бизнес-задачи и какую часть пайплайнов DevOps вы планируете решить своим Kubernetes-кластером.
Оцените сложность задачи, возьмите пессимистичный прогноз и умножьте его ещё на эмпирический коэффициент. Скорее всего, вы всё равно ошибётесь в лучшую сторону.
Можно рекомендовать Teleport, как базовое открытое инфраструктурное решение PAM. Его можно очень хорошо готовить, даже в масштабах большого энтерпрайза, прикручивая интеграции с keycloak и со множеством других identity provider’ов.
Уделите внимание безопасности на этапе проектирования. Но не в виде «а давайте сделаем красиво», а в виде реальных бизнес-процессов, когда одному подразделению нужно завести учётную запись в БД, другому надо безопасно получить пароль и как-то использовать. Пройдитесь по всему жизненному циклу секретов и организации доступов. Самая боль скрыта в бизнес-процессах, а не технологиях.
Берегите команду. Помните, что есть команды для сложных широких задач, а есть для рутинной эксплуатации. Кормить первых рутиной — верный путь потерять их через полгода.
Open Source — это очень больно. Мейнтейнить всё это самостоятельно запредельно сложно, особенно если есть регуляторные требования. Сборка — чёрная дыра из множества проектов, которые неочевидно тащат что-то из кучи источников. Если есть возможность использовать сертифицированный источник пакетов — постарайтесь так и сделать.
Ещё раз пересчитайте сложность проекта, досыпьте коэффициентов.