add pdb configuration toggle
This commit is contained in:
commit
b8453e6075
|
|
@ -114,6 +114,7 @@ configKubernetesCRD:
|
||||||
cluster_name_label: cluster-name
|
cluster_name_label: cluster-name
|
||||||
enable_pod_antiaffinity: false
|
enable_pod_antiaffinity: false
|
||||||
pod_antiaffinity_topology_key: "kubernetes.io/hostname"
|
pod_antiaffinity_topology_key: "kubernetes.io/hostname"
|
||||||
|
enable_pod_disruption_budget: true
|
||||||
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
|
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
|
||||||
# inherited_labels:
|
# inherited_labels:
|
||||||
# - application
|
# - application
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ configuration:
|
||||||
pod_management_policy: "ordered_ready"
|
pod_management_policy: "ordered_ready"
|
||||||
enable_pod_antiaffinity: false
|
enable_pod_antiaffinity: false
|
||||||
pod_antiaffinity_topology_key: "kubernetes.io/hostname"
|
pod_antiaffinity_topology_key: "kubernetes.io/hostname"
|
||||||
|
enable_pod_disruption_budget: true
|
||||||
postgres_pod_resources:
|
postgres_pod_resources:
|
||||||
default_cpu_request: 100m
|
default_cpu_request: 100m
|
||||||
default_memory_request: 100Mi
|
default_memory_request: 100Mi
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ type KubernetesMetaConfiguration struct {
|
||||||
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
|
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
|
||||||
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
|
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
|
||||||
PodManagementPolicy string `json:"pod_management_policy,omitempty"`
|
PodManagementPolicy string `json:"pod_management_policy,omitempty"`
|
||||||
|
EnablePodDisruptionBudget bool `json:"enable_pod_disruption_budget,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgresPodResourcesDefaults defines the spec of default resources
|
// PostgresPodResourcesDefaults defines the spec of default resources
|
||||||
|
|
|
||||||
|
|
@ -1274,6 +1274,11 @@ func (c *Cluster) generateCloneEnvironment(description *acidv1.CloneDescription)
|
||||||
func (c *Cluster) generatePodDisruptionBudget() *policybeta1.PodDisruptionBudget {
|
func (c *Cluster) generatePodDisruptionBudget() *policybeta1.PodDisruptionBudget {
|
||||||
minAvailable := intstr.FromInt(1)
|
minAvailable := intstr.FromInt(1)
|
||||||
|
|
||||||
|
// Is PodDisruptionBudget is disabled or if there is no master, set the budget to 0.
|
||||||
|
if (c.OpConfig.EnablePodDisruptionBudget != nil && !*c.OpConfig.EnablePodDisruptionBudget) || c.Spec.NumberOfInstances <= 0 {
|
||||||
|
minAvailable = intstr.FromInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
return &policybeta1.PodDisruptionBudget{
|
return &policybeta1.PodDisruptionBudget{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: c.podDisruptionBudgetName(),
|
Name: c.podDisruptionBudgetName(),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package cluster
|
package cluster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -9,6 +11,10 @@ import (
|
||||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/constants"
|
"github.com/zalando/postgres-operator/pkg/util/constants"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
||||||
|
|
||||||
|
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func True() *bool {
|
func True() *bool {
|
||||||
|
|
@ -21,6 +27,11 @@ func False() *bool {
|
||||||
return &b
|
return &b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toIntStr(val int) *intstr.IntOrString {
|
||||||
|
b := intstr.FromInt(val)
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
func TestGenerateSpiloJSONConfiguration(t *testing.T) {
|
func TestGenerateSpiloJSONConfiguration(t *testing.T) {
|
||||||
var cluster = New(
|
var cluster = New(
|
||||||
Config{
|
Config{
|
||||||
|
|
@ -143,6 +154,113 @@ func TestCreateLoadBalancerLogic(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGeneratePodDisruptionBudget(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
c *Cluster
|
||||||
|
out policyv1beta1.PodDisruptionBudget
|
||||||
|
}{
|
||||||
|
// With multiple instances.
|
||||||
|
{
|
||||||
|
New(
|
||||||
|
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb"}},
|
||||||
|
k8sutil.KubernetesClient{},
|
||||||
|
acidv1.Postgresql{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
|
||||||
|
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
|
||||||
|
logger),
|
||||||
|
policyv1beta1.PodDisruptionBudget{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "postgres-myapp-database-pdb",
|
||||||
|
Namespace: "myapp",
|
||||||
|
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
Spec: policyv1beta1.PodDisruptionBudgetSpec{
|
||||||
|
MinAvailable: toIntStr(1),
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// With zero instances.
|
||||||
|
{
|
||||||
|
New(
|
||||||
|
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb"}},
|
||||||
|
k8sutil.KubernetesClient{},
|
||||||
|
acidv1.Postgresql{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
|
||||||
|
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 0}},
|
||||||
|
logger),
|
||||||
|
policyv1beta1.PodDisruptionBudget{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "postgres-myapp-database-pdb",
|
||||||
|
Namespace: "myapp",
|
||||||
|
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
Spec: policyv1beta1.PodDisruptionBudgetSpec{
|
||||||
|
MinAvailable: toIntStr(0),
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// With PodDisruptionBudget disabled.
|
||||||
|
{
|
||||||
|
New(
|
||||||
|
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb", EnablePodDisruptionBudget: False()}},
|
||||||
|
k8sutil.KubernetesClient{},
|
||||||
|
acidv1.Postgresql{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
|
||||||
|
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
|
||||||
|
logger),
|
||||||
|
policyv1beta1.PodDisruptionBudget{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "postgres-myapp-database-pdb",
|
||||||
|
Namespace: "myapp",
|
||||||
|
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
Spec: policyv1beta1.PodDisruptionBudgetSpec{
|
||||||
|
MinAvailable: toIntStr(0),
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// With non-default PDBNameFormat and PodDisruptionBudget explicitly enabled.
|
||||||
|
{
|
||||||
|
New(
|
||||||
|
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-databass-budget", EnablePodDisruptionBudget: True()}},
|
||||||
|
k8sutil.KubernetesClient{},
|
||||||
|
acidv1.Postgresql{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
|
||||||
|
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
|
||||||
|
logger),
|
||||||
|
policyv1beta1.PodDisruptionBudget{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "postgres-myapp-database-databass-budget",
|
||||||
|
Namespace: "myapp",
|
||||||
|
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
Spec: policyv1beta1.PodDisruptionBudgetSpec{
|
||||||
|
MinAvailable: toIntStr(1),
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
result := tt.c.generatePodDisruptionBudget()
|
||||||
|
if !reflect.DeepEqual(*result, tt.out) {
|
||||||
|
t.Errorf("Expected PodDisruptionBudget: %#v, got %#v", tt.out, *result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShmVolume(t *testing.T) {
|
func TestShmVolume(t *testing.T) {
|
||||||
testName := "TestShmVolume"
|
testName := "TestShmVolume"
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
@ -269,6 +387,5 @@ func TestCloneEnv(t *testing.T) {
|
||||||
t.Errorf("%s %s: Expected env value %s, have %s instead",
|
t.Errorf("%s %s: Expected env value %s, have %s instead",
|
||||||
testName, tt.subTest, tt.env.Value, env.Value)
|
testName, tt.subTest, tt.env.Value, env.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.PodServiceAccountRoleBindingDefinition = fromCRD.Kubernetes.PodServiceAccountRoleBindingDefinition
|
result.PodServiceAccountRoleBindingDefinition = fromCRD.Kubernetes.PodServiceAccountRoleBindingDefinition
|
||||||
result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap
|
result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap
|
||||||
result.PodTerminateGracePeriod = time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod)
|
result.PodTerminateGracePeriod = time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod)
|
||||||
|
result.EnablePodDisruptionBudget = fromCRD.Kubernetes.EnablePodDisruptionBudget
|
||||||
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
|
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
|
||||||
result.SpiloFSGroup = fromCRD.Kubernetes.SpiloFSGroup
|
result.SpiloFSGroup = fromCRD.Kubernetes.SpiloFSGroup
|
||||||
result.ClusterDomain = fromCRD.Kubernetes.ClusterDomain
|
result.ClusterDomain = fromCRD.Kubernetes.ClusterDomain
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,10 @@ type Config struct {
|
||||||
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
||||||
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
||||||
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
||||||
|
EnablePodDisruptionBudget *bool `name:"enable_pod_disruption_budget" default:"true"`
|
||||||
ProtectedRoles []string `name:"protected_role_names" default:"admin"`
|
ProtectedRoles []string `name:"protected_role_names" default:"admin"`
|
||||||
PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""`
|
PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""`
|
||||||
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" defaults:"false"`
|
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustMarshal marshals the config or panics
|
// MustMarshal marshals the config or panics
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue