Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

K8SPSMDB-227: Add topologySpreadConstraints #1280

Merged
merged 14 commits into from
Sep 1, 2023
364 changes: 364 additions & 0 deletions config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml

Large diffs are not rendered by default.

364 changes: 364 additions & 0 deletions deploy/bundle.yaml

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions deploy/cr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ spec:
- name: rs0
size: 3
# terminationGracePeriodSeconds: 300
# topologySpreadConstraints:
# - labelSelector:
# matchLabels:
# app.kubernetes.io/name: percona-server-mongodb
# maxSkew: 1
# topologyKey: kubernetes.io/hostname
# whenUnsatisfiable: DoNotSchedule
# externalNodes:
# - host: 34.124.76.90
# - host: 34.124.76.91
Expand Down Expand Up @@ -310,6 +317,13 @@ spec:
configsvrReplSet:
size: 3
# terminationGracePeriodSeconds: 300
# topologySpreadConstraints:
# - labelSelector:
# matchLabels:
# app.kubernetes.io/name: percona-server-mongodb
# maxSkew: 1
# topologyKey: kubernetes.io/hostname
# whenUnsatisfiable: DoNotSchedule
# externalNodes:
# - host: 34.124.76.93
# - host: 34.124.76.94
Expand Down Expand Up @@ -407,6 +421,13 @@ spec:
mongos:
size: 3
# terminationGracePeriodSeconds: 300
# topologySpreadConstraints:
# - labelSelector:
# matchLabels:
# app.kubernetes.io/name: percona-server-mongodb
# maxSkew: 1
# topologyKey: kubernetes.io/hostname
# whenUnsatisfiable: DoNotSchedule
# # for more configuration fields refer to https://docs.mongodb.com/manual/reference/configuration-options/
# configuration: |
# systemLog:
Expand Down
364 changes: 364 additions & 0 deletions deploy/crd.yaml

Large diffs are not rendered by default.

364 changes: 364 additions & 0 deletions deploy/cw-bundle.yaml

Large diffs are not rendered by default.

364 changes: 364 additions & 0 deletions e2e-tests/version-service/conf/crd.yaml

Large diffs are not rendered by default.

29 changes: 24 additions & 5 deletions pkg/apis/psmdb/v1/psmdb_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func (cr *PerconaServerMongoDB) CheckNSetDefaults(platform version.Platform, log
cr.Spec.Sharding.Mongos.ReadinessProbe.FailureThreshold = 3
}

cr.Spec.Sharding.Mongos.reconcileOpts()
cr.Spec.Sharding.Mongos.reconcileOpts(cr)

