field is immutable k8s

5/22/2019

I am trying to deploy an application to GCP on kubernetes, however, the deployment fails with the error the job spec is invalid ... the field is immutable.

In the migration job, I have a section of bash in the following format:

args:
        - |
          /cloud_sql_proxy -instances=xxxxxxxxxxx:europe-west1:xxxxxxxxxxx=tcp:5432 -credential_file=/secrets/cloudsql/credentials.json -log_debug_stdout=true &
          CHILD_PID=$!
          (while true; do echo "waiting for termination file"; if [[ -f "/tmp/pod/main-terminated" ]]; then kill ; echo "Killed  as the main container terminated."; fi; sleep 1; done) &
          wait 
          if [[ -f "/tmp/pod/main-terminated" ]]; then exit 0; echo "Job completed. Exiting..."; fi

but when the file is executed, in the yaml on GCP I see that the command has been enclosed in quotes and then it returns the above mention error.

-- David Essien
bash
kubernetes

3 Answers

5/24/2019

So this issue was resolved. I had to wrap the values of the environment variables in the yaml file in quotes. That resolved the issue.

- name: DATABASE_URL:
  value: "${DATABASE_URL}"
-- David Essien
Source: StackOverflow

3/6/2020

I got the message the job spec is invalid ... the field is immutable for a different reason and wanted to briefly share it here.

I was trying to apply this yaml file:

apiVersion: extensions/v1beta1
kind: Deployment
spec:
  selector:
    matchLabels:
      app: application-name
...

Turns out that this yaml was going to replace a previous version of the same Deployment. When I ran kubectl get deployment application-name -o yaml I saw this:

apiVersion: extensions/v1beta1
kind: Deployment
spec:
  selector:
    matchLabels:
      app: application-name
      track: stable
...

Apparently the spec.selector.matchLabels is currently an array, and I was trying to replace that with a single string. My fix was deleting the deployment and re-deploying it.

-- Lukasvan3L
Source: StackOverflow

5/22/2019

If you are using args in a Pod definition it's meant to be an array with single-string items. (It doesn't run the command in a shell) For example:

args:
        - /cloud_sql_proxy
        - -instances
        - ...

or

args:  [ "/cloud_sql_proxy", "-instances", "..." ]

The way to get around this is to run the command in a shell:

command: [ "/bin/sh" ]
args: 
        - -c
        - |
          /cloud_sql_proxy -instances=xxxxxxxxxxx:europe-west1:xxxxxxxxxxx=tcp:5432 -credential_file=/secrets/cloudsql/credentials.json -log_debug_stdout=true &
          CHILD_PID=$!
          (while true; do echo "waiting for termination file"; if [[ -f "/tmp/pod/main-terminated" ]]; then kill ; echo "Killed  as the main container terminated."; fi; sleep 1; done) &
          wait 
          if [[ -f "/tmp/pod/main-terminated" ]]; then exit 0; echo "Job completed. Exiting..."; fi

The quotes(") on the array are for readability, they can be no quotes or single quotes(') too (As seen in the YAML specs)

Hope it helps.

-- Rico
Source: StackOverflow