KubernetesのConfig&Storageリソース(その2)
Config&Storageリソース
前回、利用者が直接利用するConfig&Storageリソースは3種類あることを紹介し、そのうちのSecretとConfigMapを解説しました。今回は、残る1種類であるPersistentVolumeClaimについて解説しますが、PersistentVolumeClaimを理解するために必要となるPersistentVolume、Volumeについても取り上げます。
リソースの分類 | 内容 |
---|---|
Workloadsリソース | コンテナの実行に関するリソース |
Discovery&LBリソース | コンテナを外部公開するようなエンドポイントを提供するリソース |
Config&Storageリソース | 設定・機密情報・永続化ボリュームなどに関するリソース |
Clusterリソース | セキュリティやクォータなどに関するリソース |
Metadataリソース | リソースを操作する系統のリソース |
VolumeとPersistentVolumeとPersistentVolumeClaimの違い
Volumeは既存のボリューム(ホストの領域、NFS、Ceph、GCP Volume)などをYAML Manifestに直接指定することで利用可能にするものです。そのため、利用者が新規でボリュームを作成したり、既存のボリュームを削除したりといった操作を行うことはできません。また、YAML ManifestからVolumeリソースを作成するといった処理も行いません。
一方でPersistentVolumeは、外部の永続ボリュームを提供するシステムと連携して、新規のボリュームの作成や、既存のボリュームの削除などを行うことが可能です。具体的には、YAML ManifestなどからPersistent Volumeリソースを別途作成する形になります。
PersistentVolumeにもVolumeにも同じプラグインが用意されています。例えばGCPやAWSのボリュームサービスでは、Persistent VolumeプラグインとVolumeプラグインの両方が用意されています。Persistent Volumeプラグインの方ではVolumeの作成と削除といったライフサイクルを処理することが可能(PersistentVolumeClaimを利用すればDynamic Provisioningも可能)ですが、Volumeプラグインの場合はすでにあるVolumeを利用することだけが可能です。
PersistentVolumeClaimは、その名のとおり作成されたPersistentVolumeリソースの中からアサインするためのリソースになります。Persistent Volumeはクラスタにボリュームを登録するだけなので、実際にPodから利用するにはPersistent Volume Claimを定義して利用する必要があります。また、Dynamic Provisioning機能(あとで解説します)を利用した場合は、Persistent Volume Claimが利用されたタイミングでPersistent Volumeを動的に作成することが可能なため、順番が逆に感じられるかもしれません。
Volume
Kubernetesでは、Volumeを抽象化してPodと疎結合なリソースとして定義しています。Volumeプラグインとして、下記のような様々なプラグインが提供されています。下記のリスト以外にもあるので、詳細は「https://kubernetes.io/docs/concepts/storage/volumes/」を確認して下さい。
- EmptyDir
- HostPath
- nfs
- iscsi
- cephfs
- GCPPersistentVolume
- gitRepo
PersistentVolumeとは異なり、Podに対して静的に領域を指定するような形になるため、競合などに注意してください。
EmptyDir
EmptyDirはPod用の一時的なディスク領域として利用可能です。PodがTerminateされると削除されます。
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: {} $ kubectl apply -f emptydir-sample.yml
HostPath
HostPathは、Kubernetes Node上の領域をコンテナにマッピングするプラグインです。typeにはDirectory、DirectoryOrCreate、File、Socket、BlockDeviceなどから選択します。DirectoryOrCreateとDirectoryとの差は、ディレクトリが存在しない場合に作成して起動するか否かの違いです。
apiVersion: 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: /data type: DirectoryOrCreate $ kubectl apply -f hostpath-sample.yml
PersistentVolume(PV)
PersistentVolumeは、永続化領域として確保されるVolumeです。前述のVolumeはPodの定義内に直接書き込む形で接続を行っていましたが、Persistent Volumeはリソースとして個別に作成してから利用します。すなわち、YAML Manifestを使ってPersistent Volumeリソースを作成する必要があります。
また、PersistentVolumeは厳密にはConfig&StorageリソースではなくClusterリソースに分類されますが、今回は説明の都合上この章で説明しています。
PersistentVolumeの種類
PersistentVolumeは、基本的にネットワーク越しでディスクをアタッチするタイプのディスクとなります。シングルノード時のテスト用としてHostPathが提供されていますが、PersistentVolumeとしては実用的ではありません。PersistentVolumeはPluggableな構造となっており、一例として下記のようなものがあります。下記のリスト以外にもあるので、詳細は「https://kubernetes.io/docs/concepts/storage/persistent-volumes/」を確認して下さい。
- GCE Persistent Disk
- AWS Elastic Block Store
- NFS
- iSCSI
- Ceph
- OpenStack Cinder
- GlusterFS
PersistentVolumeの作成
PersistentVolumeを作成する際には、下記のような項目を設定します。
- ラベル
- 容量
- アクセスモード
- Reclaim Policy
- マウントオプション
- Storage Class
- PersistentVolumeごとの設定
apiVersion: v1 kind: PersistentVolume metadata: name: sample-pv labels: type: nfs environment: stg spec: capacity: storage: 10G accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: slow mountOptions: - hard nfs: server: xxx.xxx.xxx.xxx path: /nfs/sample $ kubectl create -f pv_sample.yml
作成後に確認すると、正常に作成できたためBoundステータスになっていることが確認できます。
$ kubectl get pv NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE sample-pv 10Gi RWX Retain Bound 6s
以下、PersistentVolumeの設定項目について解説します。
ラベル
Dynamic Provisioningを使わずにPersistentVolumeを作成していく場合、PersistentVolumeの種類がわからなくなってしまうため、type、environment、speedなどのラベルをつけていくことをお勧めします。ラベルをつけていない場合、既存のPersistentVolumeの中から自動的に割り当てを行う必要が生じるため、ユーザの意志によるディスクのアタッチが困難になります。
一方でラベルをつけておくと、PersistentVolumeClaimでボリュームのラベルを指定できるで、スケジューリングを柔軟に行えます。
容量
容量を指定します。ここで注意するべきポイントは、Dynamic Provisioningが利用できない環境では、小さめのPersistentVolumeも用意することです。例えば下の図のよう状況で、PersistentVolumeClaimからの要求が3GBだった場合、用意されているPersistent Volumeの中から最も近い容量である10GBのものが割り当てられることになります。
アクセスモード
アクセスモードは3つ存在しています。
モード | 内容 |
---|---|
ReadWriteOnce(RWO) | 単一ノードからRead/Writeされます |
ReadOnlyMany(ROX) | 単一ノードからWrite、複数ノードからReadされます |
ReadWriteMany(RWX) | 複数ノードからRead/Writeされます |
PersistentVolumeによって、サポートしているアクセスモードは異なります。またGCP、AWS、OpenStackで提供されるブロックストレージサービスでは、ReadWriteOnceのみサポートされています。詳細は、https://kubernetes.io/docs/concepts/storage/persistent-volumes/を確認して下さい。
Reclaim Policy
Reclaim Policyは、PersistentVolumeを利用し終わった後の処理方法(破棄するか、再利用するかなど)を制御するポリシーです。
- Retain
- PersistentVolumeのデータも消さずに保持します
- また、他のPersistentVolumeClaimによって、このPersistentVolumeが再度マウントされることはありません
- Recycle
- PersistentVolumeのデータを削除(rm -rf ./*)し、再利用可能時な状態にします
- 他のPersistentVolumeClaimによって再度マウントされます。
- Delete
- PersistentVolumeが削除されます
- GCE、AWS、OpenStackなどで確保される外部ボリュームの際に利用されます
マウントオプション
PersistentVolumeの種別によっては、追加でマウントオプションを指定することが可能です。詳しくは各Persistent Volumeの仕様を確認して下さい。
Storage Class
Dynamic Provisioningの場合にユーザがPersistentVolumeClaimを使ってPersistentVolumeを要求する際に、どういったディスクが欲しいのかを指定するために利用されます。Storege Classの選択=外部ボリュームの種別選択となります。
例えばOpenStack Cinderの場合には、ボリュームを切り出す際に、どのバックエンド(Ceph、ScaleIO、Xtremioなど)か、どのゾーンかなどを選択可能です。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: sample-storageclass parameters: availability: test-zone-1a type: scaleio provisioner: kubernetes.io/cinder
PersistentVolume Pluginごとの設定
今回はNFSの例にしましたが、実際の設定項目はPersistentVolume Pluginごとに異なります。例えばspec.nfsは、GlusterFS Pluginを利用した場合には利用されません。