PersistentVolumeClaim(PVC)
PersistentVolumeClaim(PVC)
PersistentVolumeClaimは、永続化領域の要求を行うリソースです。前述のPersistentVolumeは、PersistentVolumeClaim経由で利用する形になります。PersistentVolumeClaimで指定された条件(容量、ラベル)をもとに、永続化領域の要求が発行されると、Schedulerは現在保持しているPersistentVolumeから適したVolumeを割り当てるようになっています。
PersistentVolumeClaimの設定
PersistentVolumeClaimを作成する際には、下記のような項目を設定します。
- ラベルセレクター
- 容量
- アクセスモード
- Storage Class
いずれもPersistentVolumeの部分で定義した値であり、このPersistentVolumeClaimの要求にマッチするPersistentVolumeが払い出されます。
この時注意してほしいのが、PersistentVolumeClaimの容量がPersistentVolumeの容量よりも小さければ割り当てられてしまう点です。例えば、8GBの要求に対して8GBのPersistent Volumeがあればそれが割り当てられますが、もし20GBのPersistent Volumeしかない場合にもそれが割り当てられます。
また、通常のNFSなどではNFSの仕組み上Quotaがかかっておらず、PersistentVolume作成時の容量が実質無視されてしまう点にも注意が必要です。
PersistentVolumeClaimの作成
リスト6:PersistentVolumeClaimを作成するpvc_sample.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: sample-pvc
spec:
selector:
matchLabels:
type: "nfs"
matchExpressions:
- {key: environment, operator: In, values: [stg]}
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
kubectl apply -f pvc_sample.yml
PersistentVolumeClaimを作成すると、PersistentVolumeClaimがPersistentVolumeを確保していることが確認できます。
リスト7:PersistentVolumeClaimの状態を確認
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
sample-pvc Bound sample-pv 10G RWX 4m
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
sample-pv 10G RWX Retain Bound default/sample-pvc 5m
PersistentVolumeClaimがPersistentVolumeの確保に失敗すると、ステータスはPendingのままになります。
リスト8:PersistentVolumeの確保に失敗した場合
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
sample-pvc Pending 4m
$ kubectl describe pvc sample-pvc
...
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
2m 1m 4 persistentvolume-controller Normal FailedBinding no persistent volumes available for this claim and no storage class is set
また、Podが終了してPersistentVolumeClaimの利用が終わった際に、Retainポリシーを利用している場合には、StatusがBoundからReleasedになります。Released状態のPersistentVolumeは、再度PersistentVolumeClaimから割り当てられることはありません。
リスト9:Pod終了後、StatusはReleasedに
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
sample-pv 10G RWX Retain Released default/sample-pvc 5m
Podからの利用
Podから利用する場合には、spec.volumesにpersistentVolumeClaim.claimNameを指定します。
リスト10:PodからPersistentVolumeClaimを利用するpvc_pod_sample.yml
apiVersion: v1
kind: Pod
metadata:
name: sample-pvc-pod
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
name: "http"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: sample-pvc
Dynamic Provisioning
ここまでのPersistentVolumeClaimの説明では、PersistentVolumeを事前に作成しておき、PersistentVolumeClaimの要求をもとに割り当てるため、無駄や手間が発生するという問題がありました。
これらの問題を解決するのが、Dynamic Provisioningです。Dynamic Provisioningを使ったPersistentVolumeClaimの場合、PersistentVolumeClaimが発行されたタイミングで動的にPersistentVolumeを作成して、割り当てます。そのため「容量の無駄が生じない」「事前にPersistent Volumeを作成する必要がない」といったメリットがあります。一方で、多くのProvisionerがReadWriteOnceのアクセスモードしかサポートしていない点に注意して下さい。
事前にStorageClassを作成します。
リスト11:StorageClassを作成するstorageclass_sample.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sample-storageclass
parameters:
type: pd-standard
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
$ kubectl apply -f storageclass_sample.yml
その後、Dynamic Provisioning用のStorageClassを指定して、PersistentVolumeClaimを作成します。
リスト12:PersistentVolumeClaimを作成するpvc_provisioner_sample.yml(Dynamic Provisioning)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc-provisioner
annotations:
volume.beta.kubernetes.io/storage-class: sample-storageclass
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
$ kubectl create -f pvc_provisioner_sample.yml
PersistentVolumeClaimをPodに指定して作成します。
リスト13:PersistentVolumeClaimを作成するpvc_provisioner_pod_sample.yml(Dynamic Provisioning)
apiVersion: v1
kind: Pod
metadata:
name: sample-pvc-provisioner-pod
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
name: "http"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: sample-pvc-provisioner
$ kubectl create -f pvc_provisioner_pod_sample
すると、PersistentVolumeを事前に作成していないにも関わらず、PersistentVolumeが作成されていることが確認できます。
リスト14:Dynamic ProvisioningによりPersistentVolumeが作成されている
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-2be3da43-9b25-11e7-a1b1-fa2929e9568b 3Gi RWO Retain Bound default/sample-pvc-provisioner-pod sample-storageclass 22d
StatefulSetでのPersistentVolumeClaim Template
StatefulSetでのワークロードでは、データ領域は永続化されることが多いため、spec.volumeClaimTemplateの項目があります。claimTemplateを利用すると、PersistentVolumeClaimを別途定義する必要がなくなり、簡素化することが可能です。残りはContainerのvolumeMountsにvolumeClaimTemplateで指定した名前を指定するだけで完了となり、StatefulSetのYAMLだけで完結します。
リスト15:PersistentVolumeClaim Template
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
:
:
spec:
template:
spec:
containers:
- name: sample-pvct
image: nginx:1.12
volumeMounts:
- name: pvc-template-volume
mountPath: /tmp
volumeClaimTemplates:
- metadata:
name: pvc-template-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: "sample-storageclass"
:
:
まとめ
今回までの全9回の連載で、基本的なKubernetesの使い方はマスターしたかと思います。ですが、ここまでで身につけたKubernetesの知識だけでは、実はまだProductionでの利用には十分ではありません。とはいえ、今までVMを利用していたアーキテクチャで考慮しなければならなかったこと(リソースの配分、ヘルスチェック、スケジューリング、セキュリティ)をKubernetesの機能に任せることができるため、学習コストは比較的低くて済みます。
連載は今回で一区切りとなります。細かいKubernetesの機能について
- 実運用する際の注意点
- 最新のKubernetesエコシステム
の話については、また別の機会にご紹介したいと思います。
- この記事のキーワード