Invalid spec selector after upgrading helm template

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.

3

Though @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):

  1. ReplicasSets
  2. Deployments
  3. 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.yml

it 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 Kubernetes

I 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-app

So 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.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like