안녕하세요? 오늘은 Kubernetes 환경에 JupyterHub를 설치 하는 방법에 대해서 알아 보도록 하겠습니다.
Kubernetes는 컨테이너를 쉽고 빠르게 배포/확장하고 관리를 자동화해주는 Container Orchestration Tool 입니다. Kubernetes 시스템을 통해, 다음을 제공 받을 수 있습니다.
JupyterHub는 여러 사용자가 공유하는 Jupyter Notebook 서버를 구축하는 데 사용되는 오픈 소스 프레임워크입니다. Jupyter Notebook을 사용 하는 의도는 각기 다양 합니다. 어떤 사람들은 머신러닝을 위해, 어떤 사람은 Spark Job을 통한 ETL을 위해, 어떤 사람은 다른 버전의 API를 사용 하기 위해 다양하게 사용 합니다. 이에 따라, 각자 사용 하는 노트북 파일과 커널을 분리 해 줄 필요가 있었고, 이에 따라 다양한 사용자 인증 제어, 커널 관리 등을 제공 할 수 있는 JupyterHub가 등장 하게 되었습니다.
왜 JupyterHub on K8S 일까요? JupyterHub는 Spawner라는 인터페이스를 통해, 사용자 마다 별개의 Jupyter Server를 제공 할 수 있게 합니다. K8S 환경에서는 KubeSpawner를 이용하여, K8S의 Secret, Node, Storage 등, 다양한 리소스들을 사용 할 수 있다는 것이 장점입니다.
또한, 원하는 이미지로 Pod을 생성 하는 것을 선택하게 할 수 있고, 또한, Secret에 대한 Namespace 수준의 권한 제어 등, Jupyter Server 운영의 입장에서 얻을 수 있는 이득이 많습니다.
그리고, 공식 Helm 차트를 제공하여, 편리 하고 빠른 배포 또한 제공 합니다.
사진으로 내부 아키텍처를 표현하면 다음과 같습니다.
사전에 준비 해야 할 프로그램 목록 입니다. 해당 프로그램 들에 대한 사전적인 지식이 있어야 합니다.
일단, JupyterHub Helm Chart Repository를 등록 합니다.
helm repo add jupyterhub https://jupyterhub.github.io/helm-chart/
helm repo update
그 다음 빈 폴더를 생성 한 후, 해당 폴더에 config.yaml
을 생성 합니다. config.yaml
에는 다음 내용을 작성 합니다.
사용 할 Docker Image를 명시하기 위함 입니다. 도커 이미지 내, Jupyter Kernel 세팅이 되어 있다면 사용 가능합니다.
singleuser:
image:
name: jupyter/minimal-notebook
tag: latest
만약 의존성 설치 및 다른 파일 등의 복사가 필요 하다면 다음과 같이 Dockerfile을 만든 후 build 할 수 있습니다.
FROM jupyter/minimal-notebook:latest
RUN pip install --no-cache-dir astropy
그 이후에는 터미널에 다음을 입력 합니다.
helm upgrade --cleanup-on-fail \
<helm-release-name> jupyterhub/jupyterhub \
--namespace <k8s-namespace> \
--create-namespace \
--version=<chart-version> \
--values config.yaml
<helm-release-name>
: Helm Release Name을 의미 하며, 여러 개의 차트 설치들을 구분 하기 위해 사용 합니다.<k8s-namespace>
: Kubernetes Cluster내의 어느 Namespace에 설치 할 지 선택합니다. --create-namespace
옵션을 통해, 없는 경우 Namespace를 같이 설치하는 역할 또한 수행 합니다.<chart-version>
: chart-version을 선택 합니다. 현재 최신 버전은 2.0.0 입니다.예시 입니다. 먼저, minikube 시작을 완료 해 주신 후에, Helm 명령어를 수행 합니다.
minikube start
helm upgrade --cleanup-on-fail \
jphub-k8s jupyterhub/jupyterhub \
--namespace jphub-k8s \
--create-namespace \
--version=2.0.0 \
--values config.yaml
kubectl --namespace=jphub-k8s port-forward service/proxy-public 8080:http
만약 minikube에 Jupyter Kernal Image load를 하지 않으셨다면 다음과 같이, Image load를 수행 하셔야 합니다.
minikube image load jupyter/minimal-notebook:latest
그 다음 http://localhost:8080
을 접속 하면 다음과 같은 화면들을 확인 할 수 있습니다. (기본 아이디, 비밀번호는 admin/admin 입니다.)
config.yaml을 수정 함으로 다양한 Customize를 수행 할 수 있습니다.
OAuth 인증을 수행 할 수 있습니다. 아래 예제는 Github 예제 입니다.
singleuser:
image:
name: jupyter/minimal-notebook
tag: latest
hub:
config:
GitHubOAuthenticator:
client_id: <id token>
client_secret: <secret token>
oauth_callback_url: http://localhost:8080/hub/oauth_callback
allowed_organizations:
- org:team
scope:
- read:org
JupyterHub:
authenticator_class: github
유저로 하여금, 다양한 Docker Image로 구성된 커널 중 하나를 선택 할 수 있게 할 수 있습니다. Kubespawner를 이용 하여, image, env, cpu limit, secret 등, 많은 Kubernetes 내의 자원을 이용 할 수 있습니다. 공식 Kubespawner Document도 존재 합니다.
singleuser:
# Defines the default image
image:
name: jupyter/minimal-notebook
tag: 2343e33dec46
profileList:
- display_name: "Minimal environment"
description: "To avoid too much bells and whistles: Python."
default: true
- display_name: "Datascience environment"
description: "If you want the additional bells and whistles: Python, R, and Julia."
kubespawner_override:
image: jupyter/datascience-notebook:2343e33dec46
- display_name: "Spark environment"
description: "The Jupyter Stacks spark image!"
kubespawner_override:
image: jupyter/all-spark-notebook:2343e33dec46
- display_name: "Learning Data Science"
description: "Datascience Environment with Sample Notebooks"
kubespawner_override:
image: jupyter/datascience-notebook:2343e33dec46
lifecycle_hooks:
postStart:
exec:
command:
- "sh"
- "-c"
- >
gitpuller https://github.com/data-8/materials-fa17 master materials-fa;