[Kubernetes]PersistentVolume/PersistentVolumeClaimの動作を確認する 2

#はじめに
[前回](https://qiita.com/dingtianhongjie/items/d9064471cf8c97c994d4)はPersistentVolume（PV）とPersistentVolumeClaim（PVC）の基本的な動作を確認しました。
PVをコンテナで利用する際は、PVCを経由して利用しますが、その際PVCは「こういうPVが欲しい」と要求します。今回はその要求に対して、どのようにPVが割り当てられるのかを確認してみたいと思います。

#PVの割り当て
##準備
以下6つのPVを用意しました。[前回](https://qiita.com/dingtianhongjie/items/d9064471cf8c97c994d4)のPVのマニフェストの名前と容量を変えただけです。

```
$ kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv0001   500Mi      RWX            Recycle          Available           slow                    6s
pv0002   300Mi      RWX            Recycle          Available           slow                    6s
pv0003   500Mi      RWX            Recycle          Available           slow                    6s
pv0004   300Mi      RWX            Recycle          Available           slow                    5s
pv0005   600Mi      RWX            Recycle          Available           slow                    5s
pv0006   700Mi      RWX            Recycle          Available           slow                    5s
```

##PVCの作成

まず400MiBで2つ要求します。PVCのマニフェストも[前回](https://qiita.com/dingtianhongjie/items/d9064471cf8c97c994d4)と名前と容量を変えただけです。

```
$ kubectl apply -f pvc1.yaml
persistentvolumeclaim/myclaim1 created
persistentvolumeclaim/myclaim2 created
$ kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM              STORAGECLASS   REASON   AGE
pv0001   500Mi      RWX            Recycle          Bound       default/myclaim1   slow                    77s
pv0002   300Mi      RWX            Recycle          Available                      slow                    77s
pv0003   500Mi      RWX            Recycle          Bound       default/myclaim2   slow                    77s
pv0004   300Mi      RWX            Recycle          Available                      slow                    76s
pv0005   600Mi      RWX            Recycle          Available                      slow                    76s
pv0006   700Mi      RWX            Recycle          Available                      slow                    76s
$ kubectl get pvc
NAME       STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim1   Bound    pv0001   500Mi      RWX            slow           13s
myclaim2   Bound    pv0003   500Mi      RWX            slow           13s
```

400MiB以上で一番近い500MiBのPVがBoundされていますね。
なお、ここではPVの名前順にBoundされていますが、何回かやってみると逆になることもありました。よって、同一条件であればランダムにBoundされるようです。

さらに400MiBで2つ要求します。

```
$ kubectl apply -f pvc2.yaml
persistentvolumeclaim/myclaim3 created
persistentvolumeclaim/myclaim4 created
$ kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM              STORAGECLASS   REASON   AGE
pv0001   500Mi      RWX            Recycle          Bound       default/myclaim1   slow                    95s
pv0002   300Mi      RWX            Recycle          Available                      slow                    95s
pv0003   500Mi      RWX            Recycle          Bound       default/myclaim2   slow                    95s
pv0004   300Mi      RWX            Recycle          Available                      slow                    94s
pv0005   600Mi      RWX            Recycle          Bound       default/myclaim3   slow                    94s
pv0006   700Mi      RWX            Recycle          Bound       default/myclaim4   slow                    94s
$ kubectl get pvc
NAME       STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim1   Bound    pv0001   500Mi      RWX            slow           35s
myclaim2   Bound    pv0003   500Mi      RWX            slow           35s
myclaim3   Bound    pv0005   600Mi      RWX            slow           16s
myclaim4   Bound    pv0006   700Mi      RWX            slow           16s
```

600MiBと700MiBのPVがBoundされていますね。

あと残りは300MiBのPVだけですが、さらに400MiBを2つ要求してみます。

```
$ kubectl apply -f pvc3.yaml
persistentvolumeclaim/myclaim5 created
persistentvolumeclaim/myclaim6 created
$ kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM              STORAGECLASS   REASON   AGE
pv0001   500Mi      RWX            Recycle          Bound       default/myclaim1   slow                    2m8s
pv0002   300Mi      RWX            Recycle          Available                      slow                    2m8s
pv0003   500Mi      RWX            Recycle          Bound       default/myclaim2   slow                    2m8s
pv0004   300Mi      RWX            Recycle          Available                      slow                    2m7s
pv0005   600Mi      RWX            Recycle          Bound       default/myclaim3   slow                    2m7s
pv0006   700Mi      RWX            Recycle          Bound       default/myclaim4   slow                    2m7s
$ kubectl get pvc
NAME       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim1   Bound     pv0001   500Mi      RWX            slow           63s
myclaim2   Bound     pv0003   500Mi      RWX            slow           63s
myclaim3   Bound     pv0005   600Mi      RWX            slow           44s
myclaim4   Bound     pv0006   700Mi      RWX            slow           44s
myclaim5   Pending                                      slow           11s
myclaim6   Pending                                      slow           11s
```

PVCは作成できますが、BoundされずPendingの状態になってますね。

#PVの割り当て制御
PVCは「こういうPVが欲しい」と要求します。「これ」と特定のPVを指定することができません。
PVの数が一桁くらいでしたらこのような要求でも大丈夫かも知れませんが、数十個、数百個となるとある程度制御できた方がよいでしょう。
そこでラベルを設定してみたいと思います。

##PVの作成
マニフェストでラベルを設定します。

```pv-label.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
  labels:
    env: stg
spec:
  capacity:
    storage: 500Mi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /share
    server: k8s-client
---
・・・
```
名前、容量、ラベルを変えてPVを3つ作成します。

```
$ kubectl apply -f pv-label.yaml
persistentvolume/pv0001 created
persistentvolume/pv0002 created
persistentvolume/pv0003 created
$ kubectl get pv -L env
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   ENV
pv0001   500Mi      RWX            Recycle          Available           slow                    15s   stg
pv0002   400Mi      RWX            Recycle          Available           slow                    15s   stg
pv0003   600Mi      RWX            Recycle          Available           slow                    15s   prd
```

##PVCの作成
マニフェストでラベルを設定します。

```pvc-label.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  selector:
    matchLabels:
      env: prd
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 400Mi
  storageClassName: slow
```

このマニフェストをapplyしてPVCを作成します。

```
$ kubectl apply -f pvc-label.yaml
persistentvolumeclaim/myclaim created
$ kubectl get pv -L env
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM             STORAGECLASS   REASON   AGE   ENV
pv0001   500Mi      RWX            Recycle          Available                     slow                    13m   stg
pv0002   400Mi      RWX            Recycle          Available                     slow                    13m   stg
pv0003   600Mi      RWX            Recycle          Bound       default/myclaim   slow                    13m   prd
$ kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Bound    pv0003   600Mi      RWX            slow           2m46s
```

PVCのマニフェストで指定した容量は400MiBですので、ラベルがなければ400MiBの「pv0002」がBoundされるはずですが、同じラベルの「pv0003」がBoundされていますね。

#まとめ
今回は容量をキーにして、PVとPVCの割り当て動作を確認しました。
PVCは「こういうPVが欲しい」と要求しますので、割り当てを制御するにはラベルが有効ですね。「これ」と明示的にPVを指定することはできませんが、Kubernetesの考え方からすると、これくらいの緩い制御の方があってるのでしょうね。
私も馴染めるように考え方を変えていかないといけないです。