Amazon EKSでKubeflowを立ち上げてJupyter Notebookを触るまでの道のり -Kubeflow v1.0.1 Released-

Yuya Sugano
36 min readApr 4, 2020

--

COVID-19でリモートワークが推奨されているため自宅にこもりがちです。self-isolateするだけでなくself-studyに最適な時機なのではないでしょうか。そんなわけで以前より興味のあったKubeflowをEKSのKubernetesクラスタ上に設置して簡単なJupyter Notebookを作るテストを行ってみました。KubeflowはKubernetes上で機械学習のモデル開発やエンドポイントのデプロイをサポートするオープンソースのシステムです。データサイエンスの職能領域は主にビジネス寄りとされるデータサイエンティストとエンジニア寄りの機械学習エンジニアに枝分かれして語られます。機械学習エンジニア領域ではMLOpsの興隆と共に実際に構築したモデルを運用しテストおよび改善していく必要性が以前にも増して高まってきているようです。Amazon SagemakerのようなマネージドサービスでML環境の運用を行うことも当然考えられますが、Kubeflowを使用するとクラウドやオンプレを問わず簡単にML環境を展開しMLOpsを実現することができるようになります。

Unleash a power of container and ML workflows

以下が記事執筆時点の状態です。前提として以下の条件を満たしていれば概ね理解できる内容だと思います。初心者向けです。

  • AWSの操作ができる(コンソールやaws cliを使用して)
  • 機械学習やMLOpsについて聞いたことがある、多少知識がある
  • Dockerを使用したことがある、Kubernetesに興味がある

※AWSのリソース操作にTerraform/Cloudformation等のツールは使用しておりません

目次です。

  • Amazon EKSについて
  • Kubeflowについて
  • EKSでKubeflowのデプロイ
  • NotebookサーバとJupyterNotebook

Amazon EKSについて

Amazon EKS(Elastic Kubernetes Service)はKubernetesマスターやKubernetesプロセスなどのKubernetesコントロールプレーンの管理をAWSにお任せできるKubernetesマネージドサービスです。ワーカノード(コンテナが起動するホスト)についてはEC2が利用できる他、昨年よりFargateへの対応も始まりました。AWS上でコンテナ環境を使用するには ECS on EC2 / ECS on Fargate / EKS on EC2とこれまで3つの選択肢がありましたが、EKS on Fargateが加わり4つの方法が選択できるようになりました。EKS on EC2では得られなかったサーバレスコンピューティングのメリットをEKS(Elastic Kubernetes Service)でも享受できるようになっています。FargateではEC2を使用する必要はないので、ポッドのインスタンスの管理、それに伴うパッチやスケーリングの手当が不要になります。ただしFargateを利用する場合には複数の制約事項があるため事前に確認が必要です(例えばDaemonSet、Privileged Podsが実行できないなど)。今回はFargateではなくEC2のワーカノードを使用しています。

コントロールプレーンはマスターノードおよびワーカノードで稼働する各プロセスを指しています。Kubernetesマスターにおける kube-apiserver kube-controller-manager kube-scheduler やKubernetesワーカノード上のkubelet kube-proxy プロセスです。AWS EKSではコントロールプレーンが、リージョン内の3つのアベイラビリティーゾーンにまたがって動作する2つ以上の APIサーバーノードと3つの etcd ノードで構成されます。異常なコントロールプレーンインスタンスが検出されると自動的に置き換え、必要に応じてリージョン内のアベイラビリティーゾーン全体でインスタンスを再起動します。Kubernetesのバージョン管理やコントロールプレーンの可用性がAWSによって担保されるため、信頼性やセキュリティの高いコンテナオーケストレーションが実現できます。この利点は他社のマネージドサービスにおいても同様だと思います。[1]

AWS EKSを使用することで他のAWSコンポーネントとの連携も可能になります。他のパブリッククラウドにおいても同様のコンポーネントは存在すると思いますが機能面で多少の違いはあるようでした。GKE(Google Kubernetes Engine)、ACS(Azure Container Service)が他の代表的なマネージドサービスです。

  • Amazon ECR(Elastic Container Registry)上のコンテナイメージの使用
  • ロードバランサーの使用(ELBやALB)
  • IAM(Identity and Access Management)による認証や認可
  • Amazon VPCによるネットワーク分離
  • CloudWatch Logsによるログ記録、監査記録

