Kubernetes Storage: Volume/Persistent Volume/Persistent Volume Claimについて

[「Kubernetes完全ガイド」](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804) を元に、Storage領域におけるVolumeの動作確認を行った結果をまとめます。

##実行環境
Kubernetes / kubectl version : 1.5.2
CentOS 7.4

※[構築手順1](https://qiita.com/m-eno/items/6caae931ea727f55f5c0)、[構築手順2](https://qiita.com/m-eno/items/4fa92ce812ce2a655d6c)


##Volumeとは
事前定義済みの利用可能なボリューム（ホストの領域、NFS、iSCSI、Ceph）をマニフェストに直接指定して使うもの。利用者がボリュームの作成、削除をしたり、マニフェストからボリューム自体を作る事もない

* emptyDir ：　Pod用の一時的なディスク領域。Podが終了すると削除される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/251519/9a619971-bd85-6d78-7361-af8c01f59efa.png)

出典：　[「Kubernetes完全ガイド」](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804) 

```json-doc:sample-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir
spec:
  containers:
  - image: nginx:1.12
    name: nginx-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
```
/cacheディレクトリが見える

```
[root@master ~]# kubectl exec -it sample-emptydir /bin/bash
root@sample-emptydir:/# df -h
Filesystem               Size  Used Avail Use% Mounted on
overlay                   35G  3.0G   33G   9% /
tmpfs                    920M     0  920M   0% /dev
tmpfs                    920M     0  920M   0% /sys/fs/cgroup
/dev/mapper/centos-root   35G  3.0G   33G   9% /cache
shm                       64M     0   64M   0% /dev/shm
tmpfs                    920M  8.0K  920M   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                    920M     0  920M   0% /proc/acpi
tmpfs                    920M     0  920M   0% /proc/scsi
tmpfs                    920M     0  920M   0% /sys/firmware
```

* hostPath：Kubernetesノード上の領域をコンテナにマッピング。セキュリティの観点で信頼できないコンテナがある場合は利用しない。

```json-doc:sample-hostpath.yaml
piVersion: v1
kind: Pod
metadata:
  name: sample-hostpath
spec:
  containers:
  - image: nginx:1.12
    name: nginx-container
    volumeMounts:
    - mountPath: /srv
      name: hostpath-sample
  volumes:
  - name: hostpath-sample
    hostPath:
      path: /etc
      type: DirectoryOrCreate
```
動作確認
/srv : Kubernetesノード(CentOS)上のディレクトリ   
/etc : Pod(Debian Linux)上のディレクトリ

```
[root@master ~]# kubectl exec -it sample-hostpath cat /srv/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"

[root@master ~]# kubectl exec -it sample-hostpath cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
```

##Persistent Volumeとは
永続化領域として確保されるVolume。基本的にNWストレージ（NFS、iSCSI、GCE Persistent Disk、AWS Elastic Blocl Store等）を利用する。シングルノード時のテスト用にhostPathは用意されている。

* NFSでPersistent Volumeを用意  　[※参考](https://qiita.com/YasuhiroABE/items/2e18bb546beea4660a99)

* 事前準備：CentOS7のノードにてNFSの設定

```
[root@master ~]# yum -y install nfs-utils
[root@master ~]# mkdir -p /exports/nfs

[root@master ~]# vi /etc/exports
/exports/nfs *(rw,async,no_root_squash)

[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl enable rpcbind
[root@master ~]# systemctl enable nfs-server
[root@master ~]# exportfs -r
```

```json-doc:sample-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
  annotations:
    volume.beta.kubernetes.io/storage-class: "slow"
　　#標準のディスクタイプで作成（SSD等であればfast)
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce   
    　#単一ノードからRead/Write可能
  persistentVolumeReclaimPolicy: Recycle　
　　#PVのデータを削除し、他のPVCで再利用/マウントされる
  nfs:
    server: 10.44.59.113
    path: /exports/nfs/pv0001
```

上記マニフェストを実行し、Persistent Volumeを作成

```
[root@master ~]# kubectl apply -f sample-pv.yaml
persistentvolume "pv0001" created
```

作成したPersistent Volumeを確認

```
root@master ~]# kubectl get persistentvolumes
NAME      CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS      CLAIM     REASON    AGE
pv0001    5Gi        RWO           Recycle         Available                       5m

```

## Persistent Volume Claimとは
永続化領域の要求を行うリソース。Persisteng Volumeは、Persistent Volume Claim（容量、ラベル）を元にPodに割当られる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/251519/9ed53419-5829-a8f3-d265-91f1cdecb5f3.png)
出典：　[「Kubernetes完全ガイド」](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804)

```json-doc:sample-persitent-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-app-pv-claim
  labels:
    app: sample-app
  annotations:
    "volume.beta.kubernetes.io/storage-class": "slow"
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
```
Persistent Volume Claimの作成と確認

```
[root@master ~]# kubectl apply -f sample-persitent-claim.yaml
persistentvolumeclaim "sample-app-pv-claim" created

[root@master ~]# kubectl get persistentvolumeclaim
NAME                  STATUS    VOLUME    CAPACITY   ACCESSMODES   AGE
sample-app-pv-claim   Bound     pv0001    5Gi        RWO           5m
```