Kubeflow – Jupyter Notebooks 커스텀 이미지

주피터 노트북 커스텀 이미지

주피터 노트북 커스텀 이미지 만드는 방법

주피터 노트북에서 사용할 사용자 커스텀 이미지를 만드는 방법에 대해서 알아보겠습니다.

Kubeflow에서 사용자가 만든 커스텀 이미지를 사용하려면 몇 가지 요구 사항을 충족해야합니다. Kubeflow는 컨테이너 이미지가 실행되면, 주피터가 자동적으로 시작되는 것으로 알고 있습니다. 그래서 컨테이너 이미지에 주피터를 시작하는 기본 명령을 설정해야합니다.

먼저 주피터를 시작하는 명령어가 필요합니다. 다음은 주피터를 실행하는 명령어 입니다.

jupyter notebook

그리고 주피터에게 설정 정보를 넘겨줘야합니다. 다음은 주피터 실행에 필요한 설정 정보들입니다.

  • 작업 디렉토리 : /home/jovyan 디렉토리는 쿠버네티스 PV와 마운트 됩니다. –notebook-dir=/home/jovyan
  • 접근 허용 IP : 주피터 노트북 서버에 모든 IP 에서 접근가능하도록 합니다. –ip=0.0.0.0
  • 노트북 루트 권한 : 사용자가 노트북을 루트로 실행하는것을 허용합니다. –allow-root
  • 포트 설정 : 주피터 포드의 포트를 설정합니다. –port=8888
  • 인증 비활성화 : 주피터의 인증 기능을 비활성화 합니다. Kubeflow에서 사용하는 istio가 인증을 담당하기 때문에, 주피터에서 제공하는 기능을 비활성화 시키는것입니다. –NotebookApp.token=” –NotebookApp.password=”
  • 모든 오리진(origin) 허용 : 주피터 노트북 서버에 모든 오리진이 접근할 수 있도록 허용합니다. –NotebookApp.allow_origin=’*’
  • 기본 URL 설정 : Kubeflow에서 노트북 서버를 관리하는 노트북 컨트롤러는 NB_PREFIX 라는 환경 변수를 사용하여 노트북 서버의 기본 URL을 넘겨줍니다. –NotebookApp.base_url=${NB_PREFIX}

다음은 Dockerfile에 포함해야할 CMD 예제입니다.

ENV NB_PREFIX /

CMD ["sh","-c", "jupyter notebook --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX}"]

주의 하실 점은 ${NB_PREFIX} 라는 환경 변수를 사용하기 때문에 sh 이나 bash 등을 이용해서 노트북을 실행해야합니다.

주피터 노트북 커스텀 이미지 만들기

기존 주피터 노트북 이미지로 만들기

Kubeflow에서 기본으로 제공하는 주피터 노트북 이미지를 가지고 커스텀 이미지를 만들어 보겠습니다.

다음은 https://github.com/kubeflow/kubeflow/blob/master/components/tensorflow-notebook-image/Dockerfile 을 약간 수정한 Dockerfile 입니다.

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

ARG BASE_IMAGE=tensorflow/tensorflow:2.1.0-py3-jupyter

FROM $BASE_IMAGE

ARG TF_SERVING_VERSION=0.0.0
ARG NB_USER=jovyan

# TODO: User should be refactored instead of hard coded jovyan

USER root

ENV DEBIAN_FRONTEND noninteractive

ENV NB_USER $NB_USER

ENV NB_UID 1000
ENV HOME /home/$NB_USER
ENV NB_PREFIX /


# Use bash instead of sh
SHELL ["/bin/bash", "-c"]

RUN apt-get update && apt-get install -yq --no-install-recommends \\
  apt-transport-https \\
  build-essential \\
  bzip2 \\
  ca-certificates \\
  curl \\
  g++ \\
  git \\
  gnupg \\
  graphviz \\
  locales \\
  lsb-release \\
  openssh-client \\
  sudo \\
  unzip \\
  vim \\
  wget \\
  zip \\
  emacs \\
  python3-pip \\
  python3-dev \\
  python3-setuptools \\
  && apt-get clean && \\
  rm -rf /var/lib/apt/lists/*

# Install Nodejs for jupyterlab-manager
RUN curl -sL <https://deb.nodesource.com/setup_12.x> | sudo -E bash -
RUN apt-get update && apt-get install -yq --no-install-recommends \\
  nodejs \\
  && apt-get clean && \\
  rm -rf /var/lib/apt/lists/*

ENV DOCKER_CREDENTIAL_GCR_VERSION=1.4.3
RUN curl -LO <https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases/download/v${DOCKER_CREDENTIAL_GCR_VERSION}/docker-credential-gcr_linux_amd64-${DOCKER_CREDENTIAL_GCR_VERSION}.tar.gz> && \\
    tar -zxvf docker-credential-gcr_linux_amd64-${DOCKER_CREDENTIAL_GCR_VERSION}.tar.gz && \\
    mv docker-credential-gcr /usr/local/bin/docker-credential-gcr && \\
    rm docker-credential-gcr_linux_amd64-${DOCKER_CREDENTIAL_GCR_VERSION}.tar.gz && \\
    chmod +x /usr/local/bin/docker-credential-gcr

# Install AWS CLI
RUN curl "<https://s3.amazonaws.com/aws-cli/awscli-bundle.zip>" -o "/tmp/awscli-bundle.zip" && \\
    unzip /tmp/awscli-bundle.zip && ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws && \\
    rm -rf ./awscli-bundle


RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \\
    locale-gen

ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

# Create NB_USER user with UID=1000 and in the 'users' group
# but allow for non-initial launches of the notebook to have
# $HOME provided by the contents of a PV
RUN useradd -M -s /bin/bash -N -u $NB_UID $NB_USER && \\
    chown -R ${NB_USER}:users /usr/local/bin && \\
    mkdir -p $HOME

RUN export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \\
    echo "deb <https://packages.cloud.google.com/apt> $CLOUD_SDK_REPO main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \\
    curl <https://packages.cloud.google.com/apt/doc/apt-key.gpg> | apt-key add - && \\
    apt-get update && \\
    apt-get install -y google-cloud-sdk kubectl

# Install Tini - used as entrypoint for container
RUN cd /tmp && \\
    wget --quiet <https://github.com/krallin/tini/releases/download/v0.18.0/tini> && \\
    echo "12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855 *tini" | sha256sum -c - && \\
    mv tini /usr/local/bin/tini && \\
    chmod +x /usr/local/bin/tini

# NOTE: Beyond this point be careful of breaking out
# or otherwise adding new layers with RUN, chown, etc.
# The image size can grow significantly.

# Install base python3 packages
RUN pip3 --no-cache-dir install \\
    jupyter-console==6.0.0 \\
    jupyterlab \\
    xgboost \\
    kubeflow-fairing==0.7.1.1


RUN docker-credential-gcr configure-docker && chown ${NB_USER}:users $HOME/.docker/config.json

# Configure container startup
EXPOSE 8888
USER jovyan
ENTRYPOINT ["tini", "--"]
CMD ["sh","-c", "jupyter lab --notebook-dir=/home/${NB_USER} --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX}"]

베이스 이미지를 tensorflow/tensorflow:2.1.0-py3-jupyter 로 사용하였고, 파이썬 패키지인 kubeflow-fairing을 0.7.1 버전으로 설치하였습니다. 그리고 CMD를 수정해서 주피터 노트북이 아니라, 주피터 랩이 실행되게 하였습니다.

docker build -t kangwoo/tensorflow-2.1.0-notebook-cpu:1.0.0 .

생성한 컨테이너 이미지를 컨테이너 이미지 레지스트리에 푸시 하려면 접근 권한이 필요합니다. “컨테이너 이미지 레지스트리에 접근할 수 있도록 도커 설정하기”를 참고하기 바랍니다.

docker push kangwoo/tensorflow-2.1.0-notebook-cpu:1.0.0

노트북 목록 화면에서, “NEW SERVER” 버튼을 클릭하여, 새로운 노트북 서버를 생성하는 페이지로 이동합니다.

“Custom Image”를 체크하고, 새로 만든 커스텀 이미지 주소를 입력합니다.

나머지 필드에는 적당한 값을 입력하고, “LAUNCH” 버튼을 클릭하여, 새로운 노트북 서버를 생성합니다.

노트북 서버 목록에서 CONNECT 버튼을 누르고, 노트북 랩에 접속할 수 있습니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다