紹介されているAWS EKSの開始方法です。AWS EKSでは eksctl というクラスタ作成および管理用のツールを使用することで 1. 2. および 3. まで一気通貫で出来てしまいます。

  1. aws cli または aws sdk を使って Amazon EKS クラスタを作成する
  2. Amazon EKS クラスタに登録するワーカノードを起動する
  3. Kubernetes ツール(kubectl)をクラスタと通信できるように設定する
  4. Amazon EKS クラスタでアプリケーションをデプロイし、管理する
How does Amazon EKS work?

クラスタのマスターノードへの操作はすべて kubectl で出来るため eksctl および kubectl をインストールしておけばAWS EKSによるクラスタ構築やKubernetes操作はすべて問題なく行えます。以下の手順に従ってeksctl および kubectl をインストールしましょう。aws cli のバージョン 1.16.308 以上および GitTag のバージョン 0.11.0 以上が必要です。[2]

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html

$ aws --version
aws-cli/1.16.212 Python/2.7.12 Linux/4.4.0-62-generic botocore/1.12.202

aws cli をアップグレードしました。

$ pip install awscli --upgrade --user
Collecting awscli
Downloading https://files.pythonhosted.org/packages/8f/86/54c770eac9c1dfcc4a223f8b2a275d2412b2c79282eaad0132272f29dc0c/awscli-1.16.308-py2.py3-none-any.whl (2.7MB)
|????????????????????????????????| 2.7MB 1.7MB/s
Successfully installed awscli-1.16.308

バイナリをインストールおよび解凍して /usr/local/bin に置くだけです。

$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version
[?] version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.11.1"}

クラスタの作成とサンプルのゲストアプリケーションをテストします。[3]

クラスタの作成

# クラスタおよびワーカノードを作成
$ eksctl create cluster --name guest --version 1.14 --region ap-northeast-1 --nodegroup-name standard-workers --node-type t2.small --nodes 3 --nodes-min 1 --nodes-max 4 --managed
[?] EKS cluster "guest" in "ap-northeast-1" region is ready
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 8m23s
# ワーカノードは3ノードと宣言
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-18-221.ap-northeast-1.compute.internal Ready <none> 4m44s v1.14.9-eks-1f0ca9
ip-192-168-53-155.ap-northeast-1.compute.internal Ready <none> 4m44s v1.14.9-eks-1f0ca9
ip-192-168-69-72.ap-northeast-1.compute.internal Ready <none> 2m20s v1.14.9-eks-1f0ca9

ゲストブックアプリケーションの起動

# Redisマスターポッドとレプリカセットを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-master-controller.json
replicationcontroller/redis-master created
$ kubectl get rc
NAME DESIRED CURRENT READY AGE
redis-master 1 1 1 71s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-hdsbg 1/1 Running 0 4m51s
# Redisマスターサービスを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-master-service.json
service/redis-master created
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 15m
redis-master ClusterIP 10.100.9.22 <none> 6379/TCP 4m20s
# Redisスレーブポッドとレプリカセットを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-slave-controller.json
replicationcontroller/redis-slave created
$ kubectl get rc
NAME DESIRED CURRENT READY AGE
redis-master 1 1 1 7m56s
redis-slave 2 2 1 18s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-hdsbg 1/1 Running 0 8m7s
redis-slave-7x2j9 1/1 Running 0 29s
redis-slave-rm7h2 1/1 Running 0 29s
# Redisスレーブサービスを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-slave-service.json
service/redis-slave created
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 18m
redis-master ClusterIP 10.100.9.22 <none> 6379/TCP 7m13s
redis-slave ClusterIP 10.100.55.249 <none> 6379/TCP 25s
# ゲストブックアプリのポッドとレプリカセットを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/guestbook-controller.json
replicationcontroller/guestbook created
$ kubectl get rc
NAME DESIRED CURRENT READY AGE
guestbook 3 3 3 15s
redis-master 1 1 1 12m
redis-slave 2 2 2 5m13s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
guestbook-4cjtw 1/1 Running 0 42s
guestbook-kjnpn 1/1 Running 0 42s
guestbook-wxkbz 1/1 Running 0 42s
redis-master-hdsbg 1/1 Running 0 13m
redis-slave-7x2j9 1/1 Running 0 5m40s
redis-slave-rm7h2 1/1 Running 0 5m40s
# ゲストブックアプリのサービスを作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/guestbook-service.json
service/guestbook created
$ kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
guestbook LoadBalancer 10.100.19.13 ab196b23b717c11ea95f80e3e608119e-1578654295.ap-northeast-1.elb.amazonaws.com 3000:32699/TCP 36s app=guestbook
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 24m <none>
redis-master ClusterIP 10.100.9.22 <none> 6379/TCP 13m app=redis,role=master
redis-slave ClusterIP 10.100.55.249 <none> 6379/TCP 6m17s app=redis,role=slave

