前回、Kubernetes環境でociイメージ(open container initiative image)のローカルレジストリの環境を構築しました。

先日、クラウド環境の勉強と開発環境のセットアップを兼ねてKubernetesのセットアップを行いました。 %%BlogCard https://dream.drivendevelopment.jp/dev-environment/k8s-:Kubernetesの ローカルイメージレジストリを dockerlessで作る
せっかく環境ができたのでjupyterlab + pytorchのDeeplearning環境を構築してみましょう。
dockerを使わず(cri-o環境なので)に、でもdockerfileを使って構築していきます。
buildahとdockerfile
OCIイメージの構築を行うためにbuildahを利用します。
$ sudo apt install buildah
$ buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
$ buildah containers
CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME
前回の記事のようにbuildahのコマンドを使ってimageを作成することもできるのですが、今回は楽をしたいので”dockerfile”を使って構築してみます。
dockerfile
準備したdockerfileは以下のようになります。
FROM ubuntu
LABEL maintainer="hassyheisaku"
ENV USER_NAME heisaku
ENV UID 1000
RUN useradd -m -u ${UID} ${USER_NAME}
ENV HOME /home/${USER_NAME}
ENV TZ Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV PATH ${HOME}/anaconda3/bin:${PATH}
WORKDIR ${HOME}
RUN apt-get update \
&& apt-get install -y curl \
wget \
git \
unzip \
imagemagick \
bzip2 \
vim \
libsm6 \
libgl1-mesa-dev \
build-essential \
libssl-dev
RUN wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh -P ${HOME} \
&& bash ${HOME}/Anaconda3-2020.02-Linux-x86_64.sh -b -p ${HOME}/anaconda3 \
&& rm ${HOME}/Anaconda3-2020.02-Linux-x86_64.sh \
&& ${HOME}/anaconda3/bin/conda build purge-all
RUN ${HOME}/anaconda3/bin/conda update -y --all
RUN ${HOME}/anaconda3/bin/conda install -y -c conda-forge opencv
RUN ${HOME}/anaconda3/bin/conda install -y -c intel tensorflow
RUN ${HOME}/anaconda3/bin/conda install -y keras
RUN ${HOME}/anaconda3/bin/conda install -y -c pytorch pytorch torchvision
RUN ${HOME}/anaconda3/bin/conda install -y jupyterlab
RUN ${HOME}/anaconda3/bin/conda install -y pandas matplotlib scipy scikit-learn scikit-image h5py seaborn numpy Pillow tqdm
RUN ${HOME}/anaconda3/bin/conda install -y -c conda-forge nodejs
USER ${USER_NAME}
必要そうなライブラリをひたすらインストールするような中身になってます。。。
イメージのビルド
構築はbuildah bud
オプションを使います。
$ buildah bud --tag pytorch-jupyter -f dockerfile .
:
Writing manifest to image destination
Storing signatures
--> b73156b381d
b73156b381deed36a54730b7be3152a2088c78a289baf6ea8d570ddd59be9fc5
$ buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/pytorch-jupyter latest b73156b381de 11 minutes ago 14.3 GB
docker.io/library/ubuntu latest f643c72bc252 6 days ago 75.3 MB
いろいろ突っ込んだせいか14.3GBという巨大なイメージになってしまいました。
ローカルレジストリへの登録
前回作成したローカルレジストリに登録します。
$ buildah --tls-verify=false push pytorch-jupyter docker://<local registry ip>:5000/heisaku/pytorch-jupyter:latest
kubernetesでのjupyterlabコンテナ作成
pv/pvc向けディスクの準備
jupyterlabのデータはpermanent volumeに保存したいので、先にpv/pvc向けのディスクを作成します。
前回の記事と同様にnfs
のボリュームを準備します。
マスターノード(nfs提供側)
$ sudo apt install nfs-kernel-server
$ sudo mkdir -p /var/nfs/exports
$ sudo mkdir /var/nfs/exports/jupyter # local registry用
$ sudo chown 1000.1000 /var/nfs/exports/jupyter
$ echo "/var/nfs/exports <ローカルドメイン 192.168.0.0/24>(rw,sync,no_root_squash) 127.0.0.1/32(rw,sync,no_root_squash)" | sudo tee -a /etc/exports
$ sudo systemctl restart nfs-server rpcbind
$ sudo systemctl enable nfs-server rpcbind
ワーカーノード全部(nfs client側)
$ sudo apt install -y nfs-common;
pv/pvc向けマニフェスト
jupyter-persistentvolume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: jupyter-pv
labels:
k8s-app: my-jupyter
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteMany
nfs:
path: /var/nfs/exports/jupyter
server: <nfs提供側サーバーIP>
persistentVolumeReclaimPolicy: Retain
storageClassName: sc-jupyter
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jupyter-pvc
namespace: my-jupyter
labels:
k8s-app: my-jupyter
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Gi
storageClassName: sc-jupyter
name space “my-jupyter”を作成してpv/pvcを作成します。
$ kubectl create ns my-jupyter
namespace/my-jupyter created
$ kubectl apply -f jupyter-persistentvolume.yaml
persistentvolume/jupyter-pv created
persistentvolumeclaim/jupyter-pvc created
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
jupyter-pv 50Gi RWX Retain Bound my-jupyter/jupyter-pvc sc-jupyter 98s
$ kubectl get pvc -n my-jupyter
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jupyter-pvc Bound jupyter-pv 50Gi RWX sc-registry 12m
jupyterデプロイメント向けマニフェスト
jupyter-deployment.yaml
kind: Service
apiVersion: v1
metadata:
name: my-jupyter-nodeip
namespace: my-jupyter
labels:
app: my-jupyter
spec:
type: NodePort
ports:
- name: http
port: 8888
targetPort: 8888
selector:
app: my-jupyter
externalIPs:
- <jupyterアクセス向け外部IP>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: jupyterlab-config
namespace: my-jupyter
data:
jupyterlab-pass: "heisaku"
jupyterlab-user-name: "heisaku"
jupyterlab-user-id: "1000"
jupyterlab-base-url: "/heisaku/"
jupyterlab-home-dir: "/jupyter-pvc"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyterlab-deployment
namespace: my-jupyter
labels:
app: my-jupyter
spec:
replicas: 1
selector:
matchLabels:
app: my-jupyter
template:
metadata:
labels:
app: my-jupyter
spec:
containers:
- name: my-jupyter
image: <local registry ip>:5000/heisaku/pytorch-jupyter:latest
ports:
- name: http
containerPort: 8888
env:
- name: JUPYTERLAB_PASS
valueFrom:
configMapKeyRef:
name: jupyterlab-config
key: jupyterlab-pass
- name: UID
valueFrom:
configMapKeyRef:
name: jupyterlab-config
key: jupyterlab-user-id
- name: USER_NAME
valueFrom:
configMapKeyRef:
name: jupyterlab-config
key: jupyterlab-user-name
- name: BASE_URL
valueFrom:
configMapKeyRef:
name: jupyterlab-config
key: jupyterlab-base-url
- name: HOME_DIR
valueFrom:
configMapKeyRef:
name: jupyterlab-config
key: jupyterlab-home-dir
command:
- "sh"
- "-c"
- |
PASSWORD=$(python -c 'from notebook.auth import passwd;print(passwd("'${JUPYTERLAB_PASS}'"))')
jupyter-lab --port=8888 --ip=0.0.0.0 --no-browser --NotebookApp.token='' --NotebookApp.base_url=${BASE_URL} \
--NotebookApp.password=${PASSWORD} --NotebookApp.notebook_dir=${HOME_DIR}
volumeMounts:
- mountPath: "/jupyter-pvc"
name: jupyter-pvc
volumes:
- name: jupyter-pvc
persistentVolumeClaim:
claimName: jupyter-pvc
readOnly: false
デプロイします。
$ kubectl apply -f jupyter-deployment.yaml
service/my-jupyter-clusterip created
configmap/jupyterlab-config created
deployment.apps/jupyterlab-deployment created
$ kubectl get po -n my-jupyter
NAME READY STATUS RESTARTS AGE
jupyterlab-deployment-846585dc59-qs5dc 1/1 Running 0 25m
ブラウザでアクセスしてみる
https://<external IP>:8888/heisaku/
動いたでしょうか?
まとめ
buildahでイメージを作成して、ローカルレジストリに登録して、k8sにデプロイして
と一通りの流れを試すことができましたね。
ただ、機械学習するには僕の”herobox”は非力過ぎるようで学習が一向に進まないことがわかりました。
今の環境は、もっと軽いウェブサービスの開発などに活用したほうが良さそうです。
enjoy!