Kubernetes基礎(6)：Volume-emptyDir, hostPath, PV/PVC

#Volumeとは
Container間でDataを共有するため、Volumeを使う。
###1. emptyDir
![kubernetes_volume with emptyDir.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/ff860b02-87f2-8394-ccda-8e7dcb190ba9.jpeg)
Volumeが作成された時は常にVolume中は何もない空であるため「emptyDir」という名が付けられた。

上の図で、Container1をWebの役割をするWeb Server、Container2はバックエンドを処理するWeb Application Serverとした場合、Web Serverが受信した特定のファイルをマウントされたVolumeに保存して置いて、バックエンドも同じVolumeをマウントして置くと両方のサーバーがVolumeをまるで自分のローカルにあるDirectoryのように使えるので、両方のサーバーが相互にファイルを送受信する必要がなくなります。
注意すべきことはemptyDirタイプのVolumeはPodの中で生成されるため、Podに問題が発生して再生成されると、Dataが消えてしまうことです。emptyDirタイプのVolumeを使う場合は一時的なDataを使ったほうが良いです。

<b>1-1) Pod</b>

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-1
spec:
  containers:
  - name: container1
    image: <image file name>
    volumeMounts:
    - name: empty-dir
      mountPath: /mount1
  - name: container2
    image: kubetm/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount2
  volumes:
  - name : empty-dir
    emptyDir: {}
```
※Yaml file
・mountPath/ mount1
・mountPath/ mount2
→　mountPathが違っていてもnameに指定したVolumeが同一であるため同じVolumeを指すことになります。
・emptyDir: {}
→　Volumeの属性にemptDirが記載されている。
###2. HostPath
![kubernetes_Volume with hostPath.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/4335e81c-4f9a-74d7-39ac-547873277358.jpeg)

Podが含まれているNode(Host)のPathをVolumeとして使います。
empDirと異なることは、このPathをそれぞれのPodがマウントして共有するとPodが再生成されてもNodeのDataは消えません。

HostPathタイプのVolumeを使うとき注意すべきことは
Pod2が何かの問題で再生成された時、必ずNode1に生成されることはない、Node Schedulerがリソースの状況を見てNode2にPodを生成することもあります。
また、Node1に障害が生じて、他のNodeにPodを移動することも考えられるがPodが他のNodeに移動されると、既存のNodeのVolumeにマウントすることはできなくなります。
HostPathタイプのVolumeはPodが属しているHost(Node)のシステムファイルなどを読み取ったり、PodのDataを保存するためではなくNodeのデータをPodで使うときに使うのが一般的な使い方です。
※hostPathはPodを作る前に作っておかないとPodを作るときエラーになります。

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-3
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1　　　※Nodeを指定するとPodが再生成されても同Nodeに生成されます。
  containers:
  - name: container
    image: <image file name>
    volumeMounts:
    - name: host-path
      mountPath: /mount1
  volumes:
  - name : host-path
    hostPath:
      path: /node-v
      type: DirectoryOrCreate
```
※Yaml file
・DirectoryOrCreate : 実際のPathがない場合は作成する。
・Directory : 実際のPathが存在しないといけない。
・FileOrCreate : 実際のPathにファイルがない場合は作成する。
・File : 実際のファイルが存在しないといけない。

###3. PVC / PV
![kubernetes_volume with PersistentVolume PersistentVolumeClaim.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/8f8cc16b-2567-b333-5918-b51b303e8d43.jpeg)
Podに永続性のあるVolumneを提供します。
Volumeは様々なタイプがあります。
Local Volumeもありますが、外部のリモートで使えるVolumeもあります。
AmazoneやGitに接続することもできるし、NFSを使って他のサーバーと接続することもできます。
StorageosのようにVolumeを直接作成して管理することができるSolutionもあります。
これらのことを、それぞれPrsistent Volumeを定義して接続をすることができます。

上の図を見るとPodはPersistent Volumeに直接接続せずにPersistent Volume Claimを通しPersistent Volumeに接続しています。
直接接続をしていない理由は、KubernetesはVolume使用において、Admin areaとUser areaに分けっています。
AdminはKubernetesを担当する管理者で、UserはPodにサービスをDeployして管理するサービス担当者であります。
Volumeのタイプも多く、タイプ別の設定もそれぞれ違うため、専門的にこのようなものを管理するAdminが
Persistent Volumeを作成しておくとUserはこれを使うためにPVCを作成しますが
下のYmalファイルのようにReae and Write modeにsizeを1g、storageClassName：""のように設定すれば既に作られているPVの中から選択されます。

<b>3-1) PersistentVolume</b>

```Yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-03
spec:
  capacity:
    storage: 1G
  accessModes:
  - ReadWriteOnce
  local:
    path: /node-v
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}
```

<b>3-2) PersistentVolumeClaim</b>

```Yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-04
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1G
  storageClassName: ""
```

<b>3-3) Pod</b>

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-3
spec:
  containers:
  - name: container
    image: kubetm/init
    volumeMounts:
    - name: pvc-pv
      mountPath: /mount3
  volumes:
  - name : pvc-pv
    persistentVolumeClaim:
      claimName: pvc-01
```

#Referenece
* Kubernetes Volumes : https://kubernetes.io/docs/concepts/storage/volumes/