ゲストブックアプリのサービスにロードバランサーのURLが割り当てられるので外部向けのポート3000でアプリが利用できるか確認してください。ゲストブックアプリはゲストの名前を入力して『SUBMIT』をクリックすることで、ゲストの名前が記録できるアプリケーションです。

Guestbook access with the external port 3000

以下の手順で作成したリソースの削除およびKubernetesクラスタのクリーンアップを行いました。サービスおよびレプリカセットを kubectl delete で削除した後に eksctl delete でクラスタとワーカノードを削除します。

# リソースの削除
$ kubectl delete rc/redis-master rc/redis-slave rc/guestbook svc/redis-master svc/redis-slave svc/guestbook
replicationcontroller "redis-master" deleted
replicationcontroller "redis-slave" deleted
replicationcontroller "guestbook" deleted
service "redis-master" deleted
service "redis-slave" deleted
service "guestbook" deleted
$ kubectl get rc
No resources found in default namespace.
$ kubectl get pods
No resources found in default namespace.
# クラスタおよびワーカノードの削除
$ eksctl get cluster
NAME REGION
guest ap-northeast-1
$ eksctl delete cluster --name guest
[?] all cluster resources were deleted
$ eksctl get cluster
No clusters found

リソースを削除してもクラスタが動いていると課金されるため、不要なクラスタを削除し忘れないように注意してください。次にKubernetes上でML環境を構築するKubeflowについて概要を説明します。

Kubeflowについて

KubeflowはKubernetes上で機械学習のモデルの開発やエンドポイントのデプロイをサポートするツール群を提供するシステムです。機械学習のワークフローにおいてモデルの構築や推論サービスのデプロイ、それら一連の流れをDAG(有向非巡回グラフ)で表現し実行できるパイプラインなどが用意されています。例えば、KFServingはリソース定義によって TensorFlow、XGBoost、scikit-learn、PyTorch、ONNX の機械学習モデルによる推論サービスをサーバレスにKubeflow上に構築できるコンポーネントです。Katibはラーニングレートや深層学習のハイパーパラメータを自動で学習し可視化を行う機能とNeural Architecture Search を行う機能を提供しています。Kubeflowの主要なコンポーネントは以下の通りです。[4]

  • Kubeflow UI —クラスタ内で実行している ノートブックやジョブ、パイプラインなどへのアクセスを提供するWebユーザインターフェース
  • JupyterNotebook — ノートブックを管理するJupyterNotebookサーバを起動する、複数のサーバを起動して複数のノートブックの管理が可能
  • MLフレームワーク — 機械学習や深層学習における各種ライブラリ MXNet, Chainer, PyTorch, scikit-learn, TensorFlow, XGBoostを使用可能
  • Katib — ラーニングレートや深層学習のハイパーパラメータを自動で学習し可視化を行う機能とNeural Architecture Search を行う機能を提供
  • Pipelines(パイプライン) — 機械学習におけるワークフローをDAG(有向非巡回グラフ)を用いて定義するオーケストレーションツール
  • Fairing — ハイブリッドクラウド環境においてモデルのトレーニング、ビルドからデプロイまでをトレーニングジョブとして実行するツール
  • マルチフレームワークサービング — Kubernetesのエコシステムの一部として開発されたKFServingおよびSeldon Coreという2種類のフレームワークでモデルをデプロイ可能、Tensorflow Servingなども提供
  • Metadata — MLワークフローから生成されるメタデータを管理し追跡、メタデータはワークフローの実行履歴やモデルの情報、メトリック等々
Kubeflow Overview
Kubeflow and Application versioning

