Kubernetes Jobs
are useful for one-off tasks. However, there are some problems when
you have to define sidecar containers
in your job spec. Primarily, the job's pod will not terminate
when the sidecar containers are still running. If your sidecar container is a
logging agent or a proxy for other services,
they usually do not terminate. Furthermore, the sidecar container must terminate
with an exit code of 0
or else the job may restart.
One suggested solution is to have a script watch for the creation of a file on a shared volume. When the script detects a file, the script will terminate the container. For instance, here is a sample job spec which waits for a file to be created in a shared volume in a sidecar container:
apiVersion: v1
kind: ConfigMap
metadata:
name: watchfile-config-map
labels:
name: watchfile-config-map
data:
watchfile.sh: |-
apk update && apk add inotify-tools
echo "waiting for file..."
file=/var/lib/sharedwatchfile/file.unlock
while [ ! -f "$file" ]
do
inotifywait -qqt 10 -e create -e moved_to "$(dirname $file)"
done
echo "found file"
---
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
template:
spec:
containers:
- name: db-migration
image: <your job image>
command: ["/bin/sh",
"-c",
"<run db migration script> && touch /var/lib/sharedwatchfile/file.unlock"]
volumeMounts:
- name: varlibsharedwatchfile
mountPath: /var/lib/sharedwatchfile
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/bin/sh",
"-c",
"/cloud_sql_proxy -instances=<your db instance>=tcp:5432 -credential_file=/secrets/cloudsql/credentials.json & /bin/sh /var/lib/watchfile/watchfile.sh"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: varlibwatchfile
mountPath: /var/lib/watchfile
readOnly: true
- name: varlibsharedwatchfile
mountPath: /var/lib/sharedwatchfile
readOnly: true
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: sql-kubernetes-proxy-credentials
- name: varlibwatchfile
configMap:
name: watchfile-config-map
items:
- key: watchfile.sh
path: watchfile.sh
- name: varlibsharedwatchfile
restartPolicy: Never
backoffLimit: 4
The usage of inotifywait
is to be a bit more efficient than just using
sleep
. In the above example, instead of modifying an existing image,
the commands to run the sidecar container are slightly modified and a script is
mounted via a volume to the sidecar container.
While watching for a file to be created is not exactly ideal, it is a quick workable hack until a general solution is available.