Oracle Cloud InfrastructureのFile Storage Serviceを使って、KubernetesのPodに共有ストレージをマウントする

これはなに
----------
Oracle Cloud Infrastructure(OCI、OracleのIaaS)の[File Storage Service(FSS)](https://blogs.oracle.com/cloud-infrastructure/introducing-oracle-cloud-infrastructure-file-storage-service)は、少容量から始められて、高パフォーマンス、NFS接続を謳う共有ストレージサービスです。
このエントリーでは、OCI上に構築したKubernetesのPodに、FSSの共有ストレージをマウントする手順を書きます。

OCI上にKubernetesを構築するには、[Terraformベースのインストーラー](https://github.com/oracle/terraform-kubernetes-installer)と、マネージドのKaaSサービスである[Oracle Container Engine for Kubernetes(OKE)](https://cloud.oracle.com/containers/kubernetes-engine)を使う方法があります。
このエントリーの手順は前者の方法で構築したクラスターで動作確認していますが、どちらでも適用可能と思います。


手順の概要
----------
大まかな手順は以下のとおりです。

1. FSSをセットアップする
2. PodからFSSをマウントする


1 . FSSをセットアップする
-------------------------
まずはFSSをセットアップしていきます。


### 1-1. FSSのボリュームを作成する
OCIのコンソールにログインしたら、画面左上のハンバーガーメニューアイコン![menu.png](https://qiita-image-store.s3.amazonaws.com/0/108645/e172d420-a796-9009-d522-a440a2666de2.png)をクリックします。メニューが展開したら、File Systemsをクリックします。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/108645/22a339dc-f800-60da-6c57-08219fcdd6e8.png)

File Systemsの画面が表示されたら、画面左下のメニューで、Kubernetesクラスターを構築してあるCompartmentを選択します。そのうえでCreate File Systemボタンをクリックします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/108645/b7e7003e-2e82-a833-c10c-dd1cde30df7d.png)

Create File Systemダイアログで、以下のように値を設定し、Create File Systemボタンをクリックします。

- File System Information
    * CREATE IN COMPARTMENT: （Kubernetesクラスターを構築してあるCompartmentが選択されていることを確認）
    * NAME: （値は任意。例えば fss4oke）
    * AVAILABILITY DOMAIN: （任意。FSSを構成したいAvailability Domainを選択）
- Mount Target Informantion
    * NAME: （任意。例えば fss-mount-target）
    * VIRTUAL CLOUD NETWORK: （Kubernetesクラスターを構築してあるVCNを選択）
    * SUBNET: （Worker Nodeが配置されるサブネットを選択。サブネットが配置されているADが、上のAVAILABILITY DOMAINで選択したものと一致すること）
    * PATH: （任意。例えば /fss）

![3.png](https://qiita-image-store.s3.amazonaws.com/0/108645/176abf6d-a0ad-629d-c9c8-8f8ad76f5fcb.png)

FSSが構成されたら、File Systemsの画面で、FSSの名前のリンク（上の例のとおりであればfss4oke）をクリックします。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/108645/609daa9e-bd5e-78b0-7a5e-ca8ce1a4b2c4.png)

Mount Targetの配下に、上記で作成したMount Targetが表示されています。この中にある、Private IP Adressをテキストエディタ等にコピーしておきます。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/108645/cd96f62c-b8ce-5347-fced-4be676a42d94.png)

これでFSSのボリュームの作成が完了です。


### 1-2. FSSに接続するためのネットワークの設定を行う
OCIコンソールの画面左上のハンバーガーメニューアイコンをクリックします。メニューが展開したら、Virtual Cloud Networksをクリックします。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/108645/20788516-6aff-b41d-c597-86aa968cd052.png)

Kubernetesクラスターが構築してあるVCNの、名前のリンクをクリックします。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/108645/59bc3bea-f46b-e8ec-385f-8891d9ff7103.png)

画面左のメニューでSecrity Listをクリックします。

