check resource requests also on UPDATE and SYNC + update docs

This commit is contained in:
Felix Kunde 2019-11-22 12:47:28 +01:00
parent 9480b09b2c
commit c5dfd11e29
6 changed files with 51 additions and 10 deletions

View File

@ -30,7 +30,7 @@ spec:
databases: databases:
foo: zalando foo: zalando
postgresql: postgresql:
version: "10" version: "11"
``` ```
Once you cloned the Postgres Operator [repository](https://github.com/zalando/postgres-operator) 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 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 ## Watch pods being created
```bash ```bash
@ -182,6 +186,32 @@ See [infrastructure roles secret](../manifests/infrastructure-roles.yaml)
and [infrastructure roles configmap](../manifests/infrastructure-roles-configmap.yaml) and [infrastructure roles configmap](../manifests/infrastructure-roles-configmap.yaml)
for the examples. 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 ## Use taints and tolerations for dedicated PostgreSQL nodes
To ensure Postgres pods are running on nodes without any other application pods, 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 - 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 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 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 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 cluster will not be doing any streaming. It will be in standby mode and allow
read-only transactions only. read-only transactions only.
@ -376,7 +406,7 @@ spec:
## Increase volume size ## 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 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: volume description in the cluster manifest and apply the change:

View File

@ -9,7 +9,7 @@ spec:
size: 1Gi size: 1Gi
numberOfInstances: 1 numberOfInstances: 1
postgresql: postgresql:
version: "10" version: "11"
# Make this a standby cluster and provide the s3 bucket path of source cluster for continuous streaming. # Make this a standby cluster and provide the s3 bucket path of source cluster for continuous streaming.
standby: standby:
s3_wal_path: "s3://path/to/bucket/containing/wal/of/source/cluster/" s3_wal_path: "s3://path/to/bucket/containing/wal/of/source/cluster/"

View File

@ -228,7 +228,7 @@ func (c *Cluster) Create() error {
c.setStatus(acidv1.ClusterStatusCreating) c.setStatus(acidv1.ClusterStatusCreating)
if err = c.validateResources(&c.Spec); err != nil { 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} { 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 // Volume
if oldSpec.Spec.Size != newSpec.Spec.Size { if oldSpec.Spec.Size != newSpec.Spec.Size {
c.logger.Debugf("syncing persistent volumes") c.logger.Debugf("syncing persistent volumes")

View File

@ -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 { if err = c.initUsers(); err != nil {
err = fmt.Errorf("could not init users: %v", err) err = fmt.Errorf("could not init users: %v", err)
return err return err

View File

@ -6,7 +6,7 @@ import (
"sync" "sync"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
rbacv1beta1 "k8s.io/api/rbac/v1beta1" rbacv1beta1 "k8s.io/api/rbac/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -111,7 +111,7 @@ func (c *Controller) initOperatorConfig() {
if c.opConfig.SetMemoryRequestToLimit { 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 { if err != nil {
panic(err) panic(err)
} }
@ -120,7 +120,7 @@ func (c *Controller) initOperatorConfig() {
c.opConfig.DefaultMemoryRequest = c.opConfig.DefaultMemoryLimit 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 { if err != nil {
panic(err) panic(err)
} }

View File

@ -159,10 +159,10 @@ func TestIsSmallerQuantity(t *testing.T) {
for _, tt := range requestIsSmallerQuantityTests { for _, tt := range requestIsSmallerQuantityTests {
res, err := IsSmallerQuantity(tt.request, tt.limit) res, err := IsSmallerQuantity(tt.request, tt.limit)
if err != nil { if err != nil {
t.Errorf("RequestIsSmallerThanLimit returned unexpected error: %#v", err) t.Errorf("IsSmallerQuantity returned unexpected error: %#v", err)
} }
if res != tt.out { if res != tt.out {
t.Errorf("RequestIsSmallerThanLimit expected: %#v, got: %#v", tt.out, res) t.Errorf("IsSmallerQuantity expected: %#v, got: %#v", tt.out, res)
} }
} }
} }