Created
November 5, 2025 17:21
-
-
Save erasmolpa/d22f3a92c833d429998080569f8cf9df to your computer and use it in GitHub Desktop.
backup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Velero backup for a whole namespace, but snapshot only selected PVCs. | |
| .DESCRIPTION | |
| - Performs two Velero backups: | |
| A) Everything in the namespace (except PV/PVC) | |
| B) Only selected PVCs/PVs with snapshots | |
| - Includes helper functions for restore. | |
| - Works in AKS with the Velero Azure plugin. | |
| .REQUIREMENTS | |
| - kubectl and velero CLIs in PATH | |
| - Logged into the desired cluster context | |
| - Velero installed and configured for Azure snapshots | |
| #> | |
| param( | |
| [string]$Namespace = "jfrog", | |
| [string[]]$PvcInclude = @( | |
| "artifactory-volume-jfrog-platform-artifactory-0", | |
| "data-volume-jfrog-platform-xray-0", | |
| "jfrog-postgresql-data" | |
| ), | |
| [string]$BackupPrefix = "jfrog", | |
| [string]$Ttl = "720h", | |
| [string]$LabelKey = "backup", | |
| [string]$LabelValue = "true" | |
| ) | |
| # -------------------- | |
| # Utility functions | |
| # -------------------- | |
| function Assert-Cli { | |
| param([string]$Name) | |
| if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { | |
| throw "Required CLI '$Name' not found in PATH." | |
| } | |
| } | |
| function New-Stamp { (Get-Date).ToString("yyyyMMdd-HHmm") } | |
| function Invoke-Kubectl { | |
| param([string]$Args) | |
| $cmd = "kubectl $Args" | |
| Write-Host ">> $cmd" -ForegroundColor Cyan | |
| & kubectl $Args.split(" ") | Out-String | |
| } | |
| function Invoke-Velero { | |
| param([string]$Args) | |
| $cmd = "velero $Args" | |
| Write-Host ">> $cmd" -ForegroundColor Yellow | |
| & velero $Args.split(" ") | Out-String | |
| } | |
| function Label-Pvcs { | |
| param([string]$Ns, [string[]]$Pvcs, [string]$Key, [string]$Val) | |
| foreach ($pvc in $Pvcs) { | |
| Invoke-Kubectl "-n $Ns label pvc $pvc $Key=$Val --overwrite" | |
| } | |
| } | |
| function Start-Backups { | |
| param([string]$Ns, [string]$Prefix, [string]$Ttl, [string]$LabelKey, [string]$LabelValue) | |
| $stamp = New-Stamp | |
| $bkNs = "$Prefix-ns-$stamp" | |
| $bkVols = "$Prefix-vols-$stamp" | |
| # A) Full namespace WITHOUT PVs/PVCs | |
| Invoke-Velero "backup create $bkNs --include-namespaces $Ns ` | |
| --exclude-resources persistentvolumes,persistentvolumeclaims,volumesnapshots,volumesnapshotcontents,volumesnapshotclasses ` | |
| --ttl $Ttl --wait" | |
| # B) ONLY labeled PV/PVC WITH snapshots | |
| Invoke-Velero "backup create $bkVols --include-namespaces $Ns ` | |
| --include-resources persistentvolumeclaims,persistentvolumes ` | |
| --selector $LabelKey=$LabelValue --snapshot-volumes ` | |
| --ttl $Ttl --wait" | |
| # Quick report | |
| Write-Host "`n=== Backup summaries ===" -ForegroundColor Green | |
| Invoke-Velero "describe backup $bkNs --details" | |
| Invoke-Velero "describe backup $bkVols --details" | |
| return @{ NamespaceBackup = $bkNs; VolumesBackup = $bkVols } | |
| } | |
| function Restore-Backups { | |
| <# | |
| Restores volumes first (from the *-vols-* backup) and then the namespace. | |
| Optional: map original namespace to a new one for DR testing. | |
| #> | |
| param( | |
| [string]$VolumesBackup, | |
| [string]$NamespaceBackup, | |
| [string]$NamespaceMap # e.g. "jfrog:jfrog-restore" | |
| ) | |
| if ([string]::IsNullOrEmpty($VolumesBackup) -or [string]::IsNullOrEmpty($NamespaceBackup)) { | |
| throw "Provide -VolumesBackup and -NamespaceBackup backup names." | |
| } | |
| $mapArg = "" | |
| if ($NamespaceMap) { $mapArg = "--namespace-mappings $NamespaceMap" } | |
| # 1) Restore volumes (creates PVC/PV and disks from snapshots) | |
| Invoke-Velero "restore create restore-vols-$(New-Stamp) --from-backup $VolumesBackup --restore-volumes $mapArg --wait" | |
| # 2) Restore namespace manifests | |
| Invoke-Velero "restore create restore-ns-$(New-Stamp) --from-backup $NamespaceBackup $mapArg --wait" | |
| } | |
| # -------------------- | |
| # Main | |
| # -------------------- | |
| try { | |
| Assert-Cli kubectl | |
| Assert-Cli velero | |
| Write-Host "Labeling selected PVCs in namespace '$Namespace'..." -ForegroundColor Green | |
| Label-Pvcs -Ns $Namespace -Pvcs $PvcInclude -Key $LabelKey -Val $LabelValue | Out-Null | |
| Write-Host "Starting Velero backups..." -ForegroundColor Green | |
| $bk = Start-Backups -Ns $Namespace -Prefix $BackupPrefix -Ttl $Ttl -LabelKey $LabelKey -LabelValue $LabelValue | |
| Write-Host "`nDone." | |
| Write-Host "Namespace backup : $($bk.NamespaceBackup)" | |
| Write-Host "Volumes backup : $($bk.VolumesBackup)" | |
| Write-Host @" | |
| # To restore (same namespace): | |
| Restore-Backups -VolumesBackup '$($bk.VolumesBackup)' -NamespaceBackup '$($bk.NamespaceBackup)' | |
| # To restore into a different namespace (e.g., jfrog -> jfrog-restore): | |
| Restore-Backups -VolumesBackup '$($bk.VolumesBackup)' -NamespaceBackup '$($bk.NamespaceBackup)' -NamespaceMap 'jfrog:jfrog-restore' | |
| "@ | |
| } catch { | |
| Write-Error $_.Exception.Message | |
| exit 1 | |
| } | |
| # =============================================== | |
| # 🧩 Velero Backup & Restore - Namespace jfrog | |
| # Objetivo: | |
| # - Backup completo del namespace jfrog | |
| # - Snapshot solo de PVCs seleccionados | |
| # =============================================== | |
| # --- 0️⃣ Preparación --- | |
| # Verifica que Velero y sus plugins estén configurados | |
| velero plugin get | |
| velero get backup-locations | |
| velero get volumesnapshotlocations | |
| # (Opcional) Ejecuta el job de pg_dump antes del backup | |
| # para asegurar consistencia de la base de datos | |
| # --- 1️⃣ Etiquetar los PVCs que deben snapshotearse --- | |
| kubectl -n jfrog label pvc artifactory-volume-jfrog-platform-artifactory-0 backup=true --overwrite | |
| kubectl -n jfrog label pvc data-volume-jfrog-platform-xray-0 backup=true --overwrite | |
| kubectl -n jfrog label pvc jfrog-postgresql-data backup=true --overwrite | |
| # Deja sin etiqueta los PVCs que NO quieres incluir (cache, backups temporales, etc.) | |
| # --- 2️⃣ BACKUP A: Namespace completo sin PV/PVC --- | |
| BK_NS="jfrog-ns-$(date +%Y%m%d-%H%M)" | |
| velero backup create "$BK_NS" \ | |
| --include-namespaces jfrog \ | |
| --exclude-resources persistentvolumes,persistentvolumeclaims,volumesnapshots,volumesnapshotcontents,volumesnapshotclasses \ | |
| --ttl 720h \ | |
| --wait | |
| # --- 3️⃣ BACKUP B: Solo PVC/PV etiquetados (con snapshots) --- | |
| BK_VOLS="jfrog-vols-$(date +%Y%m%d-%H%M)" | |
| velero backup create "$BK_VOLS" \ | |
| --include-namespaces jfrog \ | |
| --include-resources persistentvolumeclaims,persistentvolumes \ | |
| --selector backup=true \ | |
| --snapshot-volumes \ | |
| --ttl 720h \ | |
| --wait | |
| # --- 4️⃣ Verificación de backups --- | |
| velero get backups | |
| velero describe backup "$BK_NS" --details | |
| velero describe backup "$BK_VOLS" --details | |
| # Verifica que los PVC esperados estén en el backup de volúmenes y que las snapshots se hayan creado correctamente. | |
| # --- 5️⃣ RESTORE (Escenario de recuperación) --- | |
| # Opción A: Restaurar en otro namespace (recomendado para pruebas) | |
| velero restore create "restore-vols-$(date +%Y%m%d-%H%M)" \ | |
| --from-backup "$BK_VOLS" \ | |
| --restore-volumes \ | |
| --namespace-mappings jfrog:jfrog-restore \ | |
| --wait | |
| velero restore create "restore-ns-$(date +%Y%m%d-%H%M)" \ | |
| --from-backup "$BK_NS" \ | |
| --namespace-mappings jfrog:jfrog-restore \ | |
| --wait | |
| # Verifica: | |
| kubectl -n jfrog-restore get pods,pvc | |
| # Opción B: Restaurar en el mismo namespace (desastre real) | |
| # 1) Escala a 0 todos los pods/STS antes del restore | |
| kubectl -n jfrog scale deploy --all --replicas=0 | |
| kubectl -n jfrog scale sts --all --replicas=0 | |
| # 2) Restaura volúmenes | |
| velero restore create "restore-vols-$(date +%Y%m%d-%H%M)" \ | |
| --from-backup "$BK_VOLS" \ | |
| --restore-volumes \ | |
| --wait | |
| # 3) Restaura manifiestos del namespace | |
| velero restore create "restore-ns-$(date +%Y%m%d-%H%M)" \ | |
| --from-backup "$BK_NS" \ | |
| --wait | |
| # 4) Escala nuevamente a 1 réplica | |
| kubectl -n jfrog scale sts --all --replicas=1 | |
| kubectl -n jfrog scale deploy --all --replicas=1 | |
| # --- 6️⃣ Validaciones post-restore --- | |
| # PVC/PV | |
| kubectl -n jfrog get pvc,pv | |
| kubectl -n jfrog-restore get pvc,pv | |
| # Pods y readiness | |
| kubectl -n jfrog get pods | |
| kubectl -n jfrog-restore get pods | |
| # Logs y estado | |
| kubectl -n jfrog-restore describe pod <nombre-del-pod> | |
| # Servicios / Ingress | |
| kubectl -n jfrog-restore get svc,ingress | |
| # Verifica que los endpoints apunten correctamente y que los datos sean consistentes. | |
| # --- 7️⃣ Limpieza y rotación de backups antiguos (opcional) --- | |
| # Lista todos los backups | |
| velero get backups | |
| # Elimina backups antiguos por nombre/patrón | |
| velero delete backup $(velero get backups -o name | grep jfrog- | head -n 1) --confirm | |
| # Fin del procedimiento ✅ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment