In my application, I have a control plane component which spawns Jobs on my k8s cluster. I'd like to be able to pass in a dynamically generated (but read-only) config file to each Job. The config file will be different for each Job.
One way to do that would be to create, for each new Job, a ConfigMap containing the desired contents of the config file, and then set the ConfigMap as a VolumeMount in the Job spec when launching the Job. But now I have two entities in the cluster which are semantically tied together but don't share a lifetime, i.e. if the Job ends, the ConfigMap won't automatically go away.
Is there a way to directly "mount a string" into the Job's Pod, without separately creating some backing entity like a ConfigMap to store it? I could pass it in as an environment variable, I guess, but that seems fragile due to length restrictions.
If you want to work around using configmaps and environment variables for passing configuration, the options you are left with are command line arguments and configuration files.
You can pass the config as command line argument to each of your Job.
You can also mount the config as file in to your Job pod. But since your controller which generates the config and Job which consumes it might be running on different nodes, you need a way to pass the config to the Job pod. If you have a network attached storage which is accessible for all nodes, your controller can write to location on shared storage and Job can read from it. Else, if you have a service(database, cache etc) that can act like a data store, your controller can write to the datastore and Job can read from there.
If you do not want to modify your Job to read the config from various sources, you can have an initContainer which does the job of reading the configuration from a certain source and writes it to a local pod volume(emptyDir) and Job can just read from the local file.
The way that is traditionally done is via an initContainer
and an emptyDir
volumeMount
that allows the two containers to "communicate" over a private shared piece of disk:
spec:
initContainers:
- name: config-gen
image: docker.io/library/busybox:latest
command:
- /bin/sh
- -ec
# now you can use whatever magick you wish to generate the config
- |
echo "my-config: is-generated" > /generated/sample.yaml
echo "some-env: ${SOME_CONFIG}" >> /generated/sample.yaml
env:
- name: SOME_CONFIG
value: subject to injection like any other kubernetes env var
volumeMounts:
- name: shared-space
mountPath: /generated
containers:
- name: main
image: docker.example.com:1234
# now you can do whatever you want with the config file
command:
- /bin/cat
- /config/sample.yaml
volumeMounts:
- name: shared-space
mountPath: /config
volumes:
- name: shared-space
emptyDir: {}