Backup Azure Kubernetes Service (AKS) ด้วย Velero และ Azure Disk CSI Driver
หลายๆ ท่าน คงมีคำถาม หรือ เจอปัญหาว่า เราจะ Backup Kubernetes Resources บน Azure Kubernetes Service อย่างไร? วันนี้เราจะพาทุกท่าน Backup Kubernetes Resource กัน โดยยกตัวอย่างง่ายๆ จาก Wordpress ที่มี MariaDB เป็น Database Storage และมีการ Mount Azure Disk เป็น Persistent Volume สำหรับ MariaDB
มาเริ่มกันเลยครับ!
สิ่งที่ต้องเตรียมก่อน (สำหรับใครที่อยากลองไปพร้อมๆ กับ ผม):
- Azure Account (สำหรับใครไม่มี User, ถ้าทำการสมัครสมาชิกใหม่ ทาง Microsoft มีให้ $200 Credit นะครับ), สมัครเลย
Architecture สำหรับการ Setup ครั้งนี้:

จากภาพ:
เราจะทำการสร้าง vnet ชื่อว่า s-demo-vnet ที่มี CIDR: 10.0.0.0/16 และ subnet ชื่อว่า s-demo-snet ที่มี CIDR: 10.0.1.0/24
และ
สร้าง AKS Cluster ใน Subnet: s-demo-snet จากนั้นทำการ Install Wordpress, สร้าง Blob Storage Account ชื่อ velero-blob, Managed identity ชื่อ velero และท้ายสุด ทำการ Install Velero และ Map Managed Identity Token เพื่อเก็บ Backup Files บน Blob Storage Account ที่เราได้สร้างขึ้น ด้วย AAD Pod Identity
เรามาเริ่มกันเลย!
- การสร้าง resource group ชื่อว่า s-demo
$ az group create --name s-demo --location westus

2. ทำการสร้าง vnet ชื่อว่า s-demo-vnet ที่มี CIDR: 10.0.0.0/16
$ az network vnet create --resource-group s-demo --name s-demo-vnet --address-prefixes 10.0.0.0/16

3. ทำการสร้าง subnet ชื่อว่า s-demo-snet ที่มี CIDR: 10.0.1.0/24
$ az network vnet subnet create --resource-group s-demo --vnet-name s-demo-vnet --name s-demo-snet --address-prefixes 10.0.1.0/24

4. ทำการสร้าง AKS Cluster และ Default Node Pool
$ az aks create --resource-group s-demo -n s-demo-cluster --vnet-subnet-id "/subscriptions/[your-subscription-id]/resourceGroups/s-demo/providers/Microsoft.Network/virtualNetworks/s-demo-vnet/subnets/s-demo-snet" --node-count=1 --service-cidr 10.0.2.0/24 --dns-service-ip 10.0.2.6 --network-plugin azure --enable-managed-identity

สร้าง AKS Cluster เสร็จแล้ว !
จากนั้นทำการ Assign Permission ให้ Agent Pool Managed Identity (s-demo-cluster-agentpool) จัดการ Managed Identity และ VM ได้ เพื่อรองรับการทำงานของ AAD Pod Identity
$ export IDENTITY_CLIENT_ID="$(az identity show -g MC_s-demo_s-demo-cluster_westus -n s-demo-cluster-agentpool --subscription [your-subscription-id] --query clientId -otsv)"$ az role assignment create --role "Managed Identity Operator" --assignee $IDENTITY_CLIENT_ID --scope "/subscriptions/[your-subscription-id]/resourceGroups/s-demo" --query id -otsvaz role assignment create --role "Managed Identity Operator" --assignee $IDENTITY_CLIENT_ID --scope "/subscriptions/[your-subscription-id]/resourceGroups/MC_s-demo_s-demo-cluster_westus" --query id -otsv$ az role assignment create --role "Virtual Machine Contributor" --assignee $IDENTITY_CLIENT_ID --scope "/subscriptions/[your-subscription-id]/resourceGroups/MC_s-demo_s-demo-cluster_westus" --query id -otsv

5. ทำการสร้าง Storage Account และ Blob Container ชื่อ velero-blob เพื่อเก็บ Backup Files ของ Velero
สร้าง Storage Account ดังนี้
$ az storage account create --name velerosdemoaccount --resource-group s-demo --sku Standard_LRS --encryption-services blob --https-only true --kind BlobStorage --access-tier Hot

สร้าง Blob Container ดังนี้
$ az storage container create -n velero-blob --public-access off --account-name velerosdemoaccount

6. ทำการสร้าง Managed identity ชื่อ velero และ Assign Permission ให้ Access Blob Container ชื่อ velero-blob ได้
สร้าง Managed identity ดังนี้
$ az identity create --subscription [your-subscription-id] --resource-group s-demo --name velero

Assign Permission สำหรับ Access Blob Container ชื่อ velero-blob
$ export IDENTITY_CLIENT_ID="$(az identity show -g s-demo -n velero --subscription [your-subscription-id] --query clientId -otsv)"$ az role assignment create --role "Storage Account Contributor" --assignee $IDENTITY_CLIENT_ID --scope "/subscriptions/[your-subscription-id]/resourceGroups/s-demo/providers/Microsoft.Storage/storageAccounts/velerosdemoaccount" --query id -otsv

7. ทำการติดตั้ง AAD Pod Identity เพื่อ Map Managed Identity Token สำหรับ Access Blob Container ไปที่ Velero ที่จะลง
*** ท่านสามารถศึกษา AAD Pod Identity เพิ่มเติมได้ที่
เชื่อมต่อกับ AKS Cluster
$ az aks get-credentials --resource-group s-demo --name s-demo-cluster --admin

