Reputation: 1633
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.
Upvotes: 24
Views: 48581
Reputation: 1272
I got field is immutable error
when I tried to run jobs in my cluster with the following command:
$ kubectl apply -f config.yml
where config.yml
was defined as follows:
apiVersion: batch/v1
kind: Job
metadata:
name: my-job-name
spec:
# (...)
It worked for the first time, but the other ones with modified parameters did not. Turned out the completed job was not deleted automatically and it still figured in the job list:
$ kubectl get jobs | grep my-job-name
my-job-name 1/1 4m29s 22h
So, you have to delete the old one as follows:
$ kubectl delete job my-job-name
Now you can send a new job with the same name using kubectl apply -f config.yml
.
EDIT As @CloudWatcher said in his comment, this can apparently hit different resource types. In his case, it was a secret that needed deletion.
Upvotes: 12
Reputation: 731
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.
Upvotes: 35
Reputation: 1633
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}"
Upvotes: 1
Reputation: 61651
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.
Upvotes: 3