Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes: Is it possible to mount volumes to a container running as a CronJob?

Tags:

I'm attempting to create a Kubernetes CronJob to run an application every minute.

A prerequisite is that I need to get my application code onto the container that runs within the CronJob. I figure that the best way to do so is to use a persistent volume, a pvclaim, and then defining the volume and mounting it to the container. I've done this successfully with containers running within a Pod, but it appears to be impossible within a CronJob? Here's my attempted configuration:

apiVersion: batch/v2alpha1 kind: CronJob metadata:   name: update_db spec:   volumes:   - name: application-code     persistentVolumeClaim:       claimName: application-code-pv-claim   schedule: "*/1 * * * *"   jobTemplate:     spec:       template:         spec:           containers:           - name: update-fingerprints             image: python:3.6.2-slim             command: ["/bin/bash"]             args: ["-c", "python /client/test.py"]           restartPolicy: OnFailure 

The corresponding error:

error: error validating "cron-applications.yaml": error validating data: found invalid field volumes for v2alpha1.CronJobSpec; if you choose to ignore these errors, turn validation off with --validate=false

I can't find any resources that show that this is possible. So, if not possible, how does one solve the problem of getting application code into a running CronJob?

like image 620
theoneandonly2 Avatar asked Oct 05 '17 05:10

theoneandonly2


People also ask

How do volume mounts work in Kubernetes?

Kubernetes Volumes and volumeMounts The container data in a Pod is deleted or lost when a container crashes or restarts, but when you use a volume, the new container can pick up the data at the state before the container crashes.

Is a CronJob a pod?

To check Cronjob logs, you can list down the cronjob pod and get the logs from the pods in running state or from the finished pods.

What do CronJob resources do in a Kubernetes cluster?

Kubernetes CronJobs As the documentation explains, they are useful for periodic and recurring tasks, like running backups, sending emails, or scheduling individual tasks for a specific time, such as when your cluster is likely to be idle.

Can I mount the host filesystem as a volume in Kubernetes?

Mounting the host filesystem into a container as a volume should keep you up at night if you work with Kubernetes. Let me explain why. What is a “volume”? Since containers should be ephemeral and stateless, they need some way to save data outside of the container.

What happens when a Kubernetes container is restarted?

After a container is restarted, the new container can see all the files that were written to the volume by the previous container. Also, if a pod contains multiple containers, the volume can be used by all of them at once. Now you must have a basic idea on Kubernetes Volumes.

How do I add a volume to a Kubernetes pod?

A volume can be declared in a pod’s Kubernetes yaml manifest. You can specify .spec.volumes along with .spec.containers [*].volumeMounts to specify what kind of volume it is, and where to mount it inside of the container. Here’s an example of a pod that creates a container that mounts the host’s root directory to /host inside of the container.

What problems does the Kubernetes Volume abstraction solve?

One problem is the loss of files when a container crashes. The kubelet restarts the container but with a clean state. A second problem occurs when sharing files between containers running together in a Pod . The Kubernetes volume abstraction solves both of these problems. Familiarity with Pods is suggested.


2 Answers

A CronJob uses a PodTemplate as everything else based on Pods and can use Volumes. You placed your Volume specification directly in the CronJobSpec instead of the PodSpec, use it like this:

apiVersion: batch/v1beta1 kind: CronJob metadata:   name: update-db spec:   schedule: "*/1 * * * *"   jobTemplate:     spec:       template:         spec:           containers:           - name: update-fingerprints             image: python:3.6.2-slim             command: ["/bin/bash"]             args: ["-c", "python /client/test.py"]             volumeMounts:             - name: application-code               mountPath: /where/ever           restartPolicy: OnFailure           volumes:           - name: application-code             persistentVolumeClaim:               claimName: application-code-pv-claim 
like image 67
Simon Tesar Avatar answered Sep 20 '22 22:09

Simon Tesar


For the other question in there: "how does one solve the problem of getting application code into a running CronJob?"

You build your own image that contains the code. This is how it is normally done.

FROM python:3.6.2-slim ADD test.py /client/test.py  CMD ['python','-c','/client/test.py'] 

Build and push to the docker registry.

docker build -t myorg/updatefingerprints docker push myorg/updatefingerprints 

Use this image in the descriptor.

apiVersion: batch/v2alpha1 kind: CronJob metadata:   name: update_db spec:   volumes:   - name: application-code     persistentVolumeClaim:       claimName: application-code-pv-claim   schedule: "*/1 * * * *"   jobTemplate:     spec:       template:         spec:           containers:           - name: update-fingerprints             image: myorg/update-fingerprints             imagePullPolicy: Always           restartPolicy: OnFailure 

This requires thinking quite differently about configuration management and version control.

like image 25
Gudlaugur Egilsson Avatar answered Sep 17 '22 22:09

Gudlaugur Egilsson