{"id":15859319,"url":"https://github.com/michaelcade/argocd-kanister","last_synced_at":"2025-03-15T23:30:55.851Z","repository":{"id":44773361,"uuid":"447008793","full_name":"MichaelCade/argocd-kanister","owner":"MichaelCade","description":null,"archived":false,"fork":false,"pushed_at":"2022-02-08T18:48:34.000Z","size":32,"stargazers_count":5,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-27T04:24:56.705Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MichaelCade.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-11T23:07:18.000Z","updated_at":"2023-12-09T16:33:08.000Z","dependencies_parsed_at":"2022-09-19T06:41:06.610Z","dependency_job_id":null,"html_url":"https://github.com/MichaelCade/argocd-kanister","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichaelCade%2Fargocd-kanister","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichaelCade%2Fargocd-kanister/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichaelCade%2Fargocd-kanister/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichaelCade%2Fargocd-kanister/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MichaelCade","download_url":"https://codeload.github.com/MichaelCade/argocd-kanister/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243801610,"owners_count":20350106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-05T21:05:23.253Z","updated_at":"2025-03-15T23:30:55.562Z","avatar_url":"https://github.com/MichaelCade.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Integrating Backup into your CI/CD Pipelines using Kanister  \r\n\r\nDeploy local Minikube cluster \r\n\r\nminikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --kubernetes-version=1.21.2\r\n\r\n\r\n## How to Install Kanister \r\n\r\nadd kanister helm repository \r\n```\r\nhelm repo add kanister https://charts.kanister.io/\r\n```\r\ncreate kanister namespace\r\n```\r\nkubectl create namespace kanister \r\n```\r\ndeploy kanister using helm \r\n```\r\nhelm install myrelease --namespace kanister kanister/kanister-operator --set image.tag=0.71.0\r\n```\r\n\r\nOnce we have kanister deployed we should now show the CustomResourceDefinitions, this will show actionsets, blueprints, profiles.\r\n\r\n```\r\nkubectl get customresourcedefinitions.apiextensions.k8s.io | grep \"kanister\"\r\n```\r\n\r\n## Deploy ArgoCD \r\n\r\n```\r\nkubectl create namespace argocd\r\nkubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml\r\nkubectl port-forward svc/argocd-server -n argocd 8443:443\r\n```\r\n\r\nUsername is admin and password can be obtained with this command. open a web browser [localhost](https://localhost:8443)\r\n\r\n``` \r\nkubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=\"{.data.password}\" | base64 -d \u0026\u0026 echo\r\n```\r\n\r\n## Create a bucket in minikube with minio\r\n\r\nEnable load balancer in minikube \r\n```\r\n# run this command in another terminal\r\nminikube tunnel --profile=mc-demo\r\n```\r\n\r\nInstall minio\r\n```\r\nhelm repo add minio https://charts.min.io/\r\nkubectl create ns minio\r\nhelm install kasten-minio minio/minio --namespace=minio --version 8.0.10 \\\r\n  --set persistence.size=5Gi\r\n\r\n# feed ACCESS_KEY variable and SECRET_KEY and display them\r\nAWS_ACCESS_KEY_ID=$(kubectl -n minio get secret kasten-minio -o jsonpath=\"{.data.accesskey}\" | base64 --decode)\r\necho $AWS_ACCESS_KEY_ID\r\nAWS_SECRET_KEY=$(kubectl -n minio get secret kasten-minio -o jsonpath=\"{.data.secretkey}\" | base64 --decode)\r\necho $AWS_SECRET_KEY\r\n\r\n# Expose minio in a load balancer \r\nkubectl expose svc/kasten-minio --name=minio-lb -n minio --type=LoadBalancer\r\nEXTERNAL_IP=$(kubectl get svc -n minio minio-lb -o jsonpath='{.spec.clusterIP}')\r\necho \"http://$EXTERNAL_IP:9000/\"\r\n```\r\n\r\nopen a web browser to this addres and use `$ACCESS_KEY`and `$SECRET_KEY` to access th minio GUI.\r\n\r\nCreate a `kanister` bucket.\r\n\r\n\r\n## Create a Kanister Profile \r\nThis will give us some where to store our backups, this will be done using the KanCTL CLI tool \r\n\r\n```\r\nkanctl create profile \\\r\n   --namespace kanister \\\r\n   --bucket kanister \\\r\n   --skip-SSL-verification \\\r\n   --endpoint http://$EXTERNAL_IP:9000/ \\\r\n   s3compliant \\\r\n   --access-key $AWS_ACCESS_KEY_ID \\\r\n   --secret-key $AWS_SECRET_KEY\r\n```\r\n\r\nconfirm you now have a profile created \r\n```\r\nkubectl get profile -n kanister\r\n```\r\n\r\n## Creating a Kanister Blueprint \r\n\r\nKanister uses Blueprints to define these database-specific workflows and open-source Blueprints are available for several popular applications. It's also simple to customize existing Blueprints or add new ones.\r\n\r\n\r\n```\r\nkubectl create -f https://raw.githubusercontent.com/kanisterio/kanister/master/examples/stable/mysql/mysql-blueprint.yaml -n kanister\r\n```\r\n\r\nthis blueprint is created in the Kanister namespace check with environment\r\n\r\n```\r\nkubectl get blueprint -n kanister \r\n```\r\n\r\n# Use argo to deploy your app\r\n\r\n## Create the argo project\r\n\r\nCreate a mysql namespace.\r\n``` \r\nkubectl create ns mysql\r\n```\r\n\r\nCreate in argo a new project mysql-app :\r\n- project name : mysql\r\n- use the default project \r\n- git repo : your git repo (eg: https://github.com/michaelcourcy/argocd-kanister.git)\r\n- path : base\r\n- namespace: mysql\r\n- choose the default or availables values for the rest\r\n\r\nOnce deployed, check the service account kanister-presync can create an action or read a profile set in the kanister namespace.\r\n\r\n```\r\nkubectl auth can-i create actionset --as=system:serviceaccount:mysql:kanister-presync -n kanister\r\nkubectl auth can-i create profile --as=system:serviceaccount:mysql:kanister-presync -n kanister\r\n```\r\n\r\nThe answer should be yes for both.\r\n\r\n## Create some data \r\n\r\n```\r\nkubectl exec -ti mysql-0 -n mysql -- bash\r\n\r\nmysql --user=root --password=ultrasecurepassword\r\nCREATE DATABASE test;\r\nUSE test;\r\nCREATE TABLE pets (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);\r\nINSERT INTO pets VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);\r\nSELECT * FROM pets;\r\n+----------+-------+---------+------+------------+-------+\r\n| name     | owner | species | sex  | birth      | death |\r\n+----------+-------+---------+------+------------+-------+\r\n| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |\r\n+----------+-------+---------+------+------------+-------+\r\n1 row in set (0.00 sec)\r\nexit\r\nexit\r\n```\r\n\r\n## Sync your project \r\n\r\nBy resyncing your project you're going to trigger the creation of a backup. check on minio.\r\n\r\n## Introduce some \"bad\" change in your application stack.\r\n\r\nLet's imagine you create a mysqlclient app which is going to drop your database in your code, that's a mistake. But mistake happen. \r\n\r\nCreate this pod base/mysql-client.yaml \r\n\r\n```\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n  labels:\r\n    run: mysql-client\r\n  name: mysql-client\r\nspec:\r\n  containers:\r\n  - image: mysql:8.0.26\r\n    name: mysql-client\r\n    env:\r\n    - name: MYSQL_ROOT_PASSWORD\r\n      valueFrom:\r\n        secretKeyRef:\r\n          key: mysql-root-password\r\n          name: mysql\r\n    command: \r\n      - sh\r\n      - -o\r\n      - errexit\r\n      - -c\r\n      - |         \r\n        mysql -h mysql --user=root --password=$MYSQL_ROOT_PASSWORD -e \"DROP DATABASE test;\"\r\n  dnsPolicy: ClusterFirst\r\n  restartPolicy: Never\r\nstatus: {}\r\n```\r\n\r\nYou commit, push and sync with argo and check your data \r\n\r\n```\r\nkubectl exec -ti mysql-0 -n mysql -- bash\r\n\r\nmysql --user=root --password=ultrasecurepassword\r\nSHOW DATABASES;\r\n\r\n+--------------------+\r\n| Database           |\r\n+--------------------+\r\n| information_schema |\r\n| mysql              |\r\n| performance_schema |\r\n| sys                |\r\n+--------------------+\r\n4 rows in set (0.00 sec)\r\n```\r\n\r\nHorror !!! The sync has deleted the database but fortunaletly kanister protects your database in the execution of the presync.\r\n\r\n# Restore your database using kanctl\r\n\r\nThe sync above represents a simple change in code that could affect our data, at this stage the bad `mysql-client.yaml` should be removed or configured correctly before continuing with the restore process. \r\n\r\nBefore we restore we need to choose the appropriate restore point. \r\n\r\n`kubectl get actionset -n kanister`\r\n\r\n```\r\nNAME                                           AGE\r\nmysqlapp-backup-tue-jan-25-17-46-46-utc-2022   10m\r\nmysqlapp-backup-tue-jan-25-17-50-45-utc-2022   6m56s\r\n```\r\nWhen we have the list we can choose the correct actionset to restore from. \r\n\r\n`kanctl --namespace kanister create actionset --action restore --from \"mysqlapp-backup-tue-jan-25-17-50-45-utc-2022\"`\r\n\r\n```\r\nactionset restore-mysqlapp-backup-tue-jan-25-17-50-45-utc-2022-hsjvv created\r\n```\r\nNow we can see in detail what is happening as part of the restore process. \r\n\r\n\r\n`kubectl --namespace kanister describe actionset restore-mysqlapp-backup-tue-jan-25-17-50-45-utc-2022-hsjvv`\r\n\r\n\r\nWe can then go and check on our data and database again and make sure that our test database is restored along with our data. \r\n\r\n```\r\nkubectl exec -ti mysql-0 -n mysql -- bash\r\n\r\nmysql --user=root --password=ultrasecurepassword\r\nCREATE DATABASE test;\r\nUSE test;\r\nSELECT * FROM pets;\r\n+----------+-------+---------+------+------------+-------+\r\n| name     | owner | species | sex  | birth      | death |\r\n+----------+-------+---------+------+------------+-------+\r\n| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |\r\n+----------+-------+---------+------+------------+-------+\r\n1 row in set (0.00 sec)\r\n\r\nSHOW DATABASES;\r\n\r\nexit\r\nexit\r\n```\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelcade%2Fargocd-kanister","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelcade%2Fargocd-kanister","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelcade%2Fargocd-kanister/lists"}