Kubeflow v1.0.xよりアプリケーションバージョンやアプリケーションステータスという概念が導入されました(上図はKubeflow v1.0.1における突合表)。アプリケーションバージョン1.0.0はこのKubeflowリリースおいて必要な基準を満たしStable(安定)であることを意味しています。以下はアプリケーションステータス列におけるStable/Beta/Alphaの見方です。

  • Stable — アプリケーションバージョン1.0.0に到達するための基準を満たしていること、またコミュニティがこのリリースのKubeflowに対してアプリケーションが安定していると見なしていること
  • Beta — アプリケーションバージョン1.0.0のリリースに向けて稼働していて、Stableの基準を満たすためのタイムラインを告知していること
  • Alpha アプリケーションがまだ開発の初期段階やKubeflowへインテグレーションしている途中の段階にあること

アプリケーションステータスによってサポートレベルが異なります。使用したいコンポーネントのバージョンからサポートのレベルを確認してください。Kubeflowコミュニティ有志によるベストエフォートのサポートが基本です。ボランタリーベースなので基本的にはトラブルを自力で解決する力が求められると思います。[5]

EKSでKubeflowのデプロイ

Kubeflowの概要を見てきました。ここからは実際にAWS EKS上でKubeflow v1.0.1をデプロイした備忘録となります。AWS Open Source BlogKubeflow on Amazon EKSおよび公式のInstall Kubeflowを参考にしました。この記事ではGPU対応のP3ワーカーインスタンスを使用して深層学習ライブラリ向けのKubernetesクラスタの構築およびKubeflowのインストールを行っています。[6] [7]

※EC2でP3ワーカー2台を2時間ほど稼働させたところ$35程度の費用がかかりました、明細が気になる方は本記事最下部にスクリーンショットを掲載しています

AWSの記事の内容が一部古いためコマンドやファイルを書き換えています。まずはP3ワーカノードを使用したKubernetesクラスタの作成です。ワーカノードはデフォルト通り2つ立ち上がりました。再掲ですが本記事ではFargateは使用しておりません。

# クラスタおよびワーカノードを作成
$ eksctl create cluster eks-kubeflow-test --node-type=p3.8xlarge --nodes 2 --region ap-northeast-1 --timeout=40m
[?] EKS cluster "eks-kubeflow-test" in "ap-northeast-1" region is ready
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 7m37s
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-27-229.ap-northeast-1.compute.internal Ready <none> 85s v1.14.7-eks-1861c5
ip-192-168-73-148.ap-northeast-1.compute.internal Ready <none> 90s v1.14.7-eks-1861c5

NvidiaプラグインのDaemonsetを展開してGPUのサポートを確認してください(nvidia-device-pluginはgithubから最新のバージョンを使用)。それぞれのワーカノードで4つのGPUがサポートされています。

$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.12/nvidia-device-plugin.yml
daemonset.extensions/nvidia-device-plugin-daemonset-1.12 created
$ kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
aws-node 2 2 2 2 2 <none> 15m
kube-proxy 2 2 2 2 2 <none> 15m
nvidia-device-plugin-daemonset-1.12 2 2 2 2 2 <none> 2m30s
$ kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu,EC2:.metadata.labels.beta\.kubernetes\.io/instance-type,AZ:.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone"NAME GPU EC2 AZ
ip-192-168-27-229.ap-northeast-1.compute.internal 4 p3.8xlarge ap-northeast-1c
ip-192-168-73-148.ap-northeast-1.compute.internal 4 p3.8xlarge ap-northeast-1a

Jupyter Notebookを立ち上げるためには永続化ボリュームが必要です。こここでは動的にaws-ebsバックエンドの永続ボリュームを作成できるStorageClassを設定しておきます。ただ作成しようとしましたが既に存在しているStorageClassだとして怒られました。 gp2 というStorageClassはEKSクラスタを作成した時点で存在しているようです。

aws-ebs-storageclass.yml
$ kubectl create -f aws-ebs-storageclass.yml
Error from server (AlreadyExists): error when creating "STDIN": storageclasses.storage.k8s.io "gp2" already exists
$ kubectl get storageclass
NAME PROVISIONER AGE
gp2 (default) kubernetes.io/aws-ebs 27m

