diff --git a/project-template/README.md b/project-template/README.md index f8cf593..32d95eb 100644 --- a/project-template/README.md +++ b/project-template/README.md @@ -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. @@ -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: USER@USER.your-storagebox.de - 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, @@ -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. + diff --git a/project-template/templates/_helpers.tpl b/project-template/templates/_helpers.tpl index 8e60916..4d3a891 100644 --- a/project-template/templates/_helpers.tpl +++ b/project-template/templates/_helpers.tpl @@ -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 diff --git a/project-template/templates/cronjob-environment-variables-secret.yaml b/project-template/templates/cronjob-environment-variables-secret.yaml deleted file mode 100644 index 91e6211..0000000 --- a/project-template/templates/cronjob-environment-variables-secret.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- $buildtype := .Values.buildtype -}} -{{- $shouldCreateCronJob := true -}} -{{- if .Values.mysqlBackup -}} -{{ range $val := .Values.mysqlBackup.skipBackupOnBuildTypes }} -{{- if eq $val $buildtype -}} -{{- $shouldCreateCronJob = false -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{- if and (.Values.mysqlBackup) ($shouldCreateCronJob) -}} ---- -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - namespace: {{ .Values.namespace }} - name: {{ include "project-template.cronjob-environment-variables-secret-name" . }} - labels: - {{- include "project-template.labels" . | nindent 4 }} -data: - DB_PASSWORD: {{ .Values.mysqlBackup.dbPassword | b64enc }} - SSH_BASE64_PRIVATE_KEY: {{ .Values.mysqlBackup.sshBase64PrivateKey | b64enc }} - SSH_BASE64_PUBLIC_KEY: {{ .Values.mysqlBackup.sshBase64PPublicKey | b64enc }} -{{ end }} \ No newline at end of file diff --git a/project-template/templates/cronjob.yaml b/project-template/templates/cronjob.yaml index 3be28b7..9001a2f 100644 --- a/project-template/templates/cronjob.yaml +++ b/project-template/templates/cronjob.yaml @@ -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 -}} diff --git a/project-template/templates/deployment.yaml b/project-template/templates/deployment.yaml index 05bf209..722c19f 100644 --- a/project-template/templates/deployment.yaml +++ b/project-template/templates/deployment.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.cronjob -}} {{ $buildType := .Values.buildtype }} apiVersion: apps/v1 kind: Deployment @@ -119,4 +120,5 @@ spec: - name: {{ .name }}-{{ $buildType }}-folder emptyDir: {} {{ end }} - {{ end }} \ No newline at end of file + {{ end }} +{{- end -}} diff --git a/project-template/templates/ingress.yaml b/project-template/templates/ingress.yaml index cc26917..04dc760 100644 --- a/project-template/templates/ingress.yaml +++ b/project-template/templates/ingress.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.cronjob -}} {{- if .Values.servePublicly -}} {{- $buildtype := .Values.buildtype -}} apiVersion: networking.k8s.io/v1 @@ -38,3 +39,4 @@ spec: port: number: 80 {{ end }} +{{ end }} diff --git a/project-template/templates/pod-disruption-budget.yaml b/project-template/templates/pod-disruption-budget.yaml index 0020f87..dfe7631 100644 --- a/project-template/templates/pod-disruption-budget.yaml +++ b/project-template/templates/pod-disruption-budget.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.cronjob -}} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -20,3 +21,4 @@ spec: selector: matchLabels: {{- include "project-template.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/project-template/templates/service.yaml b/project-template/templates/service.yaml index 5682b60..aa8db7b 100644 --- a/project-template/templates/service.yaml +++ b/project-template/templates/service.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.cronjob -}} apiVersion: v1 kind: Service metadata: @@ -23,3 +24,4 @@ spec: {{- end }} selector: {{- include "project-template.selectorLabels" . | nindent 8 }} +{{- end -}}