diff --git a/restic/.gitignore b/restic/.gitignore new file mode 100644 index 0000000..7fb2ddf --- /dev/null +++ b/restic/.gitignore @@ -0,0 +1,2 @@ +credentials +password diff --git a/restic/kustomization.yaml b/restic/kustomization.yaml new file mode 100644 index 0000000..4a7d39c --- /dev/null +++ b/restic/kustomization.yaml @@ -0,0 +1,50 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: restic + +labels: +- pairs: + app.kubernetes.io/instance: restic + includeSelectors: true +- pairs: + app.kubernetes.io/part-of: restic + includeTemplates: true + +resources: +- namespace.yaml +- network-policy.yaml +- restic-prune.yaml +- secrets.yaml +- ../dch-root-ca + +configMapGenerator: +- name: restic-env + envs: + - restic.env + +patches: +- patch: |- + apiVersion: batch/v1 + kind: CronJob + metadata: + name: restic-prune + spec: + jobTemplate: + spec: + template: + spec: + containers: + - name: restic-prune + env: + - name: RESTIC_CACERT + value: /run/dch-ca/dch-root-ca.crt + volumeMounts: + - mountPath: /run/dch-ca + name: dch-ca + readOnly: true + volumes: + - name: dch-ca + configMap: + name: dch-root-ca + diff --git a/restic/namespace.yaml b/restic/namespace.yaml new file mode 100644 index 0000000..8c804ed --- /dev/null +++ b/restic/namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: restic + labels: + app.kubernetes.io/name: restic diff --git a/restic/network-policy.yaml b/restic/network-policy.yaml new file mode 100644 index 0000000..3fbddb0 --- /dev/null +++ b/restic/network-policy.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: restic + labels: + app.kubernetes.io/name: restic + app.kubernetes.io/component: restic +spec: + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - to: + - ipBlock: + cidr: 172.30.0.15/32 + ports: + - port: 443 + podSelector: {} diff --git a/restic/restic-prune.yaml b/restic/restic-prune.yaml new file mode 100644 index 0000000..032385e --- /dev/null +++ b/restic/restic-prune.yaml @@ -0,0 +1,60 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: restic-prune + labels: + app.kubernetes.io/name: restic-prune + app.kubernetes.io/component: restic +spec: + schedule: 38 9 * * 5 + timeZone: America/Chicago + concurrencyPolicy: Forbid + jobTemplate: + metadata: + labels: &labels + app.kubernetes.io/name: restic-prune + app.kubernetes.io/component: restic + spec: + template: + metadata: + labels: *labels + spec: + restartPolicy: Never + containers: + - name: restic-prune + image: ghcr.io/restic/restic + args: + - forget + - --keep-daily=14 + - --keep-weekly=4 + - --keep-monthly=12 + env: + - name: XDG_CACHE_HOME + value: /var/cache + envFrom: + - configMapRef: + name: restic-env + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /run/secrets/restic + name: secrets + readOnly: true + - mountPath: /var/cache + name: cache + - mountPath: /tmp + name: tmp + securityContext: + runAsUser: 32142 + runAsGroup: 32142 + fsGroup: 32142 + runAsNonRoot: true + volumes: + - name: cache + emptyDir: {} + - name: secrets + secret: + secretName: restic-secrets + - name: tmp + emptyDir: + medium: Memory diff --git a/restic/restic.env b/restic/restic.env new file mode 100644 index 0000000..ffb2d21 --- /dev/null +++ b/restic/restic.env @@ -0,0 +1,4 @@ +RESTIC_REPOSITORY=s3:s3.backups.pyrocufflink.blue/restic +RESTIC_PASSWORD_FILE=/run/secrets/restic/password + +AWS_SHARED_CREDENTIALS_FILE=/run/secrets/restic/credentials diff --git a/restic/secrets.yaml b/restic/secrets.yaml new file mode 100644 index 0000000..0aec915 --- /dev/null +++ b/restic/secrets.yaml @@ -0,0 +1,17 @@ +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: restic-secrets + namespace: restic + labels: &labels + app.kubernetes.io/name: restic + app.kubernetes.io/component: restic +spec: + encryptedData: + credentials: AgBegS5P+JvhbhBb7/gZ1h+eyvqbXbj5bL5nN/MUbSjmrc/eR93ipe+kAKsfe1DCOtrEKYxO52RY2RdQHcUtgowD9LChCWPVPNZSDJnOId4nVRh9dSqSdYe+fkbp2wqHZf67AjpsP6/Ga3/3RFgNoVXmSDUmn8+5ZwTCKeC304XaCXnPj3iudpO52Wr6x+GpVfZ+yuVBMKMFHIFnnMt0AmjXCqbz+LPIUP/BKZ0/15DYTj4SO3heoSYy5y8suIiF9RZW6ne5dQ3w28V7hq18TNjATahtz+csLzUCRAKYoJfuZ0+YShqn2B/ZFItS1HbsWpoM23UwrNgx5TjSpNzTsh1wqlOztRcS47vyWu9ztDuXjDm2lSJMqoLAjbumV8QU+95LIVK8OCD9ziFCYCXm+7C2fKHG9Z3eEv83bFFQBVRbUg6zgv78FWb5PKrwg55rAM6C/U3AdvVFKYu8sBN30uaGIf6tCwZiHKuzp7JvVGffe6YFmBMU2oxGiLc4ckZozIGXBS26Uk79XM3ywUx+CWOClkqRLfeIjEP0rzseyh9kfXN2rAfn1o1WH6RJLopeE7IO7vnbM8t2CqVfKiBIsIXtKQ6t7JO/8On68AWTw+iqseK3iW6ZiComdYsP5RR5pZMfKa9iSAD6CaFLflMVFslVy2BQgtxWJ9SsQrB48iq3GFSBS2GG4x8NO0gZxY+AE1dvykRZ4U/YYheoClDvibQqPKFsvq83O7zaNwD2tGYiurxoaqAI6FtRCGjA2YGW+FzfikINNTsU21+GrkeNpHYVEXcL00gVR/RtO4JRM7ndCoTUCwCtrJitYLsGS9ZK7D2EXIqe/UqQCzsoVVEwN+irHXGzaA== + password: AgAXFkg2MdfuYD7XcQanf4rrkdO4dbB0IFJRU2oECcMNzGkQKC2+LfyqZv+TgBa0VnmCh3V+suVq48vG+W3Mr9g9LGzcjb3NVsKY8oxNsidEIU6ZksI/ijU7CF7/E5snpd7DowXCye+uA9QzxolarcVucF0S6CFoj5b5O2YFz7RsozJqsfRfXl+SbGbOzjPsKAmE6jBMHGfDlGA9VdgcGFECudBXZDyaaRQtpPITqRMzDdq/fKffA+r117deXzSXW0MB6RDsWubwSSdQXVtgbeAFn2oKGaEeloreRiNwaZ4nR6a6efkvlhz5prQ7sFFhGVDjdwhkdspXly1jHIFqTIoIul9/hRIZ8gGUfDMWq7YOYnwnPpkcY4+fE6LpfY/+BC2//t2VW5uk2lYRZin62bATIZpLE2hFGym3O4Mk5hz6O/jSMvDzDNJ6zYU3oN9C94qxgoLv2IL9tV1mpLvt8hcil0wWuj7qISIf88jTsneQ3quWz8xj6kOjLO+FJD5TjFU6qIhcXTS3/M3XqQbZRucPlVVeROFB9HJpqa51AOxV5i0yuosvlmOaLpOS8UPd3fzMYNY0bopuBrktndy1sY6VdV8ELHZXHFZxruAuYJnRzoZ4EjR5/Mo9BT7JKZLpRUgnLdPQTe5VwL5E1FgjMr/b3nwSyenb63ulOzLcfcy/fpBgOk5AwgOOqjDKLUMJzLppYZT7K2wAI/81IqdclRxblGTa1smyFt7nrUUc86pSWy+/lEhZ+nFrkSF9GFmf3hQDIK/OmqVoV46uMadQGi+d + template: + metadata: + name: restic-secrets + namespace: restic + labels: *labels