apiVersion: v1 kind: Secret metadata: name: kubeone-backups-credentials namespace: kube-system type: Opaque data: AWS_ACCESS_KEY_ID: {{ required "Please provide AWS_ACCESS_KEY_ID" .Credentials.AWS_ACCESS_KEY_ID | b64enc }} AWS_SECRET_ACCESS_KEY: {{ required "Please provide AWS_SECRET_ACCESS_KEY" .Credentials.AWS_SECRET_ACCESS_KEY | b64enc }} --- apiVersion: v1 kind: Secret metadata: name: restic-config namespace: kube-system type: Opaque data: password: {{ required "Please provide resticPassword" .Params.resticPassword | b64enc }} --- apiVersion: batch/v1 kind: CronJob metadata: name: etcd-s3-backup namespace: kube-system spec: concurrencyPolicy: Forbid failedJobsHistoryLimit: 1 schedule: '@every 30m' successfulJobsHistoryLimit: 0 suspend: false jobTemplate: spec: template: spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule operator: Exists - key: node-role.kubernetes.io/master effect: NoSchedule operator: Exists restartPolicy: OnFailure volumes: - name: etcd-backup emptyDir: {} - name: host-pki hostPath: path: /etc/kubernetes/pki initContainers: - name: snapshoter image: {{ Registry "gcr.io" }}/etcd-development/etcd:v3.5.11 imagePullPolicy: IfNotPresent command: - etcdctl args: - snapshot - save - /backup/etcd-snapshot.db env: - name: ETCDCTL_API value: "3" - name: ETCDCTL_DIAL_TIMEOUT value: 3s - name: ETCDCTL_CACERT value: /etc/kubernetes/pki/etcd/ca.crt - name: ETCDCTL_CERT value: /etc/kubernetes/pki/etcd/healthcheck-client.crt - name: ETCDCTL_KEY value: /etc/kubernetes/pki/etcd/healthcheck-client.key - name: ETCD_HOSTNAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - mountPath: /backup name: etcd-backup - mountPath: /etc/kubernetes/pki name: host-pki readOnly: true containers: - name: uploader image: {{ Registry "docker.io" }}/restic/restic:0.14.0 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - |- set -euf mkdir -p /backup/pki/kubernetes mkdir -p /backup/pki/etcd cp -a /etc/kubernetes/pki/etcd/ca.crt /backup/pki/etcd/ cp -a /etc/kubernetes/pki/etcd/ca.key /backup/pki/etcd/ cp -a /etc/kubernetes/pki/ca.crt /backup/pki/kubernetes cp -a /etc/kubernetes/pki/ca.key /backup/pki/kubernetes cp -a /etc/kubernetes/pki/front-proxy-ca.crt /backup/pki/kubernetes cp -a /etc/kubernetes/pki/front-proxy-ca.key /backup/pki/kubernetes cp -a /etc/kubernetes/pki/sa.key /backup/pki/kubernetes cp -a /etc/kubernetes/pki/sa.pub /backup/pki/kubernetes restic snapshots -q || restic init -q restic backup --tag=etcd --host=${ETCD_HOSTNAME} /backup restic forget --prune --keep-last 48 env: - name: ETCD_HOSTNAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: RESTIC_REPOSITORY value: "{{ required "Please provide s3Bucket" .Params.s3Bucket }}" - name: RESTIC_PASSWORD valueFrom: secretKeyRef: name: restic-config key: password - name: AWS_DEFAULT_REGION value: "{{ required "Please provide awsDefaultRegion" .Params.awsDefaultRegion }}" - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: key: AWS_ACCESS_KEY_ID name: kubeone-backups-credentials - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: key: AWS_SECRET_ACCESS_KEY name: kubeone-backups-credentials volumeMounts: - mountPath: /backup name: etcd-backup - mountPath: /etc/kubernetes/pki name: host-pki readOnly: true