Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions charts/postgres-operator/crds/operatorconfigurations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ spec:
format: int32
minimum: 1
type: integer
connection_pooler_priority_class_name:
type: string
connection_pooler_schema:
default: pooler
type: string
Expand Down
2 changes: 2 additions & 0 deletions charts/postgres-operator/crds/postgresqls.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ spec:
format: int32
minimum: 1
type: integer
priorityClassName:
type: string
resources:
description: Resources describes requests and limits for the cluster
resouces.
Expand Down
2 changes: 2 additions & 0 deletions charts/postgres-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ configConnectionPooler:
connection_pooler_mode: "transaction"
# number of pooler instances
connection_pooler_number_of_instances: 2
# priorityClassName to assign to pooler pods
# connection_pooler_priority_class_name: ""
# default resources
connection_pooler_default_cpu_request: 500m
connection_pooler_default_memory_request: 100Mi
Expand Down
8 changes: 8 additions & 0 deletions docs/reference/cluster_manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,14 @@ for both master and replica pooler services (if `enableReplicaConnectionPooler`
* **mode**
In which mode to run connection pooler, transaction or session.

* **priorityClassName**
a name of the [priority
class](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass)
that should be assigned to the connection pooler pods. When not specified, the
value is taken from the `connection_pooler_priority_class_name` operator
parameter, if not set then the default priority class is taken. The priority
class itself must be defined in advance. Optional.

* **resources**
Resource configuration for connection pooler deployment.

Expand Down
6 changes: 6 additions & 0 deletions docs/reference/operator_parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,12 @@ operator being able to provide some reasonable defaults.
* **connection_pooler_mode**
Default pooler mode, `session` or `transaction`. Default is `transaction`.

* **connection_pooler_priority_class_name**
The name of the priority class to assign to connection pooler pods by default.
A cluster can override this with `connectionPooler.priorityClassName`. When
unset, the pooler pods use no priority class. The empty string signifies no
assignment.

* **connection_pooler_default_cpu_request**
**connection_pooler_default_memory_reques**
**connection_pooler_default_cpu_limit**
Expand Down
1 change: 1 addition & 0 deletions manifests/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ data:
connection_pooler_max_db_connections: "60"
connection_pooler_mode: "transaction"
connection_pooler_number_of_instances: "2"
# connection_pooler_priority_class_name: ""
connection_pooler_schema: "pooler"
connection_pooler_user: "pooler"
crd_categories: "all"
Expand Down
2 changes: 2 additions & 0 deletions manifests/operatorconfiguration.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ spec:
format: int32
minimum: 1
type: integer
connection_pooler_priority_class_name:
type: string
connection_pooler_schema:
default: pooler
type: string
Expand Down
1 change: 1 addition & 0 deletions manifests/postgresql-operator-default-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ configuration:
# connection_pooler_max_db_connections: 60
connection_pooler_mode: "transaction"
connection_pooler_number_of_instances: 2
# connection_pooler_priority_class_name: ""
# connection_pooler_schema: "pooler"
# connection_pooler_user: "pooler"
patroni:
Expand Down
2 changes: 2 additions & 0 deletions manifests/postgresql.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ spec:
format: int32
minimum: 1
type: integer
priorityClassName:
type: string
resources:
description: Resources describes requests and limits for the cluster
resouces.
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/acid.zalan.do/v1/operator_configuration_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ type ConnectionPoolerConfiguration struct {
DefaultCPULimit string `json:"connection_pooler_default_cpu_limit,omitempty"`
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
DefaultMemoryLimit string `json:"connection_pooler_default_memory_limit,omitempty"`
PriorityClassName string `json:"connection_pooler_priority_class_name,omitempty"`
}

// OperatorLogicalBackupConfiguration defines configuration for logical backup
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/acid.zalan.do/v1/operatorconfiguration.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ spec:
format: int32
minimum: 1
type: integer
connection_pooler_priority_class_name:
type: string
connection_pooler_schema:
default: pooler
type: string
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/acid.zalan.do/v1/postgresql.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ spec:
format: int32
minimum: 1
type: integer
priorityClassName:
type: string
resources:
description: Resources describes requests and limits for the cluster
resouces.
Expand Down
7 changes: 4 additions & 3 deletions pkg/apis/acid.zalan.do/v1/postgresql_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,10 @@ type ConnectionPooler struct {
Schema string `json:"schema,omitempty"`
User string `json:"user,omitempty"`
// +kubebuilder:validation:Enum=session;transaction
Mode string `json:"mode,omitempty"`
DockerImage string `json:"dockerImage,omitempty"`
MaxDBConnections *int32 `json:"maxDBConnections,omitempty"`
Mode string `json:"mode,omitempty"`
DockerImage string `json:"dockerImage,omitempty"`
MaxDBConnections *int32 `json:"maxDBConnections,omitempty"`
PriorityClassName string `json:"priorityClassName,omitempty"`

*Resources `json:"resources,omitempty"`
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/cluster/connection_pooler.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ func (c *Cluster) generateConnectionPoolerPodTemplate(role PostgresRole) (
Volumes: poolerVolumes,
SecurityContext: &securityContext,
ServiceAccountName: c.OpConfig.PodServiceAccountName,
PriorityClassName: util.Coalesce(
connectionPoolerSpec.PriorityClassName,
c.OpConfig.ConnectionPooler.PriorityClassName),
},
}

Expand Down Expand Up @@ -893,6 +896,16 @@ func (c *Cluster) needSyncConnectionPoolerDefaults(Config *Config, spec *acidv1.
reasons = append(reasons, msg)
}

if spec.PriorityClassName == "" {
expectedPriorityClassName := config.PriorityClassName
if podTemplate.Spec.PriorityClassName != expectedPriorityClassName {
sync = true
msg := fmt.Sprintf("priorityClassName is different (having %s, required %s)",
podTemplate.Spec.PriorityClassName, expectedPriorityClassName)
reasons = append(reasons, msg)
}
}

expectedResources, err := c.generateResourceRequirements(spec.Resources,
makeDefaultConnectionPoolerResources(&Config.OpConfig),
connectionPoolerContainer)
Expand Down
66 changes: 66 additions & 0 deletions pkg/cluster/connection_pooler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,72 @@ func TestConnectionPoolerDeploymentSpec(t *testing.T) {
}
}

