diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 00000000..537fdd7c --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: MongoDB dockerized backup agent. Runs schedule backups with retention, S3 & SFTP upload, notifications, instrumentation with Prometheus and more. +name: mgob +version: 0.9.0 diff --git a/chart/notes.md b/chart/notes.md new file mode 100644 index 00000000..8b8312bd --- /dev/null +++ b/chart/notes.md @@ -0,0 +1,27 @@ +Usage +===== +This script assumes a user has been created in the mongoDB instance with sufficient read privileges to create the +backups. + +The password set when creating the user below is referred to in the `values.yaml`-file for each plan. Make sure that +those match, or your backups will fail. + + db.createUser({ + user: "mongodb-backup", + pwd: "backup-user-pwd", + roles: [ + { role: "backup", db: "admin" } + ] + }); + +Secondly, it assumes that [Helm](https://github.com/kubernetes/helm) is installed on your cluster and that you have +a properly configured [`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl/) installed. + +To install the chart, first clone the Git repository. Secondly, edit the `values.yaml`-file to define your backup +plans. Documentation for those can be found in the default repository `readme.md`, easily accessible as the +[mgob repository start page](https://github.com/stefanprodan/mgob). When the `values.yaml`-file properly represents the +plan(s) you want to create, simply run: + + $ helm install --namespace my-kubernetes-ns ./chart + +This will install the chart on your cluster. \ No newline at end of file diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 00000000..f0d83d2e --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "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). +*/}} +{{- define "fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/chart/templates/configmap.yaml b/chart/templates/configmap.yaml new file mode 100644 index 00000000..eb7e528c --- /dev/null +++ b/chart/templates/configmap.yaml @@ -0,0 +1,8 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + role: backup + name: "mgob-config" +data: +{{ toYaml .Values.configMap.data | indent 2 }} diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 00000000..15569fe5 --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "fullname" . }} + labels: + name: {{ template "fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" +spec: + clusterIP: None + ports: + - port: {{ .Values.service.externalPort }} + targetPort: {{ .Values.service.internalPort }} + protocol: TCP + name: {{ .Values.service.name }} + selector: + app: {{ template "fullname" . }} + role: {{ .Values.selector.role }} diff --git a/chart/templates/statefulset.yaml b/chart/templates/statefulset.yaml new file mode 100644 index 00000000..1da70d52 --- /dev/null +++ b/chart/templates/statefulset.yaml @@ -0,0 +1,64 @@ +apiVersion: apps/v1 # Change to "apps/v1beta1" for Kubernetes < 1.10. +kind: StatefulSet +metadata: + name: {{ template "fullname" . }} +spec: + serviceName: {{ template "fullname" . }} + replicas: 1 + selector: + matchLabels: + role: {{ .Values.selector.role }} + template: + metadata: + labels: + role: {{ .Values.selector.role }} + spec: + containers: + - name: {{ template "fullname" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.service.internalPort }} + protocol: TCP + volumeMounts: + - name: "mgob-storage" + mountPath: "/storage" + - name: "mgob-tmp" + mountPath: "/tmp" + - name: "mgob-tmp" + mountPath: "/data" +{{- range $name, $value := .Values.configMap.data }} + - mountPath: "/config/{{ $name }}" + name: {{ $.Values.configMap.name }} + subPath: {{ $name | quote }} +{{ end }} + volumes: + - name: {{ .Values.configMap.name }} + configMap: + name: {{ .Values.configMap.name }} + items: +{{- range $name, $value := .Values.configMap.data }} + - key: {{ $name }} + path: {{ $name }} +{{ end }} + volumeClaimTemplates: + - metadata: + name: {{ .Values.storage.longTerm.name }} + annotations: + volume.beta.kubernetes.io/storage-class: {{ .Values.storage.longTerm.storageClass }} + spec: + accessModes: + - {{ .Values.storage.longTerm.accessMode }} + resources: + requests: + storage: {{ .Values.storage.longTerm.size }} + - metadata: + name: {{ .Values.storage.tmp.name }} + annotations: + volume.beta.kubernetes.io/storage-class: {{ .Values.storage.tmp.storageClass }} + spec: + accessModes: + - {{ .Values.storage.tmp.accessMode }} + resources: + requests: + storage: {{ .Values.storage.tmp.size }} diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 00000000..1e022122 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,92 @@ +# Default values for mgob. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +# Note that two backup plans are provided as templates - they contain dummy values and should be changed before +# attempting to apply the chart to your cluster. +replicaCount: 1 +image: + repository: stefanprodan/mgob + pullPolicy: IfNotPresent + + # We need edge to be able to use the "configMap.data[name].target.params", required to set the auth db. + # When this is official, update to the proper stable release. + # + # @see https://github.com/stefanprodan/mgob/commit/b70e86b3acba8c82447a568cfcdd31fbd5ee3f7c + tag: edge +service: + name: mgob + externalPort: 8090 + internalPort: 8090 +selector: + role: mongo-backup +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi +storage: + longTerm: + accessMode: "ReadWriteOnce" + storageClass: "gp2" # Note: "gp2" is for AWS. Use the storage class for your cloud provider. + name: "mgob-storage" + size: 10Gi + tmp: + accessMode: "ReadWriteOnce" + storageClass: "gp2" # Note: "gp2" is for AWS. Use the storage class for your cloud provider. + name: "mgob-tmp" + size: 3Gi +configMap: + name: "mgob-config" + data: + # Add each plan as per below. + the-first-database.yml: | + target: + host: "mongodb-replicaset" + port: 27017 + database: "my-database" + username: "mongodb-backup" + password: "backup-user-pwd" + params: "--authenticationDatabase admin" + scheduler: + cron: "0 5 * * *" + retention: 7 + timeout: 60 + s3: + url: "https://s3.amazonaws.com" + bucket: "my-db-backups" + accessKey: "ABCDEFGHIJKLMNOPQRST" + secretKey: "be0da49b599b24115c7f53c92c729cbb2c8a17e5" + api: "S3v4" + slack: + url: "https://hooks.slack.com/services/..." + channel: mongochan + username: mgob + # 'true' to notify only on failures + warnOnly: false + + the-second-database.yml: | + target: + host: "mongodb-replicaset" + port: 27017 + database: "my-database" + username: "mongodb-backup" + password: "backup-user-pwd" + params: "--authenticationDatabase admin" + scheduler: + cron: "0 5 * * *" + retention: 7 + timeout: 60 + s3: + url: "https://s3.amazonaws.com" + bucket: "my-db-backups" + accessKey: "ABCDEFGHIJKLMNOPQRST" + secretKey: "be0da49b599b24115c7f53c92c729cbb2c8a17e5" + api: "S3v4" + slack: + url: "https://hooks.slack.com/services/..." + channel: mongochan + username: mgob + # 'true' to notify only on failures + warnOnly: false