From 70afbefbe8e71b47fea43015a0170eccd5c58e39 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 17 Apr 2025 11:54:54 +0100 Subject: [PATCH 1/5] add minimal chart to package etcd backup job --- .pre-commit-config.yaml | 2 +- .yamllint.yaml | 3 + components/etcdbackup/.helmignore | 23 +++++++ components/etcdbackup/Chart.yaml | 5 ++ components/etcdbackup/templates/_helpers.tpl | 48 +++++++++++++ .../etcdbackup/templates/job-etcd-backup.yaml | 68 +++++++++++++++++++ components/etcdbackup/values.yaml | 8 +++ 7 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 components/etcdbackup/.helmignore create mode 100644 components/etcdbackup/Chart.yaml create mode 100644 components/etcdbackup/templates/_helpers.tpl create mode 100644 components/etcdbackup/templates/job-etcd-backup.yaml create mode 100644 components/etcdbackup/values.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93a96c502..096f46a17 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: check-yaml args: - --allow-multiple-documents - exclude: mkdocs.yml + exclude: "mkdocs.yml|etcdbackup/templates/.*" - id: check-yaml name: check-yaml-mkdocs # --unsafe is a workaround for the use of !! in mkdocs.yml diff --git a/.yamllint.yaml b/.yamllint.yaml index d73a31ae6..7556021ae 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -1,5 +1,8 @@ extends: default +ignore: + - components/etcdbackup/templates/ + rules: comments: ignore: .github/workflows/ diff --git a/components/etcdbackup/.helmignore b/components/etcdbackup/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/components/etcdbackup/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/components/etcdbackup/Chart.yaml b/components/etcdbackup/Chart.yaml new file mode 100644 index 000000000..028a1d421 --- /dev/null +++ b/components/etcdbackup/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: etcdbackup +description: Local, periodic backup of etcd +type: application +version: 0.1.0 diff --git a/components/etcdbackup/templates/_helpers.tpl b/components/etcdbackup/templates/_helpers.tpl new file mode 100644 index 000000000..5c119a234 --- /dev/null +++ b/components/etcdbackup/templates/_helpers.tpl @@ -0,0 +1,48 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "etcdbackup.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "etcdbackup.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "etcdbackup.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "etcdbackup.labels" -}} +helm.sh/chart: {{ include "etcdbackup.chart" . }} +{{ include "etcdbackup.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "etcdbackup.selectorLabels" -}} +app.kubernetes.io/name: {{ include "etcdbackup.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/components/etcdbackup/templates/job-etcd-backup.yaml b/components/etcdbackup/templates/job-etcd-backup.yaml new file mode 100644 index 000000000..5b6032f1d --- /dev/null +++ b/components/etcdbackup/templates/job-etcd-backup.yaml @@ -0,0 +1,68 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: etcd-backup-job + namespace: kube-system + labels: + {{- include "etcdbackup.labels" . | nindent 4 }} +spec: + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 5 + jobTemplate: + metadata: + name: etcd-backup-cronjob-run + spec: + completions: 1 + template: + metadata: + name: etcd-backup-job-run + spec: + containers: + - command: + - etcdctl + - --cert=/etc/kubernetes/pki/etcd/server.crt + - --key=/etc/kubernetes/pki/etcd/server.key + - --cacert=/etc/kubernetes/pki/etcd/ca.crt + - --endpoints={{ .Values.backup.endpoint }}:2379 + - snapshot + - save + - /var/backups/{{ .Values.backup.fileName }} + env: + - name: ETCDCTL_API + value: "3" + image: registry.k8s.io/etcd:3.5.15-0 + imagePullPolicy: IfNotPresent + name: snapshot + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/etcd + name: etcd-data + - mountPath: /etc/kubernetes/pki/etcd + name: etcd-certs + - mountPath: /var/backups + name: backups + dnsPolicy: ClusterFirst + nodeName: {{ .Values.backup.nodeName }} + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /etc/kubernetes/pki/etcd + type: "" + name: etcd-certs + - hostPath: + path: /var/lib/etcd + type: "" + name: etcd-data + - hostPath: + path: /var/backups + type: "" + name: backups + ttlSecondsAfterFinished: 604800 + schedule: 0 0 * * * + successfulJobsHistoryLimit: 3 + suspend: false diff --git a/components/etcdbackup/values.yaml b/components/etcdbackup/values.yaml new file mode 100644 index 000000000..88ec82d78 --- /dev/null +++ b/components/etcdbackup/values.yaml @@ -0,0 +1,8 @@ +backup: + # hostPath where the backups are to be stored + backupPath: /var/backups/ + # node on which the etcd backup job will be scheduled + nodeName: controlPlane1 + # IP address of the nodeName + endpoint: 127.0.0.1 + fileName: mycluster.etcd.snapshot From d547ebb8aa8ab077d27eee90492e62456ec8d362 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 17 Apr 2025 12:04:10 +0100 Subject: [PATCH 2/5] add etcdbackup component --- apps/appsets/components.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/appsets/components.yaml b/apps/appsets/components.yaml index b6790a710..a851e4da5 100644 --- a/apps/appsets/components.yaml +++ b/apps/appsets/components.yaml @@ -178,6 +178,22 @@ spec: - repoURL: '{{index .metadata.annotations "uc_repo_git_url"}}' targetRevision: '{{index .metadata.annotations "uc_repo_ref"}}' path: 'components/chrony' + - component: etcdbackup + componentNamespace: kube-system + skipComponent: '{{has "etcdbackup" ((default "[]" (index .metadata.annotations "uc_skip_components") | fromJson))}}' + sources: + - repoURL: '{{index .metadata.annotations "uc_repo_git_url"}}' + targetRevision: '{{index .metadata.annotations "uc_repo_ref"}}' + path: 'components/etcdbackup' + ref: understack + helm: + valueFiles: + - $understack/components/etcdbackup/values.yaml + - $deploy/{{.name}}/helm-configs/etcdbackup.yaml + ignoreMissingValueFiles: true + - repoURL: '{{index .metadata.annotations "uc_deploy_git_url"}}' + targetRevision: '{{index .metadata.annotations "uc_deploy_ref"}}' + ref: deploy - component: openstack-exporter componentNamespace: monitoring skipComponent: '{{has "openstack-exporter" ((default "[]" (index .metadata.annotations "uc_skip_components") | fromJson))}}' From d43ed87d3457d85480f6e63bca35c094cef75df8 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 17 Apr 2025 12:07:30 +0100 Subject: [PATCH 3/5] etcdbackup: switch to host networking This removes option to customise the etcd endpoint used for backups. We always want to backup just the local host so it was not really needed. --- components/etcdbackup/templates/job-etcd-backup.yaml | 3 ++- components/etcdbackup/values.yaml | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/components/etcdbackup/templates/job-etcd-backup.yaml b/components/etcdbackup/templates/job-etcd-backup.yaml index 5b6032f1d..f802dfc74 100644 --- a/components/etcdbackup/templates/job-etcd-backup.yaml +++ b/components/etcdbackup/templates/job-etcd-backup.yaml @@ -23,7 +23,7 @@ spec: - --cert=/etc/kubernetes/pki/etcd/server.crt - --key=/etc/kubernetes/pki/etcd/server.key - --cacert=/etc/kubernetes/pki/etcd/ca.crt - - --endpoints={{ .Values.backup.endpoint }}:2379 + - --endpoints=127.0.0.1:2379 - snapshot - save - /var/backups/{{ .Values.backup.fileName }} @@ -45,6 +45,7 @@ spec: name: backups dnsPolicy: ClusterFirst nodeName: {{ .Values.backup.nodeName }} + hostNetwork: true restartPolicy: OnFailure schedulerName: default-scheduler securityContext: {} diff --git a/components/etcdbackup/values.yaml b/components/etcdbackup/values.yaml index 88ec82d78..0bb77f33e 100644 --- a/components/etcdbackup/values.yaml +++ b/components/etcdbackup/values.yaml @@ -1,8 +1,6 @@ backup: # hostPath where the backups are to be stored backupPath: /var/backups/ - # node on which the etcd backup job will be scheduled + # node on which the etcd backup job will be scheduled to nodeName: controlPlane1 - # IP address of the nodeName - endpoint: 127.0.0.1 fileName: mycluster.etcd.snapshot From 95540be5fe3df84571e084e178e8cc8c33be0f2e Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Mon, 28 Apr 2025 18:17:34 +0100 Subject: [PATCH 4/5] etcdbackup: rename .yaml to .tpl --- .pre-commit-config.yaml | 2 +- .../{job-etcd-backup.yaml => job-etcd-backup.yaml.tpl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename components/etcdbackup/templates/{job-etcd-backup.yaml => job-etcd-backup.yaml.tpl} (100%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 096f46a17..e1c976cff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: check-yaml args: - --allow-multiple-documents - exclude: "mkdocs.yml|etcdbackup/templates/.*" + exclude: "mkdocs.yml" - id: check-yaml name: check-yaml-mkdocs # --unsafe is a workaround for the use of !! in mkdocs.yml diff --git a/components/etcdbackup/templates/job-etcd-backup.yaml b/components/etcdbackup/templates/job-etcd-backup.yaml.tpl similarity index 100% rename from components/etcdbackup/templates/job-etcd-backup.yaml rename to components/etcdbackup/templates/job-etcd-backup.yaml.tpl From 3c674157eed9b1b71b3ab37157abe6f40e5458a8 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Mon, 28 Apr 2025 18:25:10 +0100 Subject: [PATCH 5/5] etcdbackup: move to understack-infra appset --- apps/appsets/appset-understack-infra.yaml | 16 ++++++++++++++++ apps/appsets/components.yaml | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/appsets/appset-understack-infra.yaml b/apps/appsets/appset-understack-infra.yaml index 0d9209321..567255f37 100644 --- a/apps/appsets/appset-understack-infra.yaml +++ b/apps/appsets/appset-understack-infra.yaml @@ -70,6 +70,22 @@ spec: - repoURL: '{{ .values.uc_deploy_git_url }}' targetRevision: '{{ .values.uc_deploy_ref }}' path: '{{.name}}/manifests/cilium' + - component: etcdbackup + componentNamespace: kube-system + skipComponent: '{{has "etcdbackup" (.values.uc_skip_components | fromJson)}}' + sources: + - repoURL: '{{ .values.uc_repo_git_url }}' + targetRevision: '{{ .values.uc_repo_ref }}' + path: 'components/etcdbackup' + ref: understack + helm: + valueFiles: + - $understack/components/etcdbackup/values.yaml + - $deploy/{{.name}}/helm-configs/etcdbackup.yaml + ignoreMissingValueFiles: true + - repoURL: '{{ .values.uc_deploy_git_url }}' + targetRevision: '{{ .values.uc_deploy_ref }}' + ref: deploy selector: # by setting the key in the elements 'skipComponent' to 'true' it will skip installing it # ArgoCD's templating operates with strings so it's the string "true" diff --git a/apps/appsets/components.yaml b/apps/appsets/components.yaml index a851e4da5..b6790a710 100644 --- a/apps/appsets/components.yaml +++ b/apps/appsets/components.yaml @@ -178,22 +178,6 @@ spec: - repoURL: '{{index .metadata.annotations "uc_repo_git_url"}}' targetRevision: '{{index .metadata.annotations "uc_repo_ref"}}' path: 'components/chrony' - - component: etcdbackup - componentNamespace: kube-system - skipComponent: '{{has "etcdbackup" ((default "[]" (index .metadata.annotations "uc_skip_components") | fromJson))}}' - sources: - - repoURL: '{{index .metadata.annotations "uc_repo_git_url"}}' - targetRevision: '{{index .metadata.annotations "uc_repo_ref"}}' - path: 'components/etcdbackup' - ref: understack - helm: - valueFiles: - - $understack/components/etcdbackup/values.yaml - - $deploy/{{.name}}/helm-configs/etcdbackup.yaml - ignoreMissingValueFiles: true - - repoURL: '{{index .metadata.annotations "uc_deploy_git_url"}}' - targetRevision: '{{index .metadata.annotations "uc_deploy_ref"}}' - ref: deploy - component: openstack-exporter componentNamespace: monitoring skipComponent: '{{has "openstack-exporter" ((default "[]" (index .metadata.annotations "uc_skip_components") | fromJson))}}'