Summary

    My issue: Create 32 similar crons in a Kubernetes cluster

    Last week, I found myself in front of a refactoring issue. I had a Kubernetes cluster managed with Helm and I had 32 crons to transform into CronJob resources and to create and deploy. All those crons are very similar as they are Symfony commands: they are all based on the app image which is launched with a specific command such as

    bin/console my:first:cron

    I did not want to write 32 Helm templates for two reasons:

    • it is hard to maintain. Let’s imagine I want to add a configMap that applies to all of them, I will need to do it 32 times without error or without forgetting one
    • it is really boring to write.

    One Helm template to rule them all

    Here is a way to do it with only one short file.

    First write one cronjob.yaml using helm :

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
    name: "my-first-cron"
    labels: {{ include "kubernetes.labels" . | indent 4 }}
    spec:
    schedule: "*/10 * * * *"
    successfulJobsHistoryLimit: 0
    jobTemplate:
    spec:
    template:
    spec:
    restartPolicy: Never
    containers:
    - image: "{{ .Values.cronjob.repository }}:{{ .Values.image.tag }}"
    name: "my-first-cron"
    args:
    - sh
    - -c
    - |
    sleep 2s
    "./bin/console --env=prod my:first:comand"
    sleep 30
    imagePullPolicy:{{ .Values.image.pullPolicy }}
    ports:
    - name: http
    containerPort: 80
    protocol: TCPn

    And then use the `range` instruction for iterative resource creation:

    {{- range $job, $val := .Values.cronjob.crons }}
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
    name: {{ .name }}
    labels: {{ include "kubernetes.labels" $ | indent 4 }}
    spec:
    schedule: {{ .schedule | quote}}
    successfulJobsHistoryLimit: 0
    jobTemplate:
    spec:
    template:
    spec:
    restartPolicy: Never
    containers:
    - image: "{{ $.Values.cronjob.repository }}:{{ $.Values.image.tag }}"
    name: {{ .name }}
    args:
    - sh
    - -c
    - |
    sleep 2s
    "./bin/console --env=prod {{ .command}}"
    sleep 30
    imagePullPolicy: {{ $.Values.image.pullPolicy }}
    ports:
    - name: http
    containerPort: 80
    protocol: TCP
    ---
    {{- end}}

    Finally modify your values.yaml the following way:

    cronjob:
    repository: XXXX
    crons:
    "0":
    name: my-first-cron
    command: my:first:cron
    schedule: "*/10 * * * *"
    "1":
    name: my-second-cron
    command: my:second:cron
    schedule: "*/3 * * * *"

    Here are two things I wish to outline:

    • Usually to use values stored in your values.yaml file, you do it this way :

      .Values.XXX.XXX.

      However, inside the `range` instruction, you need to call it this way

      $.Values.XXX.XXX

    • The 3 dashes at the end are important otherwise, only the last cron of your list will be launched.

    I hope this article helps you, don’t hesitate to leave us feedbacks!

    If you want to know more about CronJob resource, here is the documentation link or about Helm, here is the Getting Started page.{{cta('49e69293-1ec9-4d4c-acd4-3604703ed444','justifycenter')}}