ทำการ enable velero ที่ nkp dashboard เนื่องจาก velero ต้องการ s3 storage เพื่อเก็บข้อมูล backup จึงต้อง enable rookceph และ rookceph cluster โดยจะต้องรอจนกว่าจะ running สมบูรณ์ก่อนจะ enable velero

เพิ่ม custom config เพื่อให้ Velero สามารถ backup persistent volume ได้
configuration:
backupStorageLocation:
- bucket: dkp-velero
config:
region: dkp-object-store
s3Url: https://10.38.16.132:8085
s3ForcePathStyle: "true"
insecureSkipTLSVerify: true
profile: default
provider: aws
credential:
key: aws
name: dkp-velero-ceph
features: EnableCSI
uploaderType: kopia
volumeSnapshotLocation:
- bucket: dkp-velero
config:
region: dkp-object-store
s3Url: https://10.38.16.132:8085
provider: aws
deployNodeAgent: true
initContainers:
- image: velero/velero-plugin-for-aws:v1.11.1
imagePullPolicy: IfNotPresent
name: velero-plugin-for-aws
volumeMounts:
- mountPath: /target
name: plugins
nodeAgent:
annotations:
secret.reloader.stakater.com/reload: dkp-velero-ceph
priorityClassName: dkp-critical-priority
resources:
limits: null