Add Helm AAD Pod Identity Repository
$ helm repo add aad-pod-identity https://raw.githubusercontent.com/Azure/aad-pod-identity/master/charts$ helm repo update
Install AAD Pod Idenity
$ helm install aad-pod-identity -n kube-system aad-pod-identity/aad-pod-identity

8. ทำการสร้าง AzureIdentity และ AzureIdentityBinding เพื่อ Map Managed Identity Token ไปที่ Velero ที่จะลง
$ export IDENTITY_RESOURCE_ID="$(az identity show -g s-demo -n velero --subscription [your-subscription-id] --query id -otsv)"$ kubectl create namespace velero$ cat <<EOF | kubectl apply -f -
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
name: velero-ai
namespace: velero
spec:
type: 0
resourceID: $IDENTITY_RESOURCE_ID
clientID: $IDENTITY_CLIENT_ID
EOF
$ cat <<EOF | kubectl apply -f -
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
name: velero-ai-binding
namespace: velero
spec:
azureIdentity: velero-ai
selector: velero-ai
EOF
9. ทำการติดตั้ง Velero
สร้างไฟล์ credentials-velero เพื่อให้ Velero สามารถเชื่อมต่อกับ Azure ได้
$ cat <<EOF >> credentials-velero
AZURE_SUBSCRIPTION_ID=[your-subscription-id]
AZURE_RESOURCE_GROUP=s-demo
AZURE_CLOUD_NAME=AzurePublicCloud
EOF

ทำการติดตั้ง Velero
$ velero install --provider azure --plugins velero/velero-plugin-for-microsoft-azure:v1.2.0,velero/velero-plugin-for-csi:v0.1.2 --bucket velero-blob --secret-file ./credentials-velero --backup-location-config 'resourceGroup=s-demo,storageAccount=velerosdemoaccount,subscriptionId=[your-subscription-id]' --snapshot-location-config 'apiTimeout=5m,resourceGroup=s-demo,subscriptionId=[your-subscription-id]' --image velero/velero:v1.6.3 --use-restic --use-volume-snapshots --features=EnableCSI
Parameters ที่ควรรู้:
--use-restic - สร้าง Restic Daemonset เพื่อช่วยในการ Backup Files
--use-volume-snapshots - สร้าง volume snapshot location อัตโนมัติ

ติดตั้ง Velero เสร็จแล้วครับ !
จากนั้นให้ Assign AzureIdentityBinding ไปที่ Velero เพื่อ Map Managed Identity Token
$ kubectl label pods aadpodidbinding=velero-ai -l component=velero -n velero
10. สร้าง Velero Backup Location ชื่อ velerosdemoaccount
สร้างไฟล์ bsl-credentials เพื่อให้ Velero สามารถเชื่อมต่อกับ Azure ได้
$ kubectl create secret generic -n velero bsl-credentials --from-file=azure=./credentials-velero

$ velero backup-location create velerosdemoaccount --provider azure --bucket velero-blob --config 'resourceGroup=s-demo,storageAccount=velerosdemoaccount,subscriptionId=[your-subscription-id]' --credential=bsl-credentials=azure --features=EnableCSI

จะเห็นว่าเราได้ Velero Backup Location เรียบร้อยแล้ว นั้นคือ ที่เก็บ Backup Files สำหรับ Velero ตอนที่เราทำการ Backup
11. Enable Azure Disk CSI Driver สำหรับ Persistent Volume ของ Wordpress
Assign Permission ให้ Agent Pool Managed Identity (s-demo-cluster-agentpool) จัดการ Node Pool ของ AKS Cluster ที่เราสร้างขึ้น เพื่อรองรับการทำงานของ Azure Disk CSI Driver
$ az role assignment create --role "Contributor" --assignee $IDENTITY_CLIENT_ID --scope "/subscriptions/[your-subscription-id]/resourceGroups/MC_s-demo_s-demo-cluster_westus" --query id -otsv

Enable Azure Disk CSI Driver ไปที่ AKS Cluster ที่เราสร้างขึ้น
$ curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/install-driver.sh | bash -s master snapshot --

12. ทำการสร้าง Storage Class เพื่อ Provision Persistent Volume ของ Wordpress
$ kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/example/storageclass-azuredisk-csi.yaml

13. ทำการ Deploy Wordpress ด้วย Storage Class นี้
Download Wordpress Config
$ wget https://gist.githubusercontent.com/dmakeroam/46cc530120f5d069b8c4842837fd768a/raw/b5e7a94c2f5e54a5e198fb8061b274690f16db61/wordpress.yaml
Add Bitnami Repository
$ helm repo add bitnami https://charts.bitnami.com/bitnami$ helm repo update
Deploy Wordpress
$ kubectl create ns wordpress$ helm install wordpress-site -n wordpress bitnami/wordpress --version 12.1.10 -f wordpress.yaml

Deploy Wordpress เสร็จแล้วน้า
14. ทำการ Backup Wordpress
$ velero backup create wordpress-backup-poc --include-namespaces "wordpress" --storage-location velerosdemoaccount

15. ทำการ Delete Wordpress
$ kubectl delete ns wordpress

16. ทำการ Restore Wordpress from Backup Files
$ velero create restore --from-backup wordpress-backup-poc --exclude-resources PersistentVolumes

จะเห็นว่าเราได้ Wordpress กลับมาแล้ว !

จะเห็นได้ว่า Velero และ Azure CSI Driver ช่วยตอบโจทย์การ Backup Kubernetes Resources พอสมควร เพียงแค่ไม่กี่ Commands ก็สามารถ Backup Kubernetes Resource ได้แล้ว
สำหรับท่านไหนที่สนใจศึกษาเพิ่มเติม สามารถศึกษาต่อได้ที่