Podemos utilizar a forma imperativa para criar um CronJob com o comando create cronjob. O comando abaixo cria um cronograma(schedule) para que o CronJob seja executado a cada um minuto. O Pod criado imprime a data atual no stdout(standard output) usando o comando echo.

$ kubectl create cronjob current-date \\
	--schedule="* * * * *" \\
	--image=nginx \\
  -- /bin/sh -c 'echo "Current date: $(date)"'
	
cronjob.batch/current-date created

O que seria gerado pelo comando acima caso usássemos a flag --dry-run=client?

apiVersion: batch/v1
kind: CronJob
metadata:
  creationTimestamp: null
  name: current-date
spec:
  jobTemplate:
    metadata:
      creationTimestamp: null
      name: current-date
    spec:
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers:
          - command:
            - /bin/sh
            - -c
            - 'echo "Current date: $(date)"'
            image: nginx
            name: current-date
            resources: {}
          restartPolicy: OnFailure
  schedule: '* * * * *'
status: {}

Criando CronJob manualmente acompanhando a documentação do Kubernetes.

# Avaliando API disponivel
$ kubectl api-resources | grep "^cronjobs"
	NAME          SHORTNAMES   APIVERSION  NAMESPACED   KIND
	cronjobs      cj           batch/v1    true         CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-cronjob
  labels:
    section: 06-pod-design
    field: "metadata.labels"
spec:
  schedule: "* * * * *"
  jobTemplate:
    metadata:
      name: my-cronjob-template
      labels:
        field: "spec.jobTemplate.metadata.labels"
    spec:
      template:
        metadata:
          name: my-cronjob-pod
          labels:
            field: "spec.jobTemplate.spec.template.metadata.labels"
        spec:
          containers:
            - image: nginx
              name: nginx
              command: ["/bin/sh", "-c"]
              args: ["echo \\"Current Date: $(date)\\""]
          restartPolicy: Never
      parallelism: 1
      completions: 1

Ao listar os CronJobs com o comando get cronjobs veremos o schedule, a última execução e se o CronJob esta ativo. No momento que o Pod é criado o CronJob passa o status ACTIVE de 0 para 1. É fácil identificar os Pods de um CronJob, eles recebem o nome do CronJob como prefixo.

$ kubectl get cronjobs,pods
	NAME                       SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
	cronjob.batch/my-cronjob   * * * * *   False     1        0s              13m

	NAME                            READY   STATUS              RESTARTS   AGE
	pod/my-cronjob-27527094-7mwcv   0/1     Completed           0          2m
	pod/my-cronjob-27527095-bvxk5   0/1     Completed           0          60s
	pod/my-cronjob-27527096-7pgvp   0/1     ContainerCreating   0          0s

Podemos avaliar os logs de um Pod iniciado pelo CronJob para garantir a corretude da execução

$	kubectl logs pods/my-cronjob-27527091-tws2j
	Current Date: Wed May  4 00:51:02 UTC 2022

O autor disponibiliza um exemplo declarativo do Job equivalente ao que foi criado pelo comando no começo da página.

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: current-date
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: current-date
            image: nginx
            args:
            - /bin/sh
            - -c
            - 'echo "Current date: $(date)"'
          restartPolicy: OnFailure

Documentação Kubernetes

CronJob

Referência de campos para o CronJob.