Skip to content

Instantly share code, notes, and snippets.

@arubis
Last active January 14, 2026 22:12
Show Gist options
  • Select an option

  • Save arubis/0750fea13186710902cc6ee6c4565d80 to your computer and use it in GitHub Desktop.

Select an option

Save arubis/0750fea13186710902cc6ee6c4565d80 to your computer and use it in GitHub Desktop.
Velero task fix: air-gap compatible solution.sh (solution.sh changes only, no setup.sh changes needed)
--- tasks/velero-backup-restore-minio/solution.sh 2026-01-14 12:47:37.901786653 -0700
+++ tasks/velero-backup-restore-minio-revised/solution.sh 2026-01-14 15:12:33.053285209 -0700
@@ -70,6 +70,7 @@
containers:
- name: minio
image: quay.io/minio/minio:RELEASE.2023-07-21T03-20-08Z
+ imagePullPolicy: IfNotPresent
args: ["server", "/data"]
env:
- name: MINIO_ROOT_USER
@@ -107,81 +108,45 @@
kubectl rollout status deployment/minio -n ${NAMESPACE} --timeout=120s || warn "MinIO still starting"
ok "MinIO deployed"
+# Create velero bucket
+kubectl run minio-mc --rm -i --restart=Never --image=quay.io/minio/mc:latest \
+ --overrides='{"spec":{"containers":[{"name":"mc","image":"quay.io/minio/mc:latest","imagePullPolicy":"IfNotPresent","command":["sh","-c","mc alias set m http://minio.default.svc:9000 '"${MINIO_ACCESS_KEY}"' '"${MINIO_SECRET_KEY}"' && mc mb m/'"${MINIO_BUCKET}"' --ignore-existing"]}]}}'
+ok "Velero bucket created"
+
########################################
-# 2. Velero credentials secret
+# 2. Velero credentials file
########################################
-info "[2/8] Creating Velero credentials secret"
+info "[2/8] Creating Velero credentials"
-kubectl apply -f - <<EOF
-apiVersion: v1
-kind: Secret
-metadata:
- name: velero-credentials
- namespace: ${NAMESPACE}
-type: Opaque
-stringData:
- cloud: |
- [default]
- aws_access_key_id=${MINIO_ACCESS_KEY}
- aws_secret_access_key=${MINIO_SECRET_KEY}
+cat > "${WORKDIR}/credentials-velero" <<EOF
+[default]
+aws_access_key_id=${MINIO_ACCESS_KEY}
+aws_secret_access_key=${MINIO_SECRET_KEY}
EOF
-
-ok "Velero credentials secret created"
+ok "Velero credentials created"
########################################
-# 3. Velero Helm values (air-gapped)
+# 3. Install Velero (air-gapped, using CLI)
########################################
-info "[3/8] Writing Velero Helm values"
-
-cat > "${WORKDIR}/velero-values.yaml" <<EOF
-initContainers:
- - name: velero-plugin-for-aws
- image: velero/velero-plugin-for-aws:v1.10.1
- imagePullPolicy: IfNotPresent
- volumeMounts:
- - mountPath: /target
- name: plugins
-
-deployNodeAgent: true
-
-configuration:
- defaultVolumesToFsBackup: true
-
- backupStorageLocation:
- - name: default
- provider: aws
- bucket: ${MINIO_BUCKET}
- default: true
- accessMode: ReadWrite
- config:
- region: us-east-1
- s3ForcePathStyle: true
- s3Url: http://minio.${NAMESPACE}.svc.cluster.local:9000
-
-credentials:
- useSecret: true
- secretName: velero-credentials
- secretKey: cloud
-EOF
-
-ok "Velero Helm values written"
-
-
+info "[3/8] Installing Velero into '${NAMESPACE}'"
-info "[4/8] Deploying Velero into '${NAMESPACE}'"
-
-helm upgrade --install ${VELERO_RELEASE_NAME} \
- vmware-tanzu/velero \
+velero install \
+ --provider aws \
+ --plugins velero/velero-plugin-for-aws:v1.9.2 \
+ --bucket ${MINIO_BUCKET} \
+ --secret-file "${WORKDIR}/credentials-velero" \
+ --use-node-agent \
--namespace ${NAMESPACE} \
- -f "${WORKDIR}/velero-values.yaml"
+ --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.${NAMESPACE}.svc.cluster.local:9000 \
+ --image velero/velero:v1.13.2
########################################
-# 5. Wait for Velero & node-agent
+# 4. Wait for Velero & node-agent
########################################
-info "[5/8] Waiting for Velero components"
+info "[4/8] Waiting for Velero components"
kubectl wait -n ${NAMESPACE} \
--for=condition=available deployment/velero \
@@ -191,10 +156,10 @@
ok "Velero deployment present"
########################################
-# 6. Daily backup schedule
+# 5. Daily backup schedule
########################################
-info "[6/8] Creating daily backup schedule for '${BLEATER_NS}'"
+info "[5/8] Creating daily backup schedule for '${BLEATER_NS}'"
kubectl apply -f - <<EOF
apiVersion: velero.io/v1
@@ -215,10 +180,10 @@
ok "Daily backup schedule created"
########################################
-# 7. Manual backup
+# 6. Manual backup
########################################
-info "[7/8] Creating manual backup '${VELERO_BACKUP_NAME}'"
+info "[6/8] Creating manual backup '${VELERO_BACKUP_NAME}'"
kubectl apply -f - <<EOF
apiVersion: velero.io/v1
@@ -245,6 +210,14 @@
ok "Manual backup completed"
########################################
+# 7. Delete bleater namespace (simulate failure)
+########################################
+
+info "[7/8] Deleting '${BLEATER_NS}' namespace"
+kubectl delete namespace ${BLEATER_NS} --wait --timeout=120s
+ok "Namespace deleted"
+
+########################################
# 8. Restore
########################################
@@ -262,8 +235,13 @@
- ${BLEATER_NS}
EOF
-sleep 10
-kubectl -n ${BLEATER_NS} get all >/dev/null 2>&1 || fail "Bleater restore failed"
+for i in {1..30}; do
+ PHASE=$(kubectl -n ${NAMESPACE} get restore ${VELERO_RESTORE_NAME} -o jsonpath='{.status.phase}' 2>/dev/null || true)
+ [ "$PHASE" = "Completed" ] && break
+ [ "$PHASE" = "Failed" ] || [ "$PHASE" = "PartiallyFailed" ] && fail "Restore failed"
+ sleep 5
+done
+[ "$PHASE" = "Completed" ] || fail "Restore did not complete"
ok "Bleater namespace restored successfully"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment