まず前提としてPVはリサイズが可能です。
refs: Resizing Persistent Volumes using Kubernetes - Kubernetes
1.11以降のクラスタで利用可能な機能で、事前にstorageclassの定義で allowVolumeExpansion: true
を付ける必要があります。
自分が検証した際はサイズの増加は可能で減少は行なえませんでした。 とはいえ運用上最小限の設定にしておいたなら増やすことはあれど減らすケースはほぼないと思われます。 よくある例ではMySQLのStatefulSetを定義しサービスイン後にpvcのサイズを増加したいケースでしょうか。
しかしStatefulSet経由のPVCでPVを作成してしまうとディスクサイズの変更ができません。
例えば以下のようなyamlでsts内でpvcを作ったとします。
volumeClaimTemplates: - metadata: name: my-pvc spec: accessModes: - ReadWriteOnce storageClassName: my-storageclass resources: requests: storage: 1Gi
ストレージを2GBにしたい場合は以下のように変更します。
storageClassName: my-storageclass resources: requests: - storage: 1Gi + storage: 2Gi
これをapplyしようとすると以下のようなメッセージが出て変更できません。
The StatefulSet "example-sts" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden
StatefulSetに設定したstorageのサイズを変更する例を調べると StatefulSet: support resize pvc storage in K8s v1.11 · Issue #68737 · kubernetes/kubernetes · GitHub が出てきます。
polarn commented on 5 Mar 2019 @alwinmarkcf You can delete the statefulset without the pods being deleted, by using kubectl delete sts --cascade=false
- you can then apply a new statefulset and the pods will keep living.
ではstsは削除しつつpodを削除しないようにすることで新しいstsをapplyする際にpvcのサイズを変更する方法が提案されています。
ただこれはhelmなどで管理していた場合に色々と煩雑なのであまり取りたい手段ではありませんでした。
issueのコメントで
mlmhl commented on 18 Sep 2018 Maybe a better way is to directly update the request size of according PVC object.
とコメントされていますがこれを実現する形で試行し、自分のユースケースでは問題がありませんでした。 以下のようにstsとpvcでyamlを分けてapplyします。
apiVersion: apps/v1 kind: StatefulSet metadata: name: pg-sts spec: replicas: 1 updateStrategy: type: RollingUpdate selector: matchLabels: app: pg serviceName: pg-svc template: metadata: labels: app: pg spec: volumes: - name: my-pv persistentVolumeClaim: claimName: my-pvc containers: - name: pg image: "postgres:11.5-alpine" ports: - containerPort: 5432 volumeMounts: - name: my-pv mountPath: /var/lib/postgresql/data resources: {} --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce storageClassName: my-storageclass resources: requests: storage: 1Gi
その場合、変更するのはpvc側だけでsts側は変更せずにstorageのサイズを変更できます。 この方式だとStatefulSetを使いつつPVのサイズが変更できます。
以下のURLでissueにコメントしてみたところ、StatefulSetはreplicasのpod数分pvcを作成してくれるようです。
自分は費用的にケチってreplicas: 1で運用していたので気づきませんでしたが、replicas: 3で0をmaster、その他をread replicaで使うなどといったより本番的なユースケースでは上記手法は有効ではなさそうです。
refs: https://github.com/kubernetes/kubernetes/issues/68737#issuecomment-589934270