Introduce higher and lower bounds for the number of instances (#178)
* Introduce higher and lower bounds for the number of instances Reduce the number of instances to the min_instances if it is lower and to the max_instances if it is higher. -1 for either of those means there is no lower or upper bound. In addition, terminate the operator when there is a nonsense in the configuration (i.e. max_instances < min_instances). Reviewed by Jan Mußler and Sergey Dudoladov.
This commit is contained in:
parent
0e255f82c6
commit
bf80f5225e
|
|
@ -180,6 +180,12 @@ This ConfigMap is then added as a source of environment variables to the Postgre
|
|||
|
||||
:exclamation: Note that there are environment variables defined by the operator itself in order to pass parameters to the Spilo image. The values from the operator for those variables will take precedence over those defined in the `pod_environment_configmap`.
|
||||
|
||||
### Limiting the number of instances in clusters with `min_instances` and `max_instances`
|
||||
|
||||
As a preventive measure, one can restrict the minimum and the maximum number of instances permitted by each Postgres cluster managed by the operator.
|
||||
If either `min_instances` or `max_instances` is set to a non-zero value, the operator may adjust the number of instances specified in the cluster manifest to match either the min or the max boundary.
|
||||
For instance, of a cluster manifest has 1 instance and the min_instances is set to 3, the cluster will be created with 3 instances. By default, both parameters are set to -1.
|
||||
|
||||
# Setup development environment
|
||||
|
||||
The following steps guide you through the setup to work on the operator itself.
|
||||
|
|
|
|||
|
|
@ -464,6 +464,8 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
|
|||
return nil, fmt.Errorf("could not generate volume claim template: %v", err)
|
||||
}
|
||||
|
||||
numberOfInstances := c.getNumberOfInstances(spec)
|
||||
|
||||
statefulSet := &v1beta1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: c.statefulSetName(),
|
||||
|
|
@ -471,7 +473,7 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
|
|||
Labels: c.labelsSet(),
|
||||
},
|
||||
Spec: v1beta1.StatefulSetSpec{
|
||||
Replicas: &spec.NumberOfInstances,
|
||||
Replicas: &numberOfInstances,
|
||||
ServiceName: c.serviceName(Master),
|
||||
Template: *podTemplate,
|
||||
VolumeClaimTemplates: []v1.PersistentVolumeClaim{*volumeClaimTemplate},
|
||||
|
|
@ -481,6 +483,25 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
|
|||
return statefulSet, nil
|
||||
}
|
||||
|
||||
func (c *Cluster) getNumberOfInstances(spec *spec.PostgresSpec) (newcur int32) {
|
||||
min := c.OpConfig.MinInstances
|
||||
max := c.OpConfig.MaxInstances
|
||||
cur := spec.NumberOfInstances
|
||||
newcur = cur
|
||||
|
||||
if max >= 0 && newcur > max {
|
||||
newcur = max
|
||||
}
|
||||
if min >= 0 && newcur < min {
|
||||
newcur = min
|
||||
}
|
||||
if newcur != cur {
|
||||
c.logger.Infof("adjusted number of instances from %d to %d (min: %d, max: %d)", cur, newcur, min, max)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func generatePersistentVolumeClaimTemplate(volumeSize, volumeStorageClass string) (*v1.PersistentVolumeClaim, error) {
|
||||
metadata := metav1.ObjectMeta{
|
||||
Name: constants.DataVolumeName,
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ func (c *Cluster) syncStatefulSet() error {
|
|||
c.logger.Infof("found pods without the statefulset: trigger rolling update")
|
||||
|
||||
} else {
|
||||
// statefulset is alrady there, make sure we use its definition in order to compare with the spec.
|
||||
// statefulset is already there, make sure we use its definition in order to compare with the spec.
|
||||
c.Statefulset = sset
|
||||
|
||||
desiredSS, err := c.generateStatefulSet(&c.Spec)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||
)
|
||||
|
||||
|
|
@ -33,6 +34,8 @@ type Resources struct {
|
|||
PodEnvironmentConfigMap string `name:"pod_environment_configmap" default:""`
|
||||
NodeEOLLabel map[string]string `name:"node_eol_label" default:"lifecycle-status:pending-decommission"`
|
||||
NodeReadinessLabel map[string]string `name:"node_readiness_label" default:"lifecycle-status:ready"`
|
||||
MaxInstances int32 `name:"max_instances" default:"-1"`
|
||||
MinInstances int32 `name:"min_instances" default:"-1"`
|
||||
}
|
||||
|
||||
// Auth describes authentication specific configuration parameters
|
||||
|
|
@ -108,6 +111,9 @@ func NewFromMap(m map[string]string) *Config {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
if err := validate(&cfg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &cfg
|
||||
}
|
||||
|
|
@ -123,3 +129,14 @@ func Copy(c *Config) Config {
|
|||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func validate(cfg *Config) (err error) {
|
||||
if cfg.MinInstances > 0 && cfg.MaxInstances > 0 && cfg.MinInstances > cfg.MaxInstances {
|
||||
err = fmt.Errorf("minimum number of instances %d is set higher than the maximum number %d",
|
||||
cfg.MinInstances, cfg.MaxInstances)
|
||||
}
|
||||
if cfg.Workers == 0 {
|
||||
err = fmt.Errorf("number of workers should be higher than 0")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue