I am using the Bitnami Postgresql-HA Helm charts to run a Postgresql cluster in Kubernetes. I also have a PersistentVolumeClaim (PVC) full of data that isn’t going into the database. I’d like to mount this PVC in my Postgres pods so that the database can read and reference that data.
I tried editing the postgresql.extraVolumes
and postgresql.extraVolumeMounts
parameters in the Helm chart’s values.yaml, but it came back with:
StatefulSet.apps "app" is invalid: spec: Forbidden: updates to stateful set spec for fields other than 'replicas', 'template', 'updateStrategy', and 'minReadySeconds' are forbidden
I also tried editing the pods directly with kubectl edit
and adding the volumes under spec.volumes
and spec.containers.volumeMounts
, but that came back with
spec: Forbidden: pod updates may not change fields other than 'spec.containers[*].image', 'spec.initContainers[*].image', 'spec.activeDeadlineSeconds', 'spec.tolerations' (only additions to existing tolerations), 'spec.terminationGracePeriodSeconds' (allow it to be set to 1 if it was previously negative)
The above makes me think that the answer to my question is a straight-up "no" but I haven’t come up with a definitive "no" answer from my research yet, so I’m asking the question anyways.
I know I could blow away everything I have running and re-install with Helm, but I’d rather not do that because there’s schema and users in the database that I don’t want to lose.
Thank you for the help!
2
Answers
You can’t change most of the fields of an existing running Pod. For the majority of settings, if you need to change them, you need to delete and recreate the Pod. Higher-level controllers like Deployments and StatefulSets exist in part to manage this.
The Kubernetes API documentation includes the definition of a Pod and the fields in it. You’re trying to change
containers: [{ volumeMounts: }]
, for example, but the top-level definition ofcontainers:
notes (emphasis mine)That is: once a Pod exists, you can’t add more volume mounts to it, because that would require changing the container definitions, and those can’t be changed.
StatefulSets have slightly different rules, since there is a standard mechanism for deleting and recreating Pods managed by a StatefulSet if the Pod template changes. That API documentation doesn’t call out the specific update constraints that your error message shows, but the error message is clear that you can’t add new top-level PVC templates to an existing StatefulSet.
For your high-level use case, I’d probably be content to have the data live somewhere else. In most cases the database server won’t access local files (seeding the database via SQL
COPY FROM
is the most notable exception). If you’re storing file paths in some storage in database columns, the application needs access to the database and to the storage, but those two parts don’t need to directly talk to each other.TL/DR
Under default circumstances, you can remove and recreate a
StatefulSet
without losing any data. Which would allow you to apply a new configuration with your extra volume.Detailed answer
Your first error message, is due to many fields being immutable in a
StatefulSet
.However you can usually delete a
StatefulSet
and recreate it with your additional volume, without losing data in the existing volumes. This is because it is the default behavior of aStatefulSet
to release ownership of the thePersistentVolumeClaim
on deletion and then re-attach when a newStatefulSet
with the same name is created.No volumes are deleted and no data is lost when a
StatefulSet
is removed, under default circumstances.Important:
One thing you should double-check prior to deleting your
StatefulSet
, is if its manifest has.spec.persistentVolumeClaimRetentionPolicy
block and if it does, whether or notwhenDeleted
has a value ofDelete
. If it does and you are running on a cluster with theStatefulSetAutoDeletePVC
feature gate enabled (has been enabled by default since Kubernetes1.27
), then your volumes will be deleted.The Bitnami
postgresql-ha
chart defaults everything toRetain
, so unless its been overridden in values, you should be fine with deleting theStatefulSet
and recreating.See
StatefulSet
docs here.