OpenShift Cron Jobs provide a way to run programs and scripts on a fixed schedule, without having to rely on services in long lived containers. A new container gets created to execute code for each run of the cron job, and the container gets removed after the code inside of it reports it has finished running and exited successfully. If you're not already familiar with Kubernetes Jobs or cron schedule formatting in general, here is an overview of the available scheduling options:
┌───────────── minute (0 - 59) │ ┌───────────── hour (0 - 23) │ │ ┌───────────── day of month (1 - 31) │ │ │ ┌───────────── month (1 - 12) │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday; │ │ │ │ │ 7 is also Sunday on some systems) │ │ │ │ │ │ │ │ │ │ * * * * * command to executeSo a cron schedule of "30 14 * * 5" would run at 2:30 PM every Friday, according to the timezone the host node is using. In the case of Openshift Online, the nodes are set to use UTC. Cron Jobs will launch containers that behave and run just like any other containers on OpenShift, only these will be deleted as soon as they report a successful completion. They can use secrets, volumeMounts, Image Pull Secrets, any other configuration settings you're used to using in DeploymentConfigs The restartPolicy specifies that the job will keep restarting this container when any failures are encountered during the job's run. This makes it important to ensure your commands, scripts, and programs all exit cleanly, e.g. "exit 0" for bash, "sys.exit(0)" for python, etc. These serve as as one layer of safeguards so the pods don't get stuck in an infinite restart loop.
- apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: report
spec:
schedule: "30 14 * * 5"
jobTemplate:
spec:
template:
metadata:
labels:
parent: "cronjobreport"
spec:
containers:
- name: cronreport
image: "${NAMESPACE}/report-sender-pod:latest"
command: ["/secrets/cronjob.py"]
volumeMounts:
- mountPath: /secrets
name: report-sender-pod-secrets
volumes:
- name: report-sender-pod-secrets
secret:
secretName: report-sender-pod-secrets
restartPolicy: OnFailure
And finally, here is an example of a complete template, containing two separate cron jobs and one long lived container DeploymentConfig:
---
apiVersion: v1
kind: Template
metadata:
creationTimestamp: null
generation: 1
labels:
provider: openshift
report-sender-pod-host: "true"
component: report-sender-pod
name: report-sender-pod
objects:
- apiVersion: v1
kind: ImageStream
metadata:
labels:
template: report-sender-pod
name: "report-sender"
spec:
tags:
- annotations: null
from:
kind: DockerImage
name: "/cron-report-sender/report-sender:latest"
pullSecret:
name: dockercfgjson
importPolicy:
scheduled: true
name: latest
- apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: report
spec:
schedule: "30 14 * * 5"
jobTemplate:
spec:
template:
metadata:
labels:
parent: "cronjobreport"
spec:
containers:
- name: cronreport
image: "${NAMESPACE}/report-sender-pod:latest"
command: ["/secrets/cronjob.py"]
volumeMounts:
- mountPath: /secrets
name: report-sender-pod-secrets
volumes:
- name: report-sender-pod-secrets
secret:
secretName: report-sender-pod-secrets
restartPolicy: OnFailure
- apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: report
spec:
schedule: "05 13 * * 1"
jobTemplate:
spec:
template:
metadata:
labels:
parent: "cronjobreport"
spec:
containers:
- name: cronreport
image: "${NAMESPACE}/report-sender-pod:latest"
command: ["/secrets/cronjob.py"]
volumeMounts:
- mountPath: /secrets
name: report-sender-pod-secrets
volumes:
- name: report-sender-pod-secrets
secret:
secretName: report-sender-pod-secrets
restartPolicy: OnFailure
- apiVersion: v1
kind: DeploymentConfig
metadata:
labels:
template: report-sender-pod
name: report-sender-pod
spec:
replicas: 1
selector:
deploymentconfig: report-sender-pod
strategy:
resources: {}
type: Rolling
template:
metadata:
labels:
deploymentconfig: report-sender-pod
spec:
containers:
- env:
- name: OO_PAUSE_ON_START
value: "false"
image: "report-sender-pod/report-sender-pod:latest"
imagePullPolicy: Always
name: report-sender-pod
resources: {}
securityContext: {}
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /secrets
name: report-sender-pod-secrets
dnsPolicy: ClusterFirst
restartPolicy: Always
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: report-sender-pod-secrets
secret:
secretName: report-sender-pod-secrets
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- report-sender-pod
from:
kind: ImageStreamTag
name: "${PLAT}-report-sender-pod:latest"
type: ImageChange
parameters:
- description: Platform name
name: PLAT
value: rhel7
- description: Project name
name: NAMESPACE
value: cron-report-sender