diff --git a/docs/user.md b/docs/user.md index ee8e7183c..5612f2f83 100644 --- a/docs/user.md +++ b/docs/user.md @@ -30,7 +30,7 @@ spec: databases: foo: zalando postgresql: - version: "10" + version: "11" ``` Once you cloned the Postgres Operator [repository](https://github.com/zalando/postgres-operator) @@ -40,6 +40,10 @@ you can find this example also in the manifests folder: kubectl create -f manifests/minimal-postgres-manifest.yaml ``` +Note, that the minimum volume size to properly run the `postgresql` resource is +`1Gi`. If a lower value is set in the manifest the operator will cancel ADD, +UPDATE or SYNC events on this resource with an error. + ## Watch pods being created ```bash @@ -182,6 +186,32 @@ See [infrastructure roles secret](../manifests/infrastructure-roles.yaml) and [infrastructure roles configmap](../manifests/infrastructure-roles-configmap.yaml) for the examples. +## Resource definition + +The compute resources to be used for the Postgres containers in the pods can be +specified in the postgresql cluster manifest. + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: postgresql +metadata: + name: acid-minimal-cluster +spec: + resources: + requests: + cpu: 10m + memory: 100Mi + limits: + cpu: 300m + memory: 300Mi +``` + +The minimum limit to properly run the `postgresql` resource is `256m` for `cpu` +and `256Mi` for `memory`. If a lower value is set in the manifest the operator +will cancel ADD, UPDATE or SYNC events on this resource with an error. If no +resources are defined in the manifest the operator will obtain the configured +[default requests](reference/operator_parameters.md#kubernetes-resource-requests). + ## Use taints and tolerations for dedicated PostgreSQL nodes To ensure Postgres pods are running on nodes without any other application pods, @@ -305,7 +335,7 @@ Things to note: - There is no way to transform a non-standby cluster to a standby cluster through the operator. Adding the standby section to the manifest of a running Postgres cluster will have no effect. However, it can be done through Patroni - by adding the [standby_cluster] (https://github.com/zalando/patroni/blob/bd2c54581abb42a7d3a3da551edf0b8732eefd27/docs/replica_bootstrap.rst#standby-cluster) + by adding the [standby_cluster](https://github.com/zalando/patroni/blob/bd2c54581abb42a7d3a3da551edf0b8732eefd27/docs/replica_bootstrap.rst#standby-cluster) section using `patronictl edit-config`. Note that the transformed standby cluster will not be doing any streaming. It will be in standby mode and allow read-only transactions only. @@ -376,7 +406,7 @@ spec: ## Increase volume size -PostgreSQL operator supports statefulset volume resize if you're using the +Postgres operator supports statefulset volume resize if you're using the operator on top of AWS. For that you need to change the size field of the volume description in the cluster manifest and apply the change: diff --git a/manifests/standby-manifest.yaml b/manifests/standby-manifest.yaml index 49f2b1a1f..e1bcaf104 100644 --- a/manifests/standby-manifest.yaml +++ b/manifests/standby-manifest.yaml @@ -9,7 +9,7 @@ spec: size: 1Gi numberOfInstances: 1 postgresql: - version: "10" + version: "11" # Make this a standby cluster and provide the s3 bucket path of source cluster for continuous streaming. standby: s3_wal_path: "s3://path/to/bucket/containing/wal/of/source/cluster/" diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index d2180384c..5a85b311d 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -228,7 +228,7 @@ func (c *Cluster) Create() error { c.setStatus(acidv1.ClusterStatusCreating) if err = c.validateResources(&c.Spec); err != nil { - return fmt.Errorf("unsufficient ressources: %v", err) + return fmt.Errorf("insufficient resources specified: %v", err) } for _, role := range []PostgresRole{Master, Replica} { @@ -595,6 +595,12 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error { } } + // check pod resources and volume size and cancel update if they are too low + if err := c.validateResources(&c.Spec); err != nil { + updateFailed = true + return fmt.Errorf("insufficient resources specified: %v", err) + } + // Volume if oldSpec.Spec.Size != newSpec.Spec.Size { c.logger.Debugf("syncing persistent volumes") diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index dd55cd04c..e65ded678 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -34,6 +34,11 @@ func (c *Cluster) Sync(newSpec *acidv1.Postgresql) error { } }() + if err = c.validateResources(&c.Spec); err != nil { + err = fmt.Errorf("insufficient resources specified: %v", err) + return err + } + if err = c.initUsers(); err != nil { err = fmt.Errorf("could not init users: %v", err) return err diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 9162ce27d..802523f36 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/sirupsen/logrus" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -111,7 +111,7 @@ func (c *Controller) initOperatorConfig() { if c.opConfig.SetMemoryRequestToLimit { - isSmaller, err := util.RequestIsSmallerThanLimit(c.opConfig.DefaultMemoryRequest, c.opConfig.DefaultMemoryLimit) + isSmaller, err := util.IsSmallerQuantity(c.opConfig.DefaultMemoryRequest, c.opConfig.DefaultMemoryLimit) if err != nil { panic(err) } @@ -120,7 +120,7 @@ func (c *Controller) initOperatorConfig() { c.opConfig.DefaultMemoryRequest = c.opConfig.DefaultMemoryLimit } - isSmaller, err = util.RequestIsSmallerThanLimit(c.opConfig.ScalyrMemoryRequest, c.opConfig.ScalyrMemoryLimit) + isSmaller, err = util.IsSmallerQuantity(c.opConfig.ScalyrMemoryRequest, c.opConfig.ScalyrMemoryLimit) if err != nil { panic(err) } diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 1f65dc54e..1f86ea1b4 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -159,10 +159,10 @@ func TestIsSmallerQuantity(t *testing.T) { for _, tt := range requestIsSmallerQuantityTests { res, err := IsSmallerQuantity(tt.request, tt.limit) if err != nil { - t.Errorf("RequestIsSmallerThanLimit returned unexpected error: %#v", err) + t.Errorf("IsSmallerQuantity returned unexpected error: %#v", err) } if res != tt.out { - t.Errorf("RequestIsSmallerThanLimit expected: %#v, got: %#v", tt.out, res) + t.Errorf("IsSmallerQuantity expected: %#v, got: %#v", tt.out, res) } } }