GlowByte Media

Опыт внедрения Kubeflow в кластере Kubernetes

В статье мы рассказали о внедрении ML-платформы Kubeflow в кластере Kubernetes на площадке заказчика. 
Инструменты, которые мы использовали в рамках проекта, являются программным обеспечением с открытым исходным кодом, поддерживаются авторами и сообществом. Платформа виртуализации - Hyper-V. Инструменты, созданные для облаков, не всегда быстро и легко разворачиваются, а предугадать все риски невозможно. В статье мы рассказали про поиск подходящей архитектуры, подбор версий компонентов, общие технические аспекты установки кластера Kubernetes, OKD и настройки Kubeflow. Мы описали исследование и опыт внедрения, выделив проблемные места и моменты, на которые стоит обратить внимание.
Список статей и материалов по теме можно найти в секции “Дополнительные материалы” в заключении статьи.

Требования к платформе

С полным обзором бизнес требований и историй платформы можно ознакомиться на https://vc.ru/ml/306136-kak-my-v-banke-sankt-peterburg-vnedryali-platformu-mashinnogo-obucheniya) здесь приведем краткий вариант.

Во-первых, банку было важно перейти от хаоса в жизненном цикле моделей к вменяемому ModelOps с описанием, гайдлайнами и методологией без сильной привязки к языку программирования. Во-вторых, иметь четкую и прозрачную ролевую модель и разграничение ресурсов, дабы никто не смог положить работу всех подразделений или убить Prod одной неудачной строчкой кода. Ну и напоследок, бесперебойно работать и иметь SLA с поддержкой более компетентных товарищей. Из дополнительных требований со стороны информационной безопасности была работа on-prem. Ряд моделей работал на персональных данных и производных из них, поэтому их передача в облако была невозможна (или сопряжена с долгими циклами согласования и процедурами обезличивания).

На рынке представлено много поставщиков целевых решений. Начиная от таких дорогостоящих тяжеловесов, как SAS и IBM, заканчивая стартапами с достаточно перспективными разработками наподобие Hopsworks. И вот цена - это главное ограничение, с которым мы столкнулись. У банка на тот момент не было большого количества моделей, и не было предпочтений в выборе какого-то конкретного поставщика. Поэтому было принято решение остановиться на опенсорсных решениях, которые не требуют ежегодных подписок или единовременных крупных платежей вендорам. Кроме того, т.к. направление машинного обучения - достаточно новое для банка, никто не готов был вкладываться в дорогие решения вендоров. Поэтому решили начать с малого, а в дальнейшем масштабироваться по мере появления новых задач и ресурсов.

Все эти требования, и по нашему мнению, и по мнению привлеченных для анализа контрагентов, вполне закрывались решением на основе Kubernetes: OKD (как бесплатная замена OpenShift) в качестве оркестратора, KubeFlow + Jupyter как среда ModelOps. KubeFlow прекрасно интегрируется с системами версионирования кода, что позволит нам закрыть такие задачи, как ускоренный повторный запуск и Code Review. Кроме того, функционал Pipelines позволяет проводить множество параллельных экспериментов, не отвлекаясь на ожидание завершения расчетов. Интегрированный Katib также позволяет не ждать и заниматься подбором гиперпараметров моделей в параллели с основной работой. Jupyter - де-факто стандартная IDE при работе с машинным обучением, к тому же, поддерживающая расширение функционала через плагины и сниппеты.

ML платформа


Работа с Kubeflow предусматривает сопровождение полного жизненного цикла модели, от момента ее создания, переобучения, подбора гиперпараметров до вывода в промышленную эксплуатацию. Единый веб-интерфейс, простой запуск Jupyter ноутбуков с выделением ресурсов, пайплайны c визуализацией в веб интерфейсе, ролевая модель для многопользовательской работы. Микросервисная архитектура, на которой построен Kubeflow - это плюс к масштабируемости и отказоустойчивости. Заказчик хотел единую среду разработки и развертывания моделей, одновременно удобную для работы и обслуживания, Kubeflow отлично подходит под данные требования. 
Kubeflow пригоден в облаках и on premise, для работы нужен только кластер Kubernetes или OpenShift. Как многие отличные решения, Kubeflow разрабатывали инженеры из команды Google первоначально для работы в GCP, но, как показала наша практика, работает платформа в Azure и AWS и на земле. Но сначала нужно ее установить.

Kubeflow Pipelines


Очень важный компонент платформы, ради этого функционала нам и пришлось пройти путь от OKD до Kubernetes и посмотреть все возможные варианты архитектуры.
Kubeflow Pipelines - это система для построения ML процессов в виде асинхронных графов задач (исполняемого кода). С первого взгляда может показаться, что это очередной аналог Aifrlow, однако, KP специализируется именно на ML задачах. Он позволяет максимально скрыть от DS разработчика инфраструктурные задачи и проблемы, при этом предоставляя ему доступ к k8s кластеру и его ресурсам из своего Jupyter ноутбука для запуска процессов моделирования.
Пайплайны позволяют выстроить процесс, в котором каждая задача исполняется на кластере, при этом сохраняя входные/выходные артефакты своей работы внутри Kubeflow. Все артефакты визуализируются и их можно просматривать через UI, что позволяет проводить эксперименты и сравнивать разные модели.

 Каждая задача процесса - это некоторый Python код, обернутый в Kubeflow Component (декларативное описание задачи - входы, выходы, сохраняемые артефакты, параметры запуска), работающий в отдельном контейнере на кластере. Для создания такого компонента приходится немного спускаться в инфраструктуру и создавать образ контейнера, в котором будет работать код, спецификацию компонента (yaml с описанием параметров k8s) и, собственно, декорировать код в Kubeflow Component. Это может показаться достаточно сложным для обычного DS разработчика, но на деле все сводится к заполнению конфигурационного файла по шаблону и не требует глубоких познаний в k8s. А взамен мы получаем полностью переиспользуемые компоненты ML процесса, в которых нам не надо ничего настраивать, чтобы их запустить. Мы можем создать компонент "Подготовка и очистка данных", параметризировать его в части используемых данных и применять его во всех наших пайплайнах, импортировав и заполнив параметры.

Также, стоит упомянуть про базовые функции оркестратора процессов: запуск по расписанию, параметризация вызова, параллельные задачи, циклы из задач и тп.; все они реализованы в KP.

OKD vs. Kubernetes


В первоначальной архитектуре, как инструмент для оркестрации контейнеров, был заложен OKD 3.11. OKD - это опенсорсный аналог Openshift, функционал аналогичный, но нет издержек на подписку. Необходимы были специалисты с хорошим знанием Kubernetes, инфраструктурная часть в общей массе на Windows. У OKD в данных условиях ниже порог вхождения для обслуживающего персонала, всю систему можно обслуживать через веб-интерфейс. Плюс много полезных функций в OKD работают из коробки, Kubernetes коллег сильно настораживал.

Наш роудмап


По инфраструктурной составляющей


Благодаря заказчику у нас были очень комфортные условия, все, что было выше железа, можно было устанавливать и настраивать. На старте у нас было два железных сервера и задача установить на нем OKD 3.11 + Kubeflow. В промежуточной архитектуре сервера были переделаны в гипервизоры, а в итоговой архитектуре три гипервизора.

В поисках наилучшего решения мы прошли путь от OKD 3.11 до OKD 4.4, а потом вернулись к истокам и развернули Kubernetes. Ниже таблица релизов, в ней представлены описания тестовых и боевых стендов, а также причина, по которой конфигурация была отвергнута. Я виртуально разделил варианты архитектуры на релизы, в зависимости от кардинальной смены компонентов.

Опускаю описание фазы RND между релизами, чтобы не вылететь за рамки данной статьи. В нашем случае RND заключалось в изучении документации, форумов и всех возможных ресурсов, связанных с установкой Kubeflow, промежуточные инсталляции на стендах, перебор версий, перепиливание конфигурации и тесты, тесты, тесты. На архитектуру и размер боевых стендов также влияла готовность инфраструктуры заказчика, коллеги наращивали мощности, мы готовили полнофункциональное решение, постоянно шли друг другу навстречу.

Релиз 1.х


Мы стартанули с двух железных серверов, это были хосты с Oracle Linux, на них развернули OKD 3.11 и начали эксперименты со средой исполнения контейнеров, различные варианты хранилища для кластера NFS, Gluster, Ceph. Разные сборки и версии Kubeflow. 
Здесь мы по очереди уперлись в ряд несовместимостей, то старая версию Kubernetes под капотом у OKD не работает с нужной версией Kubeflow, то среда исполнения контейнеров не работает со сборкой Agro в развернутой версии Kubeflow. Для Argo мы перебрали несколько вариантов Argo executor: docker, kubelet, kubernetes api, pns. Кроме траблшутинга мисматча версий и компонентов, мы опробовали и разные варианты хранилища для кластера. В условиях такой инсталляции победил NFS. В итоге, простая установка OKD на два хоста себя исчерпала, полный функционал с данным набором компонент реализовать не удалось, да и версия OKD 3.11 сильно устарела.

Релиз 2.х


После фазы RND, следующий релиз тестового стенда мы собрали в облаке AWS. Он получился удачным: кластер OKD 4.4 из шести машин, среда исполнения контейнеров CRi-O, модифицированная установка Kubeflow с изменением бэкенда запуска пайплайнов KFP-Tekton. Но и в этом релизе у нас были некоторые ограничения, мы были жестко завязаны на версиях компонентов.
На стенде у заказчика все также было два сервера, но OKD 4.x на два хоста невозможно, сервера было решено виртуализировать. Платформа для виртуализации в реалиях проекта была Hyper-V, нам предстояло настроить виртуальные машины и установить на них кластер OKD.

Установить OKD 4.x в облаке (AWS или Azure) - это просто и быстро, нужно всего лишь скачать пакеты для установки, внести данные аккаунта, доменное имя, ssh ключ, и в сгенерированном yaml файле прописать характеристики и количество мастер и воркер нод кластера. 

Дальше установщик работает с api облака, сам качает нужный образ ОС, нарезает виртуальные машины, подкидывает им необходимые конфигурации, не нужно думать о балансировщике, настройке DNS и хранилище, все терраформирует инсталлятор. Через 20 минут получаем готовый кластер.

Я специально так подробно остановился на данном пункте - в реалиях UPI(User Provided Infrastructure) установки, bare-metal или на виртуальные машины часть этой коробочной автоматизации просто не работает.

Вернемся к боевому стенду, после виртуализации у нас в распоряжении были два хоста на Hyper-V, управляемые через веб интерфейс локального облака Azure. С такой платформой установщик OKD нативно работать отказался, необходимые технические пререквизиты для установки были выполнены руками. 

Мы определили и создали необходимые записи DNS, нарезали все необходимые виртуальные машины, подготовили и загрузили образы Fedora CoreOS(далее FCOS), развернули Gluster на трех дополнительных узлах, подготовили балансировщик. 
Далее механика развертывания кластера была следующая: запускаем установщик, генерируем yaml файл с шаблоном кластера, модифицируем его под наши нужды, генерируем на базе данного файла ignition конфиги для FCOS, закидываем их на веб сервер, запускаем виртуальные машины, прописываем что и откуда тянуть, Федора подхватывает конфигурацию, установка пошла.

Кратко пробегусь по трудностям, с которыми мы столкнулись на этом этапе

