Skip to content

Add support for ephemeral PostgresQL instances #2691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions charts/postgres-operator/crds/operatorconfigurations.yaml
Original file line number Diff line number Diff line change
@@ -692,6 +692,9 @@ spec:
enable_patroni_failsafe_mode:
type: boolean
default: false
allow_ephemeral_volumes:
type: boolean
default: false
status:
type: object
additionalProperties:
3 changes: 3 additions & 0 deletions charts/postgres-operator/crds/postgresqls.yaml
Original file line number Diff line number Diff line change
@@ -577,6 +577,9 @@ spec:
- PreferNoSchedule
tolerationSeconds:
type: integer
useEphemeralVolume:
type: boolean
default: false
useLoadBalancer:
type: boolean
description: deprecated
Original file line number Diff line number Diff line change
@@ -42,4 +42,5 @@ configuration:
{{ tpl (toYaml .Values.configConnectionPooler) . | indent 4 }}
patroni:
{{ tpl (toYaml .Values.configPatroni) . | indent 4 }}
allow_ephemeral_volumes: {{ .Values.allowEphemeralVolumes }}
{{- end }}
3 changes: 3 additions & 0 deletions charts/postgres-operator/values.yaml
Original file line number Diff line number Diff line change
@@ -454,6 +454,9 @@ configPatroni:
# Zalando's internal CDC stream feature
enableStreams: false

# Allow ephemeral instances
allowEphemeralVolumes: false

rbac:
# Specifies whether RBAC resources should be created
create: true
1 change: 1 addition & 0 deletions manifests/configmap.yaml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ data:
# additional_pod_capabilities: "SYS_NICE"
# additional_secret_mount: "some-secret-name"
# additional_secret_mount_path: "/some/dir"
# allow_ephemeral_volumes: true
api_port: "8080"
aws_region: eu-central-1
cluster_domain: cluster.local
3 changes: 3 additions & 0 deletions manifests/operatorconfiguration.crd.yaml
Original file line number Diff line number Diff line change
@@ -690,6 +690,9 @@ spec:
enable_patroni_failsafe_mode:
type: boolean
default: false
allow_ephemeral_volumes:
type: boolean
default: false
status:
type: object
additionalProperties:
1 change: 1 addition & 0 deletions manifests/postgresql-operator-default-configuration.yaml
Original file line number Diff line number Diff line change
@@ -220,3 +220,4 @@ configuration:
# connection_pooler_user: "pooler"
patroni:
enable_patroni_failsafe_mode: false
allow_ephemeral_volumes: false
3 changes: 3 additions & 0 deletions manifests/postgresql.crd.yaml
Original file line number Diff line number Diff line change
@@ -575,6 +575,9 @@ spec:
- PreferNoSchedule
tolerationSeconds:
type: integer
useEphemeralVolume:
type: boolean
default: false
useLoadBalancer:
type: boolean
description: deprecated
6 changes: 6 additions & 0 deletions pkg/apis/acid.zalan.do/v1/crds.go
Original file line number Diff line number Diff line change
@@ -898,6 +898,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
},
},
},
"useEphemeralVolume": {
Type: "boolean",
},
"useLoadBalancer": {
Type: "boolean",
Description: "deprecated",
@@ -1966,6 +1969,9 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
},
},
},
"allow_ephemeral_volums": {
Type: "boolean",
},
},
},
"status": {
2 changes: 2 additions & 0 deletions pkg/apis/acid.zalan.do/v1/operator_configuration_type.go
Original file line number Diff line number Diff line change
@@ -287,6 +287,8 @@ type OperatorConfigurationData struct {
MinInstances int32 `json:"min_instances,omitempty"`
MaxInstances int32 `json:"max_instances,omitempty"`
IgnoreInstanceLimitsAnnotationKey string `json:"ignore_instance_limits_annotation_key,omitempty"`

AllowEphemeralVolumes *bool `json:"allow_ephemeral_volumes,omitempty"`
}

// Duration shortens this frequently used name
3 changes: 3 additions & 0 deletions pkg/apis/acid.zalan.do/v1/postgresql_type.go
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 24 additions & 8 deletions pkg/cluster/k8sres.go
Original file line number Diff line number Diff line change
@@ -1289,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)
@@ -1493,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
@@ -1540,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,
@@ -1848,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 != "" {
@@ -1861,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),
@@ -1880,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 {
3 changes: 3 additions & 0 deletions pkg/controller/operator_config.go
Original file line number Diff line number Diff line change
@@ -277,5 +277,8 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
fromCRD.ConnectionPooler.MaxDBConnections,
k8sutil.Int32ToPointer(constants.ConnectionPoolerMaxDBConnections))

// Ephemeral config
result.AllowEphemeralVolumes = util.CoalesceBool(fromCRD.AllowEphemeralVolumes, util.False())

return result
}
1 change: 1 addition & 0 deletions pkg/util/config/config.go
Original file line number Diff line number Diff line change
@@ -253,6 +253,7 @@ type Config struct {
EnableSecretsDeletion *bool `name:"enable_secrets_deletion" default:"true"`
EnablePersistentVolumeClaimDeletion *bool `name:"enable_persistent_volume_claim_deletion" default:"true"`
PersistentVolumeClaimRetentionPolicy map[string]string `name:"persistent_volume_claim_retention_policy" default:"when_deleted:retain,when_scaled:retain"`
AllowEphemeralVolumes *bool `json:"allow_ephemeral_volumes,omitempty"`
}

// MustMarshal marshals the config or panics