Container Engine for Kubernetes (OKE)の永続ボリューム（Persistent Volume）の設定方法を確認する

#はじめに
Oracle Cloud Infrastructure（OCI）のKubernetesサービス：**OKE** のPersistent Volume（PV）の設定方法を以下のマニュアルに沿って確認します。

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengcreatingpersistentvolumeclaim.htm#Creating_a_Persistent_Volume_Claim

#事前準備
Kubernetesクラスタは、以下に沿って事前に作成しています。

https://oracle-japan.github.io/ocitutorials/cloud-native/oke-for-commons/

##クラスタ構成
作成したクラスタ構成です。基本的にデフォルトのままです。

![cluster.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/5c7a1e99-2e6a-2db9-9c3c-0a0ece534c91.png)

```
$ kubectl get node
NAME          STATUS   ROLES   AGE     VERSION
10.0.10.144   Ready    node    7h42m   v1.20.8
10.0.10.158   Ready    node    7h42m   v1.20.8
10.0.10.181   Ready    node    7h42m   v1.20.8
```

#PVの作成
##StorageClass
OCIはDynamic Provisioningに対応したProvisionerがStorageClassに予め登録されています。
そのため、PVを事前に作成する必要はなく、PVCを作成するとPVもデプロイされます。

```
$ kubectl get sc
NAME            PROVISIONER                       RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
oci (default)   oracle.com/oci                    Delete          Immediate              false                  8h
oci-bv          blockvolume.csi.oraclecloud.com   Delete          WaitForFirstConsumer   false                  8h
$ kubectl describe sc oci-bv
Name:                  oci-bv
IsDefaultClass:        No
Annotations:           <none>
Provisioner:           blockvolume.csi.oraclecloud.com
Parameters:            <none>
AllowVolumeExpansion:  <unset>
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     WaitForFirstConsumer
Events:                <none>
```

##PVCの作成
マニュアルにあるPVCのマニュフェストをapplyして、PVCを作成します。容量だけは5GiBにしました。

```pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mynginxclaim
spec:
  storageClassName: "oci-bv"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
```

```
$ kubectl apply -f pvc.yaml
persistentvolumeclaim/mynginxclaim created
$ kubectl get pvc
NAME           STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mynginxclaim   Pending                                      oci-bv         8s
```

この時点ではStatusはまだPendingです。これは、StorageClassの``VolumeBindingMode``が``WaitForFirstConsumer``になっているためです。これが指定されている場合、Pod作成時にPVがデプロイされます。

##Podの作成
Podを作成して、PVをマウントします。マニュアルにあるマニフェストを使用してnginxをデプロイします。

```nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - name: http
          containerPort: 80
      volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: mynginxclaim
```

```
$ kubectl apply -f nginx.yaml 
pod/nginx created
$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx                    1/1     Running   0          90s
```
詳細を確認して、PVをマウントしていることを確認します。

```
$ kubectl describe pod nginx
Name:         nginx
Namespace:    default
Priority:     0
Node:         10.0.10.144/10.0.10.144
Start Time:   Thu, 16 Sep 2021 12:20:56 +0000
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.0.4
IPs:
  IP:  10.244.0.4
Containers:
  nginx:
    Container ID:   cri-o://8b0f77586a80008e59eb29384e3ec8e39132dd5a191035cda0fbb2af03506099
    Image:          nginx:latest
    Image ID:       docker.io/library/nginx@sha256:6fe11397c34b973f3c957f0da22b09b7f11a4802e1db47aef54c29e2813cc125
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 16 Sep 2021 12:21:41 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /usr/share/nginx/html from data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-9vzsl (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  data:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  mynginxclaim
    ReadOnly:   false
  default-token-9vzsl:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-9vzsl
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
  Normal  Scheduled               90s   default-scheduler        Successfully assigned default/nginx to 10.0.10.144
  Normal  SuccessfulAttachVolume  74s   attachdetach-controller  AttachVolume.Attach succeeded for volume "csi-3377c8ba-7eac-43bf-be88-b604bb069f84"
  Normal  Pulling                 53s   kubelet                  Pulling image "nginx:latest"
  Normal  Pulled                  46s   kubelet                  Successfully pulled image "nginx:latest" in 7.22865785s
  Normal  Created                 46s   kubelet                  Created container nginx
  Normal  Started                 46s   kubelet                  Started container nginx
```
Volumeがアタッチされていますね。

マウントされていることも確認します。

```
$ kubectl exec -it nginx -- df -h |grep /usr/share
/dev/sdb         50G   53M   47G   1% /usr/share/nginx/html
```
書き込みもできます。

```
$ kubectl exec -it nginx -- touch /usr/share/nginx/html/index.html
$ kubectl exec -it nginx -- ls /usr/share/nginx/html
index.html  lost+found
```


##PV/PVCの確認
PVとPVCを確認します。

```
$ kubectl get pvc
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mynginxclaim   Bound    csi-3377c8ba-7eac-43bf-be88-b604bb069f84   50Gi       RWO            oci-bv         3m53s
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE
csi-3377c8ba-7eac-43bf-be88-b604bb069f84   50Gi       RWO            Delete           Bound    default/mynginxclaim   oci-bv                  108s
```

PVが作成されて、PVCにBoundされています。しかし、PVCで指定した5GiBではなく、**50GiB**になっています。
これはOCIのブロックボリュームの最小が50GiBのため、切り上げられました。

OCIのコンソールでも確認します。50GBのブロックボリュームが作成されていますね。
![bv.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/b85d9d60-8373-66b8-2a23-538cd5730083.png)

#削除
削除手順も確認します。

```
$ kubectl delete -f nginx.yaml 
pod "nginx" deleted
$ kubectl get pod nginx
Error from server (NotFound): pods "nginx" not found
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE
csi-3377c8ba-7eac-43bf-be88-b604bb069f84   50Gi       RWO            Delete           Bound    default/mynginxclaim   oci-bv                  56m
$ kubectl get pvc
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mynginxclaim   Bound    csi-3377c8ba-7eac-43bf-be88-b604bb069f84   50Gi       RWO            oci-bv         58m
```

Podを削除した状態ではPVはまだ残ってますね。
次にPVCを削除します。

```
$ kubectl delete -f pvc.yaml 
persistentvolumeclaim "mynginxclaim" deleted
$ kubectl get pvc
No resources found in default namespace.
$ kubectl get pv
No resources found
```

PVも一緒に削除されました。
コンソールでも削除されていることが確認できます。

![bv-del.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/8bdc0ece-8e29-1e68-3c74-cf4bec12c0ff.png)