В данном сегменте сети не было dhcp сервера, свой мы развернуть не могли из-за политик безопасности. Для всех виртуальных машин с FCOS адреса и настройки пришлось прописывать руками, было несколько попыток установки и каждый раз много ручного вмешательства. Мы работаем в инфраструктуре банка, все сервера за прокси, все сетевые доступы необходимо согласовывать. В документации платформы описаны далеко не все адреса, которые необходимо добавить в вайтлист, некоторое время ушло на траблшутинг и новые согласования. Траблшутинг UPI установки тоже был с “сюрпризами”, логи установки OKD можно собрать только через инсталлятор, подключение на хосты через ssh в момент установки не даст ощутимой пользы, FCOS - минималистичный дистрибутив, набор доступных инструментов ограничен, система собрана для запуска контейнеров, сбор метрики для анализа был не очень удобный и прозрачный. Для установки OKD нужной версии необходима FCOS определенной версии с двумя наборами образов, один для загрузки самой ос, другой для установки с конфигурацией, которую система берет по сети. OKD определенной версии использует под капотом определенную версию Kubernetes и определенную версию среды запуска контейнеров, что важно для запуска пайплайнов KFP-tekton в модифицированной под работу в OKD версии Kubeflow. Шаг влево, шаг вправо и ничего не работает.

Несмотря на то, что все технические условия были соблюдены и тестовый стенд успешно работал, на земле кластер не собрался: анализ логов показал, что часть образов очень долго скачиваются и еще часть не может стартовать, установщик уходит в таймаут, и попытка установки повторяется по кругу. Коллеги проблем с сетью не диагностировали, мы провели несколько попыток с различными настройками, итог был один, инициализация мастер узлов не проходит, кластер не взлетает.

В бэклоге еще куча работы, накопились задачи, которые необходимо проверять на боевом кластере: интеграции с внешними системами, подготовка образов Jupyter, проброс GPU, много мелких настроек. Кластер не готов, причину установить не удается. 

Итог: Сроки горят, заказчик расстроен, команда демотивирована. На RND и долгие тесты времени нет, решение нужно вчера.

Релиз 3.0


Все рано или поздно возвращаются домой. Виртуальные машины на Ubuntu Server 20.04, система оркестрации контейнеров Kubernetes 1.19, среда исполнения контейнеров Docker. Коллеги для удобства обслуживания просили удобный интерфейс, в качестве UI мы использовали Rancher 2.5. Платформа для ML - Kubeflow версии 1.2.0. В кластере был развернут Nexus и классический стек для мониторинга Prometheus, Grafana, Alertmanager. Затем настроены интеграции внешними системами и источниками данных. Gluster был уже настроен со времен прошлого захода.

В данном релизе весь функционал заработал из коробки. Kubernetes кластер мы развернули с помощью известного инструмента Kubespray, немного его доработав под нашу установку. В кластере есть виртуальные машины с GPU, нам пригодился кластер оператор, воспользовались наработками коллег из Nvidia, необходимые ansible роли для установки драйверов и NVIDIA GPU Operator мы взяли из проекта DeepOps и официальной документации.

Были некоторые проблемы с пробросом GPU, по большей части, со стороны Hyper-V, все успешно решилось на стороне обслуживающей команды. 
Все проходило нормально, мы спешили разобрать бэклог, начали активно работать с подготовкой контейнеров. При операциях с большими образами Jupyter, а у нас есть сборки с Cuda и они достигают 16Гб, явно начало проседать быстродействие кластера, ноутбуки спаунились очень долго, PV в Glaster отрастали по 3-5 минут. Мы грешили на сеть, развернули Nexus в кластере, но проблема не решилась.

Это был рейд, точнее Storage Pool. При настройке гипервизора не самые быстрые 10-терабайтные жесткие диски объединили в storage pool получив показатели по емкости, но не по скорости чтения записи. Виртуальные машины с мастер нодами с самого начала находились на ssd - это было одно из требований на старте проекта, которое немного сбило нас с толку, кластер местами работал нормально, местами не очень. Разбирать кто и почему так сделал времени уже не было, потратив некоторое время на перенос виртуальных машин с гипервизора на гипервизор и пересборку дисков в Raid 10 мы получили нормальную производительность.