안수찬의 개발이야기

Jupyterhub를 이용하여 Jupyter Notebook 실습 환경 구축하기

Introduction

안수찬 @dobestan

안수찬 @dobestan

소프트웨어 생태계에 기여할 수 있는 실용주의 프로그래머가 되고자 합니다. 나는 안수찬이다. 그러므로 나는 할 수 있다.


python 패스트캠퍼스

Jupyterhub를 이용하여 Jupyter Notebook 실습 환경 구축하기

Posted by 안수찬 @dobestan on .
Featured

python 패스트캠퍼스

Jupyterhub를 이용하여 Jupyter Notebook 실습 환경 구축하기

Posted by 안수찬 @dobestan on .

최근에 패스트캠퍼스와 함께 몇몇 강의들을 진행해오고 있습니다. 데이터 사이언스 스쿨업무 자동화를 위한 파이썬 입문 CAMP 의 경우에는 주로 IPython Notebook 을 이용해서 실습을 진행하게 되는데, 수강생 모두 동일한 개발 환경을 갖추도록 하는 것이 큰 문제였습니다. 이러한 문제를 여러 유저가 함께 사용가능한 Jupyterhub를 이용하여 해결하였습니다.

Jupyter Preview

본 프로젝트는 다음의 목표를 가지고 진행되었습니다:

  1. 일단, 모든 수강생이 편하게 Jupyter Notebook 에 동시에 접속할 수 있어야 하고, 협업 작업도 어느정도 편하게 가능해야 한다.
  2. 서버가 확장성 ( Scalability )을 가질 필요는 굳이 없다.
  3. 파이썬 패키지에 대한 가상 환경이 수강생별로 주어질 필요가 없다. ( Virtualenv 등을 통한 패키지의 분리; 즉, 모두 동일한 파이썬 패키지를 사용한다. )
  4. 누구나 본 문서를 통해서, Jupyterhub를 설치하고 운영할 수 있도록 문서화해서 공유하자.

이러한 목표를 가지고 진행하였기에 본 문서의 내용이 Best Practice가 분명히 아니고, Jupyterhub 에서 제공하는 편리한 몇몇 기능들을 사용하지 않고 진행하였습니다. 크게 다음과 같은 순서로 진행됩니다.

  1. AWS EC2 인스턴스를 생성하고,
  2. 생성한 EC2 인스턴스에 Jupyterhub를 설치하고,
  3. LetsEncrypt를 통해서 무료 SSL을 발급받아 Jupyterhub 에 적용한 뒤,
  4. Nginx 를 통해서 80번 포트로 온 요청들을 443번 포트로 redirect 하면 Jupyterhub를 정상적으로 실행할 수 있다.
  5. 이제 수업별 계정을 생성하여 사용한다.

1. AWS EC2 인스턴스 생성하기

일단 JupyterHub 를 실행시켜둘 서버를 하나 준비하셔야 합니다. 그냥 저렴한 카페24 리눅스 가상서버 호스팅을 쓸까 하다가 ( 사실 거의 고민하지 않았습니다. 그냥 이제는 AWS로 시작하세요. ) 그냥 익숙하고 싼 것 같으면서 비싼 AWS EC2 를 사용하기로 결정하였습니다.

인스턴스 생성에 관해서는 훌륭한 블로그 포스트 가 상당히 많기 때문에 그대로 따라하시면 됩니다. Scalability에 대한 고려는 전혀 안하고 진행할 예정이기 때문에 저는 그냥 인스턴스 1개 생성해서 작업했습니다. 다만 몇 가지 설정만 추가적으로 해주시면 됩니다.

  • 웹 브라우저를 통해서 접속할 수 있도록, Security Group 에서 80번(HTTP), 443번(HTTPS) 포트는 열어주세요.
  • 실제로 1달 간 약 50명의 수강생 대상으로 운영해보니,
    • 기본 EBS 용량인 8GB는 엄청나게 부족합니다. 특히나, 데이터 분석의 경우에는 대용량의 데이터셋을 올리는 경우가 많아서 처음에 인스턴스를 생성하실 때 고려해주시면 좋겠습니다. ( 저도 이번에 새롭게 생성하면서는 100GB 로 시작했습니다; 추가 과금됩니다. )
    • 개인적인 목적이 아니라 강의 실습용으로 사용하신다면, 최소한 m4.large 정도는 사용하셔야 원활하게 사용하실 수 있습니다.
  • Elastic IP를 발급받아서 인스턴스와 연결해주시고, AWS Route53이나 기존에 네임서버를 관리하시는 곳에서 연결하시면 됩니다. ( play.dobest.io ~ 52.79.147.149 )

