MLOps без боли в облаке: как развернуть Kubeflow в продакшен-кластере Kubernetes

a9934c0c9f753e473491644a70a8e687.png

Новые экспериментальные модели машинного обучения важно быстро разворачивать в продакшене, иначе данные устареют и появятся проблемы воспроизводимости экспериментов. Но не всегда это можно сделать быстро, так как часто процесс передачи модели от Data Scientist к Data Engineer плохо налажен. Эту проблему решает подход MLOps, но, чтобы его реализовать, нужны специальные инструменты, например Kubeflow.

При этом установка и настройка Kubeflow — довольно непростой процесс. Хотя существует официальная документация, она не описывает, как развернуть Kubeflow в продакшен-варианте, а не просто на тестовой локальной машине. Также в некоторых инструкциях встречаются проблемы, которые нужно обходить и искать их решения.

Я Александр Волынский, архитектор облачной платформы Mail.ru Cloud Solutions. В этой статье познакомлю вас с Kubeflow на базовом уровне и покажу, как его разворачивать. Мы не будем подробно знакомиться со всеми компонентами Kubeflow, потому что это выходит за рамки базового ознакомления.

В ходе этой статьи мы:

  1. Создадим кластер Kubernetes на платформе Mail.ru Cloud Solutions.

  2. Установим Istio.

  3. Установим Kubeflow.

  4. Запустим JupyterHub.

  5. Обучим и опубликуем тестовую модель.

Но для начала немного расскажу про MLOps и Kubeflow.

Если вы предпочитаете видеоинструкцию, то можете посмотреть вебинар «MLOps без боли в облаке. Разворачиваем Kubeflow».

Пара слов о MLOps

MLOps (Machine Learning Operations) — это своего рода DevOps для машинного обучения, который помогает стандартизировать процесс разработки моделей машинного обучения и сокращает время их выкатки в продакшен.

MLOps помогает разбить барьер между Data Scientist и Data Engineer. Часто происходит так: Data Scientist экспериментирует, разрабатывает новую модель, отдает ее дата-инженеру и уходит снова ставить новые эксперименты и пробовать новые модели. А Data Engineer пытается развернуть эту модель в продакшене, но так как он не участвовал в ее разработке, у него может уйти на это несколько месяцев. Может пройти до полугода с момента начала разработки модели до ее развертывания в продакшене. Все это время модель не работает и не приносит пользы, данные устаревают, появляется проблема воспроизводимости экспериментов.

С MLOps новая модель быстро передается в производство и начинает приносить пользу бизнесу. Также MLOps решает задачи трекинга моделей, версионирования, мониторинга моделей в продакшене.

Kubeflow в связке с MLOps

Kubeflow — это Cloud-Native платформа с открытым исходным кодом, предназначенная для машинного обучения и Data Science. Kubeflow работает поверх Kubernetes, полностью с ним интегрирована и по максимуму использует возможности кластера вроде автомасштабируемости и гибкого контроля ресурсов.

Kubeflow включает в себя множество компонентов, решающих разные задачи Data Science и Machine Learning. Все эти компоненты Open Source, вы можете использовать их отдельно. То есть, работая с Kubeflow, можно получить опыт работы с этими компонентами и перенести его впоследствии на другие задачи.

Еще одно преимущество Kubeflow в том, что на ней можно быстро запускать JupyterHub и настраивать индивидуальное окружение для дата-сайентистов.

В традиционном подходе JupyterHub часто установлен на одном мощном сервере, в котором может быть 60–100 ядер и несколько сотен гигабайт оперативной памяти. Но со временем отдел Data Science растет, ресурсов на всех начинает не хватать. Кроме того, общее окружение приводит к конфликтам, когда кому-то из дата-сайентистов нужно обновить версии библиотек или установить новые, а другим это не нужно.

Используя Kubeflow внутри облачного Kubernetes, вы решаете эту проблему: любой Data Scientist может в несколько кликов быстро развернуть экспериментальную среду с нужным количеством ресурсов. А когда эксперимент окончен, ресурсы освобождаются и возвращаются в облако. Также Kubeflow позволяет развернуть полностью изолированные индивидуальные инстансы JupyterHub из отдельных Docker-образов. То есть каждый дата-сайентист может настроить окружение под свои потребности.

