Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

Putting chart version in spec.selector.matchLabels in apps/v1beta2 and later prevents ANY future upgrade of existing Release #7680

Closed
desaintmartin opened this issue Sep 11, 2018 · 11 comments · Fixed by #10121

Comments

@desaintmartin
Copy link
Collaborator

desaintmartin commented Sep 11, 2018

BUG REPORT

tl;dr: any Chart containing Deployment/StatefulSet/DaemonSet apps/v1beta2 or newer using a chart version in a selector or other immutable field can't be upgraded

Edit:
This is the second bug among 3 regarding "I can't upgrade my Release".

Forewords

Immutability

Required selector

This means that for apps/v1beta2 or newer, every change of an existing Deployment, StatefulSet or DaemonSet in spec.selector.mathLabels or other immutable fields will be refused by kubernetes.

The problem

In some charts, we set the chart version (directly or through the chart template) in different parts of the Deployment/StatefulSet/DaemonSet yaml files of the Chart.

This causes helm to attempt to change immutable fields and any upgrade (even if it ONLY change the version in Chart.yaml) will fail.

IN OTHER WORDS, SOME CHARTS OF THIS REPOSITORY ARE DEEPLY BROKEN AND CAN'T BE UPGRADED, only installed once.

Impacted charts

At least, impacted charts are:

How to reproduce (using redis as an example)

For each scenario, disable "cluster" option in values.yaml only for simplicity, install the redis chart using git, change the version in chart.yaml (example: 1.2.3 -> 1.2.4) without changing anything else, and try to upgrade. See it fail, and remove the chart:

cd stable/redis
vim values.yaml
helm install --name redis-test .
vim Chart.yaml
helm upgrade redis-test .
helm delete --purge redis-test

1 - Statefulset apps/v1beta2 or newer: spec.selector