![8.png](https://qiita-image-store.s3.amazonaws.com/0/108645/32128b16-aea2-2c73-b6e3-fae902401dd4.png)

KubernetesのWorker Nodeが配置されるサブネットに適用される、Security Listを選択します。

![9.png](https://qiita-image-store.s3.amazonaws.com/0/108645/1a986fe3-fe4e-3d5a-f1d1-2c5284a11408.png)

Security Listに、FSSとの通信を許可するための設定をしていきます。
Edit All Rulesボタンをクリックします。

![10.png](https://qiita-image-store.s3.amazonaws.com/0/108645/06916ac3-f24c-c5d0-bf9b-cd1f5bb96101.png)

Ingressのルールに、Stateful（StatelessのチェックをOFFに設定）のルールを作成していきます。
例えば、ルールの作成後に、以下の図のようなルール設定が追加されていればOKです。

![11.png](https://qiita-image-store.s3.amazonaws.com/0/108645/6d991d76-072b-b7b2-2ef7-802daaec5322.png)

以上でFSSのセットアップは完了です。


2 . PodからFSSをマウントする
----------------------------
ここまでの手順で構成したFSSを、2つのPodにマウントして共有ストレージとして使ってみます。
FSSはNFSとしてアクセスするので、PodにVolumeの設定をする方法は、一般的なNFSの共有ストレージをマウントする方法と変わりません。

### 2-1. Worker NodeにNFSをインストール
Worker NodeがNFSクライアントとして動く必要があるので、NFSをインストールしておく必要があります。

Worker NodeにSSH接続した上で、以下のコマンドを実行します（yumベースのパッケージマネージャを使っている例）。

    $ sudo yum install nfs-utils

これをPodが配置されうるすべてのWorker Nodeに対して実施しておきます。

### 2-2. PodからFSSをマウント
ここでは、共有ストレージ上のテキストファイルに定期的にメッセージを追記するPod(hello-fss)と、そのファイルをtailするPod(welcome-fss)とを作成して、2つのPodから共有ストレージを利用できることを確認します。

まず、hello-fssのmanifestです。

```yaml:hello-fss.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-fss
spec:
  containers:
  - name: hello-fss
    image: busybox
    args: [/bin/sh, -c, 'i=0; while true; do echo "$i: Hello FSS!">>/mnt/fss/hello.txt; i=$((i+1)); sleep 1; done']
    volumeMounts:
      - name: fss
        mountPath: "/mnt/fss"
  volumes:
  - name: fss
    nfs:
      # FIXME: use the right IP
      server: 10.0.40.8
      path: "/fss"
```

__spec.volumes__配下にFSSのMount Targetの情報を記述しています。サーバーのアドレスは、先の手順で保存しておいたIPアドレス、パスはFSS作成時に指定したものになります。
この辺りは、通常のNFSボリュームをマウントするときの記述方法と全く変わりません。

__spec.containers.args__でコンテナが実行するコマンドを記述しており、FSS内のファイル(hello.txt)に定期的にメッセージを追記しています。

続いて、welcome-fssのmanifestです。

```yaml:welcome-fss.yaml
apiVersion: v1
kind: Pod
metadata:
  name: welcome-fss
spec:
  containers:
  - name: welcome-fss
    image: busybox
    args: [/bin/sh, -c, 'tail -f /mnt/fss/hello.txt']
    volumeMounts:
      - name: fss
        mountPath: "/mnt/fss"
  volumes:
  - name: fss
    nfs:
      # FIXME: use the right IP
      server: 10.0.40.8
      path: "/fss"
```

ボリュームのマウントに関連する記述は、hello-fssと同様です。

__spec.containers.args__のコマンドでは、hello-fssが作成するファイルをtailするにように記述しています。

これで、hello-fssがhello.txtにメッセージを追記していき、welcome-fssがhello.txtをtailした結果、その標準出力に追記内容が順次表示されていく、という動きになるはずです。

それでは動作確認してみます。まずはPodをデプロイします。

```
$ kubectl create -f hello-fss.yaml
pod "hello-fss" created
```
```
$ kubectl create -f welcome-fss.yaml
pod "welcome-fss" created
```
```
$ kubectl get po     
NAME          READY     STATUS    RESTARTS   AGE
hello-fss     1/1       Running   0          10s
welcome-fss   1/1       Running   0          10s
```

続いてWelcome-fssの標準出力を確認します。

```
$ kubectl logs -f welcome-fss     
0: Hello FSS!
1: Hello FSS!
2: Hello FSS!
3: Hello FSS!
4: Hello FSS!
5: Hello FSS!
6: Hello FSS!
7: Hello FSS!
8: Hello FSS!
```

こんな感じで Hello FSS! のメッセージが表示されていけばOKです。
これで、2つのPodから、FSSで構成したひとつの共有ストレージをマウントして、ファイルを操作できていることになります。

本エントリの手順は以上です。