We will install Velero to backup and restore Kubernetes cluster resources to AWS S3.
Pre-requisites
We are using our Kubernetes homelab in this article.
Configuration files used in this article can be found on GitHub. Clone the following repository:
$ git clone https://github.com/lisenet/kubernetes-homelab.git $ cd ./kubernetes-homelab/kubernetes/helm/velero/
Access to AWS account is required. Free Tier provides 5GB of S3 storage for 12 months.
The Plan
- Install Helm.
- Configure AWS S3 bucket and IAM credentials.
- Install Velero to the Kubernetes cluster using Helm.
- Install Velero client.
- Create a backup and a backup schedule.
- Test the backup by restoring Kubernetes resources from it.
Install Helm
On a Debian-based OS, do the following:
$ curl https://baltocdn.com/helm/signing.asc | sudo apt-key add - $ sudo apt-get install -y apt-transport-https $ echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list $ sudo apt-get update $ sudo apt-get install -y helm
Add Helm repository:
$ helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
Configure AWS S3 Bucket and IAM Credentials
Create an S3 bucket. We use Terraform to do that. Also, create an IAM user for Velero that has the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeVolumes",
"ec2:DescribeSnapshots",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:CreateSnapshot",
"ec2:DeleteSnapshot"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::${BUCKET}/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::${BUCKET}"
]
}
]
}
Save IAM user’s access keys in a file velero-credentials.txt, e.g.:
[default] aws_access_key_id = AWS_ACCESS_KEY_ID aws_secret_access_key = AWS_SECRET_ACCESS_KEY
Deploy Velero
Create velero namespace inside the Kubernetes cluster:
$ kubectl create namespace velero
Install Velero using Helm. See the content of the values.yaml file on GitHub.
$ helm upgrade --install velero \ vmware-tanzu/velero \ --namespace velero \ --version "2.28.1" \ --set-file credentials.secretContents.cloud=velero-credentials.txt \ --values ./values.yaml
Install Velero Client
When Velero server is up and running, we are going to need to install the client before we can use it:
$ export VELERO_VERSION="1.8.1"
$ wget https://github.com/vmware-tanzu/velero/releases/download/v${VELERO_VERSION}/velero-v${VELERO_VERSION}-linux-amd64.tar.gz
$ tar xf velero-v${VELERO_VERSION}-linux-amd64.tar.gz
$ sudo mv velero-v${VELERO_VERSION}-linux-amd64/velero /usr/local/bin/
$ sudo chown root:root /usr/local/bin/velero
Create Backups and Backup Schedules
First of all, verify our backup location:
$ velero backup-location get NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT default aws kubernetes-homelab-velero-backups Available 2022-05-20 01:28:00 +0100 BST ReadWrite true
List all namespaces in the Kubernetes cluster:
$ kubectl get namespace -o name namespace/argocd namespace/default namespace/democratic-csi namespace/httpd-healthcheck namespace/istio-system namespace/kube-node-lease namespace/kube-public namespace/kube-system namespace/kubecost namespace/kubernetes-dashboard namespace/logging namespace/metallb-system namespace/monitoring namespace/openvpn namespace/pii-demo namespace/speedtest namespace/velero
We want to backup all of them but the velero one. Create a Velero backup job for each namespace:
$ for i in $(kubectl get ns -o name|cut -d"/" -f2|grep -ve velero);do \
velero backup create "${i}" --include-namespaces "${i}"; \
done
Create a backup schedule for each namespace to run daily at 2AM:
$ for i in $(kubectl get ns -o name|cut -d"/" -f2|grep -ve velero);do \
velero create schedule "${i}" --schedule="0 2 * * *" --include-namespaces "${i}"; \
done
Verify schedules by running the following command:
$ velero schedule get NAME STATUS CREATED SCHEDULE BACKUP TTL LAST BACKUP SELECTOR default Enabled 2022-03-20 23:24:26 +0000 GMT 0 2 * * * 720h0m0s 22h ago none democratic-csi Enabled 2022-03-20 23:24:26 +0000 GMT 0 2 * * * 720h0m0s 22h ago none httpd-healthcheck Enabled 2022-03-20 23:24:27 +0000 GMT 0 2 * * * 720h0m0s 22h ago none istio-system Enabled 2022-03-20 23:24:27 +0000 GMT 0 2 * * * 720h0m0s 22h ago none kube-node-lease Enabled 2022-03-20 23:24:27 +0000 GMT 0 2 * * * 720h0m0s 22h ago none kube-public Enabled 2022-03-20 23:24:27 +0000 GMT 0 2 * * * 720h0m0s 22h ago none kube-system Enabled 2022-03-20 23:24:28 +0000 GMT 0 2 * * * 720h0m0s 22h ago none kubecost Enabled 2022-03-20 23:24:28 +0000 GMT 0 2 * * * 720h0m0s 22h ago none kubernetes-dashboard Enabled 2022-03-20 23:24:28 +0000 GMT 0 2 * * * 720h0m0s 22h ago none logging Enabled 2022-03-20 23:24:29 +0000 GMT 0 2 * * * 720h0m0s 22h ago none metallb-system Enabled 2022-03-20 23:24:29 +0000 GMT 0 2 * * * 720h0m0s 22h ago none monitoring Enabled 2022-03-20 23:24:29 +0000 GMT 0 2 * * * 720h0m0s 22h ago none openvpn Enabled 2022-03-20 23:24:30 +0000 GMT 0 2 * * * 720h0m0s 22h ago none pii-demo Enabled 2022-03-20 23:24:30 +0000 GMT 0 2 * * * 720h0m0s 22h ago none speedtest Enabled 2022-03-20 23:24:30 +0000 GMT 0 2 * * * 720h0m0s 22h ago none
Test Velero Backup Restore
We are going to delete our Grafana deployment configuration from the monitoring namespace.
$ kubectl -n monitoring delete deploy grafana $ kubectl -n monitoring get deploy grafana Error from server (NotFound): deployments.apps "grafana" not found
Retrieve the name of the most recent backup for the monitoring namespace:
$ velero backup get | grep monitoring | head -n1 monitoring-20220519020037 Completed 0 0 2022-05-19 03:01:19 +0100 BST 29d default none
Submit a restore request to the server:
$ velero restore create monitoring --from-backup monitoring-20220519020037
Check the job status:
$ velero restore describe monitoring Name: monitoring Namespace: velero Labels: Annotations: Phase: Completed Total items to be restored: 153 Items restored: 153 Started: 2022-05-20 01:53:09 +0100 BST Completed: 2022-05-20 01:53:31 +0100 BST
Grafana pod should now be running again:
$ kubectl -n monitoring get deploy grafana NAME READY UP-TO-DATE AVAILABLE AGE grafana 1/1 1 1 112s
References
https://github.com/vmware-tanzu/velero-plugin-for-aws
