-
Notifications
You must be signed in to change notification settings - Fork 16.6k
Putting chart version in metadata.labels in a Deployment v1beta1 without selector prevents upgrade #7726
Description
BUG REPORT
Any Chart containing Deployment/StatefulSet/DaemonSet apps/v1beta1 or extensions/v1beta1 without spec.selector
using a chart version in metadata.labels
can't be upgraded.
Note:
This is the first bug among 3 regarding "I can't upgrade my Release".
For the apps/v1beta2 problem, see #7680.
For the immutable volumeClaimTemplate in StatefulSet (any version), see #7803
From the k8s documentation
-
in Deployment/StatefulSet/DaemonSet apps/v1beta1 or extensions/v1beta1, spec.selector is not mandatory.
-
If it is not specified, it is generated from
spec.metadata.labels
-
Source: Official documentation: https://v1-7.docs.kubernetes.io/docs/concepts/workloads/controllers/deployment/
If .spec.selector is unspecified, .spec.selector.matchLabels defaults to .spec.template.metadata.labels
Impacted charts
Probably all of https://github.com/helm/charts/pulls?utf8=%E2%9C%93&q=is%3Apr+%22Add+chart+and+release+labels+in+pods%22+
How to reproduce (using stable/dokuwiki as an example)
Let's install the stable/dokuwiki 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:
cd stable/dokuwiki
helm install --name test .
vim Chart.yaml
helm upgrade test .
Because of metadata.labels in templates/deployment.yaml containing:
chart: {{ template "dokuwiki" . }}
It will fail with:
Error: UPGRADE FAILED: Deployment.apps "test-dokuwiki" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"release":"test", "app":"dokuwiki", "chart":"dokuwiki-2.0.7"}: `selector` does not match template `labels`
I think it comes from the fact that during the initial installation, k8s generated the selector, but during upgrade, both helm and k8s ignore it.
But putting an explicit selector, even if it contains a chart
label, will make it upgradable:
selector:
matchLabels:
app: {{ template "dokuwiki.name" . }}
chart: {{ template "dokuwiki.chart" . }}
release: {{ .Release.Name | quote }}
helm upgrade test .
It works!
Conclusion
- We must always set selector in Deployments/StatefulSets/DaemonSets.
- Selectors can technically contain a
chart
label although it would be not wise as it would break compatibility forapps/v1beta2
and later (see Putting chart version in spec.selector.matchLabels in apps/v1beta2 and later prevents ANY future upgrade of existing Release #7680 ) - Ideally, Helm should be aware of selector (explicit or generated)
- Note that charts using v1beta1, not having explicit selector, and don't have mutable fields (i.e no chart or version) in
spec.template.metadata.labels
are not impacted.
Thankfully, this can be solved using a minor version change.