From 6b7ed6459b77a36d5311529e1a97b0c74075c225 Mon Sep 17 00:00:00 2001 From: COURCY Michael Date: Tue, 15 Nov 2022 18:37:08 +0100 Subject: [PATCH 01/15] Blueprint for percona mongodb operator --- examples/mongodb-percona/README.md | 293 +++++++++++++++ examples/mongodb-percona/cr.yaml | 489 +++++++++++++++++++++++++ examples/mongodb-percona/psmdb-bp.yaml | 91 +++++ 3 files changed, 873 insertions(+) create mode 100644 examples/mongodb-percona/README.md create mode 100644 examples/mongodb-percona/cr.yaml create mode 100644 examples/mongodb-percona/psmdb-bp.yaml diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md new file mode 100644 index 0000000000..3872edaf98 --- /dev/null +++ b/examples/mongodb-percona/README.md @@ -0,0 +1,293 @@ +# MongoDB + +[MongoDB](https://www.mongodb.com/) is a cross-platform document-oriented database. Classified as a NoSQL database, MongoDB eschews the traditional table-based relational database structure in favor of JSON-like documents with dynamic schemas, making the integration of data in certain types of applications easier and faster. + +## Prerequisites + +* Kubernetes 1.9+ +* PV support on the underlying infrastructure +* Kanister controller version 0.84.0 installed in your cluster +* Kanctl CLI installed (https://docs.kanister.io/tooling.html#kanctl) + +## Operator Details + +We will be using [percona operator for Mongodb](https://docs.percona.com/percona-operator-for-mongodb/index.html), the blueprint follow backup and restore workflow as described in the [backup/restore documentation](https://docs.percona.com/percona-operator-for-mongodb/backups.html) of the operator. + +## Limitations + +We can't use a profiles.cr.kanister.io to define the backup target because the operator force the definition of the backup target in the PerconaServerMongoDB object itself and in a secret for the AWS_ACCESS_KEY_ID and in the AWS_SECRET_ACCESS_KEY: +``` + storages: + my-s3-storage: + type: s3 + s3: + bucket: my-bucket + credentialsSecret: s3-secret + region: eu-west-3 + prefix: "mongodb/my-cluster-name/" + uploadPartSize: 10485760 + maxUploadParts: 10000 + storageClass: STANDARD + insecureSkipTLSVerify: false +``` + +Those values need to be defined (this section and the s3-secret) before you execute the blueprint. + +## Install the operator and create a cluster + +Edit cr.yaml and ensure the backup/storages section (line 443) is consistent with your s3 target, you may change : +- the region +- the bucket name +- the endpoint +- the prefix +- ... + +Also define the env variable `AWS_S3_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` according to your setting. + +Those values can't be obtained from a kanister profile because they need to be defined in the PerconaServerMongoDB object itself before any kanister action (see Limitations) + +``` +kubectl create namespace mongodb +kubectl config set-context --current --namespace=mongodb +kubectl apply -f https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.13.0/deploy/bundle.yaml +kubectl create secret generic s3-secret --from-literal AWS_ACCESS_KEY_ID=$AWS_S3_ACCESS_KEY_ID --from-literal AWS_SECRET_ACCESS_KEY=$AWS_S3_SECRET_ACCESS_KEY +kubectl apply -f cr.yaml +``` + +check the status of the mongodb cluster +``` +kubectl get psmdb +``` + +**NOTE:** + +We also enable point in time restore (pitr) for this cluster + +``` + pitr: + enabled: true + compressionType: gzip + compressionLevel: 6 +``` + +## Integrating with Kanister + +If you have deployed the operator with other name than `my-cluster-name` and namespace other than `mongodb`, you need to modify the commands used below to use the correct name and namespace + +### Create Profile +Create Profile CR if not created already + +```bash +$ kanctl create profile s3compliant --access-key \ + --secret-key \ + --bucket --region \ + --namespace mongodb +``` + +**NOTE:** + +The command will configure a location where artifacts resulting from Kanister data operations such as backup should go. This is stored as a profiles.cr.kanister.io CustomResource (CR) which is then referenced in Kanister ActionSets. Every ActionSet requires a Profile reference to complete the action. This CR (profiles.cr.kanister.io) can be shared between Kanister-enabled application instances. + +**NOTE:** + +The profile is actually useless in this case but mandatory for executing kanister action. + + +### Create Blueprint +Create Blueprint in the same namespace as the controller + +```bash +$ kubectl create -f psmdb-bp.yaml -n kasten-io +``` + +Once MongoDB is running, you can populate it with some data. Let's add a collection called "ticker": + +```bash +MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) +MONGODB_DATABASE_ADMIN_USER=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_USER}'|base64 -d) +kubectl run -i --rm --tty percona-client \ + --image=percona/percona-server-mongodb:4.4.16-16 \ + --env=MONGODB_DATABASE_ADMIN_PASSWORD=$MONGODB_DATABASE_ADMIN_PASSWORD \ + --env=MONGODB_DATABASE_ADMIN_USER=$MONGODB_DATABASE_ADMIN_USER \ + --restart=Never \ + -- bash -il +mongo "mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@my-cluster-name-mongos.mongodb.svc.cluster.local/admin?ssl=false" +``` + +Insert some data +``` +db.createCollection("ticker") +db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) +db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) +db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) +db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) +db.ticker.find({}).sort({createdAt:-1}).limit(1) +``` + +In order to test Point In Time Restore (PITR) create a ticker pod that add new entry every seconds. + +``` +MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) +MONGODB_DATABASE_ADMIN_USER=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_USER}'|base64 -d) +kubectl run percona-ticker \ + --image=percona/percona-server-mongodb:4.4.16-16 \ + --env=MONGODB_DATABASE_ADMIN_PASSWORD=$MONGODB_DATABASE_ADMIN_PASSWORD \ + --env=MONGODB_DATABASE_ADMIN_USER=$MONGODB_DATABASE_ADMIN_USER \ + -- bash -c "while true; do mongo \"mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@my-cluster-name-mongos.mongodb.svc.cluster.local/admin?ssl=false\" --eval 'db.ticker.insert( {createdAt: new Date(), randomdata: \"qstygshgqsfxxtqsfgqfhjqhsj\"} )'; sleep 1; done" +``` + +Reuse the percona-client to check you have a new entry every second, execute this command multiple times. +``` +db.ticker.find({}).sort({createdAt:-1}).limit(1) +``` + +**NOTE:** + +If you change the storage name for something else than `my-s3-storage` in the cr.yaml file you need to change this name in the blueprint accordingly. + +## Protect the Application + +You can now take a backup of the MongoDB data using an ActionSet defining backup for this application. Create an ActionSet in the same namespace as the controller. + +```bash +$ kubectl get profiles.cr.kanister.io -n mongodb +NAME AGE +s3-profile-bvc8k 2h + +$ kanctl create actionset \ + --action backup --namespace kasten-io \ + --blueprint psmdb-bp \ + --profile mongodb/s3-profile-bvc8k \ + --objects psmdb.percona.com/v1/perconaservermongodbs/mongodb/my-cluster-name + +$ kubectl --namespace kasten-io get actionsets.cr.kanister.io +NAME AGE +backup-vvskw 2h + +# View the status of the actionset +$ kubectl --namespace kasten-io describe actionset backup-vvskw +``` + +### Disaster strikes! + +Let's say someone with fat fingers accidentally deleted the mongo cluster and all the pvcs: +```bash +kubectl delete psmdb my-cluster-name +kubectl delete po percona-ticker +kubectl delete pvc --all +``` + +All pods and pvc are now gone. Recreate the cluster +``` +kubectl apply -f cr.yaml +``` + +Check the cluster is now ready +``` +kubectl get psmdb +``` + +If you try to access this data in the database, you should see that it is no longer there: +```bash +MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) +MONGODB_DATABASE_ADMIN_USER=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_USER}'|base64 -d) +kubectl run -i --rm --tty percona-client \ + --image=percona/percona-server-mongodb:4.4.16-16 \ + --env=MONGODB_DATABASE_ADMIN_PASSWORD=$MONGODB_DATABASE_ADMIN_PASSWORD \ + --env=MONGODB_DATABASE_ADMIN_USER=$MONGODB_DATABASE_ADMIN_USER \ + --restart=Never \ + -- bash -il +mongo "mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@my-cluster-name-mongos.mongodb.svc.cluster.local/admin?ssl=false" +``` + +You should have no output when trying to query the ticker collections +``` +db.ticker.find({}).sort({createdAt:-1}).limit(1) +``` + + +### Restore the Application + +To restore the missing data, you should use the backup that you created before. An easy way to do this is to leverage `kanctl`, a command-line tool that helps create ActionSets that depend on other ActionSets: + + +```bash +$ kanctl --namespace kasten-io create actionset --action restore --from "backup-vvskw" +actionset restore-backup-vvskw-sfpm6 created + +# View the status of the ActionSet +kubectl --namespace kasten-io describe actionset restore-backup-vvskw-sfpm6 +``` + +You should now see that the data has been successfully restored to MongoDB! + +```bash +db.ticker.find({}).sort({createdAt:-1}).limit(1) +{ "_id" : ObjectId("637372caf98744ac5a6e4aae"), "createdAt" : ISODate("2022-11-15T11:06:50.296Z"), "randomdata" : "qstygshgqsfxxtqsfgqfhjqhsj" } +``` + +#### Point In Time Restore + +Let's say the backup was at 15th Nov 2022 at 15:11 and we want to restore at a specific point in time after the backup at 15:13:10 the same day + +``` +kanctl --namespace kasten-io create actionset --action restore --from "backup-vvskw" --options pitr="2022-11-15 15:13:10" +``` + +### Delete the Artifacts + +The artifacts created by the backup action can be cleaned up using the following command: + +```bash +$ kanctl --namespace kasten-io create actionset --action delete --from "backup-vvskw" +actionset delete-backup-vvskw-xh29t created + +# View the status of the ActionSet +$ kubectl --namespace kasten-io describe actionset delete-backup-vvskw-xh29t +``` + +**NOTE:** + +To have the delete action working properly we need the operator up and running. + + + +### Troubleshooting + +If you run into any issues with the above commands, you can check the logs of the controller using: + +```bash +$ kubectl --namespace kasten-io logs -l app=kanister-operator +``` + +you can also check events of the actionset + +```bash +$ kubectl describe actionset restore-backup-vvskw-sfpm6 -n kasten-io +``` + +## Uninstalling the Chart + +To uninstall/delete the mongodb cluster and the operator: + +```bash +kubectl delete psmdb my-cluster-name +kubectl delete po percona-ticker +kubectl delete pvc --all +kubectl delete -f https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.13.0/deploy/bundle.yaml +kubectl delete ns mongodb +``` + +The command removes all the Kubernetes components associated with the operator and deletes the mongodb namespace. + +Delete Blueprint and Profile CR + +```bash +$ kubectl delete blueprints.cr.kanister.io psmdb-bp -n kasten-io + +$ kubectl get profiles.cr.kanister.io -n mongodb +NAME AGE +s3-profile-bvc8k 2h + +$ kubectl delete profiles.cr.kanister.io s3-profile-bvc8k -n mongodb +``` diff --git a/examples/mongodb-percona/cr.yaml b/examples/mongodb-percona/cr.yaml new file mode 100644 index 0000000000..6ed5170eb9 --- /dev/null +++ b/examples/mongodb-percona/cr.yaml @@ -0,0 +1,489 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: my-cluster-name + finalizers: + - delete-psmdb-pods-in-order +# - delete-psmdb-pvc +spec: +# platform: openshift +# clusterServiceDNSSuffix: svc.cluster.local +# clusterServiceDNSMode: "Internal" +# pause: true +# unmanaged: false + crVersion: 1.13.0 + image: percona/percona-server-mongodb:5.0.11-10 + imagePullPolicy: Always +# tls: +# # 90 days in hours +# certValidityDuration: 2160h +# imagePullSecrets: +# - name: private-registry-credentials + allowUnsafeConfigurations: false + updateStrategy: SmartUpdate +# multiCluster: +# enabled: true +# DNSSuffix: svc.clusterset.local + upgradeOptions: + versionServiceEndpoint: https://check.percona.com + apply: disabled + schedule: "0 2 * * *" + setFCV: false + secrets: + users: my-cluster-name-secrets + encryptionKey: my-cluster-name-mongodb-encryption-key +# vault: my-cluster-name-vault + pmm: + enabled: false + image: percona/pmm-client:2.30.0 + serverHost: monitoring-service +# mongodParams: --environment=ENVIRONMENT +# mongosParams: --environment=ENVIRONMENT + replsets: + + - name: rs0 + size: 3 +# externalNodes: +# - host: 34.124.76.90 +# - host: 34.124.76.91 +# port: 27017 +# votes: 0 +# priority: 0 +# - host: 34.124.76.92 +# # for more configuration fields refer to https://docs.mongodb.com/manual/reference/configuration-options/ +# configuration: | +# net: +# tls: +# mode: preferTLS +# operationProfiling: +# mode: slowOp +# systemLog: +# verbosity: 1 +# storage: +# engine: wiredTiger +# wiredTiger: +# engineConfig: +# directoryForIndexes: false +# journalCompressor: snappy +# collectionConfig: +# blockCompressor: snappy +# indexConfig: +# prefixCompression: true + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" +# advanced: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/e2e-az-name +# operator: In +# values: +# - e2e-az1 +# - e2e-az2 +# tolerations: +# - key: "node.alpha.kubernetes.io/unreachable" +# operator: "Exists" +# effect: "NoExecute" +# tolerationSeconds: 6000 +# priorityClassName: high-priority +# annotations: +# iam.amazonaws.com/role: role-arn +# labels: +# rack: rack-22 +# nodeSelector: +# disktype: ssd +# storage: +# engine: wiredTiger +# wiredTiger: +# engineConfig: +# cacheSizeRatio: 0.5 +# directoryForIndexes: false +# journalCompressor: snappy +# collectionConfig: +# blockCompressor: snappy +# indexConfig: +# prefixCompression: true +# inMemory: +# engineConfig: +# inMemorySizeRatio: 0.5 +# livenessProbe: +# failureThreshold: 4 +# initialDelaySeconds: 60 +# periodSeconds: 30 +# timeoutSeconds: 10 +# startupDelaySeconds: 7200 +# readinessProbe: +# failureThreshold: 8 +# initialDelaySeconds: 10 +# periodSeconds: 3 +# successThreshold: 1 +# timeoutSeconds: 2 +# runtimeClassName: image-rc +# sidecars: +# - image: busybox +# command: ["/bin/sh"] +# args: ["-c", "while true; do echo echo $(date -u) 'test' >> /dev/null; sleep 5;done"] +# name: rs-sidecar-1 +# volumeMounts: +# - mountPath: /volume1 +# name: sidecar-volume-claim +# - mountPath: /secret +# name: sidecar-secret +# - mountPath: /configmap +# name: sidecar-config +# sidecarVolumes: +# - name: sidecar-secret +# secret: +# secretName: mysecret +# - name: sidecar-config +# configMap: +# name: myconfigmap +# sidecarPVCs: +# - apiVersion: v1 +# kind: PersistentVolumeClaim +# metadata: +# name: sidecar-volume-claim +# spec: +# resources: +# requests: +# storage: 1Gi +# volumeMode: Filesystem +# accessModes: +# - ReadWriteOnce + podDisruptionBudget: + maxUnavailable: 1 +# minAvailable: 0 + expose: + enabled: false + exposeType: ClusterIP +# loadBalancerSourceRanges: +# - 10.0.0.0/8 +# serviceAnnotations: +# service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http +# serviceLabels: +# rack: rack-22 + resources: + limits: + cpu: "300m" + memory: "0.5G" + requests: + cpu: "300m" + memory: "0.5G" + volumeSpec: +# emptyDir: {} +# hostPath: +# path: /data +# type: Directory + persistentVolumeClaim: +# storageClassName: standard +# accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 3Gi + + nonvoting: + enabled: false +# podSecurityContext: {} +# containerSecurityContext: {} + size: 3 +# # for more configuration fields refer to https://docs.mongodb.com/manual/reference/configuration-options/ +# configuration: | +# operationProfiling: +# mode: slowOp +# systemLog: +# verbosity: 1 + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" +# advanced: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/e2e-az-name +# operator: In +# values: +# - e2e-az1 +# - e2e-az2 +# tolerations: +# - key: "node.alpha.kubernetes.io/unreachable" +# operator: "Exists" +# effect: "NoExecute" +# tolerationSeconds: 6000 +# priorityClassName: high-priority +# annotations: +# iam.amazonaws.com/role: role-arn +# labels: +# rack: rack-22 +# nodeSelector: +# disktype: ssd + podDisruptionBudget: + maxUnavailable: 1 +# minAvailable: 0 + resources: + limits: + cpu: "300m" + memory: "0.5G" + requests: + cpu: "300m" + memory: "0.5G" + volumeSpec: +# emptyDir: {} +# hostPath: +# path: /data +# type: Directory + persistentVolumeClaim: +# storageClassName: standard +# accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 3Gi + arbiter: + enabled: false + size: 1 + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" +# advanced: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/e2e-az-name +# operator: In +# values: +# - e2e-az1 +# - e2e-az2 +# tolerations: +# - key: "node.alpha.kubernetes.io/unreachable" +# operator: "Exists" +# effect: "NoExecute" +# tolerationSeconds: 6000 +# priorityClassName: high-priority +# annotations: +# iam.amazonaws.com/role: role-arn +# labels: +# rack: rack-22 +# nodeSelector: +# disktype: ssd + + sharding: + enabled: true + + configsvrReplSet: + size: 3 +# externalNodes: +# - host: 34.124.76.93 +# - host: 34.124.76.94 +# port: 27017 +# votes: 0 +# priority: 0 +# - host: 34.124.76.95 +# # for more configuration fields refer to https://docs.mongodb.com/manual/reference/configuration-options/ +# configuration: | +# operationProfiling: +# mode: slowOp +# systemLog: +# verbosity: 1 + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" +# advanced: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/e2e-az-name +# operator: In +# values: +# - e2e-az1 +# - e2e-az2 +# tolerations: +# - key: "node.alpha.kubernetes.io/unreachable" +# operator: "Exists" +# effect: "NoExecute" +# tolerationSeconds: 6000 +# priorityClassName: high-priority +# annotations: +# iam.amazonaws.com/role: role-arn +# labels: +# rack: rack-22 +# nodeSelector: +# disktype: ssd +# livenessProbe: +# failureThreshold: 4 +# initialDelaySeconds: 60 +# periodSeconds: 30 +# timeoutSeconds: 10 +# startupDelaySeconds: 7200 +# readinessProbe: +# failureThreshold: 3 +# initialDelaySeconds: 10 +# periodSeconds: 3 +# successThreshold: 1 +# timeoutSeconds: 2 +# runtimeClassName: image-rc +# sidecars: +# - image: busybox +# command: ["/bin/sh"] +# args: ["-c", "while true; do echo echo $(date -u) 'test' >> /dev/null; sleep 5;done"] +# name: rs-sidecar-1 + podDisruptionBudget: + maxUnavailable: 1 + expose: + enabled: false + exposeType: ClusterIP +# loadBalancerSourceRanges: +# - 10.0.0.0/8 +# serviceAnnotations: +# service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http +# serviceLabels: +# rack: rack-22 + resources: + limits: + cpu: "300m" + memory: "0.5G" + requests: + cpu: "300m" + memory: "0.5G" + volumeSpec: +# emptyDir: {} +# hostPath: +# path: /data +# type: Directory + persistentVolumeClaim: +# storageClassName: standard +# accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 3Gi + + mongos: + size: 3 +# # for more configuration fields refer to https://docs.mongodb.com/manual/reference/configuration-options/ +# configuration: | +# systemLog: +# verbosity: 1 + affinity: + antiAffinityTopologyKey: "kubernetes.io/hostname" +# advanced: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/e2e-az-name +# operator: In +# values: +# - e2e-az1 +# - e2e-az2 +# tolerations: +# - key: "node.alpha.kubernetes.io/unreachable" +# operator: "Exists" +# effect: "NoExecute" +# tolerationSeconds: 6000 +# priorityClassName: high-priority +# annotations: +# iam.amazonaws.com/role: role-arn +# labels: +# rack: rack-22 +# nodeSelector: +# disktype: ssd +# livenessProbe: +# failureThreshold: 4 +# initialDelaySeconds: 60 +# periodSeconds: 30 +# timeoutSeconds: 10 +# startupDelaySeconds: 7200 +# readinessProbe: +# failureThreshold: 3 +# initialDelaySeconds: 10 +# periodSeconds: 3 +# successThreshold: 1 +# timeoutSeconds: 2 +# runtimeClassName: image-rc +# sidecars: +# - image: busybox +# command: ["/bin/sh"] +# args: ["-c", "while true; do echo echo $(date -u) 'test' >> /dev/null; sleep 5;done"] +# name: rs-sidecar-1 + podDisruptionBudget: + maxUnavailable: 1 + resources: + limits: + cpu: "300m" + memory: "0.5G" + requests: + cpu: "300m" + memory: "0.5G" + expose: + exposeType: ClusterIP +# servicePerPod: true +# loadBalancerSourceRanges: +# - 10.0.0.0/8 +# serviceAnnotations: +# service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http +# serviceLabels: +# rack: rack-22 + +# mongod: +# security: +# encryptionKeySecret: "my-cluster-name-mongodb-encryption-key" + + backup: + enabled: true + image: percona/percona-backup-mongodb:1.8.1 + serviceAccountName: percona-server-mongodb-operator +# annotations: +# iam.amazonaws.com/role: role-arn +# resources: +# limits: +# cpu: "300m" +# memory: "0.5G" +# requests: +# cpu: "300m" +# memory: "0.5G" + storages: + my-s3-storage: + type: s3 + s3: + bucket: my-bucket + credentialsSecret: s3-secret + region: eu-west-3 + prefix: "mongodb/my-cluster-name/" + uploadPartSize: 10485760 + maxUploadParts: 10000 + storageClass: STANDARD + insecureSkipTLSVerify: false +# minio: +# type: s3 +# s3: +# bucket: MINIO-BACKUP-BUCKET-NAME-HERE +# region: us-east-1 +# credentialsSecret: my-cluster-name-backup-minio +# endpointUrl: http://minio.psmdb.svc.cluster.local:9000/minio/ +# insecureSkipTLSVerify: false +# prefix: "" +# azure-blob: +# type: azure +# azure: +# container: CONTAINER-NAME +# prefix: PREFIX-NAME +# credentialsSecret: SECRET-NAME + pitr: + enabled: true +# oplogSpanMin: 10 + compressionType: gzip + compressionLevel: 6 +# tasks: +# - name: daily-s3-us-west +# enabled: true +# schedule: "0 0 * * *" +# keep: 3 +# storageName: s3-us-west +# compressionType: gzip +# compressionLevel: 6 +# - name: weekly-s3-us-west +# enabled: false +# schedule: "0 0 * * 0" +# keep: 5 +# storageName: s3-us-west +# compressionType: gzip +# compressionLevel: 6 diff --git a/examples/mongodb-percona/psmdb-bp.yaml b/examples/mongodb-percona/psmdb-bp.yaml new file mode 100644 index 0000000000..ffad1aafcb --- /dev/null +++ b/examples/mongodb-percona/psmdb-bp.yaml @@ -0,0 +1,91 @@ +apiVersion: cr.kanister.io/v1alpha1 +kind: Blueprint +metadata: + name: psmdb-bp +actions: + backup: + outputArtifacts: + cloudObjects: + keyValue: + psmdbbackup: 'backup-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }}' + namespace: "{{ .Object.metadata.namespace }}" + phases: + - func: KubeOps + name: createBackupCR + args: + operation: create + namespace: "{{ .Object.metadata.namespace }}" + spec: |- + apiVersion: psmdb.percona.com/v1 + kind: PerconaServerMongoDBBackup + metadata: + finalizers: + - delete-backup + name: backup-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }} + spec: + clusterName: {{ .Object.metadata.name }} + storageName: my-s3-storage + - func: Wait + name: waitBackupReady + args: + timeout: 360s + conditions: + anyOf: + - condition: '{{ if eq "{ $.status.state }" "ready" }}true{{ else }}false{{ end }}' + objectReference: + apiVersion: v1 + group: psmdb.percona.com + resource: perconaservermongodbbackups + name: 'backup-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }}' + namespace: "{{ .Object.metadata.namespace}}" + delete: + inputArtifactNames: + - cloudObjects + phases: + - func: KubeOps + name: deleteBackupCR + args: + operation: delete + objectReference: + apiVersion: v1 + group: psmdb.percona.com + resource: perconaservermongodbbackups + name: '{{ .ArtifactsIn.cloudObjects.KeyValue.psmdbbackup }}' + namespace: '{{ .ArtifactsIn.cloudObjects.KeyValue.namespace }}' + restore: + inputArtifactNames: + - cloudObjects + phases: + - func: KubeOps + name: createRestoreFromBackup + args: + operation: create + namespace: "{{ .Object.metadata.namespace }}" + spec: |- + apiVersion: psmdb.percona.com/v1 + kind: PerconaServerMongoDBRestore + metadata: + name: restore-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }} + spec: + clusterName: {{ .Object.metadata.name }} + backupName: {{ .ArtifactsIn.cloudObjects.KeyValue.psmdbbackup }} + {{- if .Options }} + {{- if .Options.pitr }} + pitr: + type: date + date: {{ .Options.pitr }} + {{- end }} + {{- end }} + - func: Wait + name: waitRestoreReady + args: + timeout: 720s + conditions: + anyOf: + - condition: '{{ if eq "{ $.status.state }" "ready" }}true{{ else }}false{{ end }}' + objectReference: + apiVersion: v1 + group: psmdb.percona.com + resource: perconaservermongodbrestores + name: 'restore-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }}' + namespace: "{{ .Object.metadata.namespace}}" \ No newline at end of file From 53a9a69b170972454502c9bb24d3b18739c3bdbe Mon Sep 17 00:00:00 2001 From: COURCY Michael Date: Tue, 22 Nov 2022 15:05:04 +0100 Subject: [PATCH 02/15] add wait for cluster ready in a kasten context --- examples/mongodb-percona/README.md | 8 +++----- examples/mongodb-percona/psmdb-bp.yaml | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 3872edaf98..ad93eb6d1d 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -15,7 +15,7 @@ We will be using [percona operator for Mongodb](https://docs.percona.com/percona ## Limitations -We can't use a profiles.cr.kanister.io to define the backup target because the operator force the definition of the backup target in the PerconaServerMongoDB object itself and in a secret for the AWS_ACCESS_KEY_ID and in the AWS_SECRET_ACCESS_KEY: +For simplicity we did not patch the PerconaServerMongoDB object with the profiles.cr.kanister.io to define the backup target, you have to define it and the secret reference a secret that must define the AWS_ACCESS_KEY_ID and in the AWS_SECRET_ACCESS_KEY keys: ``` storages: my-s3-storage: @@ -248,9 +248,7 @@ $ kubectl --namespace kasten-io describe actionset delete-backup-vvskw-xh29t **NOTE:** -To have the delete action working properly we need the operator up and running. - - +To have the delete action working we need the operator up and running. ### Troubleshooting @@ -266,7 +264,7 @@ you can also check events of the actionset $ kubectl describe actionset restore-backup-vvskw-sfpm6 -n kasten-io ``` -## Uninstalling the Chart +## Uninstalling the operator and the blueprint To uninstall/delete the mongodb cluster and the operator: diff --git a/examples/mongodb-percona/psmdb-bp.yaml b/examples/mongodb-percona/psmdb-bp.yaml index ffad1aafcb..bb2f190338 100644 --- a/examples/mongodb-percona/psmdb-bp.yaml +++ b/examples/mongodb-percona/psmdb-bp.yaml @@ -55,7 +55,20 @@ actions: restore: inputArtifactNames: - cloudObjects - phases: + phases: + - func: Wait + name: waitMongoDBClusterReady + args: + timeout: 300s + conditions: + anyOf: + - condition: '{{ if eq "{ $.status.state }" "ready" }}true{{ else }}false{{ end }}' + objectReference: + apiVersion: v1 + group: psmdb.percona.com + resource: perconaservermongodbs + name: "{{ .Object.metadata.name}}" + namespace: "{{ .Object.metadata.namespace}}" - func: KubeOps name: createRestoreFromBackup args: From 8de0fdcf833ee3646f14b0e11559a5d00c8a1ecc Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:03:59 +0100 Subject: [PATCH 03/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index ad93eb6d1d..7af485099d 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -4,7 +4,7 @@ ## Prerequisites -* Kubernetes 1.9+ +* Kubernetes 1.20+ * PV support on the underlying infrastructure * Kanister controller version 0.84.0 installed in your cluster * Kanctl CLI installed (https://docs.kanister.io/tooling.html#kanctl) From 84e697cc644f35fe6d81894cff7d8642d41dedd4 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:05:14 +0100 Subject: [PATCH 04/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 7af485099d..744f023766 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -11,7 +11,9 @@ ## Operator Details -We will be using [percona operator for Mongodb](https://docs.percona.com/percona-operator-for-mongodb/index.html), the blueprint follow backup and restore workflow as described in the [backup/restore documentation](https://docs.percona.com/percona-operator-for-mongodb/backups.html) of the operator. +We will be using [percona operator for Mongodb](https://docs.percona.com/percona-operator-for-mongodb/index.html). +The blueprint follows backup and restore workflows as described in the +[backup/restore documentation](https://docs.percona.com/percona-operator-for-mongodb/backups.html) of the operator. ## Limitations From 2e8d1c4fccfbecdbe7f642e7a69bc0718c66df19 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:06:00 +0100 Subject: [PATCH 05/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 744f023766..75ecb91260 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -1,6 +1,10 @@ # MongoDB -[MongoDB](https://www.mongodb.com/) is a cross-platform document-oriented database. Classified as a NoSQL database, MongoDB eschews the traditional table-based relational database structure in favor of JSON-like documents with dynamic schemas, making the integration of data in certain types of applications easier and faster. +[MongoDB](https://www.mongodb.com/) is a cross-platform document-oriented +database. Classified as a NoSQL database, MongoDB eschews the traditional +table-based relational database structure in favor of JSON-like documents with +dynamic schemas, making the integration of data in certain types of +applications easier and faster. ## Prerequisites From 5ac5f79bbc295b52d185c9da0f6c3f61db4d47bb Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:07:21 +0100 Subject: [PATCH 06/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 75ecb91260..5ad89ea64b 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -39,7 +39,7 @@ For simplicity we did not patch the PerconaServerMongoDB object with the profile Those values need to be defined (this section and the s3-secret) before you execute the blueprint. -## Install the operator and create a cluster +## Install the Operator and Create a Cluster Edit cr.yaml and ensure the backup/storages section (line 443) is consistent with your s3 target, you may change : - the region From 74bdfb8aa05885402160250372e460ddc6e7e1f2 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:07:56 +0100 Subject: [PATCH 07/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 5ad89ea64b..da0096afac 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -21,7 +21,10 @@ The blueprint follows backup and restore workflows as described in the ## Limitations -For simplicity we did not patch the PerconaServerMongoDB object with the profiles.cr.kanister.io to define the backup target, you have to define it and the secret reference a secret that must define the AWS_ACCESS_KEY_ID and in the AWS_SECRET_ACCESS_KEY keys: +For simplicity, we did not patch the `PerconaServerMongoDB` object with the +`profiles.cr.kanister.io` to define the backup target. Instead, we can use the +`storages` section to define it along with a secret reference to a secret that +defines the `AWS_ACCESS_KEY_ID` and the `AWS_SECRET_ACCESS_KEY` keys: ``` storages: my-s3-storage: From 2b7e55b0cb11e44672e62f9248751622e31e6a76 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:08:36 +0100 Subject: [PATCH 08/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index da0096afac..4a7352213c 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -25,7 +25,7 @@ For simplicity, we did not patch the `PerconaServerMongoDB` object with the `profiles.cr.kanister.io` to define the backup target. Instead, we can use the `storages` section to define it along with a secret reference to a secret that defines the `AWS_ACCESS_KEY_ID` and the `AWS_SECRET_ACCESS_KEY` keys: -``` +```yaml storages: my-s3-storage: type: s3 From e1e26fd2b1475c246b87063c1c4ed34daa29bd34 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:08:57 +0100 Subject: [PATCH 09/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 4a7352213c..33caeff362 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -40,7 +40,8 @@ defines the `AWS_ACCESS_KEY_ID` and the `AWS_SECRET_ACCESS_KEY` keys: insecureSkipTLSVerify: false ``` -Those values need to be defined (this section and the s3-secret) before you execute the blueprint. +Those values need to be defined (this section and the s3-secret) before +executing the blueprint. ## Install the Operator and Create a Cluster From 42dbcc967879c951f61beeea2f9b4ff459bcb7c9 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:09:51 +0100 Subject: [PATCH 10/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 33caeff362..2fb965f6d9 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -45,7 +45,8 @@ executing the blueprint. ## Install the Operator and Create a Cluster -Edit cr.yaml and ensure the backup/storages section (line 443) is consistent with your s3 target, you may change : +Edit the `cr.yaml` to ensure the backup/storages section (line 443) is +consistent with your s3 target. The following may be changed: - the region - the bucket name - the endpoint From be6d991a9644b9d85c3dd366d4d6d9b3ce6fa862 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:10:15 +0100 Subject: [PATCH 11/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 2fb965f6d9..9ac6973b8b 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -53,9 +53,12 @@ consistent with your s3 target. The following may be changed: - the prefix - ... -Also define the env variable `AWS_S3_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` according to your setting. +Also, define the ENV variables for `AWS_S3_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY` according to requirements. -Those values can't be obtained from a kanister profile because they need to be defined in the PerconaServerMongoDB object itself before any kanister action (see Limitations) +These values can't be obtained from a Kanister profile as they need to be +defined in the `PerconaServerMongoDB` object itself before running any Kanister +actions (see Limitations). ``` kubectl create namespace mongodb From 15129e10d615251b1f593bef925b1002eb7a9f11 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:10:34 +0100 Subject: [PATCH 12/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 9ac6973b8b..957c4f519f 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -60,7 +60,7 @@ These values can't be obtained from a Kanister profile as they need to be defined in the `PerconaServerMongoDB` object itself before running any Kanister actions (see Limitations). -``` +```bash kubectl create namespace mongodb kubectl config set-context --current --namespace=mongodb kubectl apply -f https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.13.0/deploy/bundle.yaml From 0258d015531fd55e16da66e8b64ce3641a9f6344 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:10:49 +0100 Subject: [PATCH 13/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 957c4f519f..55a55ff297 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -68,7 +68,7 @@ kubectl create secret generic s3-secret --from-literal AWS_ACCESS_KEY_ID=$AWS_S3 kubectl apply -f cr.yaml ``` -check the status of the mongodb cluster +Check the status of the mongodb cluster ``` kubectl get psmdb ``` From 9c960c5e294d60d0a83f9cdac8c41b517834834f Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:11:12 +0100 Subject: [PATCH 14/15] Update examples/mongodb-percona/README.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 55a55ff297..37a78a1c85 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -69,7 +69,7 @@ kubectl apply -f cr.yaml ``` Check the status of the mongodb cluster -``` +```bash kubectl get psmdb ``` From a5fc6f7e8dc8656855020677231cfc62d69208e9 Mon Sep 17 00:00:00 2001 From: michaelcourcy Date: Wed, 11 Jan 2023 12:20:57 +0100 Subject: [PATCH 15/15] Apply suggestions from code review Fix on readme.md Co-authored-by: Pavan Navarathna <6504783+pavannd1@users.noreply.github.com> --- examples/mongodb-percona/README.md | 75 +++++++++++++++----------- examples/mongodb-percona/psmdb-bp.yaml | 2 +- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/examples/mongodb-percona/README.md b/examples/mongodb-percona/README.md index 37a78a1c85..7b43ba1b37 100644 --- a/examples/mongodb-percona/README.md +++ b/examples/mongodb-percona/README.md @@ -75,9 +75,9 @@ kubectl get psmdb **NOTE:** -We also enable point in time restore (pitr) for this cluster +We can also enable point-in-time restore (PITR) for this cluster -``` +```yaml pitr: enabled: true compressionType: gzip @@ -86,7 +86,9 @@ We also enable point in time restore (pitr) for this cluster ## Integrating with Kanister -If you have deployed the operator with other name than `my-cluster-name` and namespace other than `mongodb`, you need to modify the commands used below to use the correct name and namespace +If the operator is deployed with a name other than `my-cluster-name`, and a +namespace other than `mongodb`, modify the commands used below to use the +correct name and namespace: ### Create Profile Create Profile CR if not created already @@ -114,7 +116,8 @@ Create Blueprint in the same namespace as the controller $ kubectl create -f psmdb-bp.yaml -n kasten-io ``` -Once MongoDB is running, you can populate it with some data. Let's add a collection called "ticker": +Once MongoDB is running, populate it with some data. Let's add a collection +called "ticker": ```bash MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) @@ -129,7 +132,7 @@ mongo "mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@m ``` Insert some data -``` +```bash db.createCollection("ticker") db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqhsj"} ) @@ -138,9 +141,10 @@ db.ticker.insert( {createdAt: new Date(), randomdata: "qstygshgqsfxxtqsfgqfhjqh db.ticker.find({}).sort({createdAt:-1}).limit(1) ``` -In order to test Point In Time Restore (PITR) create a ticker pod that add new entry every seconds. +In order to test Point-In-Time Restore (PITR), create a ticker pod that adds +a new entry every second. -``` +```bash MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) MONGODB_DATABASE_ADMIN_USER=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_USER}'|base64 -d) kubectl run percona-ticker \ @@ -150,18 +154,21 @@ kubectl run percona-ticker \ -- bash -c "while true; do mongo \"mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@my-cluster-name-mongos.mongodb.svc.cluster.local/admin?ssl=false\" --eval 'db.ticker.insert( {createdAt: new Date(), randomdata: \"qstygshgqsfxxtqsfgqfhjqhsj\"} )'; sleep 1; done" ``` -Reuse the percona-client to check you have a new entry every second, execute this command multiple times. -``` +Reuse the percona-client to check if a new entry is created every second. +Execute this command multiple times. +```bash db.ticker.find({}).sort({createdAt:-1}).limit(1) ``` **NOTE:** -If you change the storage name for something else than `my-s3-storage` in the cr.yaml file you need to change this name in the blueprint accordingly. +If the storage name is changed to something other than `my-s3-storage` in the +`cr.yaml` file, change this name in the blueprint accordingly. ## Protect the Application -You can now take a backup of the MongoDB data using an ActionSet defining backup for this application. Create an ActionSet in the same namespace as the controller. +The MongoDB data can be backed up using an ActionSet defining backup for this +application. Create an ActionSet in the same namespace as the controller. ```bash $ kubectl get profiles.cr.kanister.io -n mongodb @@ -182,26 +189,26 @@ backup-vvskw 2h $ kubectl --namespace kasten-io describe actionset backup-vvskw ``` -### Disaster strikes! +### Disaster Strikes! -Let's say someone with fat fingers accidentally deleted the mongo cluster and all the pvcs: +Let's say someone accidentally deleted the mongo cluster and all the PVCs: ```bash kubectl delete psmdb my-cluster-name kubectl delete po percona-ticker kubectl delete pvc --all ``` -All pods and pvc are now gone. Recreate the cluster -``` +All the pods and PVCs are now gone. Recreate the cluster +```bash kubectl apply -f cr.yaml ``` -Check the cluster is now ready -``` +Check if the cluster is now ready +```bash kubectl get psmdb ``` -If you try to access this data in the database, you should see that it is no longer there: +The data in the database is no longer there: ```bash MONGODB_DATABASE_ADMIN_PASSWORD=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_PASSWORD}'|base64 -d) MONGODB_DATABASE_ADMIN_USER=$(kubectl get secret my-cluster-name-secrets -ojsonpath='{.data.MONGODB_DATABASE_ADMIN_USER}'|base64 -d) @@ -214,15 +221,17 @@ kubectl run -i --rm --tty percona-client \ mongo "mongodb://$MONGODB_DATABASE_ADMIN_USER:$MONGODB_DATABASE_ADMIN_PASSWORD@my-cluster-name-mongos.mongodb.svc.cluster.local/admin?ssl=false" ``` -You should have no output when trying to query the ticker collections -``` +There should be no output when trying to query the ticker collections +```bash db.ticker.find({}).sort({createdAt:-1}).limit(1) ``` ### Restore the Application -To restore the missing data, you should use the backup that you created before. An easy way to do this is to leverage `kanctl`, a command-line tool that helps create ActionSets that depend on other ActionSets: +To restore the missing data, use the backup created earlier. An easy way to do +this is to leverage `kanctl`, a command-line tool that helps create ActionSets +that depend on other ActionSets: ```bash @@ -233,24 +242,26 @@ actionset restore-backup-vvskw-sfpm6 created kubectl --namespace kasten-io describe actionset restore-backup-vvskw-sfpm6 ``` -You should now see that the data has been successfully restored to MongoDB! +The data should now be successfully restored to MongoDB! ```bash db.ticker.find({}).sort({createdAt:-1}).limit(1) { "_id" : ObjectId("637372caf98744ac5a6e4aae"), "createdAt" : ISODate("2022-11-15T11:06:50.296Z"), "randomdata" : "qstygshgqsfxxtqsfgqfhjqhsj" } ``` -#### Point In Time Restore +#### Point-In-Time Restore -Let's say the backup was at 15th Nov 2022 at 15:11 and we want to restore at a specific point in time after the backup at 15:13:10 the same day +Let's say the backup was at 15th Nov 2022 at 15:11 and we want to restore at a +specific point in time after the backup at 15:13:10 the same day -``` +```bash kanctl --namespace kasten-io create actionset --action restore --from "backup-vvskw" --options pitr="2022-11-15 15:13:10" ``` ### Delete the Artifacts -The artifacts created by the backup action can be cleaned up using the following command: +The artifacts created by the backup action can be cleaned up using the +following command: ```bash $ kanctl --namespace kasten-io create actionset --action delete --from "backup-vvskw" @@ -262,23 +273,24 @@ $ kubectl --namespace kasten-io describe actionset delete-backup-vvskw-xh29t **NOTE:** -To have the delete action working we need the operator up and running. +To have the delete action working, we need the operator up and running. ### Troubleshooting -If you run into any issues with the above commands, you can check the logs of the controller using: +In case of issues with the above commands, check the logs of the controller +using: ```bash $ kubectl --namespace kasten-io logs -l app=kanister-operator ``` -you can also check events of the actionset +Check events of the ActionSet ```bash $ kubectl describe actionset restore-backup-vvskw-sfpm6 -n kasten-io ``` -## Uninstalling the operator and the blueprint +## Uninstalling the Operator and the Blueprint To uninstall/delete the mongodb cluster and the operator: @@ -290,7 +302,8 @@ kubectl delete -f https://raw.githubusercontent.com/percona/percona-server-mongo kubectl delete ns mongodb ``` -The command removes all the Kubernetes components associated with the operator and deletes the mongodb namespace. +The command removes all the Kubernetes components associated with the operator +and deletes the `mongodb` namespace. Delete Blueprint and Profile CR diff --git a/examples/mongodb-percona/psmdb-bp.yaml b/examples/mongodb-percona/psmdb-bp.yaml index bb2f190338..50651fe24c 100644 --- a/examples/mongodb-percona/psmdb-bp.yaml +++ b/examples/mongodb-percona/psmdb-bp.yaml @@ -101,4 +101,4 @@ actions: group: psmdb.percona.com resource: perconaservermongodbrestores name: 'restore-{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02t15-04-05z07-00" }}' - namespace: "{{ .Object.metadata.namespace}}" \ No newline at end of file + namespace: "{{ .Object.metadata.namespace}}"