Kubeflowのデプロイ環境を整え設定ファイルを修正します。Kubeflowのデプロイには kfctl というツールを使用します。ここからv1.0.1のtarボールをダウンロードして解凍し /usr/bin へ配置しました。 kfctl バイナリの配置場所はパスが通っているところであればどこでも問題ありませんが、次の環境設定のシェルコマンドはバイナリがこのパスにあることを前提としています。公式サイトを参考に環境変数を設定します。同じEKSクラスタ名であればこのgistのままでいけるはずです。クラスタ名はeks-kubeflow-testとしています。

kubeflow-preparation.sh

Kubeflow v1.0.1の設定ファイルの準備をします。ディレクトリを作成し $CONFIG_URI からダウンロードした設定ファイルを kfctl_aws.yaml として保存します。

$ mkdir -p ${KF_DIR}
$ cd ${KF_DIR}
$ wget -O kfctl_aws.yaml $CONFIG_URI
$ export CONFIG_FILE=${KF_DIR}/kfctl_aws.yaml

Kubeflow v1.0.1では AWS IAM Roles for Service Account がサポートされており、IAMロールをKubernetesのサービスアカウントへと紐づけることが可能です。 kf-admin-${cluster_name}kf-user-${cluster_name} というIAMロール並びに kf-admin kf-user というサービスアカウントが作成されます。 kf-admin-${cluster_name} ロールは alb-ingress-controller profile-controller などからロールの引き受け(AssumeRole)が可能です。

- kind: KfAwsPlugin
metadata:
name: aws
spec:
auth:
basicAuth:
password:
name: password
username: admin
region: ap-northeast-1
enablePodIamPolicy: true

現時点でこの設定ファイルでKubeflowをデプロイしようとしたところ、以下のエラーが発生しております。aws-iam-authenticator はEKSで不要となったはずですが、原因がはっきりしなかったので従来の方法であるノードグループのロールへIAMポリシーを割り当てる方式をテストしました。

Code 400 with message: Could not find command aws-iam-authenticator in PATH

ポリシーをノードグループのロールへ設定します。設定ファイルのクラスタ名である kubeflow-aws${AWS_CLUSTER_NAME} へと置き換えてからノードグループ用のIAMロールを引き当てます。

$ sed -i'.bak' -e 's/kubeflow-aws/'"$AWS_CLUSTER_NAME"'/' ${CONFIG_FILE}# ノードグループのIAMロール
$ aws iam list-roles \
| jq -r ".Roles[] \
| select(.RoleName \
| startswith(\"eksctl-$AWS_CLUSTER_NAME\") and contains(\"NodeInstanceRole\")) \
.RoleName"

eksctl-eks-kubeflow-nodegroup-ng-NodeInstanceRole-ASIF1WYJNOCP

設定ファイル kfctl_aws.yaml 内の末尾の region を書き換え roles を調べたIAMロールIDで置換してください。

- kind: KfAwsPlugin
metadata:
name: aws
spec:
auth:
basicAuth:
password:
name: password
username: admin
region: ap-northeast-1
roles:
- eksctl-eks-kubeflow-nodegroup-ng-NodeInstanceRole-ASIF1WYJNOCP

kfctl apply でEKSクラスタへKubeflowをデプロイします。注意点ですが、デフォルトでKubeflowはアプリケーションを外部へ公開してしまいます(Kubeflow UIは誰でもインターネットからアクセス可能な状態)。本番で使用を検討する場合は、認証の設定を必要に応じて行ってください。

$ cd ${KF_DIR}
$ kfctl apply -V -f ${CONFIG_FILE}
...
INFO[0100] Applied the configuration Successfully! filename="cmd/apply.go:72"
kubectl -n kubeflow get all

Ingressのデプロイに3分から5分、さらに対象のホスト名のDNSの伝播にも数分かかります。このテストでは以下のようなアドレスが生成されました。対象のURLは誰でもアクセスが可能な状態となっています。

$ kubectl get ingress -n istio-system
NAME HOSTS ADDRESS PORTS AGE
istio-ingress * 29aa218d-istiosystem-istio-2af2-690877079.ap-northeast-1.elb.amazonaws.com 80 3m34s

しばらく待つとサイトへアクセスできるはずです。Namespace Nameへanonymousと入力してFinishをクリックします。ここまででKubeflowのデプロイは完了です。またKubeflow v1.0.1では名前空間の分離によってマルチテナンシーを実現することが可能となっています。