2. Jupyterhub 설치하기

Jupyterhub 는 기존에 우리가 사용하는 Jupyter Notebook ( single user notebook ) 과는 다르게 3가지 부분으로 구성됩니다. 물론 어떻게 구성되어 있는지 전혀 모르셔도 Jupyterhub를 설치하고 실행하는데에는 전혀 문제가 없습니다

  1. Hub: 여러 사용자들에 대한 정보와 Jupyter Notebook 프로세스를 관리하는 어플리케이션
  2. Proxy: 접속한 사용자 정보를 바탕으로 하나의 Jupyter Notebook 프로세스에 연결해주는 어플리케이션
  3. Single User Notebook: 하나의 계정별로 운영되는 하나의 Jupyter Notebook; 우리가 평소에 사용하는 Jupyter Notebook 프로세스라고 보시면 됩니다.

설치하시기 전에, Jupyterhub는 Python, Node.js 에 대한 의존성이 있기 때문에 배포 환경을 정확하게 맞춰주시는게 저는 맞다고 생각합니다. ( 공식 문서의 경우에는 그냥 System Python, System Node.js 로 설치합니다. )

설치는 다음의 문서를 참고하시면 됩니다:

$ pip install jupyterhub

이렇게 jupyterhub가 정상적으로 설치되면, 다음의 명령어로 기본 설정 파일인 jupyterhub_config.py을 생성할 수 있습니다:

$ jupyterhub --generate-config
$ ls -l
jupyterhub_config.py  
jupyterhub_cookie_secret  
jupyterhub.sqlite  

이렇게 생성된 jupyterhub_config.py 을 수정함으로써 Jupyterhub 의 기능을 변경하거나 확장하실 수 있습니다. 파이썬 파일이라 설정 파일 자체가 programmable 한 것이 엄청나게 장점이라고 생각됩니다. 그리고 이 포스트에서는 그렇게 할 만한 것이 없었다고 한다.

지금은 모든 곳에서 접속할 수 있도록, 또 기본으로 443번 포트를 통해서 접속할 수 있도록 설정을 변경해주시면 됩니다.

# jupyterhub_config.py
c.JupyterHub.ip = '0.0.0.0'  
c.JupyterHub.port = 443  

다만, 현재는 SSL이 적용되어 있지 않기 때문에 접속되지 않습니다.

3. SSL 적용하기

Jupyterhub는 기본적으로 SSL이 적용된 상태로 https 로만 접속이 가능합니다. ( 그리고 초록색 있는게 멋있습니다. ) 따라서 SSL 인증서를 발급받아, 적용해주시는게 좋습니다.

작년 같은 경우에만 해도, SSL 인증서를 구매해서 사용했어야 했는데, Let's Encrypt 라는 훌륭한 서비스가 나오게 되면서 누구나 편리하게 + 무료로 SSL을 발급받을 수 있게 되었습니다. 여기에서는 Let's Encrypt 를 통해서 인증서를 발급받아 사용하겠습니다.

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto --help
$ ./letsencrypt-auto certonly --standalone -d play.dobest.io

이렇게 특정 도메인에 대한 SSL 인증서를 발급받을 수 있고, 개인키 파일과 인증키 파일은 /etc/letsencrypt/live/play.dobest.io/ 에 저장되게 됩니다.

  • 개인키: /etc/letsencrypt/live/play.dobest.io/privkey.pem
  • 인증키: /etc/letsencrypt/live/play.dobest.io/fullchain.pem

따라서, jupyterhub_config.py 파일에서 다음과 같이 적용해주시면 됩니다:

# jupyterhub_config.py

c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/play.dobest.io/fullchain.pem'  
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/play.dobest.io/privkey.pem'  

이렇게 Jupyterhub 설치 후, SSL 까지 제대로 적용을 하셨다면 정상적으로 Jupyterhub를 실행하실 수 있습니다.

$ sudo jupyterhub

