はじめに。以下の投稿では Splunkbase上で利用可能なSplunk WorksのソリューションであるDeep Learning Toolkit (DLTK)の機能について説明しています。Splunkは、Streaming MLやSplunk Machine Learning Environment (SMLE)など、緊密に統合されたML機能を新たに搭載し、MLポートフォリオを拡大しています。SplunkのMLポートフォリオの方向性については、Lila Fridley氏のブログ「機械学習ガイド:適切なワークフローの選択」をご覧ください。
Splunk Deep Learning Toolkit(DLTK)は、コンピュートリソースを外部のコンテナ環境にオフロードできる非常に強力なツールです。さらに、GPUやSPARK環境を利用することもできます。前回のDimitris Lambrou氏によるブログ「The Power of Deep Learning Analytics and GPU Acceleration」では、GPUベースの環境構築について詳しく紹介していますのでこちらもご覧ください。
Splunk DLTKはコンテナ環境としてKubernetesやOpenShiftだけでなく、Dockerにも対応しています。今回の記事では、DLTK 3.3とAmazon EKSをkubernetes環境として利用するためのセットアップを進めていきます。
事前準備
EKSとKubernetesを管理するには、まずノートPCにいくつかのCLIツールをインストールする必要があります。スタートアップの詳細については、このドキュメントを参照してください。
- Install awscli
- Install ekscli
- Install kubectl
注:EKSを管理するには、IAMユーザーがAmazonEKSClusterPolicyを持っている必要があります。
また、Splunk DeepLearning Toolkitも事前にインストールしておきましょう。このブログはDLTK 3.xを対象としています
セットアップ概要
この後のセットアップの流れを見てみましょう。Amazon EKSではComputer NodeとしてFargateとManaged Nodeがありますが、今回はManaged Nodeを使用しています。また、ストレージサービスはReadWriteManyに対応している必要があるので、今回はEFSを使用しました。ちなみにDLTK 4.0ではデフォルトのgp2が使えるようになっなっています。
- マネージドノードでEKSクラスタを作成
- ReadWriteMany対応のEFSストレージサービスの作成とセットアップ
- EFS用のStorageClassとPersisetntVolumeの作成
- DLTK NodePortアクセス用のSecurityGroupの設定
- (Option) : 名前空間の新規作成
- Splunk DLTKを設定してEKSにアクセス
- EKSのためのポッドの実行
Step 1: マネージドノードでEKSクラスタを作成
最初に EKSクラスターを作成します。詳細はこちらをご覧ください。
$ eksctl create cluster \ --name <> \ --nodegroup-name < > \ --region < > \ --node-type < > \ --nodes <<1>> \ --ssh-access \ --ssh-public-key < > \ --managed
今回は検証用にt3.mediumのインスタンスタイプと1ノードを使用しています。その他の項目は必要に応じてカスタマイズしてください。クラスタやノードグループの作成に時間がかかります。
無事に作成されているか確認してみましょう。
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1443/TCP 14d
$ kubectl get node NAME STATUS ROLES AGE VERSION ip-192-168-81-176.us-east-2.compute.internal Ready9d v1.18.9-eks-d1db3c
Step2: ReadWriteMany対応のEFSストレージサービスの作成とセットアップ
Splunk DLTK 3.xではストレージに「ReadWriteMany」のボリュームを使用しているため、EFSサービスを利用する必要があります。
EFS セットアップの詳細については、こちらを参照してお進みください。
1. Amazon EFS CSI ドライバを Amazon EKS クラスタにデプロイする
$ kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/ecr/?ref=release-1.0"
2. Amazon EKSクラスタ用のAmazon EFSファイルシステムを作成する
A. Cluster's CIDR 情報を取得する
Amazon EKSクラスタのVPC IDを探します。このIDはAmazon EKSコンソールで見つけることができますが、以下のAWS CLIコマンドを使用することもできます。
$ aws eks describe-cluster --name <cluster_name> --query "cluster.resourcesVpcConfig.vpcId" --output text
クラスタのVPCのCIDR範囲を探します。これはAmazon VPCコンソールで見つけることができますが、以下のAWS CLIコマンドを使用することもできます。
$ aws ec2 describe-vpcs --vpc-ids vpc-<exampledb76d3e813&tt; --query "Vpcs[].CidrBlock" --output text
このCIDR情報は次のステップで使うことになります。
B. 新しいセキュリティグループを作成して、NFSアクセスを許可する
Amazon EFS マウントポイント用のインバウンド NFS トラフィックを許可するセキュリティグループを作成します。
- https://console.aws.amazon.com/vpc/で Amazon VPC コンソールを開きます。
- 左側のナビゲーションパネルでセキュリティグループを選択し、セキュリティグループの作成を選択します。
- セキュリティグループの名前と説明を入力し、Amazon EKS クラスタが使用している VPC を選択します。
- インバウンド ルール で、[ルールの追加] を選択します。
- [タイプ] で、[NFS] を選択します。
- [Source]で[Custom]を選択し、前の手順で取得したVPC CIDRの範囲を貼り付けます。
- セキュリティ グループの作成] を選択します。
C. Amazon EKSクラスタ用のAmazon EFSファイルシステムを作成する
- https://console.aws.amazon.com/efs/で Amazon Elastic File System コンソールを開きます。
- 左側のナビゲーションペインで「ファイルシステム」を選択し、「ファイルシステムの作成」を選択します。
- ファイルシステムの作成ページで、カスタマイズを選択します。
- ファイルシステム設定ページでは、情報を入力または選択する必要はありませんが、必要に応じて入力し、次へを選択します。
- ネットワーク アクセス ページで、Virtual Private Cloud (VPC) の場合は、VPC を選択します。
- [マウント ターゲット] の下で、デフォルトのセキュリティ グループがすでにリストされている場合は、デフォルトのセキュリティ グループ名のボックスの右上にある X を選択して、各マウント ポイントから削除し、前の手順で作成したセキュリティ グループをマウント ターゲットごとに選択し、[次へ] を選択します。
- [ファイル システム ポリシー] ページで、[次へ] を選択します。
- [レビューと作成] ページで、[作成] を選択します。
D. アクセスポイントの作成
デフォルトでは、rootユーザーのみがこのファイルシステムにアクセスできるため、DLTKクラスタはコンテナのデプロイに失敗します。そのために新しいアクセスポイントを作成する必要があります。
- 左側のナビゲーションペインでアクセスポイントを選択し、アクセスポイントの作成を選択します。
- ファイルシステムを選択し、このアクセスポイントのルートディレクトリを入力します。(例: /dltk)
- ルートディレクトリの作成権限で オーナーの uid/gid/パーミッションを入力します。(例:500/500/0777)
Step 3. EFS用のStorageClassとPersisetntVolumeの作成
StorageClass
このyamlファイルをローカルのラップトップにコピーして作成します。
storageclass.yaml
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: <<efs-sc>> provisioner: efs.csi.aws.com allowVolumeExpansion: true
この storageclass をクラスタにデプロイします。
$ kubectl apply -f storageclass.yaml
deploymentを確認します。
$ kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE efs-sc efs.csi.aws.com Delete Immediate true 14d gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 14d
Persistent Volume
このyamlファイルをローカルのラップトップにコピーして作成します。
pv.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: <<dltk-efs-volume>> spec: capacity: storage: 20Gi volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Delete storageClassName: efs-sc csi: driver: efs.csi.aws.com volumeHandle: <<fs-xxxxx>>::<<fsap-xxxxxxxx>>
環境の名前とVolumeHandle("fs-xxxxx "と "fsap-xxxxxxxx")を変更します。AWSコンソールでEFSの設定を確認します。
このPersistent Volumeをクラスタに配置します。
$ kubectl apply -f pv.yaml
Verify the deployment.
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE dltk-efs-volume 20Gi RWX Delete Available default/dltk efs-sc 25h
Step 4. DLTK NodePortアクセス用のSecurityGroupの設定
DLTK 3.xではkubernetesのIngressタイプとしてLoad BalancerやNode Portをサポートしています。現時点ではIngressタイプとしてNode Portを使用しています。
- EC2コンソールでEKSノードを探す
- 割り当てられたセキュリティグループを開きます。(nodegroup-ng-dltk-remoteAccess)
このノードポート範囲をセキュリティグループに追加します。
30000-32767: Node Port
Step 5. (Option) : 名前空間の新規作成
このステップは任意であり、必要であれば省略しても構いません。このステップをスキップした場合は、DLTKのデフォルトの名前空間を使用します。
1. my-namespace.yamlという名前のYAMLファイルを新規に作成します。 (名前空間名<<dltk >>を好きなように変更してください。)
my-namespace.yamla
kind: Namespace metadata: name: <<dltk>> $ kubectl apply -f ./my-namespace.yaml
2. 名前空間を確認してください。
$ kubectl get namespaces NAME STATUS AGE default Active 15d dltk Active 33h kube-node-lease Active 15d kube-public Active 15d kube-system Active 15d
Splunk DLTKを設定してEKSにアクセス
DLTKアプリ 上の Configuration → Setup に進みます。
- Node Port Internal Hostname : EKSのノードポートのInternal IPアドレスの1つ
- Node Port External Hostname : EKSのノードポートのパブリックIPアドレスの1つ
- Namespace : 前のステップで作成した名前空間です
- Storage Class : 前のステップで作成したストレージクラスです。
Step 7. EKSのためのポッドの実行
[Container] に移動します。クラスタターゲットのkubernetesを選択します。そしてStart!
トラブルシューティングに便利なKubectlコマンド
セットアップでエラーが発生した場合は、このコマンドを使用してトラブルシューティングを行ってください。
- Check the Deployments status
$ kubectl get deployments --namespace=dltk NAME READY UP-TO-DATE AVAILABLE AGE dev 1/1 1 1 30h $ kubectl describe deployment dev --namespace=dltk << More detail Information>>
- Pods status
$ kubectl get pods --namespace=dltk NAME READY STATUS RESTARTS AGE dev-7f9cdcc6d7-mzcdb 1/1 Running 0 30h $ kubectl describe pod <> --namespace=dltk << More detail Information>>
- Persistent Volume Claim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE dltk Bound dltk-efs-volume1 20Gi RWX efs-sc 34h $ kubectl describe pvc <> --namespace=dltk << More detail Information>>
- Persistent Volume
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE dltk-efs-volume1 20Gi RWX Delete Bound dltk/dltk efs-sc 34h $ kubectl describe pv << dltk-efs-volume1>>
- Container Logs
$ kubectl logs -f <<POD name>> --namespace=dltk
Splunk Infrastructure Monitoring によるEKS監視
さらに、Splunk Infrastructure Monitoring を使ってAmazon EKSを監視することで、学習負荷をリアルタイムで監視することができます。
サマリー
EKS環境でDLTKのセットアップが完了すると、コンピュータのリソースを簡単に拡張したり、縮退したりすることができます。さらに、複数のDLTKでこのEKSを共有することで、リソースを最適化することができます。
本日は、開発・テスト用のセットアップフローをご紹介しました。本番用に実行する必要がある場合は、お近くのSplunkのエンジニアにご相談ください。
このブログを書くにあたり、Philipp Driegerさんのアドバイスやサポートに感謝したいと思います。
最後にSplunk が提供するすべての ML サービスの詳細については、「機械学習ガイド:適切なワークフローの選択」をご覧ください。また今後出てくるBlogをお楽しみに。
----------------------------------------------------
Thanks!
丸山 潤一