Другие возможности Kubeflow:

  • быстрая публикация моделей через компоненты TensorFlow Serving, Seldon Core — можно делать их доступными по REST-протоколу или gRPC;

  • удобный UI для управления экспериментами и мониторингом моделей — можно собрать свой Kubeflow из открытых компонентов, но управлять без UI им будет намного сложнее;

  • оркестрация сложных пайплайнов машинного обучения из множества шагов — платформа частично заменяет AirFlow;

  • встроенный компонент, который отвечает за подбор гиперпараметров;

  • возможности управления метаданными и Feature Store.

Важно заметить, что некоторые из компонентов Kubeflow еще находятся в бета-версии. Но уже сейчас можно начать пользоваться Kubeflow, потому что это одна из немногих Production-Ready платформ, решающая задачи MLOps и машинного обучения. Для начала Kubeflow можно использовать как гибкий вариант JupyterHub, а потом постепенно знакомиться с остальными возможностями.

Итак, приступаем к установке Kubeflow.

Инструкция по установке и настройке Kubeflow

Шаг 1: создаем кластер Kubernetes

Сначала нам необходимо развернуть кластер Kubernetes. Мы будем делать это на нашей облачной платформе Mail.ru Cloud Solutions.

Перед созданием кластера нужно настроить сеть, сгенерировать и загрузить SSH-ключ для подключения к виртуальной машине. Вы можете самостоятельно настрои сеть по инструкции.

Сначала заходим в панель MCS и создаем кластер Kubernetes. Кластер можно создать в разных конфигурациях, выбираем «Другое», указываем версию Kubernetes 1.16.4. Это не самая актуальная версия, которая есть на платформе, но, по словам разработчиков Kubeflow, она лучше всего протестирована. Также выбираем два предустановленных сервиса: мониторинг на базе Prometheus/Grafana и Ingress Controller.

77288c951457f440b2b2542b09c4963d.jpg

На следующем шаге выбираем конфигурацию кластера. Тип виртуальной машины «Standard 4–8», размер диска 200 Гб. Выбираем заранее настроенную сеть и отмечаем «Назначить внешний IP» — это нужно, чтобы потом подключиться к этой машине. Затем выбираем SSH-ключ для подключения, который сгенерирован и загружен заранее.

47a24f6f43b973213d3ac012402e91fb.jpg

На следующей вкладке нужно указать минимальные системные требования для рабочей ноды Kubeflow. В минимальных системных требованиях указано 4 ядра, 50 Гб диска и 12 Гб оперативной памяти. Создаем ноду с запасом: 8 ядер, 200 Гб диска и 16 Гб оперативной памяти.

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

ac7235b0a3f0bdc189ed7006bc81b2f5.jpg

Если возникнут сложности, вот полная инструкция по созданию кластера Kubernetes.

После того как кластер создался, нужно подключиться к мастер-ноде и внести некоторые изменения. Это нужно, так как Kubeflow требует для работы одну фичу, которая пока не активна, но скоро мы ее включим по стандарту. Для этого сначала нужно назначить белый внешний IP-адрес. Поэтому в панели MCS заходим в раздел «Облачные вычисления» — «Виртуальные машины». Напротив мастер-ноды в выпадающем меню выбираем «Управлять IP-адресами».

00c902d44f3822532d1d1640601473f3.jpg

В появившемся окне в столбце «Внешний» назначаем внешний IP-адрес и копируем его, как только он создается.

19039df84fceedc9068af3311472cb4d.jpg

Теперь подключаемся по SSH к мастер-ноде Kubernetes, подставляя свои параметры:

ssh -i your_key.pem centos@ip_of_master

Открываем файл /etc/kubernetes/apiserver для редактирования:

sudo vim /etc/kubernetes/apiserver

В строку KUBE_API_ARGS добавляем параметры. Это нужно для того, чтобы заработали Kubeflow и Istio:

--service-account-issuer=kubernetes.default.svc
--service-account-signing-key-file=/etc/kubernetes/certs/ca.key
--service-account-api-audiences=api,istio-ca

Теперь можно отвязать внешний IP-адрес от мастер-ноды.

6ac394b1eef2c6c886d59f112298d2cd.jpg

Затем нужно перезагрузить Kubernetes-кластер после внесения изменений. Для этого в разделе «Кластеры Kubernetes» сначала останавливаем кластер, а потом запускаем заново.

3c26c872839abc3892b4d75f4bd13e27.jpg

Когда кластер Kubernetes остановлен, вы платите только за место на дисках, что удобно при проведении экспериментов в облаке.

Далее нужно подготовить виртуальную машину, в которой мы будем выполнять все дальнейшие действия. Сначала создайте виртуальную машину с ОС Ubuntu 18.04 и подключитесь к ней по SSH. Затем установите kubectl и импортируйте конфигурационный файл, чтобы подключиться к созданному кластеру Kubernetes. Также вы можете развернуть все это на своей машине.

Шаг 2: устанавливаем istioctl и Istio

Kubeflow и Istio можно установить одним пакетом сразу, но мы будем устанавливать их отдельно. Потому что на момент написания этой инструкции Istio, который идет в комплекте с Kubeflow, не заработал.

Скачиваем пакет с Istio. Рекомендуем именно версию 1.3.1, потому что на момент написания инструкции именно она рекомендована для работы с Kubeflow:

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.3.1 TARGET_ARCH=x86_64 sh -

Добавляем путь к переменной PATH:

export PATH="$PATH:/home/ubuntu/istio/istio-1.3.1/bin"

Проверяем установку:

istioctl verify-install

Если вы видите такое сообщение, значит, все готово для установки Istio:

-----------------------
Install Pre-Check passed! The cluster is ready for Istio installation.

Устанавливаем Istio Custom Resource Definitions:

cd ~/istio/istio-1.3.1
for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i; done
kubectl apply -f install/kubernetes/istio-demo.yaml

Нужно проверить, все ли поды запустились:

kubectl get pods -n istio-system

Нужно дождаться, пока все поды будут в статусе Running или Completed:

cf2348b5793de1d472891b881a9c1afb.jpg

Шаг 3: устанавливаем Kubeflow

Сначала нужно скачать и распаковать kfctl — утилиту для работы с Kubeflow.

Затем задаем переменные:

export PATH=$PATH:"~/"
export CONFIG_URI="https://raw.githubusercontent.com/kubeflow/manifests/v1.1-branch/kfdef/kfctl_istio_dex.v1.1.0.yaml"
export KF_NAME=kubeflow-mcs
export BASE_DIR=~/
export KF_DIR=${BASE_DIR}/${KF_NAME}

Далее создаем директорию и конфигурационный файл в ней:

mkdir -p ${KF_DIR}
cd ${KF_DIR}
kfctl build -V -f ${CONFIG_URI}
export CONFIG_FILE=${KF_DIR}/kfctl_istio_dex.v1.1.0.yaml

Нужно отредактировать конфигурационный файл и удалить из него все, что связано с Istio. Иначе в процессе установки Kubeflow Istio снова попробует установиться и из-за этого все сломается:

nano $CONFIG_FILE

Нужно удалить эти блоки:

0afab49058892f64c562f6e188444260.jpg

Применяем конфигурационный файл:

kfctl apply -V -f ${CONFIG_FILE}

Нужно подождать, пока создадутся все поды. Статус подов можно проверить командами:

kubectl get pods -n kubeflow 

и

kubectl get pods -n intio-system

Нужно дождаться, пока все поды будут в статусе Running или Completed:

d845a05ad5ef7c7c99e657ef6a542d43.jpg

Рекомендуется сразу сменить в Kubeflow пароль по умолчанию. Для этого создадим конфигурационный файл для авторизации:

kubectl get configmap dex -n auth -o jsonpath='{.data.config\.yaml}' > dex-config.yaml

Дальше нужно получить хеш пароля, для этого зайдем на сайт https://passwordhashing.com/BCrypt, вводим пароль и копируем полученный хеш, чтобы потом прописать его в YAML-файл.

0e80d7735e3ed6cf3ee4779551897cfa.jpg

Далее открываем конфигурационный файл для редактирования:

nano dex-config.yaml

Вписываем полученный хеш:

d97394fa3e707cd25ebec601703fe163.jpg

Применяем этот конфигурационный файл:

kubectl create configmap dex --from-file=config.yaml=dex-config.yaml -n auth --dry-run -oyaml | kubectl apply -f -

Перезапускаем Dex, который отвечает за процесс аутентификации:

kubectl rollout restart deployment dex -n auth

Затем, чтобы Kubeflow был доступен по HTTPS, необходимо в Kubernetes внести изменения в конфигурацию Kubeflow Gateway:

cat <

Примечание. В следующих шагах генерируем самоподписанный сертификат, и Chrome будет выдавать предупреждение, когда будем заходить в Kubeflow. При этом может быть проблема, что Kubeflow будет недоступен по внешнему IP-адресу. Чтобы это исправить, можно сменить тип istio-ingressgateway на NodePort и обратно на LoadBalancer:

kubectl patch service -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort"}}'

Ждем около минуты, затем:

kubectl patch service -n istio-system istio-ingressgateway -p '{"spec": {"type": "LoadBalancer"}}'

