Skip to content

Commit

Permalink
Merge pull request #43 from worldiety/feature/cronjobs
Browse files Browse the repository at this point in the history
Add support for generic cronjobs
  • Loading branch information
fredlahde authored Apr 23, 2024
2 parents a931952 + 68e5551 commit 66724b7
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 127 deletions.
64 changes: 34 additions & 30 deletions project-template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,39 @@ found within this repository.
This section describes the values that could or must be overwritten by your project. Most of these
values do not need to be changed or will be already applied if you are using the default CI pipeline.

#### cronjob

Normally, this chart deploys your application with a deployment. Thus it will run forever.
If you instead want to deploy a short, repeating and planned task, this option is for you.

For deploying a cronjob you need to provide a cron schedule:

```yaml
cronjob:
schedule: "0 4 * * *"
````

This config will deploy a CronJob API object instead of a deployment. In addition, no service, ingress and pod disruption budget will be deployed.
You can supply additional flags:

- `concurrencyPolicy` : Configures whether jobs are allowed to run concurrently. Default: `Forbid`. [See here for more info](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#concurrency-policy)
- `successfulJobsHistoryLimit` : Configures how many successful jobs shoud be kept. Default: 5. [See here for more info](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#jobs-history-limits)
- `failedJobsHistoryLimit ` : Configures whether jobs are allowed to run concurrently. Default: 5. [See here for more info](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#jobs-history-limits)
- `startingDeadlineSeconds ` : Configures how long after the initial deadline a job is allowed to be scheduled. Default: Not defined. [See here for more info](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#jobs-history-limits)
- `suspend`: Set this to `true` to instruct the cronjob to stop spawning jobs [See here for more info](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#schedule-suspension)

The following is an example cronjob configuration with all possible flags set:

```yaml
cronjob:
concurrencyPolicy: Forbid
schedule: "0 4 * * *"
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 5
startingDeadlineSeconds: 3600
suspend: false
```

#### name

Set a name for the object, which will be deployed to the cluster. It must be unique within a namespace. This name will applied to each object (deployment, service, ingress etc.) in the cluster, which is created by the chart.
Expand Down Expand Up @@ -286,36 +319,6 @@ and add the buildtype's for the stages, where the crawling should be disabled.

> **OPTIONAL** - Default: Crawling on each stage

#### mysqlBackup

If set a [k8s CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) will be created.
It will backup each database and sends the backup to the `sshStorageUrl`.

The [mysql-scp-backup](https://github.com/worldiety/mysql-scp-backup) Docker Container will be used in this cronjob.
This container supports multiple MySQL versions, e.g. 5.7 and 8+ (update-to-date).
Choose your `containerImageTag` variable according to the information in the [mysql-scp-backup](https://github.com/worldiety/mysql-scp-backup) README.
You use [this script](https://github.com/worldiety/mysql-scp-backup/blob/main/create-keys.sh) to create a new ssh keypair and persist it on your storage provider.

mysqlBackup:
# cron string: https://crontab.guru/#30_4_*_*_*
schedule: "30 4 * * *"
# for mysql 5.7 this might be changed according to: https://github.com/worldiety/mysql-scp-backup
containerImageTag: "0.0.5"
# db host will be created automatically, e.g. SERVICE.NAMESPACE.svc.cluster.local
dbPort: 3306
dbUser: backup-username
dbPassword: "${DB_PASSWORD}"
dbNames: database1,database2
backupsToKeep: 2
sshStorageUrl: [email protected]
sshBase64PrivateKey: "${SSH_BASE64_PRIVATE_KEY}"
sshBase64PPublicKey: "${SSH_BASE64_PUBLIC_KEY}"
skipBackupOnBuildTypes:
- dev
- stage

> **OPTIONAL** - Default: No CronJob (e.g. backup) will be created.
#### priorityClasses

In situations when the cluster or this namespace runs out of CPU/RAM ressources,
Expand All @@ -329,3 +332,4 @@ setting the `priorityClasses` in your `deployment-values.yaml` file.
prod: wdy-production

> **OPTIONAL** - Default: The mappings from above will be applied.

8 changes: 0 additions & 8 deletions project-template/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,6 @@ List of environment variables.
{{- end}}
{{- end }}

{{/*
Creates the cronjob env vars secret name.
*/}}
{{- define "project-template.cronjob-environment-variables-secret-name" -}}
{{- $fullName := include "project-template.fullname" . -}}
{{- printf "%s-cronjob-env-vars-secret-name" $fullName -}}
{{- end -}}

{{/*
Get and validate the PriorityClassName values.
Default values are set in the `values.yaml` of this Helm Chart
Expand Down

This file was deleted.

173 changes: 110 additions & 63 deletions project-template/templates/cronjob.yaml
Original file line number Diff line number Diff line change
@@ -1,77 +1,124 @@
{{- $buildtype := .Values.buildtype -}}
{{- $shouldCreateCronJob := true -}}
{{- if .Values.mysqlBackup -}}
{{ range $val := .Values.mysqlBackup.skipBackupOnBuildTypes }}
{{- if eq $val $buildtype -}}
{{- $shouldCreateCronJob = false -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $buildType := .Values.buildtype -}}
{{- if .Values.cronjob -}}

{{- if and (.Values.mysqlBackup) ($shouldCreateCronJob) -}}
---
apiVersion: batch/v1
kind: CronJob
metadata:
namespace: {{ include "project-template.namespace" . }}
name: {{ .Values.name | replace "ä" "ae" |replace "ö" "oe" | replace "ü" "ue" }}-mysql-backup
name: {{ .Values.name }}
spec:
schedule: "{{ .Values.mysqlBackup.schedule }}"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
schedule: "{{- .Values.cronjob.schedule -}}"
concurrencyPolicy: {{- .Values.cronjob.concurrencyPolicy | default "Forbid" -}}
successfulJobsHistoryLimit: {{- .Values.cronjob.successfulJobsHistoryLimit | default "5" -}}
failedJobsHistoryLimit: {{- .Values.cronjob.failedJobsHistoryLimit | default "5" -}}
{{- if .Values.cronjob.startingDeadlineSeconds -}}
startingDeadlineSeconds: {{- .Values.cronjob.startingDeadlineSeconds -}}
{{- end -}}
suspend: {{ .Values.cronjob.suspend | default false }}
jobTemplate:
spec:
template:
metadata:
labels:
{{- include "project-template.selectorLabels" . | nindent 14 }}
spec:
serviceAccountName: {{ include "project-template.namespace" . }}-user
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsGroup: 1000
runAsUser: 1000
fsGroup: 1000
{{- if .Values.gitlabImage }}
imagePullSecrets:
- name: {{ include "project-template.image-pull-secret-name" . }}
{{- end }}
priorityClassName: {{ include "project-template.get-priorityClassName" . }}
restartPolicy: Never
containers:
- name: {{ include "project-template.fullname" . }}-{{ $buildtype }}-mysql-scp-backup
image: worldiety/mysql-scp-backup:{{ .Values.mysqlBackup.containerImageTag }}
volumeMounts:
- mountPath: /tmp
name: {{ include "project-template.fullname" . }}-{{ $buildtype }}-cronjob-tmp-folder
imagePullPolicy: IfNotPresent
env:
# all configuration options can be found: https://github.com/worldiety/mysql-scp-backup
- name: DB_HOST
# value: SERVICE.NAMESPACE.svc.cluster.local
value: {{ include "project-template.fullname" . }}.{{ include "project-template.namespace" . }}.svc.cluster.local
- name: DB_PORT
value: "{{ .Values.mysqlBackup.dbPort }}"
- name: DB_USER
value: {{ .Values.mysqlBackup.dbUser }}
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "project-template.cronjob-environment-variables-secret-name" . }}
key: DB_PASSWORD
- name: DB_NAMES
value: {{ .Values.mysqlBackup.dbNames }}
- name: SERVICE_NAME
value: {{ include "project-template.fullname" . }}
- name: TEMP_LOCATION
value: /tmp
- name: BACKUPS_TO_KEEP
value: "{{ .Values.mysqlBackup.backupsToKeep }}"
- name: SSH_STORAGE_URL
value: {{ .Values.mysqlBackup.sshStorageUrl }}
- name: SSH_BASE64_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: {{ include "project-template.cronjob-environment-variables-secret-name" . }}
key: SSH_BASE64_PRIVATE_KEY
- name: SSH_BASE64_PUBLIC_KEY
valueFrom:
secretKeyRef:
name: {{ include "project-template.cronjob-environment-variables-secret-name" . }}
key: SSH_BASE64_PUBLIC_KEY
restartPolicy: OnFailure
- name: {{ .Values.name }}
{{- if .Values.dockerhubImage }}
image: {{ .Values.dockerhubImage | quote }}
{{- else }}
image: {{ printf "%s:%s" .Values.gitlabImage.repository .Values.gitlabImage.tag }}
{{- end }}
{{- if .Values.probe -}}
livenessProbe:
httpGet:
path: {{ .Values.probe.path }}
{{- if .Values.probe.port }}
port: {{ .Values.probe.port }}
{{- else -}}
port: {{ .Values.containerPort }}
{{- end -}}
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: {{ .Values.probe.path }}
{{- if .Values.probe.port }}
port: {{ .Values.probe.port }}
{{- else }}
port: {{ .Values.containerPort }}
{{- end }}
failureThreshold: 30
periodSeconds: 10
{{ end }}
# We do not need to specify a pullPolicy, because we want to use the default behaviour:
# Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
# ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
#
# We want to always pull the image, because we might use dev/stage/prod as image tags, not only 'latest'
# The DEBUG_imagePullPolicy variable is for testing this chart locally with minikube and *not* intendetd to be used
# in production
imagePullPolicy: {{ .Values.DEBUG_imagePullPolicy | default "Always" }}
volumeMounts:
{{- if .Values.persistentVolumes }}
{{- range .Values.persistentVolumes }}
- mountPath: {{ .path }}
name: {{ .name }}-{{ $buildType }}-folder
{{- end }}
{{- end }}
{{- if .Values.temporaryVolumes -}}
{{- range .Values.temporaryVolumes }}
- mountPath: {{ .path }}
name: {{ .name }}-{{ $buildType }}-folder
{{- end }}
{{- end }}
ports:
{{- if .Values.containerPort }}
- containerPort: {{ .Values.containerPort }}
name: http
{{- else }}
{{- range $key, $val := .Values.ports }}
- containerPort: {{ $val.container }}
name: {{ $key }}
{{- end }}
{{- end }}
resources:
{{- if .Values.resources -}}
{{- toYaml .Values.resources | nindent 16 }}
{{- end }}
env:
{{- include "project-template.environment-variables-list" . | indent 16 }}
securityContext:
readOnlyRootFilesystem: true
privileged: false
allowPrivilegeEscalation: false
capabilities:
drop:
- all
volumes:
- name: {{ include "project-template.fullname" . }}-{{ $buildtype }}-cronjob-tmp-folder
{{- if .Values.persistentVolumes -}}
{{ range .Values.persistentVolumes }}
- name: {{ .name }}-{{ $buildType }}-folder
persistentVolumeClaim:
claimName: {{ .name }}-{{ $buildType }}-folder
{{ end }}
{{- end }}

{{- if .Values.temporaryVolumes -}}
{{ range .Values.temporaryVolumes }}
- name: {{ .name }}-{{ $buildType }}-folder
emptyDir: {}
# Specifies the number of retries before marking this job failed.
backoffLimit: 5
{{ end }}
{{ end }}
{{ end }}
{{- end -}}
4 changes: 3 additions & 1 deletion project-template/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if not .Values.cronjob -}}
{{ $buildType := .Values.buildtype }}
apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -119,4 +120,5 @@ spec:
- name: {{ .name }}-{{ $buildType }}-folder
emptyDir: {}
{{ end }}
{{ end }}
{{ end }}
{{- end -}}
2 changes: 2 additions & 0 deletions project-template/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if not .Values.cronjob -}}
{{- if .Values.servePublicly -}}
{{- $buildtype := .Values.buildtype -}}
apiVersion: networking.k8s.io/v1
Expand Down Expand Up @@ -38,3 +39,4 @@ spec:
port:
number: 80
{{ end }}
{{ end }}
2 changes: 2 additions & 0 deletions project-template/templates/pod-disruption-budget.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if not .Values.cronjob -}}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
Expand All @@ -20,3 +21,4 @@ spec:
selector:
matchLabels:
{{- include "project-template.selectorLabels" . | nindent 6 }}
{{- end -}}
2 changes: 2 additions & 0 deletions project-template/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if not .Values.cronjob -}}
apiVersion: v1
kind: Service
metadata:
Expand All @@ -23,3 +24,4 @@ spec:
{{- end }}
selector:
{{- include "project-template.selectorLabels" . | nindent 8 }}
{{- end -}}

0 comments on commit 66724b7

Please sign in to comment.