Всем привет,
В статье мы рассказали о внедрении ML-платформы Kubeflow в кластере Kubernetes на площадке заказчика.
Инструменты, которые мы использовали в рамках проекта, являются программным обеспечением с открытым исходным кодом, поддерживаются авторами и сообществом. Платформа виртуализации - Hyper-V. Инструменты, созданные для облаков, не всегда быстро и легко разворачиваются, а предугадать все риски невозможно. В статье мы рассказали про поиск подходящей архитектуры, подбор версий компонентов, общие технические аспекты установки кластера Kubernetes, OKD и настройки Kubeflow. Мы описали исследование и опыт внедрения, выделив проблемные места и моменты, на которые стоит обратить внимание.
Список статей и материалов по теме можно найти в секции “Дополнительные материалы” в заключении статьи.
Во-первых, банку было важно перейти от хаоса в жизненном цикле моделей к вменяемому ModelOps с описанием, гайдлайнами и методологией без сильной привязки к языку программирования. Во-вторых, иметь четкую и прозрачную ролевую модель и разграничение ресурсов, дабы никто не смог положить работу всех подразделений или убить Prod одной неудачной строчкой кода. Ну и напоследок, бесперебойно работать и иметь SLA с поддержкой более компетентных товарищей. Из дополнительных требований со стороны информационной безопасности была работа on-prem. Ряд моделей работал на персональных данных и производных из них, поэтому их передача в облако была невозможна (или сопряжена с долгими циклами согласования и процедурами обезличивания).
На рынке представлено много поставщиков целевых решений. Начиная от таких дорогостоящих тяжеловесов, как SAS и IBM, заканчивая стартапами с достаточно перспективными разработками наподобие Hopsworks. И вот цена - это главное ограничение, с которым мы столкнулись. У банка на тот момент не было большого количества моделей, и не было предпочтений в выборе какого-то конкретного поставщика. Поэтому было принято решение остановиться на опенсорсных решениях, которые не требуют ежегодных подписок или единовременных крупных платежей вендорам. Кроме того, т.к. направление машинного обучения - достаточно новое для банка, никто не готов был вкладываться в дорогие решения вендоров. Поэтому решили начать с малого, а в дальнейшем масштабироваться по мере появления новых задач и ресурсов.
Все эти требования, и по нашему мнению, и по мнению привлеченных для анализа контрагентов, вполне закрывались решением на основе Kubernetes: OKD (как бесплатная замена OpenShift) в качестве оркестратора, KubeFlow + Jupyter как среда ModelOps. KubeFlow прекрасно интегрируется с системами версионирования кода, что позволит нам закрыть такие задачи, как ускоренный повторный запуск и Code Review. Кроме того, функционал Pipelines позволяет проводить множество параллельных экспериментов, не отвлекаясь на ожидание завершения расчетов. Интегрированный Katib также позволяет не ждать и заниматься подбором гиперпараметров моделей в параллели с основной работой. Jupyter - де-факто стандартная IDE при работе с машинным обучением, к тому же, поддерживающая расширение функционала через плагины и сниппеты.
Kubeflow пригоден в облаках и on premise, для работы нужен только кластер Kubernetes или OpenShift. Как многие отличные решения, Kubeflow разрабатывали инженеры из команды Google первоначально для работы в GCP, но, как показала наша практика, работает платформа в Azure и AWS и на земле. Но сначала нужно ее установить.
Kubeflow Pipelines - это система для построения ML процессов в виде асинхронных графов задач (исполняемого кода). С первого взгляда может показаться, что это очередной аналог Aifrlow, однако, KP специализируется именно на ML задачах. Он позволяет максимально скрыть от DS разработчика инфраструктурные задачи и проблемы, при этом предоставляя ему доступ к k8s кластеру и его ресурсам из своего Jupyter ноутбука для запуска процессов моделирования.
Пайплайны позволяют выстроить процесс, в котором каждая задача исполняется на кластере, при этом сохраняя входные/выходные артефакты своей работы внутри Kubeflow. Все артефакты визуализируются и их можно просматривать через UI, что позволяет проводить эксперименты и сравнивать разные модели.
Каждая задача процесса - это некоторый Python код, обернутый в Kubeflow Component (декларативное описание задачи - входы, выходы, сохраняемые артефакты, параметры запуска), работающий в отдельном контейнере на кластере. Для создания такого компонента приходится немного спускаться в инфраструктуру и создавать образ контейнера, в котором будет работать код, спецификацию компонента (yaml с описанием параметров k8s) и, собственно, декорировать код в Kubeflow Component. Это может показаться достаточно сложным для обычного DS разработчика, но на деле все сводится к заполнению конфигурационного файла по шаблону и не требует глубоких познаний в k8s. А взамен мы получаем полностью переиспользуемые компоненты ML процесса, в которых нам не надо ничего настраивать, чтобы их запустить. Мы можем создать компонент "Подготовка и очистка данных", параметризировать его в части используемых данных и применять его во всех наших пайплайнах, импортировав и заполнив параметры.
Также, стоит упомянуть про базовые функции оркестратора процессов: запуск по расписанию, параметризация вызова, параллельные задачи, циклы из задач и тп.; все они реализованы в KP.
В поисках наилучшего решения мы прошли путь от OKD 3.11 до OKD 4.4, а потом вернулись к истокам и развернули Kubernetes. Ниже таблица релизов, в ней представлены описания тестовых и боевых стендов, а также причина, по которой конфигурация была отвергнута. Я виртуально разделил варианты архитектуры на релизы, в зависимости от кардинальной смены компонентов.
Опускаю описание фазы RND между релизами, чтобы не вылететь за рамки данной статьи. В нашем случае RND заключалось в изучении документации, форумов и всех возможных ресурсов, связанных с установкой Kubeflow, промежуточные инсталляции на стендах, перебор версий, перепиливание конфигурации и тесты, тесты, тесты. На архитектуру и размер боевых стендов также влияла готовность инфраструктуры заказчика, коллеги наращивали мощности, мы готовили полнофункциональное решение, постоянно шли друг другу навстречу.
Здесь мы по очереди уперлись в ряд несовместимостей, то старая версию Kubernetes под капотом у OKD не работает с нужной версией Kubeflow, то среда исполнения контейнеров не работает со сборкой Agro в развернутой версии Kubeflow. Для Argo мы перебрали несколько вариантов Argo executor: docker, kubelet, kubernetes api, pns. Кроме траблшутинга мисматча версий и компонентов, мы опробовали и разные варианты хранилища для кластера. В условиях такой инсталляции победил NFS. В итоге, простая установка OKD на два хоста себя исчерпала, полный функционал с данным набором компонент реализовать не удалось, да и версия OKD 3.11 сильно устарела.
На стенде у заказчика все также было два сервера, но 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, закидываем их на веб сервер, запускаем виртуальные машины, прописываем что и откуда тянуть, Федора подхватывает конфигурацию, установка пошла.
Несмотря на то, что все технические условия были соблюдены и тестовый стенд успешно работал, на земле кластер не собрался: анализ логов показал, что часть образов очень долго скачиваются и еще часть не может стартовать, установщик уходит в таймаут, и попытка установки повторяется по кругу. Коллеги проблем с сетью не диагностировали, мы провели несколько попыток с различными настройками, итог был один, инициализация мастер узлов не проходит, кластер не взлетает.
В бэклоге еще куча работы, накопились задачи, которые необходимо проверять на боевом кластере: интеграции с внешними системами, подготовка образов Jupyter, проброс GPU, много мелких настроек. Кластер не готов, причину установить не удается.
Итог: Сроки горят, заказчик расстроен, команда демотивирована. На RND и долгие тесты времени нет, решение нужно вчера.
В данном релизе весь функционал заработал из коробки. 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 мы получили нормальную производительность.
План Б
Когда у нас возникли первые сомнения что мы не не соберем боевой стенд на OKD4.4 + Kubeflow, было принято решение подстраховаться и проработать план Б. Так как задача стояла собрать платформу для ML на базе opensource, то единственный вариант это сделать без Kubeflow - это подобрать отдельные инструменты, настроить между ними интеграции и CI\CD процессы. Резервный стек: Jupyterhub, MLFlow, Airflow, Gitlab, Graylog, Grafana, Prometheus все это или в ванильном Kubernetes или в OKD, но уже без привязки к версиям. Работает этот стек просто: IDE для разработки моделей в Jupyter, отслеживание экспериментов в MLFlow, запуск моделей по расписанию в Airflow, процессы CI\CD реализуем в Gitlab, логи, и мониторинг системы и моделей собираем с помощью Graylog, Grafana, Prometheus. План Б на фоне обещанного Kubeflow выглядел не так монолитно, был отвергнут заказчиком и мы вернулись к связке Kubeflow + Kubernetes.
Jupyter
Еще часть интересных задач мы реализовали в рамках кастомизации образов Jupyter. Задача была поставить большой набор библиотек, подготовить разные версии python и собрать отдельный образ с R-studio. В процессе сборки возникало много конфликтов с зависимостями, часть пакетов ставилась через pip, часть через git и conda, много собиралось из исходного кода с помощью make. К этому дикому миксу мы добавили пакеты с cuda, такой образ собирался 2-3 часа. Сначала в качестве базового образа использовался Debian, но в рамках данного дистрибутива не хватало готовых пакетов, история с зависимостями повторялась. В итоге сборку мы продолжали на базовом образе Cuda с Ubuntu 18.04 под капотом.
Так же был собран легковесный образ без GPU и образ R-Studio. Позже в эти образы был интегрирован Dask и плагины для Jupyter lab.
Настройка Kubeflow
У нас были специфические требования к ролевой модели, завязанной на распределении пользователей в группах в AD, Kubeflow из коробки пробрасывать профили так не умел. Мы отключили автоматическое создание именных профилей и прописали пользователей в определенные пространства имен руками, авторизацию в систему настроили на уровне фильтра групп. Настроили ограничения на использование ресурсов в пространствах имен.
Мы используем кастомные образы Jupyter, поправили configmap спаунера, убрали настройки из коробки, добавили свои, образы пулим из локального nexus.
Под капотом еще есть Knative-serving для запуска serverless моделей, пришлось повозиться с настройками прокси для корректного запуска.
Dask dashboard. В контейнере с dask включили jupyter-proxy и настроили через него дашборд. Пришлось немного повозиться с whitelist для доступа к дашборду. В итоге просто написали обычную лямбда функцию на питоне, которая динамически добавляет src host и порт в whitelist. И еще мы отключили istio sidecar injection в неймспейсе, где поднимаются ноутбуки с dask. Dask реализован в двух вариантах, можно запускать напрямую в кластере, а можно через UI Jupyter`а используя зашитый в образ extension.
Что умеет платформа после доработок:
На уровне Kubernetes ничего сильно менять не пришлось, в основном стандартные настройки и установка необходимых инструментов. Из того, что заняло ресурс: настройка RBAC, интеграция с AD, DNS, настройка сертификатов для https, подкручивание proxy\noproxy, ldaps и сертификаты. Как софт старт Storage Class использовал NFS, позже подключили Gluster используя heketi. Heketi живет в подах в самом кластере, настроен в StatefulSet для доступности.
Мы реализовали достаточно простую, но эффективную ролевую модель с разделением ресурсов и неймспейсов между подразделениями, а также с двумя уровнями пользователей: пользователи системы, которые могут работать в системе и производить эксперименты, и продвинутые пользователи, которым доступны инструменты для вывода моделей в выделенную зону prod и работа в этой зоне. Предоставление и отзыв доступа к платформе осуществляется через предоставление пользователю группы в AD по действующим в банке процедурам.
Мы наладили процесс поддержки пользователей через выделенных администраторов системы с интеграцией с поддержкой контрагента через JIRA.
Не бывает маленьких проектов на базе Kubernetes, не бывает простых проектов с open source. Для DS и ML практик зачастую вообще нет готовой или проверенной методологии. Платформы и инструменты только создаются, активно развиваются, переходят в микросервисную архитектуру, в облака и в serverless. Любое активно развивающееся направление требует свежих, революционных идей и людей, готовых к подобным вызовам. Для нашей команды - это интересный опыт, который поможет в реализации следующих проектов на базе Kubernetes и OpenShift. Идея единой платформы, которой выступил Kubeflow, очень интересна и перспективна, концепцию интересно развивать и предлагать в качестве базы для проектов среднего масштаба. Надеюсь, данный опыт поможет нашим клиентам еще быстрее и эффективнее решать бизнес задачи, а нам предлагать им интересные решения.
Мы очень любим Jupyter, но не очень любим собирать кастомные образы, да и легковесным такой контейнер назвать тяжело.
Минусы нашлись и у основного инструмента автоматизации, Kubeflow pipelines: относительно высокий порог вхождения (выше чем у airflow, luigi и подобных инструментов), данный инструмент неудобен для оркестрации простых задач/функций (слишком много кода и конфигов приходится писать). В текущей реализации работает, но все еще нуждается в доработках и может стать оптимальным решением.
OpenShift, OKD, Kubernetes
https://docs.nvidia.com/datacenter/kubernetes/openshift-on-gpu-install-guide/
https://www.openshift.com/blog/simplifying-deployments-of-accelerated-ai-workloads-on-red-hat-openshift-with-nvidia-gpu-operator
https://github.com/openshift/okd
https://docs.okd.io/latest/installing/installing_bare_metal/installing-bare-metal.html#creating-machines-bare-metal
https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/
https://docs.okd.io/latest/installing/installing_bare_metal/installing-restricted-networks-bare-metal.html#installation-configure-proxy_installing-restricted-networks-bare-metal
https://thenewstack.io/tutorial-install-kubernetes-and-kubeflow-on-a-gpu-host-with-nvidia-deepops/
Kubeflow
https://www.kubeflow.org/
https://github.com/IBM/KubeflowDojo
https://github.com/kubeflow
https://www.youtube.com/watch?v=3rHF9iOpmkg&list=PLaR6Rq6Z4Iqe6ADimTyxufa_O3VL3vkXW&index=171&ab_channel=OpenShift
https://towardsdatascience.com/make-kubeflow-into-your-own-data-science-workspace-cc8162969e29
https://docs.containerplatform.hpe.com/52/reference/kubernetes/kubernetes-administrator/kubeflow/kubeflow.html
https://github.com/argoproj/argo-workflows/blob/master/docs/workflow-executors.md
GlusterFS
https://www.gluster.org/
https://github.com/heketi/heketi
Jupyter и подготовка образов
https://github.com/iot-salzburg/gpu-jupyter
https://zero-to-jupyterhub.readthedocs.io/en/latest/
https://tanzu.vmware.com/developer/blog/data-science-with-python-jupyterhub-on-kubernetes-part-1/
https://tanzu.vmware.com/developer/blog/data-science-with-python-jupyterhub-on-kubernetes-part-2/
https://blog.jupyter.org/how-to-deploy-jupyterhub-with-kubernetes-on-openstack-f8f6120d4b1
Dask
https://kubernetes.dask.org/en/latest/
https://docs.dask.org/en/latest/
В статье мы рассказали о внедрении 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 мы получили нормальную производительность.
Краткое описание релизов
Тестовая среда | Боевая среда |
Релиз: 1.0 Платформа: Облако Azure OC: CentOS 7 Количество хостов: 1 Платформа оркестрации контейнеров: OKD 3.11 Версия Kubernetes: 1.14 Среда исполнения контейнеров: Docker Хранилище кластера: Ceph Ограничения: Нет Блокировка: Ceph - не установился на виртуальные диски в Azure Решение: Тестируем разворот на боевой среде, прикидываем замену Ceph | Релиз: 1.0 Платформа: Baremetal OC: Oracle Linux Количество хостов: 2 Платформа оркестрации контейнеров: OKD 3.11 Версия Kubernetes: 1.14 Среда исполнения контейнеров: Docker Хранилище кластера: Ceph Блокировка: Gluster на двух хостах не развернулся, Ceph не работал в нужном режиме. Решение: Использовать NFS |
Релиз: 1.1 Платформа: Baremetal OC: Oracle Linux Количество хостов: 2 Платформа оркестрации контейнеров: OKD 3.11 Версия Kubernetes: 1.14 Среда исполнения контейнеров: Cri-o Хранилище кластера: NFS Ограничения: Не заработала динамическая провизия томов. Блокировка: Не работает ArgoCI, не завелся функционал emptyDir, Kubeflow pipelines не работает. Решение: Пробуем другую среду исполнения контейнеров. Настройки Agro executor: docker, kubelet, kubernetes api, pns | |
2.0 Платформа: AWS Операционная система: Fedora CoreOS 31.20200521.20 Количество хостов: 6 Платформа оркестрации контейнеров: 4.4.0-0.okd-2020-05-23-055148-beta5 Версия Kubernetes: 1.17.1 Среда исполнения контейнеров: Cri-o Хранилище кластера: EBS Ограничения: Нет Блокировка: Нет Особенности: Полностью кастомная сборка Kubeflow, изменен бэкенд запуска пайплайнов - KFP-Tekton | 2.0 Платформа: UPI Azure (Hyper-V) Операционная система: Fedora CoreOS 31.20200521.20 Количество хостов: 12 Платформа оркестрации контейнеров: OKD 4.4.0-0.okd-2020-05-23-055148-beta5 Версия Kubernetes: 1.17.1 Среда исполнения контейнеров: Cri-o Хранилище кластера: GlusterFS Ограничения: Нет Особенности: Полностью кастомная сборка Kubeflow, изменен бэкенд запуска пайплайнов - KFP-Tekton Блокировка: Кластер не установился, ошибки в процессе установки, проблемы с пуллом образов, таймауты при разворачивании контейнеров, проблемы при инициализации мастер нод. Решение: Переходим к варианту на kubernetes |
3.0 Платформа: Yandex Cloud Операционная система: Ubuntu Server 20.04 Количество хостов: 3 Версия Kubernetes: 1.19 Среда исполнения контейнеров: Docker Хранилище кластера: NFS\Gluster Ограничения: Нет Блокировка: Нет Особенности: Ванильный Kubernetes | 3.0 Платформа: UPI Azure (Hyper-V) Операционная система: Ubuntu Server 20.04 Количество хостов: 12 Версия Kubernetes: 1.19 Среда исполнения контейнеров: Docker Хранилище кластера: Gluster Ограничения: Нет Блокировка: Нет Особенности: Ванильный Kubernetes, много кастомных настроек |
Когда у нас возникли первые сомнения что мы не не соберем боевой стенд на OKD4.4 + Kubeflow, было принято решение подстраховаться и проработать план Б. Так как задача стояла собрать платформу для ML на базе opensource, то единственный вариант это сделать без Kubeflow - это подобрать отдельные инструменты, настроить между ними интеграции и CI\CD процессы. Резервный стек: Jupyterhub, MLFlow, Airflow, Gitlab, Graylog, Grafana, Prometheus все это или в ванильном Kubernetes или в OKD, но уже без привязки к версиям. Работает этот стек просто: IDE для разработки моделей в Jupyter, отслеживание экспериментов в MLFlow, запуск моделей по расписанию в Airflow, процессы CI\CD реализуем в Gitlab, логи, и мониторинг системы и моделей собираем с помощью Graylog, Grafana, Prometheus. План Б на фоне обещанного Kubeflow выглядел не так монолитно, был отвергнут заказчиком и мы вернулись к связке Kubeflow + Kubernetes.
Jupyter
Еще часть интересных задач мы реализовали в рамках кастомизации образов Jupyter. Задача была поставить большой набор библиотек, подготовить разные версии python и собрать отдельный образ с R-studio. В процессе сборки возникало много конфликтов с зависимостями, часть пакетов ставилась через pip, часть через git и conda, много собиралось из исходного кода с помощью make. К этому дикому миксу мы добавили пакеты с cuda, такой образ собирался 2-3 часа. Сначала в качестве базового образа использовался Debian, но в рамках данного дистрибутива не хватало готовых пакетов, история с зависимостями повторялась. В итоге сборку мы продолжали на базовом образе Cuda с Ubuntu 18.04 под капотом.
Так же был собран легковесный образ без GPU и образ R-Studio. Позже в эти образы был интегрирован Dask и плагины для Jupyter lab.
Настройка Kubeflow
У нас были специфические требования к ролевой модели, завязанной на распределении пользователей в группах в AD, Kubeflow из коробки пробрасывать профили так не умел. Мы отключили автоматическое создание именных профилей и прописали пользователей в определенные пространства имен руками, авторизацию в систему настроили на уровне фильтра групп. Настроили ограничения на использование ресурсов в пространствах имен.
Мы используем кастомные образы Jupyter, поправили configmap спаунера, убрали настройки из коробки, добавили свои, образы пулим из локального nexus.
Под капотом еще есть Knative-serving для запуска serverless моделей, пришлось повозиться с настройками прокси для корректного запуска.
Dask dashboard. В контейнере с dask включили jupyter-proxy и настроили через него дашборд. Пришлось немного повозиться с whitelist для доступа к дашборду. В итоге просто написали обычную лямбда функцию на питоне, которая динамически добавляет src host и порт в whitelist. И еще мы отключили istio sidecar injection в неймспейсе, где поднимаются ноутбуки с dask. Dask реализован в двух вариантах, можно запускать напрямую в кластере, а можно через UI Jupyter`а используя зашитый в образ extension.
Что умеет платформа после доработок:
- Все вызовы api работают за прокси
- Из контейнеров настроены интеграции с Bitbucket и Jenkins
- Из контейнеров можно работать с керберезированныим средами и источниками данных
- Работает запуск serverless моделей с помощью knative
- Работает Dask, можно запускать кластер из интерфейса Jupyter
- Контейнеры можно запускать с установленными лимитами на определенной ноде кластера
- Разграничены ресурсы в неймспейсах по подразделениям
- Настроена ролевая модель доступа
На уровне Kubernetes ничего сильно менять не пришлось, в основном стандартные настройки и установка необходимых инструментов. Из того, что заняло ресурс: настройка RBAC, интеграция с AD, DNS, настройка сертификатов для https, подкручивание proxy\noproxy, ldaps и сертификаты. Как софт старт Storage Class использовал NFS, позже подключили Gluster используя heketi. Heketi живет в подах в самом кластере, настроен в StatefulSet для доступности.
Какие задачи были решены в ходе проекта
Команда на старте состояла из менеджера проекта, архитектора, аналитика и инженера. В момент, когда необходимо было форсировать освоение скоупа, команда была усилена еще двумя инженерами.- Анализ бизнес требований заказчика;
- Анализ инфраструктуры заказчика;
- Подготовка и согласование технических требований;
- Подготовка стенда для тестирования;
- Подготовка стенда для установки кластера;
- Разработка, согласование и ведение технической документации;
- Разработка и подготовка учебных материалов;
- Проведение сессий обучения для пользователей и технического персонала;
- Подготовка образов Jupiter для среды разработки в соответствии с техническим заданием;
- Настройка интеграций с внешними системами;
- Подготовка методики и проведение сессий ПСИ;
- Дополнительный архитектурный анализ, сайзинг кластера;
- Сопровождение системы на старте боевой эксплуатации;
- Техническая поддержка.
Реализованные ожидания
Мы помогли заказчику в реализации подходов к ModelOps, помогли настроить инструменты, которые способствовали внедрению методологии ModelOps с версионированием кода, ревью, сборками, экспериментами и мониторингом метрик. Пользователи могут писать код на любом языке, собраны дефолтные образы под Python и R, но функционал conda и Jupyter позволяют установить любое ядро в Jupyter и использовать его.Мы реализовали достаточно простую, но эффективную ролевую модель с разделением ресурсов и неймспейсов между подразделениями, а также с двумя уровнями пользователей: пользователи системы, которые могут работать в системе и производить эксперименты, и продвинутые пользователи, которым доступны инструменты для вывода моделей в выделенную зону prod и работа в этой зоне. Предоставление и отзыв доступа к платформе осуществляется через предоставление пользователю группы в AD по действующим в банке процедурам.
Мы наладили процесс поддержки пользователей через выделенных администраторов системы с интеграцией с поддержкой контрагента через JIRA.
Заключение
Отдельную благодарность выражаем команде Банка «Санкт-Петербург», проект иногда требовал терпения и быстрой реакции, хорошей координации и новых подходов, коллеги предоставили нам все необходимое для максимально продуктивной и комфортной работы, развивались в рамках проекта вместе с нами, активно создавали удобный для себя инструмент.Не бывает маленьких проектов на базе Kubernetes, не бывает простых проектов с open source. Для DS и ML практик зачастую вообще нет готовой или проверенной методологии. Платформы и инструменты только создаются, активно развиваются, переходят в микросервисную архитектуру, в облака и в serverless. Любое активно развивающееся направление требует свежих, революционных идей и людей, готовых к подобным вызовам. Для нашей команды - это интересный опыт, который поможет в реализации следующих проектов на базе Kubernetes и OpenShift. Идея единой платформы, которой выступил Kubeflow, очень интересна и перспективна, концепцию интересно развивать и предлагать в качестве базы для проектов среднего масштаба. Надеюсь, данный опыт поможет нашим клиентам еще быстрее и эффективнее решать бизнес задачи, а нам предлагать им интересные решения.
И немного минусов...
Но, кроме плюсов, у Kubeflow есть и минусы. Часть проблем из-за open source, другая - из-за специфики ML. Итак, на земле больше нюансов при внедрении, чем в облаке, много “сырых” инструментов на грани альфа и бета версий, отсутствие полномасштабной поддержки и серьезные пробелы в документации. Если брать инсталляции для заказчиков с повышенными требованиями к информационной безопасности, то не все компоненты системы пройдут согласования без замечаний и доработок.Мы очень любим Jupyter, но не очень любим собирать кастомные образы, да и легковесным такой контейнер назвать тяжело.
Минусы нашлись и у основного инструмента автоматизации, Kubeflow pipelines: относительно высокий порог вхождения (выше чем у airflow, luigi и подобных инструментов), данный инструмент неудобен для оркестрации простых задач/функций (слишком много кода и конфигов приходится писать). В текущей реализации работает, но все еще нуждается в доработках и может стать оптимальным решением.
Дополнительные материалы
Список материалов которые мы использовали в процессе RND и подготовки боевого стенда для данного проекта.OpenShift, OKD, Kubernetes
https://docs.nvidia.com/datacenter/kubernetes/openshift-on-gpu-install-guide/
https://www.openshift.com/blog/simplifying-deployments-of-accelerated-ai-workloads-on-red-hat-openshift-with-nvidia-gpu-operator
https://github.com/openshift/okd
https://docs.okd.io/latest/installing/installing_bare_metal/installing-bare-metal.html#creating-machines-bare-metal
https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/
https://docs.okd.io/latest/installing/installing_bare_metal/installing-restricted-networks-bare-metal.html#installation-configure-proxy_installing-restricted-networks-bare-metal
https://thenewstack.io/tutorial-install-kubernetes-and-kubeflow-on-a-gpu-host-with-nvidia-deepops/
Kubeflow
https://www.kubeflow.org/
https://github.com/IBM/KubeflowDojo
https://github.com/kubeflow
https://www.youtube.com/watch?v=3rHF9iOpmkg&list=PLaR6Rq6Z4Iqe6ADimTyxufa_O3VL3vkXW&index=171&ab_channel=OpenShift
https://towardsdatascience.com/make-kubeflow-into-your-own-data-science-workspace-cc8162969e29
https://docs.containerplatform.hpe.com/52/reference/kubernetes/kubernetes-administrator/kubeflow/kubeflow.html
https://github.com/argoproj/argo-workflows/blob/master/docs/workflow-executors.md
GlusterFS
https://www.gluster.org/
https://github.com/heketi/heketi
Jupyter и подготовка образов
https://github.com/iot-salzburg/gpu-jupyter
https://zero-to-jupyterhub.readthedocs.io/en/latest/
https://tanzu.vmware.com/developer/blog/data-science-with-python-jupyterhub-on-kubernetes-part-1/
https://tanzu.vmware.com/developer/blog/data-science-with-python-jupyterhub-on-kubernetes-part-2/
https://blog.jupyter.org/how-to-deploy-jupyterhub-with-kubernetes-on-openstack-f8f6120d4b1
Dask
https://kubernetes.dask.org/en/latest/
https://docs.dask.org/en/latest/
Опыт внедрения Kubeflow в кластере Kubernetes
Всем привет,В статье мы рассказали о внедрении ML-платформы Kubeflow в кластере Kubernetes на площадке заказчика. Инструменты, которые мы использовали в рамках проекта, являются программным...
habr.com