6

"I just want to run a cronjob in Kubernetes in every 10 seconds. what would be the imperative command for that?"

Ishara Nuwan
  • 69
  • 1
  • 1
  • 2

3 Answers3

8

You can’t use CronJob kubernetes object for running less than 1 minute. You might be using the wrong tool for a process that has to run so often. https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/

Create an infinite loop on a Deployment (daemonize it)

You’ll need to use a bash formula (or whatever programming language you like best, Go, Java, Python or Ruby) to make an infinite loop and sleep 10 seconds per each execution inside a Deployment. Here an example with bash/sh:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cronjob-deployment
  labels:
    app: cronjob
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cronjob
  template:
    metadata:
      labels:
        app: cronjob
    spec:
      containers:
      - name: cronjob
        image: busybox
        args:
        - /bin/sh
        - -c
        - while true; do echo call ./script.sh here; sleep 10; done

Create 1 CronJob with several containers

If you still want to use CronJobs you can do it with 6 containers inside the definition. One without delay, and the others with 10, 20, 30, 40 and 50 seconds of delay.

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: no_delay
            image: busybox
            args:
            - /bin/sh
            - -c
            - echo call ./script.sh here
          - name: 10_seconds
            image: busybox
            args:
            - /bin/sh
            - -c
            - sleep 10; echo call ./script.sh here
          - name: 20_seconds
            image: busybox
            args:
            - /bin/sh
            - -c
            - sleep 20; echo call ./script.sh here
          - name: 30_seconds
            image: busybox
            args:
            - /bin/sh
            - -c
            - sleep 30; echo call ./script.sh here
          - name: 40_seconds
            image: busybox
            args:
            - /bin/sh
            - -c
            - sleep 40; echo call ./script.sh here
          - name: 50_seconds
            image: busybox
            args:
            - /bin/sh
            - -c
            - sleep 50; echo call ./script.sh here
          restartPolicy: OnFailure

Of course, one of the problems you might encounter is that your process might be overlapped (runned concurrently at the same time). This will depend on the amount of seconds your process needs to run, and the time kubernetes needs to schedule and create a container.

morhook
  • 685
  • 7
  • 19
  • 1
    It should be mentioned that the "pod" will not be listed as `CronJob` resource. What one could do is to schedule a `CronJob` every minute and within this `CronJob` execute a script every 10 seconds, six times in a row. – Turing85 Aug 15 '20 at 21:04
  • Thanks @Turing85! Updated answer with your good idea. – morhook Aug 15 '20 at 22:25
  • that's more or less similar to daemonizing. – Nick Aug 17 '20 at 12:52
  • Yes! It is. I'll update the main answer with that terminology that seems more correct – morhook Aug 19 '20 at 19:00
4

If your task needs to run that frequently, cron is the wrong tool.

Aside from the fact that it simply won't launch jobs that frequently, you also risk some serious problems if the job takes longer to run than the interval between launches. Rewrite your task to daemonize and run persistently, then launch it from cron if necessary (while making sure that it won't relaunch if it's already running).

Nick
  • 1,882
  • 11
  • 16
1

You can write a script that executes for 6 times with an interval of 10 seconds. and set Kubernetes cron job to run every minute. in that manner, in every minute your script starts running which in turn execute the task in every 10 seconds.

script to run logic in every 10 seconds for 6 times when cron job executes after one minute.

This will print hello world in every 10 seconds for 6 times : #!/bin/bash -x a=0

until [ $a -gt 5 ] do echo "hello world" a=expr $a + 1 sleep 10 done

cronjob sample :

apiVersion: batch/v1beta1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: imagePullPolicy: IfNotPresent command: - /bin/sh - -c - ./sample.sh restartPolicy: OnFailure ~

So in that way your cron job executes in every one minute .which in turns starts your srcipt which runs in every 10 seconds and execute buisness logic for 6 minutes.

This is the idea which you can follow to make cron job work in seconds as Kubernetes does not provide value for scheduling lower than 1 minute.

Although in this approach you need to set the strategy of not overlapping next execution of cron job. for example, if your business logic takes 15 seconds to executes and you are running business logic every 10 seconds 6 times in a minute. As business logic takes 15seconds so ideally, it should run for 4 times rather 6 times in a minute. Accordingly, you need to tweak the repetition inside the script.