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.
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}"
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.
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.