Merge branch 'master' into delete-volume-on-scale-down
This commit is contained in:
commit
a562a6ed59
|
|
@ -68,6 +68,8 @@ spec:
|
|||
type: boolean
|
||||
etcd_host:
|
||||
type: string
|
||||
kubernetes_use_configmaps:
|
||||
type: boolean
|
||||
max_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ spec:
|
|||
type: integer
|
||||
retry_timeout:
|
||||
type: integer
|
||||
synchronous_mode:
|
||||
type: boolean
|
||||
synchronous_mode_strict:
|
||||
type: boolean
|
||||
maximum_lag_on_failover:
|
||||
type: integer
|
||||
podAnnotations:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ configGeneral:
|
|||
enable_unused_pvc_deletion: false
|
||||
# etcd connection string for Patroni. Empty uses K8s-native DCS.
|
||||
etcd_host: ""
|
||||
# Select if setup uses endpoints (default), or configmaps to manage leader (DCS=k8s)
|
||||
# kubernetes_use_configmaps: false
|
||||
# Spilo docker image
|
||||
docker_image: registry.opensource.zalan.do/acid/spilo-12:1.6-p2
|
||||
# max number of instances in Postgres cluster. -1 = no limit
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ configGeneral:
|
|||
enable_unused_pvc_deletion: "false"
|
||||
# etcd connection string for Patroni. Empty uses K8s-native DCS.
|
||||
etcd_host: ""
|
||||
# Select if setup uses endpoints (default), or configmaps to manage leader (DCS=k8s)
|
||||
# kubernetes_use_configmaps: "false"
|
||||
# Spilo docker image
|
||||
docker_image: registry.opensource.zalan.do/acid/spilo-12:1.6-p2
|
||||
# max number of instances in Postgres cluster. -1 = no limit
|
||||
|
|
|
|||
|
|
@ -217,6 +217,12 @@ explanation of `ttl` and `loop_wait` parameters.
|
|||
automatically created by Patroni for cluster members and permanent replication
|
||||
slots. Optional.
|
||||
|
||||
* **synchronous_mode**
|
||||
Patroni `synchronous_mode` parameter value. The default is set to `false`. Optional.
|
||||
|
||||
* **synchronous_mode_strict**
|
||||
Patroni `synchronous_mode_strict` parameter value. Can be used in addition to `synchronous_mode`. The default is set to `false`. Optional.
|
||||
|
||||
## Postgres container resources
|
||||
|
||||
Those parameters define [CPU and memory requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/)
|
||||
|
|
@ -376,10 +382,11 @@ present.
|
|||
How many instances of connection pooler to create.
|
||||
|
||||
* **schema**
|
||||
Schema to create for credentials lookup function.
|
||||
Database schema to create for credentials lookup function.
|
||||
|
||||
* **user**
|
||||
User to create for connection pooler to be able to connect to a database.
|
||||
You can also choose a role from the `users` section or a system user role.
|
||||
|
||||
* **dockerImage**
|
||||
Which docker image to use for connection pooler deployment.
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ Those are top-level keys, containing both leaf keys and groups.
|
|||
Patroni native Kubernetes support is used. The default is empty (use
|
||||
Kubernetes-native DCS).
|
||||
|
||||
* **kubernetes_use_configmaps**
|
||||
Select if setup uses endpoints (default), or configmaps to manage leader when
|
||||
DCS is kubernetes (not etcd or similar). In OpenShift it is not possible to
|
||||
use endpoints option, and configmaps is required. By default,
|
||||
`kubernetes_use_configmaps: false`, meaning endpoints will be used.
|
||||
|
||||
* **docker_image**
|
||||
Spilo Docker image for Postgres instances. For production, don't rely on the
|
||||
default image, as it might be not the most up-to-date one. Instead, build
|
||||
|
|
@ -613,11 +619,14 @@ operator being able to provide some reasonable defaults.
|
|||
the required minimum.
|
||||
|
||||
* **connection_pooler_schema**
|
||||
Schema to create for credentials lookup function. Default is `pooler`.
|
||||
Database schema to create for credentials lookup function to be used by the
|
||||
connection pooler. Is is created in every database of the Postgres cluster.
|
||||
You can also choose an existing schema. Default schema is `pooler`.
|
||||
|
||||
* **connection_pooler_user**
|
||||
User to create for connection pooler to be able to connect to a database.
|
||||
Default is `pooler`.
|
||||
You can also choose an existing role, but make sure it has the `LOGIN`
|
||||
privilege. Default role is `pooler`.
|
||||
|
||||
* **connection_pooler_image**
|
||||
Docker image to use for connection pooler deployment.
|
||||
|
|
|
|||
11
docs/user.md
11
docs/user.md
|
|
@ -527,7 +527,7 @@ spec:
|
|||
This will tell the operator to create a connection pooler with default
|
||||
configuration, through which one can access the master via a separate service
|
||||
`{cluster-name}-pooler`. In most of the cases the
|
||||
[default configuration](reference/operator_parameters.md#connection-pool-configuration)
|
||||
[default configuration](reference/operator_parameters.md#connection-pooler-configuration)
|
||||
should be good enough. To configure a new connection pooler individually for
|
||||
each Postgres cluster, specify:
|
||||
|
||||
|
|
@ -540,7 +540,8 @@ spec:
|
|||
# in which mode to run, session or transaction
|
||||
mode: "transaction"
|
||||
|
||||
# schema, which operator will create to install credentials lookup function
|
||||
# schema, which operator will create in each database
|
||||
# to install credentials lookup function for connection pooler
|
||||
schema: "pooler"
|
||||
|
||||
# user, which operator will create for connection pooler
|
||||
|
|
@ -560,11 +561,11 @@ The `enableConnectionPooler` flag is not required when the `connectionPooler`
|
|||
section is present in the manifest. But, it can be used to disable/remove the
|
||||
pooler while keeping its configuration.
|
||||
|
||||
By default, `pgbouncer` is used as connection pooler. To find out about pooler
|
||||
modes read the `pgbouncer` [docs](https://www.pgbouncer.org/config.html#pooler_mode)
|
||||
By default, [`PgBouncer`](https://www.pgbouncer.org/) is used as connection pooler.
|
||||
To find out about pool modes read the `PgBouncer` [docs](https://www.pgbouncer.org/config.html#pooler_mode)
|
||||
(but it should be the general approach between different implementation).
|
||||
|
||||
Note, that using `pgbouncer` a meaningful resource CPU limit should be 1 core
|
||||
Note, that using `PgBouncer` a meaningful resource CPU limit should be 1 core
|
||||
or less (there is a way to utilize more than one, but in K8s it's easier just to
|
||||
spin up more instances).
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ spec:
|
|||
ttl: 30
|
||||
loop_wait: &loop_wait 10
|
||||
retry_timeout: 10
|
||||
synchronous_mode: false
|
||||
synchronous_mode_strict: false
|
||||
maximum_lag_on_failover: 33554432
|
||||
|
||||
# restore a Postgres DB with point-in-time-recovery
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ data:
|
|||
# connection_pooler_default_cpu_request: "500m"
|
||||
# connection_pooler_default_memory_limit: 100Mi
|
||||
# connection_pooler_default_memory_request: 100Mi
|
||||
connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-5"
|
||||
connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-6"
|
||||
# connection_pooler_max_db_connections: 60
|
||||
# connection_pooler_mode: "transaction"
|
||||
# connection_pooler_number_of_instances: 2
|
||||
|
|
@ -43,6 +43,7 @@ data:
|
|||
# enable_team_superuser: "false"
|
||||
enable_teams_api: "false"
|
||||
# etcd_host: ""
|
||||
# kubernetes_use_configmaps: "false"
|
||||
# infrastructure_roles_secret_name: postgresql-infrastructure-roles
|
||||
# inherited_labels: application,environment
|
||||
# kube_iam_role: ""
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ spec:
|
|||
type: boolean
|
||||
etcd_host:
|
||||
type: string
|
||||
kubernetes_use_configmaps:
|
||||
type: boolean
|
||||
max_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ metadata:
|
|||
configuration:
|
||||
# enable_crd_validation: true
|
||||
etcd_host: ""
|
||||
# kubernetes_use_configmaps: false
|
||||
docker_image: registry.opensource.zalan.do/acid/spilo-12:1.6-p2
|
||||
# enable_shm_volume: true
|
||||
# enable_unused_pvc_deletion: false
|
||||
|
|
@ -127,7 +128,7 @@ configuration:
|
|||
connection_pooler_default_cpu_request: "500m"
|
||||
connection_pooler_default_memory_limit: 100Mi
|
||||
connection_pooler_default_memory_request: 100Mi
|
||||
connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-5"
|
||||
connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-6"
|
||||
# connection_pooler_max_db_connections: 60
|
||||
connection_pooler_mode: "transaction"
|
||||
connection_pooler_number_of_instances: 2
|
||||
|
|
|
|||
|
|
@ -184,6 +184,10 @@ spec:
|
|||
type: integer
|
||||
maximum_lag_on_failover:
|
||||
type: integer
|
||||
synchronous_mode:
|
||||
type: boolean
|
||||
synchronous_mode_strict:
|
||||
type: boolean
|
||||
podAnnotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
|
|
|
|||
|
|
@ -358,6 +358,12 @@ var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{
|
|||
"maximum_lag_on_failover": {
|
||||
Type: "integer",
|
||||
},
|
||||
"synchronous_mode": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"synchronous_mode_strict": {
|
||||
Type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
"podAnnotations": {
|
||||
|
|
@ -727,6 +733,9 @@ var OperatorConfigCRDResourceValidation = apiextv1beta1.CustomResourceValidation
|
|||
"etcd_host": {
|
||||
Type: "string",
|
||||
},
|
||||
"kubernetes_use_configmaps": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"max_instances": {
|
||||
Type: "integer",
|
||||
Description: "-1 = disabled",
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ type OperatorLogicalBackupConfiguration struct {
|
|||
type OperatorConfigurationData struct {
|
||||
EnableCRDValidation *bool `json:"enable_crd_validation,omitempty"`
|
||||
EtcdHost string `json:"etcd_host,omitempty"`
|
||||
KubernetesUseConfigMaps bool `json:"kubernetes_use_configmaps,omitempty"`
|
||||
DockerImage string `json:"docker_image,omitempty"`
|
||||
Workers uint32 `json:"workers,omitempty"`
|
||||
MinInstances int32 `json:"min_instances,omitempty"`
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ type Patroni struct {
|
|||
RetryTimeout uint32 `json:"retry_timeout"`
|
||||
MaximumLagOnFailover float32 `json:"maximum_lag_on_failover"` // float32 because https://github.com/kubernetes/kubernetes/issues/30213
|
||||
Slots map[string]map[string]string `json:"slots"`
|
||||
SynchronousMode bool `json:"synchronous_mode"`
|
||||
SynchronousModeStrict bool `json:"synchronous_mode_strict"`
|
||||
}
|
||||
|
||||
//StandbyCluster
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ type patroniDCS struct {
|
|||
LoopWait uint32 `json:"loop_wait,omitempty"`
|
||||
RetryTimeout uint32 `json:"retry_timeout,omitempty"`
|
||||
MaximumLagOnFailover float32 `json:"maximum_lag_on_failover,omitempty"`
|
||||
SynchronousMode bool `json:"synchronous_mode,omitempty"`
|
||||
SynchronousModeStrict bool `json:"synchronous_mode_strict,omitempty"`
|
||||
PGBootstrapConfiguration map[string]interface{} `json:"postgresql,omitempty"`
|
||||
Slots map[string]map[string]string `json:"slots,omitempty"`
|
||||
}
|
||||
|
|
@ -283,6 +285,12 @@ PatroniInitDBParams:
|
|||
if patroni.Slots != nil {
|
||||
config.Bootstrap.DCS.Slots = patroni.Slots
|
||||
}
|
||||
if patroni.SynchronousMode {
|
||||
config.Bootstrap.DCS.SynchronousMode = patroni.SynchronousMode
|
||||
}
|
||||
if patroni.SynchronousModeStrict != false {
|
||||
config.Bootstrap.DCS.SynchronousModeStrict = patroni.SynchronousModeStrict
|
||||
}
|
||||
|
||||
config.PgLocalConfiguration = make(map[string]interface{})
|
||||
config.PgLocalConfiguration[patroniPGBinariesParameterName] = fmt.Sprintf(pgBinariesLocationTemplate, pg.PgVersion)
|
||||
|
|
@ -672,6 +680,10 @@ func (c *Cluster) generateSpiloPodEnvVars(uid types.UID, spiloConfiguration stri
|
|||
envVars = append(envVars, v1.EnvVar{Name: "ETCD_HOST", Value: c.OpConfig.EtcdHost})
|
||||
}
|
||||
|
||||
if c.patroniKubernetesUseConfigMaps() {
|
||||
envVars = append(envVars, v1.EnvVar{Name: "KUBERNETES_USE_CONFIGMAPS", Value: "true"})
|
||||
}
|
||||
|
||||
if cloneDescription.ClusterName != "" {
|
||||
envVars = append(envVars, c.generateCloneEnvironment(cloneDescription)...)
|
||||
}
|
||||
|
|
@ -1406,7 +1418,7 @@ func (c *Cluster) generateService(role PostgresRole, spec *acidv1.PostgresSpec)
|
|||
Type: v1.ServiceTypeClusterIP,
|
||||
}
|
||||
|
||||
if role == Replica {
|
||||
if role == Replica || c.patroniKubernetesUseConfigMaps() {
|
||||
serviceSpec.Selector = c.roleLabelsSet(false, role)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,11 +70,13 @@ func TestGenerateSpiloJSONConfiguration(t *testing.T) {
|
|||
LoopWait: 10,
|
||||
RetryTimeout: 10,
|
||||
MaximumLagOnFailover: 33554432,
|
||||
SynchronousMode: true,
|
||||
SynchronousModeStrict: true,
|
||||
Slots: map[string]map[string]string{"permanent_logical_1": {"type": "logical", "database": "foo", "plugin": "pgoutput"}},
|
||||
},
|
||||
role: "zalandos",
|
||||
opConfig: config.Config{},
|
||||
result: `{"postgresql":{"bin_dir":"/usr/lib/postgresql/11/bin","pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"users":{"zalandos":{"password":"","options":["CREATEDB","NOLOGIN"]}},"dcs":{"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}}}}`,
|
||||
result: `{"postgresql":{"bin_dir":"/usr/lib/postgresql/11/bin","pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"users":{"zalandos":{"password":"","options":["CREATEDB","NOLOGIN"]}},"dcs":{"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"synchronous_mode":true,"synchronous_mode_strict":true,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}}}}`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
|
|
@ -510,6 +510,15 @@ func (c *Cluster) patroniUsesKubernetes() bool {
|
|||
return c.OpConfig.EtcdHost == ""
|
||||
}
|
||||
|
||||
func (c *Cluster) patroniKubernetesUseConfigMaps() bool {
|
||||
if !c.patroniUsesKubernetes() {
|
||||
return false
|
||||
}
|
||||
|
||||
// otherwise, follow the operator configuration
|
||||
return c.OpConfig.KubernetesUseConfigMaps
|
||||
}
|
||||
|
||||
func (c *Cluster) needConnectionPoolerWorker(spec *acidv1.PostgresSpec) bool {
|
||||
if spec.EnableConnectionPooler == nil {
|
||||
return spec.ConnectionPooler != nil
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
|||
// general config
|
||||
result.EnableCRDValidation = fromCRD.EnableCRDValidation
|
||||
result.EtcdHost = fromCRD.EtcdHost
|
||||
result.KubernetesUseConfigMaps = fromCRD.KubernetesUseConfigMaps
|
||||
result.DockerImage = fromCRD.DockerImage
|
||||
result.Workers = fromCRD.Workers
|
||||
result.MinInstances = fromCRD.MinInstances
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ type Config struct {
|
|||
ConnectionPooler
|
||||
|
||||
WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to'
|
||||
KubernetesUseConfigMaps bool `name:"kubernetes_use_configmaps" default:"false"`
|
||||
EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use K8s as a DCS
|
||||
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-12:1.6-p2"`
|
||||
Sidecars map[string]string `name:"sidecar_docker_images"`
|
||||
|
|
|
|||
Loading…
Reference in New Issue