Skip to content

Instantly share code, notes, and snippets.

@erasmolpa
Created November 5, 2025 17:21
Show Gist options
  • Select an option

  • Save erasmolpa/d22f3a92c833d429998080569f8cf9df to your computer and use it in GitHub Desktop.

Select an option

Save erasmolpa/d22f3a92c833d429998080569f8cf9df to your computer and use it in GitHub Desktop.
backup
<#
.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