다만, 현재까지의 설정에서는 https://play.dobest.io/ 로는 접속이 가능하지만, http://play.dobest.io/ 로는 접속이 불가능합니다. 개인적으로는 이 부분이 Jupyterhub 에서 개선되어 자체적으로 해결될 수 있으면 참 좋겠다고 생각합니다.

4. Nginx

위의 HTTP로는 접속이 불가능한 문제는, 80번 포트 ( HTTP )로 접속한 경우 443번 포트 ( HTTPS )로 연결되도록 하면 금방 해결하실 수 있습니다. 다양한 방법들이 있겠지만 저는 Nginx 로 해결하였습니다. 물론 apt-get 을 통해서 설치하실 수도 있지만 저는 Nginx 의 경우에는 직접 소스를 빌드해서 사용하는 것을 선호합니다.

$ cd
$ NGINX_VERSION=1.8.1
$ wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
$ tar -xvzf nginx-${NGINX_VERSION}.tar.gz
$ cd nginx-${NGINX_VERSION}/
$ ./configure
$ make
$ sudo make install
$ sudo wget https://raw.githubusercontent.com/JasonGiedymin/nginx-init-ubuntu/master/nginx -O /etc/init.d/nginx
$ sudo chmod +x /etc/init.d/nginx

$ sudo update-rc.d -f nginx defaults

이렇게 Nginx 설치가 완료된 시점에서 80번 포트에서 443번 포트로 redirect 되도록 nginx 설정을 변경해주시면 됩니다. apt-get으로 설치하셨으면, /etc/nginx/sites-available/... 에, 위와 같이 소스를 빌드하셨으면 /usr/local/nginx/conf/nginx.conf 에 설정파일이 있습니다.

# /usr/local/nginx/conf/nginx.conf

...
    server {
        listen       80;
        server_name  play.dobest.io;
        return 301 https://$server_name$request_uri;
    }
...

사실 SSL 인증에 대한 부분도 Nginx 로 처리하고, proxy_pass를 통해서 Jupyterhub 프로세스로 연결해주는 방식이 맞지만, 여기서는 복잡할 것 같아 일부 생략하였습니다.

5. 유저별/수업별 계정 생성하기

저는 유저별 계정보다는 수업별 계정을 만드는게 낫겠다고 생각했습니다. 그 이유는 다음과 같습니다.

  1. 유저별 계정을 만들게 되면, 결국 유저별로 Jupyter Notebook 프로세스가 1개씩 실행되게 되는건데 리소스가 많이 들어비용을 감당할 자신이 없었습니다. 비효율적이라고 생각되었습니다.
  2. 수업에서 제가 작성하는 소스코드나 같이 수업을 듣는 수강생들이 작성하는 소스코드를 바로바로 확인할 수 있도록 하는 것이 낫다고 생각되었습니다.

따라서, 수업별로 계정을 따로 생성해주었습니다. JupyterHub의 기본 Authenticator는 PAM Authentication을 제공을 하기 때문에 수업별로 서버의 유저를 생성해주시면 됩니다. ubuntu 유저의 username, password로 jupyterhub 에 접속이 가능합니다.

단, 유저의 홈 디렉토리에 *.ipynb 파일들이 생성되기 때문에, 유저를 생성하실 때 홈 디렉토리도 같이 생성해주셔야 합니다:

$ sudo useradd -m dobestan
$ sudo passwd dobestan

추가적으로, 관리자 계정이나 이 유저에 대한 관리, 그리고 기본 Authenticator 를 확장해서 Github OAuth2 를 적용하는 방법 등에 대해서는 공식 문서에 너무 잘 설명되어 있기 때문에 여기서는 생략하겠습니다.

6. 사용하기

자, 이제는 서버에서 필요한 패키지를 설치하고, https://play.dobest.io/ 로 접속하셔서 사용하시면 됩니다. 이제 우리에게는 AWS로 부터 서버비가 청구되는 것을 기다리는 일만 남아있습니다.

학교나 교육기관에서 수업용/실습용으로 사용하시는 경우에는 제 이메일 [dobestan@gmail.com] 을 통해서 요청주시면 제가 수업용으로 사용하고 있는 https://play.dobest.io에 계정 생성해드리도록 하겠습니다.

안수찬 @dobestan

안수찬 @dobestan

https://dobest.io/

소프트웨어 생태계에 기여할 수 있는 실용주의 프로그래머가 되고자 합니다. 나는 안수찬이다. 그러므로 나는 할 수 있다.

View Comments...