EKS東京リージョンでGPUコンテナクラスタを立ててみる

EKS東京リージョンでGPUコンテナクラスタを立ててみる:


EKSクラスタの構築

AWSの公式ドキュメントではCloudFormationなどを駆使して、EKSクラスタを構築する方法が記載されていますが、ここではそれらを隠蔽してくれるeksctlを使います。


eksctlのインストール

$ brew tap weaveworks/tap 
$ brew install weaveworks/tap/eksctl 


クラスタの作成

ここではp2.xlarge * 1のクラスタを構築します。

$ eksctl create cluster --name gpu-cluster --region ap-northeast-1 --nodes 1 --nodes-min 1 --nodes-max 1 --node-type p2.xlarge --version=1.11 


NVIDIA device pluginのインストール

GPUのスケジューリングを有効にするためにNVIDIA device pluginをインストールします。

$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.11/nvidia-device-plugin.yml 


(Optional) GPU Mutating Webhookの追加

nvidia.com/gpuリソースを指定しないコンテナからGPUが見えてしまう問題のために、Mutating Admission Webhookを追加します。


クライアントCAの取得・アップロード

EKSではGKEなどと違い、kube-systemのConfigMap:extension-apiserver-authenticationにclient-ca-fileが入っていないので入れておきます。

$ aws eks describe-cluster \ 
        --region=ap-northeast-1 \ 
        --name=gpu-cluster \ 
        --output=text \ 
        --query 'cluster.{certificateAuthorityData: certificateAuthority.data, endpoint: endpoint}' | \ 
        awk '{print $1}' | \ 
        base64 -D 
で出力されたCAをConfigMapに入れます。

$ kubectl edit configmap extension-apiserver-authentication -n kube-system 
apiVersion: v1 
data: 
+ client-ca-file: | 
+   -----BEGIN CERTIFICATE----- 
+   xxxx 
+   -----END CERTIFICATE----- 
  requestheader-allowed-names: '["front-proxy-client"]' 
  requestheader-client-ca-file: | 
    -----BEGIN CERTIFICATE----- 
    xxxx 
    -----END CERTIFICATE----- 
  requestheader-extra-headers-prefix: '["X-Remote-Extra-"]' 
  requestheader-group-headers: '["X-Remote-Group"]' 
  requestheader-username-headers: '["X-Remote-User"]' 
kind: ConfigMap 


gpu-mutating-webhookのデプロイ

$ git clone https://github.com/takmatsu/gpu-mutating-webhook.git 
$ cd gpu-mutating-webhook 
$ kubectl apply -f deployment/namespace.yaml 
$ ./deployment/webhook-create-signed-cert.sh 
$ cat deployment/mutatingwebhook.yaml | \ 
    deployment/webhook-patch-ca-bundle.sh > \ 
    deployment/mutatingwebhook-ca-bundle.yaml 
$ kubectl apply -f deployment/deployment.yaml 
$ kubectl apply -f deployment/service.yaml 
$ kubectl apply -f deployment/mutatingwebhook-ca-bundle.yaml 


(Optional) EFS Provisonerの追加

EKSではデフォルトでPersistent VolumeとしてAWSElasticBlockStoreが使えますが、ReadWriteOnceのみしか使えないため、ReadWriteManyなどが使いたい場合はEFS Provisonerを使用するとRWXなPVがDynamic Provisioningできます。


EFSの作成

aws efs create-file-system --creation-token gpu-nfs --region ap-northeast-1 


EFSにSecurityGroupの設定

  • EFSのIDの確認
$ aws efs describe-file-systems 
  • サブネットの確認
$ aws ec2 describe-subnets --filters Name=tag:Name,Values=\*gpu-cluster\* Name=tag:aws\:cloudformation\:logical-id,Values=\*Public\* --query 'Subnets[].{SubnetId: SubnetId}' --output text 
  • セキュリティグループの確認
$ aws ec2 describe-security-groups --filters Name=group-name,Values=\*gpu-cluster\* --query 'SecurityGroups[].{GroupName: GroupName, GroupId: GroupId}' --output text | grep ClusterSharedNodeSecurityGroup | awk {'print $1'} 
  • 設定
$ aws efs create-mount-target --file-system-id fs-****** --subnet-id subnet-****** --security-groups sg-****** 
×サブネット分


efs-provisonerのデプロイ

$ git clone https://github.com/kubernetes-incubator/external-storage.git 
$ cd external-storage/aws/efs 
  • namespaceの作成
$ NAMESPACE=efs-provisioner 
$ kubectl create namespace $NAMESPACE 
  • RBACの設定
$ sed -i '' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml 
$ kubectl apply -f deploy/rbac.yaml -n $NAMESPACE 
  • manifestの編集
$ vi deploy/manifest.yaml 
@@ -4,8 +4,8 @@ kind: ConfigMap 
 metadata: 
   name: efs-provisioner 
 data: 
-  file.system.id: yourEFSsystemid 
-  aws.region: regionyourEFSisin 
+  file.system.id: fs-***** 
+  aws.region: ap-northeast-1 
   provisioner.name: example.com/aws-efs 
   dns.name: "" 
 --- 
@@ -53,7 +53,7 @@ spec: 
       volumes: 
         - name: pv-volume 
           nfs: 
-            server: yourEFSsystemID.efs.yourEFSregion.amazonaws.com 
+            server: fs-*****.efs.ap-northeast-1.amazonaws.com 
             path: / 
  • デプロイ
kubectl apply -f deploy/manifests.yaml -n $NAMESPACE 


その他

  • GPUインスタンスは高いので、使わないときにワーカーノードに使っているAuto Scaling Groupを0にするLambdaなどを書くといいかもしれない、K8sを使っているとステートを持つ情報はコントロールプレーンか外部ストレージに入っているので戻すと自動復旧する(はず)

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)