Amazon FSx for NetApp ONTAPをAmazon EKSのPersistentVolumeのバックエンドとして使ってみた（準備編）

# はじめに
- [前回の記事](https://qiita.com/seijitanabe/items/f16af0425d2f2f00af24)でAmazon EKSで使えるPersistentVolumeについて調べてみたので、今回は実践編の準備編。
- Amazon FSx for NetApp ONTAP（以下、FSx for ONTAP）をPersistentVolumeのバックエンドとして使ってみる。

# 環境準備（Amazon EKSクラスター以外）
- Amazon EKSクラスター以外のリソースはCloudFormationでサクっと作成した。
    - テンプレートは[こちら](https://github.com/seijitanabe/my-cfn-templates/blob/main/deploy-fsxn-sandbox/deploy-fsxn-sandbox.yml)。個人的に検証等で使うAWS環境のCloudFormationテンプレートを整備しはじめており、その一部として作ったものである。
    - 個人の検証用ということで、認証情報を直接パラメーターで渡したりといったセキュリティ的にアンチパターンな部分もあるので転用は自己責任でお願いしたい。
    - CloudFormationスタックのデプロイを流してから全てのリソースがデプロイ完了するまで36分かかった。FSx for ONTAP以外は2分以内に作成が完了するが、FSx for ONTAPが長い。
- これでVPCやサブネットなどのネットワーク周りとFSx for ONTAPの作成は完了。

# 環境準備（Amazon EKSクラスター）
- 個人的な検証にはなるべくお金をかけたくない。ということで、コストを抑えるために[Spot by NetApp](https://spot.io/)を使ってAmazon EKSクラスターをデプロイする。
- Spot by NetAppのサービスの1つ「Ocean」は、Amazon EKSクラスターで利用するAmazon EC2インスタンスの運用とコストを最適化してくれるサービス。
- Worker Node用のAmazon EC2インスタンスにスポットインスタンスを利用し、スポットインスタンスの中断を検知すると自動的にインスタンスを起動し直したり、Worker Nodeのスケーリングなどを自動でやってくれる。
- これにより、Amazon EKSのインフラを気にすることなくサーバーレス感覚で激安に使うことができる。Amazon EC2インスタンス20台までは無料で使えるので使わない手はない。
- ということで、以下の通り作成いていく。

## Spot by NetAppアカウント作成
- Spot by NetAppアカウントが無い場合、こちらの動画に従ってSpot by NetAppのアカウントを作成し、AWSアカウントと紐づけを行う。
<iframe width="560" height="315" src="https://www.youtube.com/embed/N4GKzFOTH30" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## Amazon EKSクラスターデプロイ
- 上記が完了すると、Spotコンソール画面左のメニューから「**Ocean**」→「**Cloud Clusters**」を開き、「**Create Cluster**」ボタンをクリック。
  ![ocean1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/833b3f7e-eb85-f72b-faea-927e5fe4e049.png)
- 今回は新規作成なので「**EKS** - **Create an EKS Cluster**」を選択。
  ![ocean2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/38abee95-0701-8546-30a5-759b3dd8bcb7.png)
- ウィザードに従って以下の手順を実施。

### STEP1: 
- 「**Generate Token**」をクリックし、Token作成へ。
  ![ocean3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/19103f2f-cc08-0c18-38d0-387d359e7729.png)
- 「**Token Name**」に適当な名前を入力し、「**GENERATE**」ボタンをクリック。
  ![ocean4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/8a82da5b-207d-2651-4675-9148a5ebd9b9.png)
- Tokenが作られたことを確認し、「**DONE**」をクリック。
  ![ocean5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/7610de6c-ded7-d7a1-43f5-19f813d11f49.png)

### STEP2: Set the generated EKS Cluster parameters
- 「**Cluster Name**」に適当な名前を入力し、「**Region**」、「**Key Pair**」は使用するものをそれぞれ選択。
  ![ocean6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/5dc75485-51d5-8cce-1747-712503420099.png)

### STEP3: Provision the EKS and Ocean clusters
-「**Use existing VPC & subnets**」にチェックを入れ、「**Launch CloudFormation Stack**」をクリック。
  ![ocean6-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/97d61931-4f68-749c-176a-ea3afb4d16c7.png)
- AWSマネジメントコンソールのCloudFormationスタック作成画面が開くので、必要情報を入力/選択し、「**AWS CloudFormationによってIAMリソースがカスタム名で作成される場合があることを承認します**」にチェックを入れ、「**スタックの作成**」ボタンをクリック。
  ![ocean7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/306e3f5c-06d0-542c-9874-a8d69a9222d4.png)
- スタックの作成が完了するまで待つ。
- スタックの「**出力**」タブに表示されている「**NodeInstanceRole**」の値をメモっておく。
　![ocean10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/cf248336-666f-ea35-8ae1-2cf8bec85126.png)

### STEP4: Configure Worker Nodes Managed by Ocean To Join The EKS Cluster
-  **AWS CLI**と**kubectl**をインストール済みの端末から以下のコマンド/スクリプトをコピー&ペーストで実行。今回は冒頭のCloudFormationで作ったEC2インスタンスを使用。
  ![ocean8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/12efea76-8ede-2432-1da4-d6689d94f393.png)
- 実行結果はこんな感じ。
  ```
  $ aws eks update-kubeconfig --name st-eks-test-cluster
  Added new context arn:aws:eks:ap-northeast-1:xxxxxxxxxxxx:cluster/st-eks-test-cluster to /home/ec2-user/.kube/config
  ```
  ```
  $ kubectl get svc
  NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
  kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   9m12s
  ```
  ```
  $ #!/usr/bin/env bash
  $ curl -fsSL http://spotinst-public.s3.amazonaws.com/integrations/kubernetes/cluster-controller/scripts/init.sh | \
  > SPOTINST_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  > SPOTINST_ACCOUNT=act-xxxxxxcf \
  > SPOTINST_CLUSTER_IDENTIFIER=st-eks-test-cluster \
  > bash
  2022-04-06T01:17:14.435Z downloading
  2022-04-06T01:17:15.518Z rendering
  2022-04-06T01:17:15.533Z applying
  secret/spotinst-kubernetes-cluster-controller created
  configmap/spotinst-kubernetes-cluster-controller-config created
  serviceaccount/spotinst-kubernetes-cluster-controller created
  clusterrole.rbac.authorization.k8s.io/spotinst-kubernetes-cluster-controller created
  clusterrolebinding.rbac.authorization.k8s.io/spotinst-kubernetes-cluster-controller created
  deployment.apps/spotinst-kubernetes-cluster-controller created
  ```

### STEP5: Update AWS Authentication Config-Map
- 先程の端末で以下コマンドをコピー&ペーストして、ConfigMapをダウンロード。
  ![ocean9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/0b10591e-07ac-3f9e-eaca-ab41bdc4c52e.png)
  ```
  $ curl -O https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/aws-auth-cm.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  100   282  100   282    0     0    644      0 --:--:-- --:--:-- --:--:--   645
  ```
- ダウンロードしたConfigMapを編集。`rolearn`の値を、STEP3の最後でメモっていた「**NodeInstanceRole**」の値に書き換え。　
  ```
  $ vi aws-auth-cm.yaml
  ```
  ```
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: aws-auth
    namespace: kube-system
  data:
    mapRoles: |
      - rolearn: <ARN of instance role (not instance profile)>　<---ココを「NodeInstanceRole」の値に書き換え 
        username: system:node:{{EC2PrivateDNSName}}
        groups:
          - system:bootstrappers
          - system:nodes
  ```
- 以下コマンドをコピー&ペーストして、ConfigMapを作成。
  ![ocean11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/102afa78-3577-fa16-fe66-e41412740165.png)
  ```
  $ kubectl apply -f aws-auth-cm.yaml
  configmap/aws-auth created
  ```
- 「**Done**」ボタンをクリック。
  ![ocean12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/7925915e-5575-9e27-8b68-0ed2747edd8f.png)
- Ocean Clusterが作成されたことを確認。
  ![ocean13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/488e8eae-f289-1884-4b05-2c2de760f77e.png)

## 確認
- NodeやPodがデプロイされていることを確認。
  ```
  $ kubectl get nodes
  NAME                                           STATUS     ROLES    AGE   VERSION
  ip-10-0-1-21.ap-northeast-1.compute.internal   NotReady   <none>   31s   v1.21.5-eks-bc4871b
  ```
  ```
  $ kubectl get pods --all-namespaces
  NAMESPACE     NAME                                                      READY   STATUS    RESTARTS   AGE
  kube-system   aws-node-t4cnr                                            1/1     Running   0          11m
  kube-system   coredns-76f4967988-22s7v                                  1/1     Running   0          21m
  kube-system   coredns-76f4967988-7q6x9                                  1/1     Running   0          21m
  kube-system   kube-proxy-x4l2w                                          1/1     Running   0          11m
  kube-system   spotinst-kubernetes-cluster-controller-586cb8c588-mcdn7   1/1     Running   0          12m
  ```
- Spotコンソールから見るとこんな感じ。68.88%もコスト削減できているらしい。
  ![ocean14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/2e583335-fd54-ec24-18fd-68a4386648ff.png)
  ![ocean15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/d946df72-2f63-5ca0-5e54-efe2c4e5fdfa.png)
  ![ocean16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/a6e73f71-127b-d8a7-5b99-4fb448449a09.png)
- これでAmazon EKSクラスタとFSx for ONTAPはできた。実践編の準備編が完了。
- こんな感じの環境が出来上がった。
  ![archetecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523630/0ca7124a-b06a-2a4f-55ce-9f5ab8b0ed62.png)

# 次回予告
- タイトルに反して、ほとんどSpot Oceanの設定手順紹介になってしまった。
- 次回は実践編の本編。PersistentVolumeを作ってみるところまでやってみたい。