NotebookサーバとJupyterNotebook

Kubeflow UIへアクセスできることを確認してください。左側のメニューに『Pipelines』や『Notebook Servers』など主要な項目が並んでいます。まずは『Notebook Servers』をクリックしてNotebook Serverを作成します。Notebook ServerはDockerコンテナでJupyterNotebookを走らせるための箱です。名前空間で分離することでユーザのプロファイルに応じたアクセス制限を行うことができます。このテストでは名前空間anonymousのみ使用しています。

Kubeflow UI-> Notebook Servers

ユーザプロファイルに応じた名前空間を選択して、Notebook Serverをローンチします。サーバ名、名前空間、使用するDockerイメージなどを設定して『Create』をクリックしてください。Notebook Serverの作成については公式サイトに詳細が記載されています。英語ですがスクリーンショットがあるので容易に理解できる内容だと思います。[8]

ここではkubeflow-testという名前のNotebook Serverをanonymous名前空間で作成しました。『CONNECT』をクリックするとお馴染みのJupyter Notebookが立ち上がります。

Name: kubeflow-test, Namespace: anonymous

Tensorflow1.14のDockerコンテナを使用しているので、TensorflowでMNIST手書き文字の分類のサンプルを実行してみました。

Mnist Tensorflow sample in Kubeflow

ここからAWS ECR(Elastic Container Registry)との連携やKatib/Pipelinesを試したかったのですがP3ワーカノードを2時間ほど稼働させたところ$30以上課金されたためにテストを止めました。Jupyter Notebookで開発したモデルは前述のKFServingやSeldon Coreを使用し、Kubernetesのモデルサービングポッドとしてデプロイが可能です。ここまでくるとほぼAmazon SageMakerと同じような構図になってきます。AWSの基盤を使っている場合は素直にSageMakerを使ったほうがリソースやバジェット効率は良くなりそうです。

ML workflow in Kubeflow with AWS EKS

最後に作成したKubeflowのリソース削除とKubernetesクラスターの削除を行いました。

$ cd ${KF_DIR}
$ kfctl delete -f ${CONFIG_FILE}
# No output
$ eksctl get cluster
NAME REGION
eks-kubeflow-test ap-northeast-1
$ eksctl delete cluster --name=eks-kubeflow-test
$ eksctl get cluster
No clusters found

参考までにAWS EKSでP3ワーカノード2台を2時間ほど走らせた際の課金状況です。EKSサービス自体にはほぼ課金がありませんでしたが、ワーカノードとして使用したEC2に$36.59の費用がかかりました。EKSクラスタを走らせっぱなしにしないように気を付けてください。

AWS Service Charges suck.

以上です。

【再掲】Amazon EKS on Fargate 制約事項

  • ポッド当たり4 vCPU/30Gのメモリが割り当て可能なリソースである
  • ステートフルワークロードに対応していない、パーシステントボリューム、ファイルシステムは現在サポートされない
  • DaemonSet/Privileged Podsは実行できない
  • HostNetwork/HostPortには対応していない
  • AWS ALBのみに対応している

まとめ

  • AWS EKSはAWS上のKubernetesマネージドサービスでKubernetesマスターやKubernetesプロセスなどのKubernetesコントロールプレーンの管理が不要となるだけでなく、コントロールプレーンの可用性もAWSによって確保される
  • AWS EKS on FargateではワーカーノードにEC2を利用する際に考慮する必要のあったインスタンスの管理、パッチやスケーリングの手当、インスタンスのセキュリティ対応などが原則不要となる
  • KubeflowはKubernetesクラスタ上で機械学習のモデルの開発やエンドポイントのデプロイをサポートするツール群を提供するオープンソースソフトウェアである
  • Kubeflowを使用するとクラウドやオンプレを問わず簡単にML環境を構築しMLOpsを実現することができる

--

--

Yuya Sugano
Yuya Sugano

Written by Yuya Sugano

Cloud Architect and Blockchain Enthusiast, techflare.blog, Vinyl DJ, Backpacker. ブロックチェーン・クラウド(AWS/Azure)関連の記事をパブリッシュ。バックパッカーとしてユーラシア大陸を陸路横断するなど旅が趣味。

No responses yet