ストレージ

PV、PVC、StorageClass

K8sストレージモデル

Podは一時的(ephemeral)。永続データにはPersistent Volumeを使用。 PVとPVCでストレージのプロビジョニングと消費を分離し、StorageClassで動的プロビジョニング。

Pod
アプリケーション
→ 参照
PVC
ストレージ要求
→ バインド
PV
実ストレージ
→ 接続
Storage
AWS EBS, GCE PD等

ボリュームタイプ

emptyDir

Pod内のコンテナ間で共有。Podが削除されるとデータも消失。一時ファイル向け。

hostPath

ノードのファイルシステムをマウント。ノード固有データへのアクセス。セキュリティリスクあり。

persistentVolumeClaim

PVCを参照。永続ストレージの標準的な使用方法。

configMap / secret

設定データをファイルとしてマウント。

PersistentVolume (PV)

PVはクラスタリソースとしての実ストレージ。 管理者が事前に作成(静的)またはStorageClassで自動作成(動的)。

pv.yaml
yaml
1apiVersion: v1
2kind: PersistentVolume
3metadata:
4 name: pv-data
5spec:
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
1apiVersion: v1
2kind: PersistentVolumeClaim
3metadata:
4 name: data-claim
5spec:
6 accessModes:
7 - ReadWriteOnce
8 resources:
9 requests:
10 storage: 5Gi
11 storageClassName: standard # 省略するとデフォルトStorageClass
12
13---
14# Podでの使用
15apiVersion: v1
16kind: Pod
17metadata:
18 name: app
19spec:
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操作
2kubectl get pvc
3kubectl describe pvc data-claim
4
5# PVとのバインド状態確認
6kubectl get pv,pvc

StorageClass

StorageClassは動的プロビジョニングのテンプレート。 PVC作成時に自動でPVを作成。クラウドプロバイダのCSIドライバと連携。

storageclass.yaml
yaml
1apiVersion: storage.k8s.io/v1
2kind: StorageClass
3metadata:
4 name: fast-ssd
5 annotations:
6 storageclass.kubernetes.io/is-default-class: "true"
7provisioner: ebs.csi.aws.com # AWS EBS CSI Driver
8parameters:
9 type: gp3
10 fsType: ext4
11 encrypted: "true"
12reclaimPolicy: Delete # PVC削除時にPVも削除
13volumeBindingMode: WaitForFirstConsumer # Pod配置時にバインド
14allowVolumeExpansion: true # ボリューム拡張を許可
15
16---
17# GCPの場合
18apiVersion: storage.k8s.io/v1
19kind: StorageClass
20metadata:
21 name: standard
22provisioner: pd.csi.storage.gke.io
23parameters:
24 type: pd-standard
25volumeBindingMode: WaitForFirstConsumer

StatefulSetでの使用

StatefulSetのvolumeClaimTemplatesで各Podに専用PVCを自動作成。 Pod再起動時も同じPVCが維持される。

statefulset-storage.yaml
yaml
1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4 name: postgres
5spec:
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ドライバのログを確認