I've upgraded helm templates (by hand)
Fragment of previous depoloyment.yaml:
apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ template "measurement-collector.fullname" . }} labels: app: {{ template "measurement-collector.name" . }} chart: {{ template "measurement-collector.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ template "measurement-collector.name" . }} release: {{ .Release.Name }}New one:
apiVersion: apps/v1beta2
kind: Deployment
metadata: name: {{ include "measurement-collector.fullname" . }} labels: {{ include "measurement-collector.name" . }} {{ include "measurement-collector.chart" . }} {{ .Release.Name }} {{ .Release.Service }}
spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{ include "measurement-collector.name" . }} {{ .Release.Name }}new service.yaml:
name: {{ include "measurement-collector.fullname" . }} labels: {{ include "measurement-collector.name" . }} {{ include "measurement-collector.chart" . }} {{ .Release.Name }} {{ .Release.Service }}
spec: type: {{ .Values.service.type }} ports: protocol: TCP name: http selector: {{ include "measurement-collector.name" . }} {{ .Release.Name }}Then after running: helm upgrade -i measurement-collector chart/measurement-collector --namespace prod --wait
I get:
Error: UPGRADE FAILED: Deployment.apps "measurement-collector" is invalid: spec.selector: Invalid value:
v1.LabelSelector{MatchLabels:map[string]string{"":"measurement-collector", "":"measurement-collector"},
MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable 1 3 Answers
If you change the selector label, then you will need to purge the release first before deploying.
3Though @TigerBear answer is correct, I think I need to explain it in a little bit more details. This problem is caused by a simple reason - immutability of the selectors. You cannot update selectors for (I am not sure this is the complete list, feel free to correct me):
- ReplicasSets
- Deployments
- DaemonSets
In other words, for example if you have a Deployment with label 'my-app: ABC' within selectors, after that you have updated label inside selector onto this: 'my-app: XYZ', and then simply applied this changes, e.g. like this:
kubectl apply -f deployment-file-name.ymlit will not work - you have to recreate the deployment.
Related github k8s issue, also there is a little note about it in the Deployment doc
The other answers are correct but I didn't understand them because I was dealing with a helm chart. In my case, I changed the helm chart name and got a similar error.
The change I made in my helm/Chart.yaml was
apiVersion: v2
name: my-app ==> was changed to ==> my-new-app
description: A Helm chart for KubernetesI didn't realize that that change is used to name other things in the template. In particular, the deployment was changed as well. For example,
# Source: my-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec: replicas: 1 selector: matchLabels: my-app <<< THIS became my-new-app my-app <<< THIS became my-new-appSo the error was actually related to something that I didn't directly edit, which is why (to me) the error message was confusing.
By changing the Chart Name the selector was changed and that is not allowed when running helm upgrade. I also realize the underlying reason helm upgrade fails is because kubernetes doesn't support this.