ストレージ
PV、PVC、StorageClass
K8sストレージモデル
Podは一時的(ephemeral)。永続データにはPersistent Volumeを使用。 PVとPVCでストレージのプロビジョニングと消費を分離し、StorageClassで動的プロビジョニング。
Pod
アプリケーション
→ 参照アプリケーション
PVC
ストレージ要求
→ バインドストレージ要求
PV
実ストレージ
→ 接続実ストレージ
Storage
AWS EBS, GCE PD等
AWS EBS, GCE PD等
ボリュームタイプ
emptyDir
Pod内のコンテナ間で共有。Podが削除されるとデータも消失。一時ファイル向け。
hostPath
ノードのファイルシステムをマウント。ノード固有データへのアクセス。セキュリティリスクあり。
persistentVolumeClaim
PVCを参照。永続ストレージの標準的な使用方法。
configMap / secret
設定データをファイルとしてマウント。
PersistentVolume (PV)
PVはクラスタリソースとしての実ストレージ。 管理者が事前に作成(静的)またはStorageClassで自動作成(動的)。
pv.yaml
yaml
1 apiVersion: v1 2 kind: PersistentVolume 3 metadata: 4 name: pv-data 5 spec: 6 capacity: 7 storage: 10Gi 8 accessModes: 9 - ReadWriteOnce # 単一ノードで読み書き 10 persistentVolumeReclaimPolicy: Retain # PVC削除後も保持 11 storageClassName: standard 12 13 # ストレージバックエンド(例) 14 hostPath: 15 path: /mnt/data 16 17 # AWSの場合 18 # awsElasticBlockStore: 19 # volumeID: vol-xxx 20 # fsType: ext4
ReadWriteOnce (RWO)
単一ノードでR/W
ReadOnlyMany (ROX)
複数ノードでR
ReadWriteMany (RWX)
複数ノードでR/W(NFS等)
PersistentVolumeClaim (PVC)
PVCはユーザー側のストレージ要求。 要件(サイズ、アクセスモード、StorageClass)を指定すると、条件に合うPVがバインドされる。
pvc.yaml
yaml
1 apiVersion: v1 2 kind: PersistentVolumeClaim 3 metadata: 4 name: data-claim 5 spec: 6 accessModes: 7 - ReadWriteOnce 8 resources: 9 requests: 10 storage: 5Gi 11 storageClassName: standard # 省略するとデフォルトStorageClass 12 13 --- 14 # Podでの使用 15 apiVersion: v1 16 kind: Pod 17 metadata: 18 name: app 19 spec: 20 containers: 21 - name: app 22 image: myapp 23 volumeMounts: 24 - mountPath: /data 25 name: data-volume 26 volumes: 27 - name: data-volume 28 persistentVolumeClaim: 29 claimName: data-claim
1 # PVC操作 2 kubectl get pvc 3 kubectl describe pvc data-claim 4 5 # PVとのバインド状態確認 6 kubectl get pv,pvc
StorageClass
StorageClassは動的プロビジョニングのテンプレート。 PVC作成時に自動でPVを作成。クラウドプロバイダのCSIドライバと連携。
storageclass.yaml
yaml
1 apiVersion: storage.k8s.io/v1 2 kind: StorageClass 3 metadata: 4 name: fast-ssd 5 annotations: 6 storageclass.kubernetes.io/is-default-class: "true" 7 provisioner: ebs.csi.aws.com # AWS EBS CSI Driver 8 parameters: 9 type: gp3 10 fsType: ext4 11 encrypted: "true" 12 reclaimPolicy: Delete # PVC削除時にPVも削除 13 volumeBindingMode: WaitForFirstConsumer # Pod配置時にバインド 14 allowVolumeExpansion: true # ボリューム拡張を許可 15 16 --- 17 # GCPの場合 18 apiVersion: storage.k8s.io/v1 19 kind: StorageClass 20 metadata: 21 name: standard 22 provisioner: pd.csi.storage.gke.io 23 parameters: 24 type: pd-standard 25 volumeBindingMode: WaitForFirstConsumer
StatefulSetでの使用
StatefulSetのvolumeClaimTemplatesで各Podに専用PVCを自動作成。 Pod再起動時も同じPVCが維持される。
statefulset-storage.yaml
yaml
1 apiVersion: apps/v1 2 kind: StatefulSet 3 metadata: 4 name: postgres 5 spec: 6 serviceName: postgres 7 replicas: 3 8 selector: 9 matchLabels: 10 app: postgres 11 template: 12 metadata: 13 labels: 14 app: postgres 15 spec: 16 containers: 17 - name: postgres 18 image: postgres:15 19 volumeMounts: 20 - name: data 21 mountPath: /var/lib/postgresql/data 22 volumeClaimTemplates: 23 - metadata: 24 name: data 25 spec: 26 accessModes: ["ReadWriteOnce"] 27 storageClassName: fast-ssd 28 resources: 29 requests: 30 storage: 20Gi 31 # 結果: data-postgres-0, data-postgres-1, data-postgres-2 のPVCが作成
SRE/インフラ観点
設計ポイント
- • 動的プロビジョニング(StorageClass)を優先
- • WaitForFirstConsumerでノード配置を最適化
- • volumeBindingModeでPVの作成タイミングを制御
運用
- • reclaimPolicy: Retain で本番データを保護
- • allowVolumeExpansionでオンライン拡張を有効化
- • スナップショット(VolumeSnapshot)でバックアップ
トラブルシューティング
- • PVC Pending → StorageClassやクォータを確認
- • Pod起動失敗 → describe podでマウントエラー確認
- • CSIドライバのログを確認