func TestConnectionPoolerPriorityClassName(t *testing.T) {
newCluster := func(specPooler, opPooler, specPod, opPod string) *Cluster {
c := New(
Config{
OpConfig: config.Config{
Resources: config.Resources{
PodPriorityClassName: opPod,
},
ConnectionPooler: config.ConnectionPooler{
PriorityClassName: opPooler,
},
},
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)
c.Spec = acidv1.PostgresSpec{
PodPriorityClassName: specPod,
ConnectionPooler: &acidv1.ConnectionPooler{PriorityClassName: specPooler},
}
return c
}

tests := []struct {
subTest string
cluster *Cluster
expected string
}{
{
subTest: "pooler spec wins over everything",
cluster: newCluster("pooler-spec", "pooler-op", "pod-spec", "pod-op"),
expected: "pooler-spec",
},
{
subTest: "pooler operator default when spec empty",
cluster: newCluster("", "pooler-op", "pod-spec", "pod-op"),
expected: "pooler-op",
},
{
subTest: "does not inherit cluster pod priority class",
cluster: newCluster("", "", "pod-spec", "pod-op"),
expected: "",
},
{
subTest: "does not inherit operator pod priority class",
cluster: newCluster("", "", "", "pod-op"),
expected: "",
},
{
subTest: "empty when nothing set",
cluster: newCluster("", "", "", ""),
expected: "",
},
}

for _, role := range [2]PostgresRole{Master, Replica} {
for _, tt := range tests {
podSpec, err := tt.cluster.generateConnectionPoolerPodTemplate(role)
if err != nil {
t.Fatalf("%s [%s]: unexpected error %v", role, tt.subTest, err)
}
if podSpec.Spec.PriorityClassName != tt.expected {
t.Errorf("%s [%s]: got priorityClassName %q, expected %q",
role, tt.subTest, podSpec.Spec.PriorityClassName, tt.expected)
}
}
}
}

func testServiceAccount(cluster *Cluster, podSpec *v1.PodTemplateSpec, role PostgresRole) error {
poolerServiceAccount := podSpec.Spec.ServiceAccountName

Expand Down
1 change: 1 addition & 0 deletions pkg/controller/operator_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.ConnectionPooler.ConnectionPoolerDefaultMemoryRequest = fromCRD.ConnectionPooler.DefaultMemoryRequest
result.ConnectionPooler.ConnectionPoolerDefaultCPULimit = fromCRD.ConnectionPooler.DefaultCPULimit
result.ConnectionPooler.ConnectionPoolerDefaultMemoryLimit = fromCRD.ConnectionPooler.DefaultMemoryLimit
result.ConnectionPooler.PriorityClassName = fromCRD.ConnectionPooler.PriorityClassName

result.ConnectionPooler.MaxDBConnections = util.CoalesceInt32(
fromCRD.ConnectionPooler.MaxDBConnections,
Expand Down
1 change: 1 addition & 0 deletions pkg/util/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ type ConnectionPooler struct {
Image string `name:"connection_pooler_image" default:"ghcr.io/zalando/postgres-operator/pgbouncer:latest"`
Mode string `name:"connection_pooler_mode" default:"transaction"`
MaxDBConnections *int32 `name:"connection_pooler_max_db_connections" default:"60"`
PriorityClassName string `name:"connection_pooler_priority_class_name"`
ConnectionPoolerDefaultCPURequest string `name:"connection_pooler_default_cpu_request"`
ConnectionPoolerDefaultMemoryRequest string `name:"connection_pooler_default_memory_request"`
ConnectionPoolerDefaultCPULimit string `name:"connection_pooler_default_cpu_limit"`
Expand Down