Дальше необходимо узнать новый внешний IP-адрес:

kubectl get svc -n istio-system

Копируем адрес:

c8926b917892e14b59db245894ccda4b.jpg

Необходимо сгенерировать сертификат для этого IP-адреса. Ниже в коде на место INSERT_IP_RECEIVED_ON_PREV_STEP нужно вставить IP-адрес из предыдущего шага:

export INGRESS_IP=INSERT_IP_RECEIVED_ON_PREV_STEP

cat <

Шаг 4: запускаем JupyterHub

В браузере переходим по внешнему IP в панель управления Kubeflow. Для входа используем логин и пароль, которые сгенерировали в предыдущем разделе «Установка Kubeflow».

c8c1b0d957c80c5c23873135db3b20c2.jpg

При первом входе необходимо создать Namespace. По умолчанию предлагается имя admin, для примера создадим admin-kubeflow. Новым пользователям также надо будет сгенерировать под себя Namespace.

Далее нам понадобятся credentials от Docker Hub. Сначала переводим их в base64:

echo -n USER:PASSWORD | base64

Создаем конфигурационный файл, для того чтобы JupyterHub мог работать с docker-registry:

nano config.json

Вставляем код. Вместо generated_base64_string нужно вставить ваш хеш от Docker Hub:

{
"auths": {
    "https://index.docker.io/v1/": {
      "auth": "generated_base64_string"
    }
  }
}

Далее создаем config-map, который будет содержать credentials для доступа к нашему Docker Registry. Необходимо указать название вашего Namespace вместо ${NAMESPACE}, в данном примере это admin-kubeflow:

kubectl create --namespace ${NAMESPACE} configmap docker-config --from-file=config.json

Проверяем, что файл создался:

k get configmap -n admin-kubeflow

Тут видно, что нужный docker-config был создан 24 секунды назад, значит, все хорошо:

2217fb898681d20b2c77a57490ad79ee.jpg

Теперь нужно запустить инстанс JupyterHub. Возвращаемся в панель управления Kubeflow, переходим в раздел Notebook Servers и создаем новый инстанс. Выбираем Image версии 1.15. Вы можете использовать любой другой кастомный Image, но тогда придется устанавливать нужные версии библиотек. Для теста задаем 3 CPU и 3 Гб оперативной памяти, но вы можете задать объем ресурсов гибко под свои задачи.

ed0ee7d38c3054511bdfb13fca087676.jpg

Также при создании инстанса создается Persistent Storage, который позволяет сохранить данные, даже когда Kubeflow будет перезапущен, им также можно управлять и задавать объем.

5a93b6765f357475d6afa541a1ba0cba.jpg

Остальные параметры оставляем по умолчанию.

После того как Jupyter Notebook запустится, подключаемся к нему.

a4259223a9c8da91d77d52617ae4eacd.jpg

Запускаем терминал.

282e753c25ff59671ace6faddb5adda4.jpg

В терминале клонируем репозиторий, в котором находятся примеры pipeline. В данном примере использую свой репозиторий, а не официальный, потому что на момент написания этой инструкции официальные примеры устарели и не работают:

git clone https://github.com/stockblog/kubeflow_examples.git git_kubeflow_examples

Шаг 5: обучаем и публикуем тестовую модель

На этом шаге мы обучим в Kubernetes и опубликуем модель, запустим эксперименты и посмотрим на результаты. Работа будет проходить в двух Jupyter-блокнотах, которые находятся в склонированном репозитории: mnist_mcs_k8s.ipynb и Simple Notebook Pipeline.ipynb. Мы по очереди откроем эти блокноты и будем последовательно запускать ячейки.

Этот процесс лучше посмотреть на коротком видео:

Если использовать подход MLOps и специальные инструменты, например Kubeflow, можно значительно ускорить процесс выкатки экспериментальных моделей в продакшен, а это значит, что они будут быстрее решать бизнес-задачи.

Также 23 марта в 18:00 я проведу вебинар «MLflow в облаке. Простой и быстрый способ вывести ML-модели в продакшен». На вебинаре мы пройдем все этапы установки и настройки MLflow в максимально близком к production варианте, а также покажем, как реализовать использование облачных сервисов в качестве различных backend-сервисов MLflow. Регистрация здесь.

Что еще почитать по теме:

  1. Как развернуть кластер Kubernetes на платформе MCS.

  2. 90+ самых полезных инструментов для Kubernetes.

  3. Наш телеграм-канал Вокруг Kubernetes в Mail.ru Group.

© Habrahabr.ru