if err := cr.Spec.Sharding.Mongos.Configuration.SetDefaults(); err != nil {
return errors.Wrap(err, "failed to set configuration defaults")
Expand Down Expand Up @@ -558,10 +558,10 @@ func (rs *ReplsetSpec) SetDefaults(platform version.Platform, cr *PerconaServerM
rs.Expose.ExposeType = corev1.ServiceTypeClusterIP
}

rs.MultiAZ.reconcileOpts()
rs.MultiAZ.reconcileOpts(cr)

if rs.Arbiter.Enabled {
rs.Arbiter.MultiAZ.reconcileOpts()
rs.Arbiter.MultiAZ.reconcileOpts(cr)
}

if !cr.Spec.UnsafeConf && cr.DeletionTimestamp == nil {
Expand Down Expand Up @@ -694,7 +694,7 @@ func (nv *NonVotingSpec) SetDefaults(cr *PerconaServerMongoDB, rs *ReplsetSpec)
nv.ServiceAccountName = WorkloadSA
}

nv.MultiAZ.reconcileOpts()
nv.MultiAZ.reconcileOpts(cr)

if nv.ContainerSecurityContext == nil {
nv.ContainerSecurityContext = rs.ContainerSecurityContext
Expand Down Expand Up @@ -741,8 +741,9 @@ func (rs *ReplsetSpec) setSafeDefaults(log logr.Logger) {
}
}

func (m *MultiAZ) reconcileOpts() {
func (m *MultiAZ) reconcileOpts(cr *PerconaServerMongoDB) {
m.reconcileAffinityOpts()
m.reconcileTopologySpreadConstraints(cr)

if m.PodDisruptionBudget == nil {
defaultMaxUnavailable := intstr.FromInt(1)
Expand Down Expand Up @@ -786,6 +787,24 @@ func (m *MultiAZ) reconcileAffinityOpts() {
}
}

func (m *MultiAZ) reconcileTopologySpreadConstraints(cr *PerconaServerMongoDB) {
if cr.CompareVersion("1.15.0") < 0 {
return
}

for i := range m.TopologySpreadConstraints {
if m.TopologySpreadConstraints[i].MaxSkew == 0 {
m.TopologySpreadConstraints[i].MaxSkew = 1
}
if m.TopologySpreadConstraints[i].TopologyKey == "" {
m.TopologySpreadConstraints[i].TopologyKey = defaultAffinityTopologyKey
}
if m.TopologySpreadConstraints[i].WhenUnsatisfiable == "" {
m.TopologySpreadConstraints[i].WhenUnsatisfiable = corev1.DoNotSchedule
}
}
}

func (v *VolumeSpec) reconcileOpts() error {
if v.EmptyDir == nil && v.HostPath == nil && v.PersistentVolumeClaim.PersistentVolumeClaimSpec == nil {
v.PersistentVolumeClaim.PersistentVolumeClaimSpec = &corev1.PersistentVolumeClaimSpec{}
Expand Down
5 changes: 3 additions & 2 deletions pkg/apis/psmdb/v1/psmdb_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ func TestSetSafeDefault(t *testing.T) {
cr := &api.PerconaServerMongoDB{
ObjectMeta: metav1.ObjectMeta{Name: "psmdb-mock", Namespace: "psmdb"},
Spec: api.PerconaServerMongoDBSpec{
Replsets: []*api.ReplsetSpec{{Name: "rs0", Size: 3}, {Name: "rs1", Size: 3}},
Sharding: api.Sharding{Enabled: true, Mongos: &api.MongosSpec{Size: 3}},
CRVersion: version.Version,
Replsets: []*api.ReplsetSpec{{Name: "rs0", Size: 3}, {Name: "rs1", Size: 3}},
Sharding: api.Sharding{Enabled: true, Mongos: &api.MongosSpec{Size: 3}},
},
}

Expand Down
21 changes: 11 additions & 10 deletions pkg/apis/psmdb/v1/psmdb_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,17 @@ func (spec *PMMSpec) ShouldUseAPIKeyAuth(secret *corev1.Secret) bool {
}

type MultiAZ struct {
Affinity *PodAffinity `json:"affinity,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
PriorityClassName string `json:"priorityClassName,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
PodDisruptionBudget *PodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"`
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
Affinity *PodAffinity `json:"affinity,omitempty"`
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
PriorityClassName string `json:"priorityClassName,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
PodDisruptionBudget *PodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"`
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
RuntimeClassName *string `json:"runtimeClassName,omitempty"`

Resources corev1.ResourceRequirements `json:"resources,omitempty"`

Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/psmdb/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/psmdb/mongos.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func MongosTemplateSpec(cr *api.PerconaServerMongoDB, initImage string, log logr
HostAliases: cr.Spec.Sharding.Mongos.HostAliases,
SecurityContext: cr.Spec.Sharding.Mongos.PodSecurityContext,
Affinity: PodAffinity(cr, cr.Spec.Sharding.Mongos.MultiAZ.Affinity, ls),
TopologySpreadConstraints: PodTopologySpreadConstraints(cr, cr.Spec.Sharding.Mongos.MultiAZ.TopologySpreadConstraints, ls),
NodeSelector: cr.Spec.Sharding.Mongos.MultiAZ.NodeSelector,
Tolerations: cr.Spec.Sharding.Mongos.MultiAZ.Tolerations,
TerminationGracePeriodSeconds: cr.Spec.Sharding.Mongos.MultiAZ.TerminationGracePeriodSeconds,
Expand Down
16 changes: 16 additions & 0 deletions pkg/psmdb/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func StatefulSpec(ctx context.Context, cr *api.PerconaServerMongoDB, replset *ap
HostAliases: replset.HostAliases,
SecurityContext: podSecurityContext,
Affinity: PodAffinity(cr, multiAZ.Affinity, customLabels),
TopologySpreadConstraints: PodTopologySpreadConstraints(cr, multiAZ.TopologySpreadConstraints, customLabels),
NodeSelector: multiAZ.NodeSelector,
Tolerations: multiAZ.Tolerations,
TerminationGracePeriodSeconds: multiAZ.TerminationGracePeriodSeconds,
Expand Down Expand Up @@ -228,6 +229,21 @@ func PodAffinity(cr *api.PerconaServerMongoDB, af *api.PodAffinity, labels map[s
return nil
}

func PodTopologySpreadConstraints(cr *api.PerconaServerMongoDB, tscs []corev1.TopologySpreadConstraint, ls map[string]string) []corev1.TopologySpreadConstraint {
result := make([]corev1.TopologySpreadConstraint, 0, len(tscs))

for _, tsc := range tscs {
if tsc.LabelSelector == nil && tsc.MatchLabelKeys == nil {
tsc.LabelSelector = &metav1.LabelSelector{
MatchLabels: ls,
}
}

result = append(result, tsc)
}
return result
}

func isEncryptionEnabled(cr *api.PerconaServerMongoDB, replset *api.ReplsetSpec) (bool, error) {
enabled, err := replset.Configuration.IsEncryptionEnabled()
if err != nil {
Expand Down
Loading