Платформа Jupyter позволяет начинающим разработчикам, аналитикам данных и студентам быстрее начать программировать на Python. Предположим, ваша команда растёт — в ней теперь не только программисты, но и менеджеры, аналитики, исследователи. Рано или поздно отсутствие совместного рабочего окружения и сложность настройки начнут тормозить работу. Справиться с этой проблемой поможет JupyterHub — многопользовательский сервер c возможностью запускать Jupyter одной кнопкой. Он отлично подходит для тех, кто преподаёт Python, а также для аналитиков. Пользователю нужен только браузер: никаких проблем с установкой ПО на ноутбук, совместимостью, пакетами. Мейнтейнеры Jupyter активно развивают JupyterHub наряду с JupyterLab и nteract.

Меня зовут Андрей Петрин, я руководитель группы аналитики роста в Яндексе. В докладе на Moscow Python Meetup я напомнил о плюсах Jupyter и рассказал про архитектуру и принципы работы JupyterHub, а также про опыт применения этих систем в Яндексе. В конце вы узнаете, как поднять JupyterHub на любом компьютере.


— Начну с того, кто такие аналитики в Яндексе. Существует аналогия, что это такая многорукая Шива, которая умеет делать сразу много разных вещей и сочетает в себе много ролей.

Всем привет! Меня зовут Андрей Петрин, я руководитель группы аналитики роста в Яндексе. Я расскажу про библиотеку JupyterHub, которая в свое время сильно упростила нам жизнь в аналитике Яндекса, мы буквально почувствовали буст продуктивности большого количества команд.




Например, аналитики в Яндексе — это немножко менеджеры. Аналитики всегда знают сроки, таймлайн процесса, что в какой момент необходимо делать.

Это немножко разработчики, они знакомы с разными способами обработки данных. Например, на слайде в руках Шивы те библиотеки Python, которые приходят на ум мне, это не полный список, но то, что используется на ежедневной основе. Естественно, разработка у нас ведется не только на Python, но я буду рассказывать в первую очередь о Python.

Аналитики — немножко математики, нам необходимо принимать решения взвешенно, смотреть на настоящие данные, не на менеджерскую точку зрения, а искать какую-то истину и разбираться в этом.

Во всей этой задаче нам достаточно сильно помогает экосистема Jupyter.



Это такая платформа для интерактивного программирования и создания отчетов-ноутбуков. Ключевой сущностью Jupyter-ноутбуков является такой ноутбук, где есть большое количество разнообразных виджетов, интерактивных элементов, которые можно изменять. В качестве главной сущности — микроэлементы кода, которые ты программируешь. Их можно напечатать в ноутбуке в твоем браузере, который ты постоянно используешь. Это могут быть как картинки, так и интерактивные HTML-производные элементы. Можно просто печатать, делать принт, отображать элементы — разнообразные вещи.

Система Jupyter развивается давно, поддерживает различные языки программирования различных версий, Python 2 и 3, Go, разнообразные вещи. Позволяет круто решать наши повседневные задачи.

Чем мы в аналитике занимаемся и как нам Jupyter в этом сильно помогает?



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

Для этой задачи мы строим граф смежности всех хостов интернета, граф похожести двух сайтов друг на друга. При помощи ручной разметки хостов получаем некоторую первичную базу о том, какие сайты в интернете есть, и дальше экстраполируем ручную разметку на весь интернет. Буквально в каждой из задач мы используем Jupyter. Он позволяет с точки зрения построения графа смежности постоянно запускать операции на MapReduce, строить такие графы, проводить такую дата-аналитику.

Ручную разметку мы автоматизировали в Jupyter при помощи виджетов-инпутов. У нас для каждого хоста есть предполагаемая тематика, которая, скорее всего, правильная. Мы почти всегда угадываем тематику, но для ручной разметки человек все-таки нужен.

И получаются всякие интересные картинки.



Например, здесь изображены сайты тематики спорта и соответствующие поисковые запросы, которые в спортивной тематике присутствуют.



Тематика энциклопедий. Сайтов и в целом уникальных запросов поменьше, но основные запросы побольше.



Тематика homework — готовые домашние задания. Достаточно интересная, потому что внутри нее есть два независимых кластера сайтов, похожих друг на друга, но не похожих на остальных. Это хороший пример тематики, которую хотелось бы разбить на две. Одна половина сайтов явно решает одну задачу внутри домашних заданий, другая — другую.



Было достаточно интересно делать оптимизатор ставок, совсем другую задачку. В Яндексе закупается некоторое количество мобильных приложений, в том числе за деньги, и мы уже умеем предсказывать lifetime пользователя, сколько мы можем получить от установки какого-то приложения для каждого пользователя, но выясняется, что к сожалению, это знание сложно передать маркетологу, тому исполнителю, кто будет заниматься закупкой трафика. Это происходит обычно из-за того, что всегда есть какой-то бюджет, есть немаленькое количество ограничений. Необходимо делать такую задачу многомерной оптимизацию, интересную с точки зрения аналитики, но нужно сделать прибор для менеджера.



Здесь сильно помогает Jupyter. Это интерфейс, который мы разработали в Jupyter, чтобы пользователь-менеджер, не обладающий знаниями Python, мог войти и получить результат нашего прогноза. Можно выбрать там, выбираем ли мы Android или iOS, на каких странах, какое приложение. Есть достаточно сложные управляторы и ручки, которые можно изменять, например, какие-то прогрессбары, размер бюджета, какая-то толерантность к риску. Эти задачи решены при помощи Jupyter, и мы очень довольны тем, что аналитик, являясь многорукой Шивой, может решать эти задачи один.

Лет пять назад мы пришли к тому, что есть некоторые ограничения и проблемы платформы, с которыми хочется бороться. Первая проблема в том, что у нас достаточно много разных аналитиков, каждый из которых все время на разных версиях, операционных системах и т. д. Часто код, который работает у одного человека, не запускается у другого.

Еще большая проблема — версии пакетов. Думаю, не надо рассказывать, как тяжело поддерживать какой-то консистентный environment, чтобы все могло запуститься из коробки.

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

Здесь к нам на помощь пришла библиотека JupyterHub.



Это очень простое приложение, оно состоит из четырех компонент, просто разделяющихся.

Первая часть приложения отвечает за авторизацию. Мы должны проверить пароль и логин, можем ли мы пустить этого человека.

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

Проксирование. Есть единая точка доступа ко всему серверу, и JupyterHub определяет, к какому пользователю на какой порт нужно идти, для пользователя все абсолютно прозрачно. Естественно, некоторое управление БД и всей системой.



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

Если пользователь уже залогинен, то его напрямую проксируют в собственный сервер, и Jupyter-ноутбук фактически просто общается с человеком напрямую, иногда спрашивая у сервера про доступ, разрешен ли этому пользователю доступ к этому ноутбуку и т. д.



Интерфейс достаточно простой и удобный. По умолчанию при развертывании используется username и пароль того компьютера, где это развернуто. Если у вас есть сервер, где есть несколько пользователей, то логином и паролем является логин и пароль к системе, и пользователь видит свою домашнюю директорию /home как свою домашнюю директорию. Очень удобно, не нужно думать ни о каких пользователях.





Остальные интерфейсы в целом достаточно привычны для вас. Это стандартные Jupyter-ноутбуки, которые вы все видели. Можно посмотреть активные ноутбуки.



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



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

В целом система очень сильно развивается.



На картинке курс в UC Berkley, который закончился в этом декабре, это был самый большой курс по data science в мире, по-моему, его прослушали 1200 студентов, которые не умели программировать, и пришли учиться программированию. Это было сделано на платформе JupyterHub, студентам не нужно было устанавливать никакой Python у себя на компьютере, они могли просто зайти в браузере на этот сервер.