Because of templates/redis-master-statefulset.yaml containing:
chart: {{ template "redis.chart" . }}
into spec.selector and `spec.template.metadata.labels

It will cause:

Error: UPGRADE FAILED: StatefulSet.apps "redis-test-master" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden.

(note that here, metadata.labels.Chart does not cause issue because of explicit selector)

(Edit: previous versions of this issue had other examples, since moved to their own issues)

Let's remove this line, uninstall, then reinstall, upgrade: it works.

Conclusion

tl;dr: don't put fields that may change in selector

This is a really blocking problem, even solving this will require to break impacted charts (major version bump).
The only known workaround is to run kubectl delete cascade=false for offending Deployments, StatefulSets or DaemonSets until this is solved, which only kind of works...

A lot of PRs going the wrong way have been merged lately (see this one as example: #6909)

And a few attempts without really understanding the problems were tried to solve it: #7441

Helm has several related won't-fix issues: helm/helm#2494

cc @mattfarina
cc helm/chart-testing#19 for testing this
cc https://github.com/helm/charts/issues/3011 to document this
cc #5657 to document solving (a.k.a breaking) this

@desaintmartin
Copy link
Collaborator Author

I've edited the issue because it is even wider than I thought: most of v1beta1 charst are broken as well.

@scottrigby
Copy link
Member

scottrigby commented Sep 12, 2018

Thanks for linking this issue to the original k8s PR (kubernetes/kubernetes#50719). In the the charts documentation issue (#7692) I was thinking it may be a good idea to link to the relevant section(s) in the k8s documentation instead, since that’s more readable.

But as I'm looking through the k8s docs, it seems like the details may be a bit complicated, and your findings so far don't seem to match the documentation. For example:

From https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#label-selector-updates:

Note: In API version apps/v1, a Deployment’s label selector is immutable after it gets created.

And also in https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#selector

In API version apps/v1, .spec.selector and .metadata.labels do not default to .spec.template.metadata.labels if not set. So they must be set explicitly. Also note that .spec.selector is immutable after creation of the Deployment in apps/v1.

But your findings show that this happened with Deployment even before apps/v1?

And this doesn't seem to be fully documented on all affected resources (I couldn't find any mention of this for StatefulSet, except a note that pod selectors are now required after k8s 1.8: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-selector).

Anyway, I'm noting this here rather than the documentation issue #7692 because I'm not sure we have correct notes to link to that are consistent with your findings on this problem - they may also not be comprehensive (of all affected resources). This may be a separate k8s documentation issue if it turns out to be the case.

@desaintmartin
Copy link
Collaborator Author

  • Well, the documentation is not clear regarding the impacted version. I can confirm spec.selector.matchLabelsis immutable since apps/v1beta2, in concordance of the linked PR and my own tests. If you see https://v1-8.docs.kubernetes.io/docs/concepts/workloads/controllers/deployment/#label-selector-updates, you'll see that it mentions apps/v1beta2...

  • Let me update the issue with the documentation

  • It is simpler for StatefulSet: everything but a few fields are immutable, at least according to the very explicit error Maybe Kubernetes lack documentation about this. Unfortunately, the API documentation does not state anything about mutability of fields.

  • Finally, for apps/v1beta1 (or extensions/v1beta1) without selector, it is much simpler: helm seems to try to upgrade the spec.template.metadata.labels without updating the (initially generated by kubernetes) spec.selector.matchLabels. We just need to explicitely set spec.selector.matchLabels (in this case, even with chart label) in a minor upgrade. May we separate this into a separate issue?

@desaintmartin
Copy link
Collaborator Author

Issue updated to source from documentation. Still no source for StatefulSet.

@desaintmartin desaintmartin changed the title Putting chart version in metadata.labels, spec.selector.matchLabels or other immutable fields prevent ANY upgrade of existing Release Putting chart version in spec.selector.matchLabels or other immutable fields prevents ANY future upgrade of existing Release Sep 13, 2018
@desaintmartin
Copy link
Collaborator Author

desaintmartin commented Sep 13, 2018

I have updated the whole issue to only focus on the blocking problem regarding apps/v1beta2 and newer.
I created another issue for v1beta1 here: #7726

@desaintmartin desaintmartin changed the title Putting chart version in spec.selector.matchLabels or other immutable fields prevents ANY future upgrade of existing Release Putting chart version in spec.selector.matchLabels or other immutable fields in apps/v1beta2 and later prevents ANY future upgrade of existing Release Sep 18, 2018
@desaintmartin desaintmartin changed the title Putting chart version in spec.selector.matchLabels or other immutable fields in apps/v1beta2 and later prevents ANY future upgrade of existing Release Putting chart version in spec.selector.matchLabels in apps/v1beta2 and later prevents ANY future upgrade of existing Release Sep 18, 2018
@desaintmartin
Copy link
Collaborator Author

Edited to move the volumeClaimTemplate bug to its own issue since it is different than the selector problem: #7803

k8s-ci-robot pushed a commit that referenced this issue Sep 24, 2018
…by removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (#7687)

See #7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
k8s-ci-robot pushed a commit that referenced this issue Sep 24, 2018
…removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (#7686)

Also set a selector to all Deployments.

See #7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
@desaintmartin
Copy link
Collaborator Author

cc @cheyang for horovod.

jicowan pushed a commit to jicowan/charts that referenced this issue Oct 2, 2018
…by removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (helm#7687)

See helm#7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
Signed-off-by: jenkin-x <[email protected]>
Jnig pushed a commit to Jnig/charts that referenced this issue Nov 13, 2018
…by removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (helm#7687)

See helm#7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
Signed-off-by: Jakob Niggel <[email protected]>
Jnig pushed a commit to Jnig/charts that referenced this issue Nov 13, 2018
…removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (helm#7686)

Also set a selector to all Deployments.

See helm#7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
Signed-off-by: Jakob Niggel <[email protected]>
Jnig pushed a commit to Jnig/charts that referenced this issue Nov 13, 2018
@stale
Copy link

stale bot commented Nov 20, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions.

@stale stale bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Nov 20, 2018
@desaintmartin
Copy link
Collaborator Author

AFAIK no more charts have this problem, closing.

@desaintmartin
Copy link
Collaborator Author

Monogodb is still impacted, see their statefulset with .Values.selector.matchLabels.chart.
cc @jkirkham-ratehub @prydonius @tompizmor @sameersbn @carrodher @juan131

@desaintmartin desaintmartin reopened this Dec 18, 2018
@stale stale bot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 18, 2018
@juan131
Copy link
Collaborator

juan131 commented Dec 19, 2018

I just created this PR to fix it @desaintmartin
#10121

wgiddens pushed a commit to wgiddens/charts that referenced this issue Jan 18, 2019
…by removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (helm#7687)

See helm#7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
wgiddens pushed a commit to wgiddens/charts that referenced this issue Jan 18, 2019
…removing 'chart' label from spec.selector or spec.VolumeClaimTemplate. (helm#7686)

Also set a selector to all Deployments.

See helm#7680.

Signed-off-by: Cédric de Saint Martin <[email protected]>
wgiddens pushed a commit to wgiddens/charts that referenced this issue Jan 18, 2019
scottrigby pushed a commit to scottrigby/harbor-helm that referenced this issue Mar 7, 2019
1. Upgrade the Kubernetes API versions to the latest stable ones
2. Remove the mutable label for helm release upgrade, related issue: helm/charts#7680

Signed-off-by: Wenkai Yin <[email protected]>
jmlrt added a commit to jmlrt/helm-charts that referenced this issue May 15, 2020
This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
jmlrt added a commit to elastic/helm-charts that referenced this issue May 18, 2020
…c.selector.matchLabels (#622)

This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
jmlrt added a commit to elastic/helm-charts that referenced this issue May 18, 2020
…c.selector.matchLabels (#622)

This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
jmlrt added a commit to elastic/helm-charts that referenced this issue May 18, 2020
…c.selector.matchLabels (#622)

This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
jmlrt added a commit to elastic/helm-charts that referenced this issue May 18, 2020
…c.selector.matchLabels (#622)

This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
jmlrt added a commit to jmlrt/helm-charts that referenced this issue May 27, 2020
…c.selector.matchLabels (elastic#622)

This fix metricbeat chart upgrades when .Chart.Version change.

UPGRADE FAILED
Error: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
Error: UPGRADE FAILED: Deployment.apps "metricbeat-metricbeat-metrics" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"metricbeat-metricbeat-metrics", "chart":"metricbeat-7.7.0", "heritage":"Tiller", "release":"metricbeat"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

See helm/charts#7680 for more details
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants