Remove team from statefulset selector (#271)

* Remove 'team' label from the statefulset selector.

I was never supposed to be there, but implicitely statefulset
creates a selector out of meta.labels field. That is the problem
with recent Kubernetes, since statefulset cannot pick up pods
with non-matching label selectors, and we rely on statefulset
picking up old pods after statefulset replacement.

Make sure selector changes trigger replacement of the statefulset.

In the case new selector has more labels than the old one nothing
should be done with a statefulset, otherwise the new statefulset
won't see orphaned pods from the old one, as they won't match the
selector. 

See https://github.com/kubernetes/kubernetes/issues/46901#issuecomment-356418393
This commit is contained in:
Oleksii Kliukin 2018-04-06 13:58:47 +02:00 committed by GitHub
parent c44cd9e4e6
commit 9bf80afa6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 0 deletions

View File

@ -340,6 +340,20 @@ func (c *Cluster) compareStatefulSetWith(statefulSet *v1beta1.StatefulSet) *comp
needsRollUpdate = true
reasons = append(reasons, "new statefulset's metadata labels doesn't match the current one")
}
if (c.Statefulset.Spec.Selector != nil) && (statefulSet.Spec.Selector != nil) {
if !reflect.DeepEqual(c.Statefulset.Spec.Selector.MatchLabels, statefulSet.Spec.Selector.MatchLabels) {
// forbid introducing new labels in the selector on the new statefulset, as it would cripple replacements
// due to the fact that the new statefulset won't be able to pick up old pods with non-matching labels.
if !util.MapContains(c.Statefulset.Spec.Selector.MatchLabels, statefulSet.Spec.Selector.MatchLabels) {
c.logger.Warningf("new statefulset introduces extra labels in the label selector, cannot continue")
return &compareStatefulsetResult{}
}
}
needsReplace = true
needsRollUpdate = true
reasons = append(reasons, "new statefulset's selector doesn't match the current one")
}
if !reflect.DeepEqual(c.Statefulset.Spec.Template.Annotations, statefulSet.Spec.Template.Annotations) {
needsRollUpdate = true
needsReplace = true

View File

@ -564,6 +564,7 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
},
Spec: v1beta1.StatefulSetSpec{
Replicas: &numberOfInstances,
Selector: c.labelsSelector(),
ServiceName: c.serviceName(Master),
Template: *podTemplate,
VolumeClaimTemplates: []v1.PersistentVolumeClaim{*volumeClaimTemplate},

View File

@ -355,6 +355,10 @@ func (c *Cluster) labelsSet(shouldAddExtraLabels bool) labels.Set {
return labels.Set(lbls)
}
func (c *Cluster) labelsSelector() *metav1.LabelSelector {
return &metav1.LabelSelector{c.labelsSet(false), nil}
}
func (c *Cluster) roleLabelsSet(role PostgresRole) labels.Set {
lbls := c.labelsSet(false)
lbls[c.OpConfig.PodRoleLabel] = string(role)