add preferred during scheduling pod anti affinity (#2048)

* add preferred during scheduling pod anti affinity

Co-authored-by: Felix Kunde <felix-kunde@gmx.de>
This commit is contained in:
Francois Parquet 2023-01-02 18:22:47 +01:00 committed by GitHub
parent 93a253bde1
commit be7b52db92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 215 additions and 89 deletions

View File

@ -281,6 +281,9 @@ spec:
pod_antiaffinity_topology_key: pod_antiaffinity_topology_key:
type: string type: string
default: "kubernetes.io/hostname" default: "kubernetes.io/hostname"
pod_antiaffinity_preferred_during_scheduling:
type: boolean
default: false
pod_environment_configmap: pod_environment_configmap:
type: string type: string
pod_environment_secret: pod_environment_secret:

View File

@ -167,6 +167,8 @@ configKubernetes:
pdb_name_format: "postgres-{cluster}-pdb" pdb_name_format: "postgres-{cluster}-pdb"
# override topology key for pod anti affinity # override topology key for pod anti affinity
pod_antiaffinity_topology_key: "kubernetes.io/hostname" pod_antiaffinity_topology_key: "kubernetes.io/hostname"
# switches pod anti affinity type to `preferredDuringSchedulingIgnoredDuringExecution`
# pod_antiaffinity_preferred_during_scheduling: true
# namespaced name of the ConfigMap with environment variables to populate on every pod # namespaced name of the ConfigMap with environment variables to populate on every pod
# pod_environment_configmap: "default/my-custom-config" # pod_environment_configmap: "default/my-custom-config"
# name of the Secret (in cluster namespace) with environment variables to populate on every pod # name of the Secret (in cluster namespace) with environment variables to populate on every pod

View File

@ -15,7 +15,7 @@ CRDs set `enable_crd_registration` config option to `false`.
CRDs are defined with a `openAPIV3Schema` structural schema against which new CRDs are defined with a `openAPIV3Schema` structural schema against which new
manifests of [`postgresql`](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql.crd.yaml) or [`OperatorConfiguration`](https://github.com/zalando/postgres-operator/blob/master/manifests/operatorconfiguration.crd.yaml) manifests of [`postgresql`](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql.crd.yaml) or [`OperatorConfiguration`](https://github.com/zalando/postgres-operator/blob/master/manifests/operatorconfiguration.crd.yaml)
resources will be validated. On creation you can bypass the validation with resources will be validated. On creation you can bypass the validation with
`kubectl create --validate=false`. `kubectl create --validate=false`.
By default, the operator will register the CRDs in the `all` category so By default, the operator will register the CRDs in the `all` category so
@ -516,6 +516,9 @@ configuration:
enable_pod_antiaffinity: true enable_pod_antiaffinity: true
``` ```
By default the type of pod anti affinity is `requiredDuringSchedulingIgnoredDuringExecution`,
you can switch to `preferredDuringSchedulingIgnoredDuringExecution` by setting `pod_antiaffinity_preferred_during_scheduling: true`.
By default the topology key for the pod anti affinity is set to By default the topology key for the pod anti affinity is set to
`kubernetes.io/hostname`, you can set another topology key e.g. `kubernetes.io/hostname`, you can set another topology key e.g.
`failure-domain.beta.kubernetes.io/zone`. See [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys. `failure-domain.beta.kubernetes.io/zone`. See [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys.
@ -1091,7 +1094,7 @@ data:
USE_WALG_BACKUP: "true" USE_WALG_BACKUP: "true"
USE_WALG_RESTORE: "true" USE_WALG_RESTORE: "true"
CLONE_USE_WALG_RESTORE: "true" CLONE_USE_WALG_RESTORE: "true"
WALG_AZ_PREFIX: "azure://container-name/$(SCOPE)/$(PGVERSION)" # Enables Azure Backups (SCOPE = Cluster name) (PGVERSION = Postgres version) WALG_AZ_PREFIX: "azure://container-name/$(SCOPE)/$(PGVERSION)" # Enables Azure Backups (SCOPE = Cluster name) (PGVERSION = Postgres version)
``` ```
3. Setup your operator configuration values. With the `psql-backup-creds` 3. Setup your operator configuration values. With the `psql-backup-creds`

View File

@ -1378,6 +1378,9 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
"pod_antiaffinity_topology_key": { "pod_antiaffinity_topology_key": {
Type: "string", Type: "string",
}, },
"pod_antiaffinity_preferred_during_scheduling": {
Type: "boolean",
},
"pod_environment_configmap": { "pod_environment_configmap": {
Type: "string", Type: "string",
}, },

View File

@ -91,16 +91,17 @@ type KubernetesMetaConfiguration struct {
NodeReadinessLabelMerge string `json:"node_readiness_label_merge,omitempty"` NodeReadinessLabelMerge string `json:"node_readiness_label_merge,omitempty"`
CustomPodAnnotations map[string]string `json:"custom_pod_annotations,omitempty"` CustomPodAnnotations map[string]string `json:"custom_pod_annotations,omitempty"`
// TODO: use a proper toleration structure? // TODO: use a proper toleration structure?
PodToleration map[string]string `json:"toleration,omitempty"` PodToleration map[string]string `json:"toleration,omitempty"`
PodEnvironmentConfigMap spec.NamespacedName `json:"pod_environment_configmap,omitempty"` PodEnvironmentConfigMap spec.NamespacedName `json:"pod_environment_configmap,omitempty"`
PodEnvironmentSecret string `json:"pod_environment_secret,omitempty"` PodEnvironmentSecret string `json:"pod_environment_secret,omitempty"`
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"` PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"` MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"`
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"` PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
EnableReadinessProbe bool `json:"enable_readiness_probe,omitempty"` PodManagementPolicy string `json:"pod_management_policy,omitempty"`
EnableCrossNamespaceSecret bool `json:"enable_cross_namespace_secret,omitempty"` EnableReadinessProbe bool `json:"enable_readiness_probe,omitempty"`
EnableCrossNamespaceSecret bool `json:"enable_cross_namespace_secret,omitempty"`
} }
// PostgresPodResourcesDefaults defines the spec of default resources // PostgresPodResourcesDefaults defines the spec of default resources

View File

@ -354,7 +354,12 @@ func (c *Cluster) generateConnectionPoolerPodTemplate(role PostgresRole) (
nodeAffinity := c.nodeAffinity(c.OpConfig.NodeReadinessLabel, spec.NodeAffinity) nodeAffinity := c.nodeAffinity(c.OpConfig.NodeReadinessLabel, spec.NodeAffinity)
if c.OpConfig.EnablePodAntiAffinity { if c.OpConfig.EnablePodAntiAffinity {
labelsSet := labels.Set(c.connectionPoolerLabels(role, false).MatchLabels) labelsSet := labels.Set(c.connectionPoolerLabels(role, false).MatchLabels)
podTemplate.Spec.Affinity = generatePodAffinity(labelsSet, c.OpConfig.PodAntiAffinityTopologyKey, nodeAffinity) podTemplate.Spec.Affinity = generatePodAffinity(
labelsSet,
c.OpConfig.PodAntiAffinityTopologyKey,
nodeAffinity,
c.OpConfig.PodAntiAffinityPreferredDuringScheduling,
)
} else if nodeAffinity != nil { } else if nodeAffinity != nil {
podTemplate.Spec.Affinity = nodeAffinity podTemplate.Spec.Affinity = nodeAffinity
} }

View File

@ -495,17 +495,27 @@ func (c *Cluster) nodeAffinity(nodeReadinessLabel map[string]string, nodeAffinit
} }
} }
func generatePodAffinity(labels labels.Set, topologyKey string, nodeAffinity *v1.Affinity) *v1.Affinity { func generatePodAffinity(labels labels.Set, topologyKey string, nodeAffinity *v1.Affinity, preferredDuringScheduling bool) *v1.Affinity {
// generate pod anti-affinity to avoid multiple pods of the same Postgres cluster in the same topology , e.g. node // generate pod anti-affinity to avoid multiple pods of the same Postgres cluster in the same topology , e.g. node
podAffinity := v1.Affinity{
PodAntiAffinity: &v1.PodAntiAffinity{ podAffinityTerm := v1.PodAffinityTerm{
RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{{ LabelSelector: &metav1.LabelSelector{
LabelSelector: &metav1.LabelSelector{ MatchLabels: labels,
MatchLabels: labels,
},
TopologyKey: topologyKey,
}},
}, },
TopologyKey: topologyKey,
}
podAffinity := v1.Affinity{
PodAntiAffinity: &v1.PodAntiAffinity{},
}
if preferredDuringScheduling {
podAffinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution = []v1.WeightedPodAffinityTerm{{
Weight: 1,
PodAffinityTerm: podAffinityTerm,
}}
} else {
podAffinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = []v1.PodAffinityTerm{podAffinityTerm}
} }
if nodeAffinity != nil && nodeAffinity.NodeAffinity != nil { if nodeAffinity != nil && nodeAffinity.NodeAffinity != nil {
@ -727,6 +737,7 @@ func (c *Cluster) generatePodTemplate(
shmVolume *bool, shmVolume *bool,
podAntiAffinity bool, podAntiAffinity bool,
podAntiAffinityTopologyKey string, podAntiAffinityTopologyKey string,
podAntiAffinityPreferredDuringScheduling bool,
additionalSecretMount string, additionalSecretMount string,
additionalSecretMountPath string, additionalSecretMountPath string,
additionalVolumes []acidv1.AdditionalVolume, additionalVolumes []acidv1.AdditionalVolume,
@ -767,7 +778,12 @@ func (c *Cluster) generatePodTemplate(
} }
if podAntiAffinity { if podAntiAffinity {
podSpec.Affinity = generatePodAffinity(labels, podAntiAffinityTopologyKey, nodeAffinity) podSpec.Affinity = generatePodAffinity(
labels,
podAntiAffinityTopologyKey,
nodeAffinity,
podAntiAffinityPreferredDuringScheduling,
)
} else if nodeAffinity != nil { } else if nodeAffinity != nil {
podSpec.Affinity = nodeAffinity podSpec.Affinity = nodeAffinity
} }
@ -1376,6 +1392,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
mountShmVolumeNeeded(c.OpConfig, spec), mountShmVolumeNeeded(c.OpConfig, spec),
c.OpConfig.EnablePodAntiAffinity, c.OpConfig.EnablePodAntiAffinity,
c.OpConfig.PodAntiAffinityTopologyKey, c.OpConfig.PodAntiAffinityTopologyKey,
c.OpConfig.PodAntiAffinityPreferredDuringScheduling,
c.OpConfig.AdditionalSecretMount, c.OpConfig.AdditionalSecretMount,
c.OpConfig.AdditionalSecretMountPath, c.OpConfig.AdditionalSecretMountPath,
additionalVolumes) additionalVolumes)
@ -2122,6 +2139,7 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) {
util.False(), util.False(),
false, false,
"", "",
false,
c.OpConfig.AdditionalSecretMount, c.OpConfig.AdditionalSecretMount,
c.OpConfig.AdditionalSecretMountPath, c.OpConfig.AdditionalSecretMountPath,
[]acidv1.AdditionalVolume{}); err != nil { []acidv1.AdditionalVolume{}); err != nil {

View File

@ -1360,6 +1360,95 @@ func TestNodeAffinity(t *testing.T) {
assert.Equal(t, s.Spec.Template.Spec.Affinity.NodeAffinity, nodeAff, "cluster template has correct node affinity") assert.Equal(t, s.Spec.Template.Spec.Affinity.NodeAffinity, nodeAff, "cluster template has correct node affinity")
} }
func TestPodAntiAffinityrRequiredDuringScheduling(t *testing.T) {
var err error
var spiloRunAsUser = int64(101)
var spiloRunAsGroup = int64(103)
var spiloFSGroup = int64(103)
spec := acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"},
},
Volume: acidv1.Volume{
Size: "1G",
},
}
cluster := New(
Config{
OpConfig: config.Config{
PodManagementPolicy: "ordered_ready",
ProtectedRoles: []string{"admin"},
Auth: config.Auth{
SuperUsername: superUserName,
ReplicationUsername: replicationUserName,
},
Resources: config.Resources{
SpiloRunAsUser: &spiloRunAsUser,
SpiloRunAsGroup: &spiloRunAsGroup,
SpiloFSGroup: &spiloFSGroup,
},
EnablePodAntiAffinity: true,
},
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)
s, err := cluster.generateStatefulSet(&spec)
if err != nil {
assert.NoError(t, err)
}
assert.Nil(t, s.Spec.Template.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, "pod anti-affinity should not use preferredDuringScheduling")
assert.NotNil(t, s.Spec.Template.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, "pod anti-affinity should use requiredDuringScheduling")
}
func TestPodAntiAffinityPreferredDuringScheduling(t *testing.T) {
var err error
var spiloRunAsUser = int64(101)
var spiloRunAsGroup = int64(103)
var spiloFSGroup = int64(103)
spec := acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"},
},
Volume: acidv1.Volume{
Size: "1G",
},
}
cluster := New(
Config{
OpConfig: config.Config{
PodManagementPolicy: "ordered_ready",
ProtectedRoles: []string{"admin"},
Auth: config.Auth{
SuperUsername: superUserName,
ReplicationUsername: replicationUserName,
},
Resources: config.Resources{
SpiloRunAsUser: &spiloRunAsUser,
SpiloRunAsGroup: &spiloRunAsGroup,
SpiloFSGroup: &spiloFSGroup,
},
EnablePodAntiAffinity: true,
PodAntiAffinityPreferredDuringScheduling: true,
},
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)
s, err := cluster.generateStatefulSet(&spec)
if err != nil {
assert.NoError(t, err)
}
assert.NotNil(t, s.Spec.Template.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, "pod anti-affinity should use preferredDuringScheduling")
assert.Nil(t, s.Spec.Template.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, "pod anti-affinity should not use requiredDuringScheduling")
}
func testDeploymentOwnerReference(cluster *Cluster, deployment *appsv1.Deployment) error { func testDeploymentOwnerReference(cluster *Cluster, deployment *appsv1.Deployment) error {
owner := deployment.ObjectMeta.OwnerReferences[0] owner := deployment.ObjectMeta.OwnerReferences[0]

View File

@ -123,6 +123,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.MasterPodMoveTimeout = util.CoalesceDuration(time.Duration(fromCRD.Kubernetes.MasterPodMoveTimeout), "10m") result.MasterPodMoveTimeout = util.CoalesceDuration(time.Duration(fromCRD.Kubernetes.MasterPodMoveTimeout), "10m")
result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity
result.PodAntiAffinityTopologyKey = util.Coalesce(fromCRD.Kubernetes.PodAntiAffinityTopologyKey, "kubernetes.io/hostname") result.PodAntiAffinityTopologyKey = util.Coalesce(fromCRD.Kubernetes.PodAntiAffinityTopologyKey, "kubernetes.io/hostname")
result.PodAntiAffinityPreferredDuringScheduling = fromCRD.Kubernetes.PodAntiAffinityPreferredDuringScheduling
result.PodToleration = fromCRD.Kubernetes.PodToleration result.PodToleration = fromCRD.Kubernetes.PodToleration
// Postgres Pod resources // Postgres Pod resources

View File

@ -170,72 +170,73 @@ type Config struct {
SidecarContainers []v1.Container `name:"sidecars"` SidecarContainers []v1.Container `name:"sidecars"`
PodServiceAccountName string `name:"pod_service_account_name" default:"postgres-pod"` PodServiceAccountName string `name:"pod_service_account_name" default:"postgres-pod"`
// value of this string must be valid JSON or YAML; see initPodServiceAccount // value of this string must be valid JSON or YAML; see initPodServiceAccount
PodServiceAccountDefinition string `name:"pod_service_account_definition" default:""` PodServiceAccountDefinition string `name:"pod_service_account_definition" default:""`
PodServiceAccountRoleBindingDefinition string `name:"pod_service_account_role_binding_definition" default:""` PodServiceAccountRoleBindingDefinition string `name:"pod_service_account_role_binding_definition" default:""`
MasterPodMoveTimeout time.Duration `name:"master_pod_move_timeout" default:"20m"` MasterPodMoveTimeout time.Duration `name:"master_pod_move_timeout" default:"20m"`
DbHostedZone string `name:"db_hosted_zone" default:"db.example.com"` DbHostedZone string `name:"db_hosted_zone" default:"db.example.com"`
AWSRegion string `name:"aws_region" default:"eu-central-1"` AWSRegion string `name:"aws_region" default:"eu-central-1"`
WALES3Bucket string `name:"wal_s3_bucket"` WALES3Bucket string `name:"wal_s3_bucket"`
LogS3Bucket string `name:"log_s3_bucket"` LogS3Bucket string `name:"log_s3_bucket"`
KubeIAMRole string `name:"kube_iam_role"` KubeIAMRole string `name:"kube_iam_role"`
WALGSBucket string `name:"wal_gs_bucket"` WALGSBucket string `name:"wal_gs_bucket"`
GCPCredentials string `name:"gcp_credentials"` GCPCredentials string `name:"gcp_credentials"`
WALAZStorageAccount string `name:"wal_az_storage_account"` WALAZStorageAccount string `name:"wal_az_storage_account"`
AdditionalSecretMount string `name:"additional_secret_mount"` AdditionalSecretMount string `name:"additional_secret_mount"`
AdditionalSecretMountPath string `name:"additional_secret_mount_path" default:"/meta/credentials"` AdditionalSecretMountPath string `name:"additional_secret_mount_path" default:"/meta/credentials"`
EnableEBSGp3Migration bool `name:"enable_ebs_gp3_migration" default:"false"` EnableEBSGp3Migration bool `name:"enable_ebs_gp3_migration" default:"false"`
EnableEBSGp3MigrationMaxSize int64 `name:"enable_ebs_gp3_migration_max_size" default:"1000"` EnableEBSGp3MigrationMaxSize int64 `name:"enable_ebs_gp3_migration_max_size" default:"1000"`
DebugLogging bool `name:"debug_logging" default:"true"` DebugLogging bool `name:"debug_logging" default:"true"`
EnableDBAccess bool `name:"enable_database_access" default:"true"` EnableDBAccess bool `name:"enable_database_access" default:"true"`
EnableTeamsAPI bool `name:"enable_teams_api" default:"true"` EnableTeamsAPI bool `name:"enable_teams_api" default:"true"`
EnableTeamSuperuser bool `name:"enable_team_superuser" default:"false"` EnableTeamSuperuser bool `name:"enable_team_superuser" default:"false"`
TeamAdminRole string `name:"team_admin_role" default:"admin"` TeamAdminRole string `name:"team_admin_role" default:"admin"`
RoleDeletionSuffix string `name:"role_deletion_suffix" default:"_deleted"` RoleDeletionSuffix string `name:"role_deletion_suffix" default:"_deleted"`
EnableTeamMemberDeprecation bool `name:"enable_team_member_deprecation" default:"false"` EnableTeamMemberDeprecation bool `name:"enable_team_member_deprecation" default:"false"`
EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"` EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"`
EnablePostgresTeamCRD bool `name:"enable_postgres_team_crd" default:"false"` EnablePostgresTeamCRD bool `name:"enable_postgres_team_crd" default:"false"`
EnablePostgresTeamCRDSuperusers bool `name:"enable_postgres_team_crd_superusers" default:"false"` EnablePostgresTeamCRDSuperusers bool `name:"enable_postgres_team_crd_superusers" default:"false"`
EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"` EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"`
EnableMasterPoolerLoadBalancer bool `name:"enable_master_pooler_load_balancer" default:"false"` EnableMasterPoolerLoadBalancer bool `name:"enable_master_pooler_load_balancer" default:"false"`
EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"`
EnableReplicaPoolerLoadBalancer bool `name:"enable_replica_pooler_load_balancer" default:"false"` EnableReplicaPoolerLoadBalancer bool `name:"enable_replica_pooler_load_balancer" default:"false"`
CustomServiceAnnotations map[string]string `name:"custom_service_annotations"` CustomServiceAnnotations map[string]string `name:"custom_service_annotations"`
CustomPodAnnotations map[string]string `name:"custom_pod_annotations"` CustomPodAnnotations map[string]string `name:"custom_pod_annotations"`
EnablePodAntiAffinity bool `name:"enable_pod_antiaffinity" default:"false"` EnablePodAntiAffinity bool `name:"enable_pod_antiaffinity" default:"false"`
PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"` PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"`
StorageResizeMode string `name:"storage_resize_mode" default:"pvc"` PodAntiAffinityPreferredDuringScheduling bool `name:"pod_antiaffinity_preferred_during_scheduling" default:"false"`
EnableLoadBalancer *bool `name:"enable_load_balancer"` // deprecated and kept for backward compatibility StorageResizeMode string `name:"storage_resize_mode" default:"pvc"`
ExternalTrafficPolicy string `name:"external_traffic_policy" default:"Cluster"` EnableLoadBalancer *bool `name:"enable_load_balancer"` // deprecated and kept for backward compatibility
MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{namespace}.{hostedzone}"` ExternalTrafficPolicy string `name:"external_traffic_policy" default:"Cluster"`
ReplicaDNSNameFormat StringTemplate `name:"replica_dns_name_format" default:"{cluster}-repl.{namespace}.{hostedzone}"` MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{namespace}.{hostedzone}"`
PDBNameFormat StringTemplate `name:"pdb_name_format" default:"postgres-{cluster}-pdb"` ReplicaDNSNameFormat StringTemplate `name:"replica_dns_name_format" default:"{cluster}-repl.{namespace}.{hostedzone}"`
EnablePodDisruptionBudget *bool `name:"enable_pod_disruption_budget" default:"true"` PDBNameFormat StringTemplate `name:"pdb_name_format" default:"postgres-{cluster}-pdb"`
EnableInitContainers *bool `name:"enable_init_containers" default:"true"` EnablePodDisruptionBudget *bool `name:"enable_pod_disruption_budget" default:"true"`
EnableSidecars *bool `name:"enable_sidecars" default:"true"` EnableInitContainers *bool `name:"enable_init_containers" default:"true"`
SharePGSocketWithSidecars *bool `name:"share_pg_socket_with_sidecars" default:"false"` EnableSidecars *bool `name:"enable_sidecars" default:"true"`
Workers uint32 `name:"workers" default:"8"` SharePGSocketWithSidecars *bool `name:"share_pg_socket_with_sidecars" default:"false"`
APIPort int `name:"api_port" default:"8080"` Workers uint32 `name:"workers" default:"8"`
RingLogLines int `name:"ring_log_lines" default:"100"` APIPort int `name:"api_port" default:"8080"`
ClusterHistoryEntries int `name:"cluster_history_entries" default:"1000"` RingLogLines int `name:"ring_log_lines" default:"100"`
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"` ClusterHistoryEntries int `name:"cluster_history_entries" default:"1000"`
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"` TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"` PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
EnableReadinessProbe bool `name:"enable_readiness_probe" default:"false"` PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
ProtectedRoles []string `name:"protected_role_names" default:"admin,cron_admin"` EnableReadinessProbe bool `name:"enable_readiness_probe" default:"false"`
PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""` ProtectedRoles []string `name:"protected_role_names" default:"admin,cron_admin"`
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"` PostgresSuperuserTeams []string `name:"postgres_superuser_teams" default:""`
EnableLazySpiloUpgrade bool `name:"enable_lazy_spilo_upgrade" default:"false"` SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"`
EnableCrossNamespaceSecret bool `name:"enable_cross_namespace_secret" default:"false"` EnableLazySpiloUpgrade bool `name:"enable_lazy_spilo_upgrade" default:"false"`
EnablePgVersionEnvVar bool `name:"enable_pgversion_env_var" default:"true"` EnableCrossNamespaceSecret bool `name:"enable_cross_namespace_secret" default:"false"`
EnableSpiloWalPathCompat bool `name:"enable_spilo_wal_path_compat" default:"false"` EnablePgVersionEnvVar bool `name:"enable_pgversion_env_var" default:"true"`
EnableTeamIdClusternamePrefix bool `name:"enable_team_id_clustername_prefix" default:"false"` EnableSpiloWalPathCompat bool `name:"enable_spilo_wal_path_compat" default:"false"`
MajorVersionUpgradeMode string `name:"major_version_upgrade_mode" default:"off"` EnableTeamIdClusternamePrefix bool `name:"enable_team_id_clustername_prefix" default:"false"`
MajorVersionUpgradeTeamAllowList []string `name:"major_version_upgrade_team_allow_list" default:""` MajorVersionUpgradeMode string `name:"major_version_upgrade_mode" default:"off"`
MinimalMajorVersion string `name:"minimal_major_version" default:"11"` MajorVersionUpgradeTeamAllowList []string `name:"major_version_upgrade_team_allow_list" default:""`
TargetMajorVersion string `name:"target_major_version" default:"14"` MinimalMajorVersion string `name:"minimal_major_version" default:"9.6"`
PatroniAPICheckInterval time.Duration `name:"patroni_api_check_interval" default:"1s"` TargetMajorVersion string `name:"target_major_version" default:"14"`
PatroniAPICheckTimeout time.Duration `name:"patroni_api_check_timeout" default:"5s"` PatroniAPICheckInterval time.Duration `name:"patroni_api_check_interval" default:"1s"`
EnablePatroniFailsafeMode *bool `name:"enable_patroni_failsafe_mode" default:"false"` PatroniAPICheckTimeout time.Duration `name:"patroni_api_check_timeout" default:"5s"`
EnablePatroniFailsafeMode *bool `name:"enable_patroni_failsafe_mode" default:"false"`
} }
// MustMarshal marshals the config or panics // MustMarshal marshals the config or panics