Kubeflow 1.0 on AWS #2 Notebookの作成


はじめに

これは、Kubeflow 1.0 をAWSで構築する記事です。
動作確認が主な目的ですので、本番環境での利用は全く想定していません。

前回まで

Kubeflow 1.0 on AWS #1 構築

今回の内容

Kubeflow上で Jupyter Notebookを作成してみます

Notebookの作成(GUI)

New Serverを選択

demo1と名前で Notebook を作成します

こんな感じでで作成中になります

作成が終わって、CONNECTを選択します

Notebookに繋がりました

Notebookを操作してみる

デフォルトだとpython3しかないようです

rootもsudoも使えないので、root権限が必要な作業はカスタムイメージを作成する必要がありそうです

スクショは載せていないですが、gitは入ってました

Keras は入っていないっぽい( pip等で入れればいいだけなので大した問題ではない)

試しにこちらと同じコード(keras)を流すと動きました。学習時間を短縮するために、epoch数は2に変えました

Kerasのバージョンが違うっぽいので、 accをaccuracyに置換しました

所感

Notebookとしては問題なく動いているようです

環境確認

get all -n anonymous
NAME          READY   STATUS    RESTARTS   AGE
pod/demo1-0   2/2     Running   0          28m

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/demo1   ClusterIP   10.100.123.227   <none>        80/TCP    28m

NAME                     READY   AGE
statefulset.apps/demo1   1/1     28m

kubectl get pv | grep demo1

pvc-e68e0e8e-6eae-11ea-8b88-0ee99a06437c 10Gi RWO Delete Bound anonymous/workspace-demo1 gp2 30m
```

Notebookの実態は、StatefulSetであり、PV(AWSなのでEBS)がついていることがわかります。
そして、Serviceとして、ClusterIPを持っているようです。

istioのvirtualserviceの確認

kubectl get virtualservice -A
NAMESPACE   NAME                         GATEWAYS                      HOSTS                      AGE
anonymous   notebook-anonymous-demo1     [kubeflow/kubeflow-gateway]   [*]                        37m
kubeflow    argo-ui                      [kubeflow-gateway]            [*]                        23h
kubeflow    centraldashboard             [kubeflow-gateway]            [*]                        23h
kubeflow    google-api-vs                                              [www.googleapis.com]       23h
kubeflow    google-storage-api-vs                                      [storage.googleapis.com]   23h
kubeflow    grafana-vs                   [kubeflow-gateway]            [*]                        23h
kubeflow    jupyter-web-app              [kubeflow-gateway]            [*]                        23h
kubeflow    katib-ui                     [kubeflow-gateway]            [*]                        23h
kubeflow    kfam                         [kubeflow-gateway]            [*]                        23h
kubeflow    metadata-grpc                [kubeflow-gateway]            [*]                        23h
kubeflow    metadata-ui                  [kubeflow-gateway]            [*]                        23h
kubeflow    ml-pipeline-tensorboard-ui   [kubeflow-gateway]            [*]                        23h
kubeflow    ml-pipeline-ui               [kubeflow-gateway]            [*]                        23h
kubeflow    tensorboard                  [kubeflow-gateway]            [*]                        23h
bash-4.2# 

notebook-anonymous-demo というvirtualserviceが作成されていることが分かります。

kubectl get virtualservice notebook-anonymous-demo1 -n anonymous -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  creationTimestamp: "2020-03-25T15:40:06Z"
  generation: 1
  name: notebook-anonymous-demo1
  namespace: anonymous
  ownerReferences:
  - apiVersion: kubeflow.org/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: Notebook
    name: demo1
    uid: e68f6959-6eae-11ea-9e97-0a81a7804a98
  resourceVersion: "567338"
  selfLink: /apis/networking.istio.io/v1alpha3/namespaces/anonymous/virtualservices/notebook-anonymous-demo1
  uid: e693d4ed-6eae-11ea-9e97-0a81a7804a98
spec:
  gateways:
  - kubeflow/kubeflow-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /notebook/anonymous/demo1/
    rewrite:
      uri: /notebook/anonymous/demo1/
    route:
    - destination:
        host: demo1.anonymous.svc.cluster.local
        port:
          number: 80
    timeout: 300s

こちらの設定で、/notebook/anonymous/demo1/ というpathなら、notebookにつながるようになっていることが分かります。

ちなみにstatefulset自体のyamlは以下のようになっています

kubectl get statefulset demo1 -n anonymous -o yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2020-03-25T15:40:05Z"
  generation: 1
  name: demo1
  namespace: anonymous
  ownerReferences:
  - apiVersion: kubeflow.org/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: Notebook
    name: demo1
    uid: e68f6959-6eae-11ea-9e97-0a81a7804a98
  resourceVersion: "567535"
  selfLink: /apis/apps/v1/namespaces/anonymous/statefulsets/demo1
  uid: e690c53b-6eae-11ea-9e97-0a81a7804a98
spec:
  podManagementPolicy: OrderedReady
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      statefulset: demo1
  serviceName: ""
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo1
        notebook-name: demo1
        statefulset: demo1
    spec:
      containers:
      - env:
        - name: NB_PREFIX
          value: /notebook/anonymous/demo1
        image: gcr.io/kubeflow-images-public/tensorflow-1.15.2-notebook-cpu:1.0.0
        imagePullPolicy: IfNotPresent
        name: demo1
        ports:
        - containerPort: 8888
          name: notebook-port
          protocol: TCP
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /home/jovyan
          name: workspace-demo1
        - mountPath: /dev/shm
          name: dshm
        workingDir: /home/jovyan
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 100
      serviceAccount: default-editor
      serviceAccountName: default-editor
      terminationGracePeriodSeconds: 30
      volumes:
      - name: workspace-demo1
        persistentVolumeClaim:
          claimName: workspace-demo1
      - emptyDir:
          medium: Memory
        name: dshm
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
status:
  collisionCount: 0
  currentReplicas: 1
  currentRevision: demo1-dc56967ff
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updateRevision: demo1-dc56967ff
  updatedReplicas: 1

notebookを削除する

GUIから普通に削除します。PersistentStorageを使っているとデータは残るようです

GUIからは消えましたが、確かにPV/PVCが残っていることは確認できました

kubectl get pvc -n anonymous
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
workspace-demo1   Bound    pvc-e68e0e8e-6eae-11ea-8b88-0ee99a06437c   10Gi       RWO            gp2            48m

もう一度 notebookを作成する

demo2というnotebookを新規で作成し、既存のストレージを作成するという選択肢があるので、それを選択しました

接続してみます

予想通りですが、データが残っていることが分かります。
既存のPVCを指定できるので、例えば、EFSでPVCを作成して、Notebookのデータは共有ストレージに保存する的なこともできそうです。(いつかやってみたいと思います)