krausshalt

krausshalt

Scheduled jobs in kubernetes

Sometimes it's necessary to have work done not on demand (i.e. with a web service reacting to requests) but rather on a schedule.

What first came to my mind was a constantly running service which does the same as cron is doing on *nix systems. But since we are using kubernetes as our container orchestrator I thought they may be have something in place for my use case, and in fact they do!

In kubernetes world this feature is called "CronJob" and it behaves exactly like the UNIX counterpart.

Boiled down to the basics it's just:

  • a Name
  • a cron schedule string (I'm always using https://crontab.guru/ to make sure I'm doing it right)
  • a Docker image
  • a command (or list of commands) what to do

The only thing to consider is what should happen if the schedule triggers but the execution from the previous run is not yet completed. kubernetes offers you three options known as concurrency policies from which you can choose:

  • Allow (default): The cron job allows concurrently running jobs
  • Forbid: The cron job does not allow concurrent runs; if it is time for a new job run and the previous job run hasn’t finished yet, the cron job skips the new job run
  • Replace: If it is time for a new job run and the previous job run hasn’t finished yet, the cron job replaces the currently running job run with a new job run Source: https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/

And last but not least an example of one of our jobs which runs since months reliable on production:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: job-foo-bar-thing
spec:
  schedule: "*/5 * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: job-foo-bar-thing
            image: {{DOCKER_IMAGE}}
            imagePullPolicy: Always
            env:
              - name: PORT
                value: "80"
              - name: NODE_ENV
                value: {{NODE_ENV}}
              - name: LOG_LEVEL
                value: {{LOG_LEVEL}}

            args:
            - npm
            - start
          restartPolicy: Never