ข้อมูล custom configuration ต้องการ s3 bucket และ secret key เพื่อ connect ไปยัง s3 bucket โดยสร้าง secret key ได้ตามตัวอย่างดังนี้
apiVersion: v1
kind: Secret
metadata:
name: dkp-velero-ceph
namespace: kommander-default-workspace
type: Opaque
stringData:
aws: |
[default]
aws_access_key_id = 2N8IL5CIUIWHR2MC287L
aws_secret_access_key = bNzQDPy23GzdWKDuokZOtlT1fO7oR01YcOTicBCM
หลังจาก enable แล้วตรวจสอบว่า velero pod ทำงานได้ปกติ รวมถึงตรวจสอบ backup location และ volume snapshot location
~/repos/note k get pod -A | grep velero
kommander object-bucket-claims-check-dkp-velero-229gs 0/1 Completed 0 10d
kommander velero-54db8ff6f8-vcvfw 1/1 Running 0 12m
kommander velero-backup-storage-location-updater-5d849446c9-kt4h8 1/1 Running 0 11m
kommander velero-pre-install-wt6nv 0/1 Completed 0 13m
~/repos/lab k get backupstoragelocations -A
NAMESPACE NAME PHASE LAST VALIDATED AGE DEFAULT
kommander default Available 1s 25m true
~/repos/lab k get volumesnapshotlocations -A
NAMESPACE NAME AGE
kommander default 26m
ติดตั้ง Velero cli สำหรับการใช้งาน
# For Apple Silicon Macs (M1/M2/M3) Download ARM64 version
curl -LO https://github.com/vmware-tanzu/velero/releases/latest/download/velero-darwin-arm64.tar.gz
# Extract and install
tar -xzf velero-darwin-arm64.tar.gz
sudo mv velero-*/velero /usr/local/bin/
chmod +x /usr/local/bin/velero
rm -rf velero-* velero-darwin-arm64.tar.gz
#Ubuntu/Debian (APT)
# Add Velero repository
curl -s https://packagecloud.io/install/repositories/vmware/velero/script.deb.sh | sudo bash
# Install Velero
sudo apt-get install velero
#CentOS/RHEL/Fedora (YUM/DNF)
# Add Velero repository
curl -s https://packagecloud.io/install/repositories/vmware/velero/script.rpm.sh | sudo bash
# Install Velero (CentOS/RHEL)
sudo yum install velero
# Or for Fedora
sudo dnf install velero
ตรวจสอบ version ของ Velero หลังจากติดตั้ง
~/repos/note velero version
Client:
Version: v1.15.2
Git commit: 804d73c4f2349f1ca9bd3d6c751956e1d2021c01
Velero จะใช้ kubeconfig file เพื่อ connect ไปยัง kubernetes จึงต้อง export kubeconfig environment ก่อน จากนั้นตรวจสอบว่า velero เห็น backup location หรือไม่
~/repos/lab export KUBECONFIG=/Users/pongsak.khamdee/repos/lab/cluster2-kubeconfig.yaml
~/repos/lab velero get backup-location -n kommander
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws dkp-velero Available 2025-07-03 21:54:38 +0700 +07 ReadWrite true
~/repos/lab velero get snapshot-location -n kommander
NAME PROVIDER
default aws
ติดตั้ง wordpress เพื่อใช้ในการทดสอบ backup และ restore โดยติดตั้งที่ namespace application ตามตัวอย่าง yaml ดังนี้
apiVersion: v1
kind: Secret
metadata:
name: mysql-pass
type: Opaque
stringData:
password: nutanix
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:8.0
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:6.4-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DEBUG
value: "1"
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
spec:
ingressClassName: kommander-traefik
rules:
- host: wordpress.10.38.204.16.sslip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress
port:
number: 80
ตรวจสอบว่า wordpress ทำงานได้ปกติ และเพิ่ม page เข้าไปใน wordpress เพื่อใช้ในการตรวจสอบการ restore
~/repos/lab k get pod -n application
NAME READY STATUS RESTARTS AGE
wordpress-57ff4b4485-6tl9g 1/1 Running 0 10h
wordpress-mysql-6dd978bc8b-jr2gq 1/1 Running 0 10h
ทำการ backup wordpress ด้วย velero cli
[nutanix@harbor ~]$ velero backup create wordpress10 --include-namespaces application --snapshot-volumes=true -n kommander --wait
Backup request "wordpress10" submitted successfully.
Waiting for backup to complete. You may safely press ctrl-c to stop waiting - your backup will continue in the background.
.............
Backup completed with status: Completed. You may check for more information using the commands `velero backup describe wordpress10` and `velero backup logs wordpress10`.
ตรวจสอบข้อมูลที่ velero ทำการ backup ได้จาก cli ดังนี้
[nutanix@harbor ~]$ velero backup describe wordpress10 --insecure-skip-tls-verify -n kommander --details
Name: wordpress10
Namespace: kommander
Labels: velero.io/storage-location=default
Annotations: velero.io/resource-timeout=10m0s
velero.io/source-cluster-k8s-gitversion=v1.31.4
velero.io/source-cluster-k8s-major-version=1
velero.io/source-cluster-k8s-minor-version=31
Phase: Completed
Namespaces:
Included: application
Excluded: <none>
Resources:
Included: *
Excluded: <none>
Cluster-scoped: auto
Label selector: <none>
Or label selector: <none>
Storage Location: default
Velero-Native Snapshot PVs: true
Snapshot Move Data: false
Data Mover: velero
TTL: 720h0m0s
CSISnapshotTimeout: 10m0s
ItemOperationTimeout: 4h0m0s
Hooks: <none>
Backup Format Version: 1.1.0
Started: 2025-07-06 08:13:24 +0000 UTC
Completed: 2025-07-06 08:13:37 +0000 UTC
Expiration: 2025-08-05 08:13:24 +0000 UTC
Total items to be backed up: 29
Items backed up: 29
Backup Item Operations:
Operation for volumesnapshots.snapshot.storage.k8s.io application/velero-wp-pv-claim-hwnp8:
Backup Item Action Plugin: velero.io/csi-volumesnapshot-backupper
Operation ID: application/velero-wp-pv-claim-hwnp8/2025-07-06T08:13:32Z
Items to Update:
volumesnapshots.snapshot.storage.k8s.io application/velero-wp-pv-claim-hwnp8
volumesnapshotcontents.snapshot.storage.k8s.io /snapcontent-7e8eaf1f-5c59-46ec-9356-887e65b15769
Phase: Completed
Created: 2025-07-06 08:13:32 +0000 UTC
Started: 2025-07-06 08:13:32 +0000 UTC
Updated: 2025-07-06 08:13:37 +0000 UTC
Operation for volumesnapshots.snapshot.storage.k8s.io application/velero-mysql-pv-claim-s6q97:
Backup Item Action Plugin: velero.io/csi-volumesnapshot-backupper
Operation ID: application/velero-mysql-pv-claim-s6q97/2025-07-06T08:13:37Z
Items to Update:
volumesnapshots.snapshot.storage.k8s.io application/velero-mysql-pv-claim-s6q97
volumesnapshotcontents.snapshot.storage.k8s.io /snapcontent-e8de1f6e-4bce-43e7-9894-c7a180c9dd2d
Phase: Completed
Created: 2025-07-06 08:13:37 +0000 UTC
Started: 2025-07-06 08:13:37 +0000 UTC
Updated: 2025-07-06 08:13:37 +0000 UTC
Resource List:
apiextensions.k8s.io/v1/CustomResourceDefinition:
- ciliumendpoints.cilium.io
apps/v1/Deployment:
- application/wordpress
- application/wordpress-mysql
apps/v1/ReplicaSet:
- application/wordpress-7456589d7f
- application/wordpress-mysql-7cf779d5dd
cilium.io/v2/CiliumEndpoint:
- application/wordpress-7456589d7f-8s8fk
- application/wordpress-mysql-7cf779d5dd-c6mpk
discovery.k8s.io/v1/EndpointSlice:
- application/wordpress-mysql-hcrbc
- application/wordpress-zpdjc
networking.k8s.io/v1/Ingress:
- application/wordpress-ingress
snapshot.storage.k8s.io/v1/VolumeSnapshot:
- application/velero-mysql-pv-claim-s6q97
- application/velero-wp-pv-claim-hwnp8
snapshot.storage.k8s.io/v1/VolumeSnapshotClass:
- nutanix-snapshot-class
snapshot.storage.k8s.io/v1/VolumeSnapshotContent:
- snapcontent-7e8eaf1f-5c59-46ec-9356-887e65b15769
- snapcontent-e8de1f6e-4bce-43e7-9894-c7a180c9dd2d
v1/ConfigMap:
- application/kube-root-ca.crt
v1/Endpoints:
- application/wordpress
- application/wordpress-mysql
v1/Namespace:
- application
v1/PersistentVolume:
- pvc-32abc23d-9637-4343-af61-86e24dbbab5d
- pvc-65ca02e4-4396-45fc-b91d-f7f915db0095
v1/PersistentVolumeClaim:
- application/mysql-pv-claim
- application/wp-pv-claim
v1/Pod:
- application/wordpress-7456589d7f-8s8fk
- application/wordpress-mysql-7cf779d5dd-c6mpk
v1/Secret:
- application/mysql-pass
v1/Service:
- application/wordpress
- application/wordpress-mysql
v1/ServiceAccount:
- application/default
Backup Volumes:
Velero-Native Snapshots: <none included>
CSI Snapshots:
application/mysql-pv-claim:
Snapshot:
Operation ID: application/velero-mysql-pv-claim-s6q97/2025-07-06T08:13:37Z
Snapshot Content Name: snapcontent-e8de1f6e-4bce-43e7-9894-c7a180c9dd2d
Storage Snapshot ID: NutanixVolumes-079a8061-ad99-451e-aace-195ba16a72dd:88d833af-04d3-4f7e-b1d5-671cf7ec4656
Snapshot Size (bytes): 21474836480
CSI Driver: csi.nutanix.com
Result: succeeded
application/wp-pv-claim:
Snapshot:
Operation ID: application/velero-wp-pv-claim-hwnp8/2025-07-06T08:13:32Z
Snapshot Content Name: snapcontent-7e8eaf1f-5c59-46ec-9356-887e65b15769
Storage Snapshot ID: NutanixVolumes-29fd7391-322f-4fa3-bf35-a857011e0991:8d300ddc-de02-4650-9b88-baa4afb35376
Snapshot Size (bytes): 21474836480
CSI Driver: csi.nutanix.com
Result: succeeded
Pod Volume Backups: <none included>
HooksAttempted: 0
HooksFailed: 0
ตรวจสอบสถานะการ backup
~/repos/lab velero get backup -n kommander-default-workspace
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
23:39:26 +0700 +07 29d default <none>
wordpress10 Completed 0 0 2025-07-06
ทำการ ลบ wordpress application
~/repos/lab k delete ns application
namespace "application" deleted
ทำการ restore wordpress application ซึ่งตัวอย่างนี้เป็นการ restore จากอีก cluster โดยให้ทั้งสอง cluster ใช้ S3 bucket เดียวกัน
~/repos/lab velero restore create wordpress-restore-10 --from-backup wordpress10 --restore-volumes=true -n kommander-default-workspace
Restore request "wordpress-restore-10" submitted successfully.
Run `velero restore describe wordpress-restore-10` or `velero restore logs wordpress-restore-10` for more details.
เรียกใช้ wordpress เพื่อตรวจสอบว่าข้อมูลมีการ restore กลับมาครบถ้วน

