From cb65c20db9dccc2fcf4c75296d00af355f50a20e Mon Sep 17 00:00:00 2001 From: Nicholas Cioli Date: Fri, 12 Jul 2024 01:35:23 -0400 Subject: [PATCH] add postgres config for ephemeral volumes --- .../postgres-operator/crds/postgresqls.yaml | 3 ++ manifests/postgresql.crd.yaml | 3 ++ pkg/apis/acid.zalan.do/v1/crds.go | 3 ++ pkg/apis/acid.zalan.do/v1/postgresql_type.go | 3 ++ .../acid.zalan.do/v1/zz_generated.deepcopy.go | 5 +++ pkg/cluster/k8sres.go | 35 +++++++++++++------ 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml index 0498625f2..d950946e0 100644 --- a/charts/postgres-operator/crds/postgresqls.yaml +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -577,6 +577,9 @@ spec: - PreferNoSchedule tolerationSeconds: type: integer + useEphemeralVolume: + type: boolean + default: false useLoadBalancer: type: boolean description: deprecated diff --git a/manifests/postgresql.crd.yaml b/manifests/postgresql.crd.yaml index 4bd757f38..f487ed312 100644 --- a/manifests/postgresql.crd.yaml +++ b/manifests/postgresql.crd.yaml @@ -575,6 +575,9 @@ spec: - PreferNoSchedule tolerationSeconds: type: integer + useEphemeralVolume: + type: boolean + default: false useLoadBalancer: type: boolean description: deprecated diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go index 65e104070..286a9c46b 100644 --- a/pkg/apis/acid.zalan.do/v1/crds.go +++ b/pkg/apis/acid.zalan.do/v1/crds.go @@ -898,6 +898,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{ }, }, }, + "useEphemeralVolume": { + Type: "boolean", + }, "useLoadBalancer": { Type: "boolean", Description: "deprecated", diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 612cf7041..fe69788c8 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -93,6 +93,9 @@ type PostgresSpec struct { // deprecated json tags InitContainersOld []v1.Container `json:"init_containers,omitempty"` PodPriorityClassNameOld string `json:"pod_priority_class_name,omitempty"` + + // Ephemeral settings + UseEphemeralVolume *bool `json:"useEphemeralVolume,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index 30dab7a0d..a88875cf7 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -881,6 +881,11 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.UseEphemeralVolume != nil { + in, out := &in.UseEphemeralVolume, &out.UseEphemeralVolume + *out = new(bool) + **out = **in + } return } diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 1a6f3b885..60bf18812 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -692,7 +692,6 @@ func generateContainer( privilegedMode bool, privilegeEscalationMode *bool, additionalPodCapabilities *v1.Capabilities, - useEphemeralVolumes *bool, ) *v1.Container { return &v1.Container{ Name: name, @@ -1290,10 +1289,12 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef initContainers []v1.Container sidecarContainers []v1.Container podTemplate *v1.PodTemplateSpec - volumeClaimTemplate *v1.PersistentVolumeClaim + volumeClaimTemplate *[]v1.PersistentVolumeClaim additionalVolumes = spec.AdditionalVolumes ) + useEphemeralVolume := c.OpConfig.AllowEphemeralVolumes != nil && spec.UseEphemeralVolume != nil && (*c.OpConfig.AllowEphemeralVolumes && *spec.UseEphemeralVolume) + defaultResources := makeDefaultResources(&c.OpConfig) resourceRequirements, err := c.generateResourceRequirements( spec.Resources, defaultResources, constants.PostgresContainerName) @@ -1395,7 +1396,6 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef c.OpConfig.Resources.SpiloPrivileged, c.OpConfig.Resources.SpiloAllowPrivilegeEscalation, generateCapabilities(c.OpConfig.AdditionalPodCapabilities), - nil, ) // Patroni responds 200 to probe only if it either owns the leader lock or postgres is running and DCS is accessible @@ -1495,9 +1495,23 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef return nil, fmt.Errorf("could not generate pod template: %v", err) } - if volumeClaimTemplate, err = c.generatePersistentVolumeClaimTemplate(spec.Volume.Size, - spec.Volume.StorageClass, spec.Volume.Selector); err != nil { - return nil, fmt.Errorf("could not generate volume claim template: %v", err) + // Generate the volumes, optionally using an ephemeral volume + if useEphemeralVolume { + empty := make([]v1.PersistentVolumeClaim, 0) + volumeClaimTemplate = &empty + + // Also add the ephemeral volume to the spec + podTemplate.Spec.Volumes = append(podTemplate.Spec.Volumes, v1.Volume{ + Name: constants.DataVolumeName, + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }) + } else { + if volumeClaimTemplate, err = c.generatePersistentVolumeClaimTemplate(spec.Volume.Size, + spec.Volume.StorageClass, spec.Volume.Selector); err != nil { + return nil, fmt.Errorf("could not generate volume claim template: %v", err) + } } // global minInstances and maxInstances settings can overwrite manifest @@ -1542,7 +1556,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef Selector: c.labelsSelector(), ServiceName: c.serviceName(Master), Template: *podTemplate, - VolumeClaimTemplates: []v1.PersistentVolumeClaim{*volumeClaimTemplate}, + VolumeClaimTemplates: *volumeClaimTemplate, UpdateStrategy: updateStrategy, PodManagementPolicy: podManagementPolicy, PersistentVolumeClaimRetentionPolicy: &persistentVolumeClaimRetentionPolicy, @@ -1850,7 +1864,7 @@ func (c *Cluster) addAdditionalVolumes(podSpec *v1.PodSpec, } func (c *Cluster) generatePersistentVolumeClaimTemplate(volumeSize, volumeStorageClass string, - volumeSelector *metav1.LabelSelector) (*v1.PersistentVolumeClaim, error) { + volumeSelector *metav1.LabelSelector) (*[]v1.PersistentVolumeClaim, error) { var storageClassName *string if volumeStorageClass != "" { @@ -1863,7 +1877,7 @@ func (c *Cluster) generatePersistentVolumeClaimTemplate(volumeSize, volumeStorag } volumeMode := v1.PersistentVolumeFilesystem - volumeClaim := &v1.PersistentVolumeClaim{ + volumeClaim := v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: constants.DataVolumeName, Annotations: c.annotationsSet(nil), @@ -1882,7 +1896,7 @@ func (c *Cluster) generatePersistentVolumeClaimTemplate(volumeSize, volumeStorag }, } - return volumeClaim, nil + return &[]v1.PersistentVolumeClaim{volumeClaim}, nil } func (c *Cluster) generateUserSecrets() map[string]*v1.Secret { @@ -2290,7 +2304,6 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) { c.OpConfig.SpiloPrivileged, // use same value as for normal DB pods c.OpConfig.SpiloAllowPrivilegeEscalation, nil, - nil, ) logicalBackupJobLabel := map[string]string{