Естественно, при дальнейших стадиях обучения необходимость установки пакетов появилась, но это классно решает проблему первого входа. Когда вы преподаете Python, и человек совсем с этим не знаком, довольно часто вы понимаете, что какие-то рутины, связанные с установками пакетов, поддержанием какой-то системы и тому подобное, это немного лишнее. Вы хотите вдохновить человека, рассказать о том, что это за мир, не углубляясь в детали, которые человек сможет освоить в будущем.

Установка:

python3 -m pip install jupyterhub
sudo apt-get install npm nodejs-legacy 
npm install -g configurable-http-proxy 

Поддерживается исключительно Python 3, внутри JupyterHub можно запускать ячейки во втором Python, но сам JupyterHub работает только на третьем. Единственная зависимость — вот эта configurable-http-proxy, именно она используется в Python для упрощения.

Конфигурация:

jupyterhub --generate-config

Первое, что вы захотите сделать, это сгенерить конфиг. Все заработает само, даже без каких-либо настроек, по умолчанию будет поднят локальный сервер с каким-то портом 8000, с доступом к вашим пользователям по логину и паролю, работать будет только под судой, будет работать буквально из коробки, но generate-config создаст вам файлик JupyterHub config, где буквально в виде документации можно прочитать абсолютно все его настройки. Это очень удобно, можно даже не заходя в документацию, понять, в каких строчках что нужно включить, там все закомментировано, можно управлять, все настройки по умолчанию видны.



Хочется сделать некую паузу и оговорку. По умолчанию, когда вы будете это развертывать, вы будете это развертывать у себя на каком-то сервере, и если вы не предпримете определенные усилия, а именно не будете использовать HTTPS, то сервер поднимется по HTTP, и ваши пароли и логины пользователей, которые будут входить, будут в открытом виде светиться при общении с JupyterHub. Это очень опасная история, невероятное количество проблем тут можно огрести. Поэтому не игнорируйте проблему с HTTPS. Если у вас нет собственного сертификата HTTPS, вы можете его создать, либо есть замечательный сервис letsencrypt.org, который позволяет бесплатно получить сертификаты, и вы сможете на своем домене запускать без проблем и без денег. Это достаточно удобно, не игнорируйте это.

По умолчанию хаб работает из под root, очевидно, он спаунит из под конкретного пользователя собственные ноутбуки. Это можно изменить, но по умолчанию это так. И все пользователи локальные, домашняя директория прокидывается для каждого конкретного пользователя. Подробнее расскажу, что можно еще сделать.

Классность JupyterHub в том, что это такой конструктор. Буквально в каждом элементе из диаграммы, что я показал, можно вставлять, встраивать собственные элементы, которые упрощают работу. Например, предположим, вам не хочется, чтобы ваши пользователи вбивали логин и пароль системный, это не очень безопасно или неудобно. Вам хочется сделать другую систему логина. Это можно сделать при помощи oauth и, например, github.



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



Поддерживаются из коробки другие способы авторизации пользователей. Если есть LDAP — можно его. Можно любой OAuth, есть REMOTE_USER Authenticator, позволяющий удаленным серверам проверять доступ к вашему локальному. Все что душе угодно.



Предположим, у вас есть несколько типов задач. Например, одна использует GPU, и для этого вам нужен один стек технологий, определенный набор пакетов, и хочется отделить его от CPU с другим сценарием использования. Для этого можно написать собственный спаунер. Это система, которая создает пользовательские Jupyter-ноутбуки. Здесь изображена настойка при помощи Docker, вы можете собрать Docker-файл, который будет разворачиваться под каждого пользователя, и пользователь будет не локальным, а в своем внутреннем контейнере.

Есть некоторое количество других удобных фишек JupyterHub, сервисы.



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

Есть готовый сервис cull_idle_servers, который позволяет выключать любые пользовательские сервера после неактивности. Все данные будут сохранены, просто не будут использоваться ресурсы, вы сможете немного сэкономить.



Я рассказал, что буквально на каждый кусочек этой схемы можно что-то свое включить. Можно сделать некоторый аддон к прокси, каким-то своим образом делать прокидывание пользователей. Можно написать собственный авторизатор, можно напрямую общаться с БД при помощи сервисов. Можно создавать собственные спаунеры.

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



Вам нужен JupyterHub в случае, если у вас несколько человек используют Jupyter. И необязательно, чтобы они использовали Jupyter для одного и того же. Это удобная система, которая позволит этих людей объединить и избежать дальнейших проблем. А если они, тем более, делают одну и ту же задачу — скорее всего, им будет нужен более-менее консистентный набор пакетов.

То же самое в случае, если вам поступают жалобы о том, что у меня замечательно построилась модель, какой-то аналитик Васечкин пытается ее воспроизвести и она не работает. В свое время у нас была постоянная проблема. И безусловно, консистентный стейт сервера в этом сильно помогает.

Очень классно использовать это для обучения Python. Есть сервис nbgrader, который поверх JupyterHub позволяет делать удобные батарейки с отправкой студентам домашнего задания. Они сами заполняют решения, отправляют обратно, есть автоматическое тестирование, которое проверяет ячейки Jupyter и позволяет сразу выставлять оценки. Очень удобная система, рекомендую.

Представьте, что вы пришли на какой-то семинар, где вы хотите что-то показать на Python. При этом вы не хотите потратить первые три часа на то, чтобы у всех все заработало из вашего how to. Вы хотите сразу начать делать что-то интересное.

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

Комментарии (1)


  1. bougakov
    15.04.2018 23:44

    Лично пробовал jupyterhub, когда для VPN арендовал сервер в Германии и понял, что он бОльшую часть времени простаивает. К сожалению, из-за каких-то сложностей с websockets оно отвратительно работало в Google Chrome. Чистый jupyter таких проблем не давал.

    Для заворачивания трафика к jupyter в HTTPS можно использовать nginx с такой конфигурацией:

    ##############################################
    # python.example.com
    ##############################################

    upstream notebook {
    server localhost:8888;
    }
    server {
    listen 80;
    # listen [::]:80;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/python.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/python.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    if ($scheme != "https") {
    return 301 https://$host$request_uri;
    } # managed by Certbot
    server_name python.example.com;
    # Jupyter:
    location / {
    proxy_pass http://notebook;
    proxy_set_header Host $host;
    }
    location ~ /api/kernels/ {
    proxy_pass http://notebook;
    proxy_set_header Host $host;
    # websocket support
    proxy_http_version
    proxy_set_header Upgrade "websocket";
    proxy_set_header Connection "Upgrade";
    proxy_read_timeout 86400;
    }
    location ~ /terminals/ {
    proxy_pass http://notebook;
    proxy_set_header Host $host;
    # websocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade "websocket";
    proxy_set_header Connection "Upgrade";
    proxy_read_timeout 86400;
    }
    }


    Letsencrypt подключается так:

    apt-get install -y python-certbot-nginx nginx build-essential
    mkdir -p /etc/letsencrypt

    echo 'rsa-key-size = 4096
    pre-hook = /sbin/iptables -I INPUT -p tcp --dport 443 -j ACCEPT && systemctl stop nginx
    #post-hook = /sbin/iptables -D INPUT -p tcp --dport 443 -j ACCEPT
    renew-hook = /usr/sbin/ipsec reload && /usr/sbin/ipsec secrets && systemctl start nginx
    ' > /etc/letsencrypt/cli.ini
    certbot certonly --non-interactive --agree-tos --email you@example.com --standalone -d python.example.com


    Последняя команда вносится в crontab, чтобы сертификаты перевыпускались регулярно.

    Весьма рекомендуется дать Letsencrypt хотя бы баксов пять пожертвования: letsencrypt.org/donate