【Kubernetes】StatefulSetでPodごとにログを保存する方法|volumeClaimTemplatesとreclaimPolicyの動作を検証
KubernetesでStatefulSetを使うと、「Podごとに専用のボリューム」を持たせることができます。
ただし、スケール操作(3→2→3など)を行うと、ログが消えるケースがあるため注意が必要です。
この記事では、以下の内容を実際の検証手順とともに解説します。
- StatefulSetでPod名を取得してログに書き込む方法
- volumeClaimTemplatesの仕組み
- スケールダウン後にログが消える原因
- reclaimPolicyをRetainに変更する方法
- スケール後もログを保持する方法
記事の目次
StatefulSetを作成してPodごとにログを書き込む
まずはStatefulSetを作成します。
ファイル名は statefulSet-write-podName.yaml とします。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sample-statefulset
spec:
serviceName: sample-statefulset
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: busybox-container
image: busybox
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
command:
- sh
- -c
- |
echo "Starting container in pod $POD_NAME" >> /usr/share/date/log.txt
while true; do date >> /usr/share/date/log.txt; sleep 180; done
volumeMounts:
- name: date-log
mountPath: /usr/share/date/
volumeClaimTemplates:
- metadata:
name: date-log
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi作成します。
kubectl apply -f statefulSet-write-podName.yamlPodごとのログを確認する
作成されたPodは以下のようになります。
sample-statefulset-0
sample-statefulset-1
sample-statefulset-2ログを確認します。
kubectl exec -it sample-statefulset-0 -- cat /usr/share/date/log.txt
kubectl exec -it sample-statefulset-1 -- cat /usr/share/date/log.txt
kubectl exec -it sample-statefulset-2 -- cat /usr/share/date/log.txt
それぞれのPodで違うログが保存されていることが確認できます。
StatefulSetは同じボリュームを共有していない
StatefulSet + volumeClaimTemplates を使用すると、Podごとに専用のPVCが自動作成されます。
replicas: 3 の場合は以下のようになります。
sample-statefulset-0 → PVC: date-log-sample-statefulset-0
sample-statefulset-1 → PVC: date-log-sample-statefulset-1
sample-statefulset-2 → PVC: date-log-sample-statefulset-2つまり、Podごとに別のボリュームを持つ設計になっています。
スケールダウンしてみる(3 → 2)
次にPod数を減らしてみます。
kubectl scale statefulset sample-statefulset --replicas=2
もう一度スケールアップ(2 → 3)
kubectl scale statefulset sample-statefulset --replicas=3再度 sample-statefulset-2 が作成されます。
ログを確認します。
kubectl exec -it sample-statefulset-2 -- cat /usr/share/date/log.txt
以前のログが消えてる?
以前のログが消えている原因
原因は StorageClassのreclaimPolicyがDeleteになっているためです。
確認してみます。
kubectl get sc
Delete の場合、Pod削除時にPVCとPVも削除されるため、ログも消えてしまいます、、。
StorageClassを変更して、PersistVolumeが残るようにする
既存のStorageClassは直接変更できません。
そのため、コピーして新しく作成します。

下記コマンドを実行してyamlを作成
kubectl get sc standard -o yaml > standard-retain.yaml名前とreclaimPolicy: Retain を変更
変更前
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"},"labels":{"addonmanager.kubernetes.io/mode":"EnsureExists"},"name":"standard"},"provisioner":"k8s.io/minikube-hostpath"}
storageclass.kubernetes.io/is-default-class: "true"
creationTimestamp: "2025-07-18T07:02:00Z"
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: standard
resourceVersion: "310"
uid: b611f5ee-6b0f-4636-a49b-04f716a8f9d4
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Delete
volumeBindingMode: Immediate変更後
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"},"labels":{"addonmanager.kubernetes.io/mode":"EnsureExists"},"name":"standard"},"provisioner":"k8s.io/minikube-hostpath"}
storageclass.kubernetes.io/is-default-class: "true"
creationTimestamp: "2025-07-18T07:02:00Z"
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: standard-2
resourceVersion: "310"
uid: b611f5ee-6b0f-4636-a49b-04f716a8f9d4
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Retain
volumeBindingMode: Immediate作成します。
kubectl apply -f standard-retain.yaml
StatefulSet側もStorageClassを変更する
volumeClaimTemplatesに storageClassName を追加します。
volumeClaimTemplates:
- metadata:
name: date-log
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
storageClassName: standard-2再作成します。
kubectl replace --force -f statefulSet-write-podName.yaml再度スケールしてログが残るか確認
まずはログを確認
kubectl exec -it sample-statefulset-2 -- cat /usr/share/date/log.txt
次にスケールダウン
kubectl scale statefulset sample-statefulset --replicas=2
もう一度スケールアップ
kubectl scale statefulset sample-statefulset --replicas=3ログを確認
kubectl exec -it sample-statefulset-2 -- cat /usr/share/date/log.txt
今度はログが消えずに残っていることが確認できます。
まとめ
今回のポイントは以下の4つです。
- StatefulSetはPodごとに専用PVCを作成する
- volumeClaimTemplatesを使うと自動でボリュームが作成される
- reclaimPolicyがDeleteだとスケール時にログが消える
- Retainに変更するとログを保持できる
- タグ:
- Kubenetes