parent
2e9b6533e7
commit
26a7fdfa9f
|
|
@ -151,6 +151,36 @@ Postgres pods by default receive tolerations for `unreachable` and `noExecute` t
|
||||||
Depending on your setup, you may want to adjust these parameters to prevent master pods from being evicted by the Kubernetes runtime.
|
Depending on your setup, you may want to adjust these parameters to prevent master pods from being evicted by the Kubernetes runtime.
|
||||||
To prevent eviction completely, specify the toleration by leaving out the `tolerationSeconds` value (similar to how Kubernetes' own DaemonSets are configured)
|
To prevent eviction completely, specify the toleration by leaving out the `tolerationSeconds` value (similar to how Kubernetes' own DaemonSets are configured)
|
||||||
|
|
||||||
|
### Enable pod anti affinity
|
||||||
|
|
||||||
|
To ensure Postgres pods are running on different topologies, you can use [pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)
|
||||||
|
and configure the required topology in the operator ConfigMap.
|
||||||
|
|
||||||
|
Enable pod anti affinity by adding following line to the operator ConfigMap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: postgres-operator
|
||||||
|
data:
|
||||||
|
enable_pod_antiaffinity: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
By default the topology key for the pod anti affinity is set to `kubernetes.io/hostname`,
|
||||||
|
you can set another topology key e.g. `failure-domain.beta.kubernetes.io/zone` by adding following line
|
||||||
|
to the operator ConfigMap, see [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: postgres-operator
|
||||||
|
data:
|
||||||
|
enable_pod_antiaffinity: "true"
|
||||||
|
pod_antiaffinity_topology_key: "failure-domain.beta.kubernetes.io/zone"
|
||||||
|
```
|
||||||
|
|
||||||
### Add cluster-specific labels
|
### Add cluster-specific labels
|
||||||
|
|
||||||
In some cases, you might want to add `labels` that are specific to a given
|
In some cases, you might want to add `labels` that are specific to a given
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,14 @@ configuration they are grouped under the `kubernetes` key.
|
||||||
that should be assigned to the Postgres pods. The priority class itself must be defined in advance.
|
that should be assigned to the Postgres pods. The priority class itself must be defined in advance.
|
||||||
Default is empty (use the default priority class).
|
Default is empty (use the default priority class).
|
||||||
|
|
||||||
|
* **enable_pod_antiaffinity**
|
||||||
|
toggles [pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) on the Postgres pods, to avoid multiple pods
|
||||||
|
of the same Postgres cluster in the same topology , e.g. node. The default is `false`.
|
||||||
|
|
||||||
|
* **pod_antiaffinity_topology_key**
|
||||||
|
override
|
||||||
|
[topology key](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels)
|
||||||
|
for pod anti affinity. The default is `kubernetes.io/hostname`.
|
||||||
|
|
||||||
## Kubernetes resource requests
|
## Kubernetes resource requests
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ type KubernetesMetaConfiguration struct {
|
||||||
// TODO: use namespacedname
|
// TODO: use namespacedname
|
||||||
PodEnvironmentConfigMap string `json:"pod_environment_configmap,omitempty"`
|
PodEnvironmentConfigMap string `json:"pod_environment_configmap,omitempty"`
|
||||||
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
|
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
|
||||||
|
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity" default:"false"`
|
||||||
|
PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgresPodResourcesDefaults defines the spec of default resources
|
// PostgresPodResourcesDefaults defines the spec of default resources
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,26 @@ func nodeAffinity(nodeReadinessLabel map[string]string) *v1.Affinity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generatePodAffinity(labels labels.Set, topologyKey string, nodeAffinity *v1.Affinity) *v1.Affinity {
|
||||||
|
// 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{
|
||||||
|
RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{{
|
||||||
|
LabelSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: labels,
|
||||||
|
},
|
||||||
|
TopologyKey: topologyKey,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if nodeAffinity != nil && nodeAffinity.NodeAffinity != nil {
|
||||||
|
podAffinity.NodeAffinity = nodeAffinity.NodeAffinity
|
||||||
|
}
|
||||||
|
|
||||||
|
return &podAffinity
|
||||||
|
}
|
||||||
|
|
||||||
func tolerations(tolerationsSpec *[]v1.Toleration, podToleration map[string]string) []v1.Toleration {
|
func tolerations(tolerationsSpec *[]v1.Toleration, podToleration map[string]string) []v1.Toleration {
|
||||||
// allow to override tolerations by postgresql manifest
|
// allow to override tolerations by postgresql manifest
|
||||||
if len(*tolerationsSpec) > 0 {
|
if len(*tolerationsSpec) > 0 {
|
||||||
|
|
@ -419,6 +439,8 @@ func generatePodTemplate(
|
||||||
kubeIAMRole string,
|
kubeIAMRole string,
|
||||||
priorityClassName string,
|
priorityClassName string,
|
||||||
shmVolume bool,
|
shmVolume bool,
|
||||||
|
podAntiAffinity bool,
|
||||||
|
podAntiAffinityTopologyKey string,
|
||||||
) (*v1.PodTemplateSpec, error) {
|
) (*v1.PodTemplateSpec, error) {
|
||||||
|
|
||||||
terminateGracePeriodSeconds := terminateGracePeriod
|
terminateGracePeriodSeconds := terminateGracePeriod
|
||||||
|
|
@ -437,7 +459,9 @@ func generatePodTemplate(
|
||||||
addShmVolume(&podSpec)
|
addShmVolume(&podSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodeAffinity != nil {
|
if podAntiAffinity {
|
||||||
|
podSpec.Affinity = generatePodAffinity(labels, podAntiAffinityTopologyKey, nodeAffinity)
|
||||||
|
} else if nodeAffinity != nil {
|
||||||
podSpec.Affinity = nodeAffinity
|
podSpec.Affinity = nodeAffinity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -813,7 +837,9 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State
|
||||||
c.OpConfig.PodServiceAccountName,
|
c.OpConfig.PodServiceAccountName,
|
||||||
c.OpConfig.KubeIAMRole,
|
c.OpConfig.KubeIAMRole,
|
||||||
effectivePodPriorityClassName,
|
effectivePodPriorityClassName,
|
||||||
mountShmVolumeNeeded(c.OpConfig, spec)); err != nil {
|
mountShmVolumeNeeded(c.OpConfig, spec),
|
||||||
|
c.OpConfig.EnablePodAntiAffinity,
|
||||||
|
c.OpConfig.PodAntiAffinityTopologyKey); err != nil {
|
||||||
return nil, fmt.Errorf("could not generate pod template: %v", err)
|
return nil, fmt.Errorf("could not generate pod template: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.NodeReadinessLabel = fromCRD.Kubernetes.NodeReadinessLabel
|
result.NodeReadinessLabel = fromCRD.Kubernetes.NodeReadinessLabel
|
||||||
result.PodPriorityClassName = fromCRD.Kubernetes.PodPriorityClassName
|
result.PodPriorityClassName = fromCRD.Kubernetes.PodPriorityClassName
|
||||||
|
|
||||||
|
result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity;
|
||||||
|
result.PodAntiAffinityTopologyKey = fromCRD.Kubernetes.PodAntiAffinityTopologyKey;
|
||||||
|
|
||||||
result.DefaultCPURequest = fromCRD.PostgresPodResources.DefaultCPURequest
|
result.DefaultCPURequest = fromCRD.PostgresPodResources.DefaultCPURequest
|
||||||
result.DefaultMemoryRequest = fromCRD.PostgresPodResources.DefaultMemoryRequest
|
result.DefaultMemoryRequest = fromCRD.PostgresPodResources.DefaultMemoryRequest
|
||||||
result.DefaultCPULimit = fromCRD.PostgresPodResources.DefaultCPULimit
|
result.DefaultCPULimit = fromCRD.PostgresPodResources.DefaultCPULimit
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,8 @@ type Config struct {
|
||||||
EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"`
|
EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"`
|
||||||
EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"`
|
EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"`
|
||||||
CustomServiceAnnotations map[string]string `name:"custom_service_annotations"`
|
CustomServiceAnnotations map[string]string `name:"custom_service_annotations"`
|
||||||
|
EnablePodAntiAffinity bool `name:"enable_pod_antiaffinity" default:"false"`
|
||||||
|
PodAntiAffinityTopologyKey string `name:"pod_antiaffinity_topology_key" default:"kubernetes.io/hostname"`
|
||||||
// deprecated and kept for backward compatibility
|
// deprecated and kept for backward compatibility
|
||||||
EnableLoadBalancer *bool `name:"enable_load_balancer"`
|
EnableLoadBalancer *bool `name:"enable_load_balancer"`
|
||||||
MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{team}.{hostedzone}"`
|
MasterDNSNameFormat StringTemplate `name:"master_dns_name_format" default:"{cluster}.{team}.{hostedzone}"`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue