Skip to content

Prove Kubernetes Backups Can Beat Ransomware

## Why Kubernetes Backup Testing Needs to Be More Than a Checkbox

Kubernetes has changed how organizations deploy applications, but it has not eliminated the old recovery problem: when something breaks, can the business get back online quickly and correctly?

For small and midsize businesses, nonprofits, and enterprise IT teams, the risk is no longer limited to a failed disk or an accidental database deletion. Ransomware operators increasingly target identity systems, cloud control planes, CI/CD pipelines, container registries, and backup repositories. A Kubernetes cluster can be rebuilt from infrastructure-as-code, but the applications running on it often depend on persistent volumes, secrets, custom resources, ingress configuration, DNS records, certificates, and external services.

A backup report that says successful is not the same as a recovery capability. The only useful question is this: can you restore a known-good application into a clean environment, validate that it works, and do it within the recovery time your business requires?

This article explains how to design a Kubernetes backup validation process that proves ransomware recovery instead of merely assuming it. The examples use Velero because it is widely adopted and supports common Kubernetes backup patterns, but the principles apply to commercial platforms as well.

## The Real Problem: Kubernetes State Is Spread Across Layers

Traditional server backups were often centered on a virtual machine or a physical host. Kubernetes distributes state across several layers:

– Kubernetes API objects such as Deployments, Services, Ingresses, ConfigMaps, Roles, and custom resources
– Persistent volumes provisioned by a CSI driver
– Application-level data inside databases, queues, and object stores
– Secrets and certificates
– Container images stored in a registry
– External dependencies such as DNS, identity providers, payment gateways, and SMTP relays
– Infrastructure configuration such as load balancers, firewall rules, IAM roles, and storage classes

A backup plan that captures only YAML manifests but not persistent volumes will fail for stateful applications. A plan that captures volumes but not secrets may restore pods that cannot authenticate to anything. A plan that depends on the same compromised cloud account may fail during a ransomware incident.

That is why Kubernetes recovery planning should start with application recovery requirements, not with a tool selection.

## Define Recovery Objectives Per Application

Before building backup schedules, classify workloads by business impact. A public marketing site, an internal reporting service, and a payment processing application do not need the same recovery design.

At minimum, document the following for each production namespace or application:

| Field | Example |
|—|—|
| Application owner | Finance systems team |
| Namespace | `finance-prod` |
| Data stores | PostgreSQL PVC, S3-compatible document bucket |
| RPO | 15 minutes for database, 24 hours for reports |
| RTO | 2 hours |
| Restore target | Same region and alternate region |
| Dependencies | External IdP, SMTP relay, DNS, container registry |
| Validation test | Login, create invoice, run monthly report |

Two terms matter here:

– **Recovery Point Objective, or RPO:** how much data the organization can afford to lose.
– **Recovery Time Objective, or RTO:** how long the organization can tolerate the application being unavailable.

If leadership expects a two-hour recovery but the only backup runs nightly, there is a business expectation gap. The time to discover that gap is during planning, not during an incident.

## Build a Layered Kubernetes Backup Strategy

A durable recovery design usually combines several layers instead of relying on one mechanism.

### 1. Git as the Source for Declarative Configuration

Use GitOps or infrastructure-as-code for manifests, Helm values, Terraform, policy definitions, and cluster add-ons. Git is not a complete backup of your running cluster, but it is excellent for reconstructing desired configuration.

A practical repository layout might look like this:

“`text
platform/
clusters/
prod-us-east/
dr-us-west/
namespaces/
network-policies/
kyverno-policies/
apps/
billing-api/
helm-values-prod.yaml
helm-values-dr.yaml
customer-portal/
“`

Git should be protected with multifactor authentication, branch protection, signed commits where appropriate, and backups independent of the Git hosting provider.

### 2. Kubernetes API Object Backups

Tools such as Velero can back up Kubernetes API resources. This includes objects that may not be stored in Git, such as dynamically created PersistentVolumeClaims, some custom resources, or emergency changes made during an incident.

A namespace-scoped backup example:

“`bash
velero backup create finance-prod-api \
–include-namespaces finance-prod \
–snapshot-volumes=false \
–ttl 720h
“`

This captures Kubernetes objects but intentionally skips volume snapshots. Separating API object backups from volume backups can make testing easier and reduce confusion about what each backup contains.

### 3. Persistent Volume Snapshots

For applications using PersistentVolumeClaims, use CSI snapshots when your storage provider supports them. A Velero backup that includes snapshots may look like this:

“`bash
velero backup create finance-prod-full \
–include-namespaces finance-prod \
–snapshot-volumes=true \
–ttl 720h
“`

Volume snapshots are fast, but they are not always application-consistent. A database may need pre-backup hooks, native dump tooling, write quiescing, or transaction log shipping to meet a strict RPO.

### 4. Application-Native Backups

For databases, native backup methods often provide more reliable recovery than storage snapshots alone. PostgreSQL, MySQL, Microsoft SQL Server, MongoDB, and other systems have specific backup and restore requirements.

For example, a PostgreSQL deployment might use continuous archiving to object storage plus periodic base backups. Kubernetes volume snapshots can still be useful, but they should not be your only database recovery mechanism unless you have tested crash consistency and point-in-time recovery.

### 5. Immutable or WORM-Protected Backup Storage

Ransomware recovery depends on backups that attackers cannot easily delete, encrypt, or overwrite. In cloud environments, use features such as object lock, versioning, retention policies, separate backup accounts, and tightly scoped IAM permissions.

A dangerous pattern is storing backups in the same cloud account with broad administrator access used by everyday operators. If that account is compromised, backups may disappear with the production cluster.

A better pattern is:

– Production cluster writes backups to a dedicated backup bucket.
– The cluster identity can create objects but cannot delete or shorten retention.
– Backup administrators use separate accounts with phishing-resistant MFA.
– Retention is enforced by the storage platform, not by a script.
– Restore credentials are documented and tested.

## Configure Backups with Restore Testing in Mind

Backups should be labeled and organized so that restore drills are easy to automate. For example, label namespaces by recovery tier:

“`bash
kubectl label namespace finance-prod backup-tier=gold
kubectl label namespace intranet-prod backup-tier=silver
kubectl label namespace dev-tools backup-tier=bronze
“`

Then create scheduled backups by selector:

“`bash
velero schedule create gold-hourly \
–schedule=’0 * * * *’ \
–selector backup-tier=gold \
–snapshot-volumes=true \
–ttl 168h

velero schedule create silver-daily \
–schedule=’0 2 * * *’ \
–selector backup-tier=silver \
–snapshot-volumes=true \
–ttl 720h
“`

Be careful with selectors. Labels must be consistently applied, and onboarding checklists should include backup classification. A new production namespace without a backup label is a future incident.

You can enforce this with policy. For example, a Kyverno policy can require a `backup-tier` label on namespaces:

“`yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-backup-tier
spec:
validationFailureAction: Enforce
rules:
– name: namespace-must-have-backup-tier
match:
any:
– resources:
kinds:
– Namespace
validate:
message: Namespaces must define backup-tier as gold, silver, bronze, or none.
pattern:
metadata:
labels:
backup-tier: ‘?*’
“`

This does not prove the application is recoverable, but it prevents one of the most common operational mistakes: forgetting to include a namespace in the backup program.

## Design a Restore Drill That Actually Proves Something

A meaningful restore test should answer more than whether pods start. It should verify that the application functions and that the runbook is usable by someone other than the engineer who wrote it.

A good restore drill includes five phases.

### Phase 1: Select the Recovery Scenario

Test different failure modes throughout the year:

– Accidental namespace deletion
– Corrupted database migration
– Compromised cluster requiring restore into a clean cluster
– Cloud region outage requiring restore into another region
– Deleted or rotated secrets
– Broken container registry access

Ransomware-focused tests should assume the original cluster is untrusted. Restoring into the same cluster may be useful for small incidents, but it does not prove you can recover from a full compromise.

### Phase 2: Restore Into an Isolated Environment

Create a separate recovery cluster or namespace that will not interfere with production. For serious drills, use a clean cluster with independent credentials.

Example restore into a new namespace:

“`bash
velero restore create finance-prod-dr-test \
–from-backup finance-prod-full-20260915010000 \
–namespace-mappings finance-prod:finance-restore-test
“`

After restoring, check status:

“`bash
velero restore describe finance-prod-dr-test
velero restore logs finance-prod-dr-test | less
kubectl get pods -n finance-restore-test
kubectl get pvc -n finance-restore-test
“`

Do not stop when the restore command says completed. Some objects may have been skipped, mutated by admission controllers, or restored without the external dependencies they need.

### Phase 3: Reconnect or Mock Dependencies

Applications usually depend on services outside the namespace. During restore testing, decide whether to connect to test dependencies or mock them.

For example:

– Use a test identity provider client instead of production SSO.
– Use a sandbox payment gateway.
– Disable outbound email or redirect it to a mail capture service.
– Point DNS to a temporary hostname.
– Use read-only access to restored object storage data.

A restored application that immediately sends duplicate invoices or customer emails is not a successful test. Recovery drills need safety controls.

### Phase 4: Validate Business Transactions

Create a small validation script for each application. It should test real business behavior, not just HTTP 200 responses.

Example smoke test:

“`bash
#!/usr/bin/env bash
set -euo pipefail

BASE_URL=’https://finance-restore-test.example.org’
TOKEN=$(./get-test-token.sh)

curl -fsS -H “Authorization: Bearer ${TOKEN}” \
“${BASE_URL}/healthz”

curl -fsS -H “Authorization: Bearer ${TOKEN}” \
“${BASE_URL}/api/customers?limit=1” | jq .

INVOICE_ID=$(curl -fsS -X POST \
-H “Authorization: Bearer ${TOKEN}” \
-H ‘Content-Type: application/json’ \
-d ‘{“customerId”:”test-customer”,”amount”:1.00}’ \
“${BASE_URL}/api/invoices/draft” | jq -r .id)

curl -fsS -H “Authorization: Bearer ${TOKEN}” \
“${BASE_URL}/api/invoices/${INVOICE_ID}” | jq .status
“`

This type of test gives executives and auditors a much stronger assurance than a screenshot of a backup console.

### Phase 5: Measure RTO and RPO

Record the actual times:

– When the drill started
– When the backup was selected
– When infrastructure was available
– When restore completed
– When validation passed
– How much data was missing or replayed

If the RTO is two hours and the drill takes six, that is not a failure of the team. It is valuable information. You can now improve the runbook, adjust tooling, pre-stage infrastructure, or reset business expectations.

## Protect Secrets Without Making Restore Impossible

Secrets are one of the trickiest parts of Kubernetes recovery. Backing them up in plaintext is risky. Excluding them entirely can make restores fail.

Common approaches include:

– Encrypt Kubernetes secrets at rest in the cluster.
– Use an external secrets operator backed by a cloud secret manager or vault.
– Store sealed secrets in Git.
– Back up secret manager data using the vendor’s recommended method.
– Document emergency access procedures separately from the cluster.

If you use an external secrets pattern, your restore process must include the operator and its credentials. A restored Deployment that references missing secrets will not become ready.

A typical External Secrets manifest may look like this:

“`yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: finance-api-secrets
namespace: finance-prod
spec:
refreshInterval: 1h
secretStoreRef:
name: production-secret-store
kind: ClusterSecretStore
target:
name: finance-api-secrets
data:
– secretKey: database-url
remoteRef:
key: finance/prod/database-url
“`

During a DR test, you may need a different `ClusterSecretStore` that points to recovery or sandbox secrets. This is one reason Helm values, Kustomize overlays, or GitOps environment folders are important.

## Watch for Kubernetes Backup Blind Spots

Even mature teams miss details. The following blind spots are common in real deployments.

### Custom Resource Definitions and Operators

Many applications depend on operators. Restoring a custom resource without the matching CRD and controller may do nothing. Install platform operators before restoring application resources, or include them in a clearly ordered runbook.

### StorageClass Differences

A restore into another region or cloud account may not have the same StorageClass names. Velero restore resource modifiers or pre-created compatible StorageClasses can solve this, but they must be tested.

Example StorageClass mapping concept:

“`yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: change-storage-class
namespace: velero
data:
change-storage-class.yaml: |
version: v1
resourceModifierRules:
– conditions:
groupResource: persistentvolumeclaims
patches:
– operation: replace
path: /spec/storageClassName
value: standard-dr
“`

### Ingress, DNS, and Certificates

A restored application may be healthy internally but unreachable externally. Your runbook should include DNS changes, certificate issuance, ingress controller dependencies, firewall rules, and load balancer provisioning.

### Container Image Availability

If ransomware or a cloud outage affects your registry, Kubernetes cannot pull images. Critical images should be replicated to a secondary registry or cached in a controlled environment. Document how image pull secrets are restored.

### Backup Tool Credentials

The backup tool itself needs credentials. If those credentials are stored only inside the failed cluster, your recovery plan has a circular dependency. Keep break-glass restore credentials in a secure, tested location.

## Automate Evidence Collection

Backup validation is more useful when it produces evidence. This matters for cyber insurance, compliance programs, board reporting, and internal accountability.

After each drill, save:

– Backup name and timestamp
– Restore command or automation job ID
– Restore logs
– Kubernetes events from the restored namespace
– Validation test output
– RTO and RPO measurements
– Exceptions and remediation tasks

A simple evidence collection script might include:

“`bash
#!/usr/bin/env bash
set -euo pipefail

NS=’finance-restore-test’
RESTORE=’finance-prod-dr-test’
OUT=”restore-evidence-$(date +%Y%m%d-%H%M%S)”
mkdir -p “${OUT}”

velero restore describe “${RESTORE}” > “${OUT}/restore-describe.txt”
velero restore logs “${RESTORE}” > “${OUT}/restore-logs.txt”
kubectl get all -n “${NS}” -o wide > “${OUT}/k8s-resources.txt”
kubectl get events -n “${NS}” –sort-by=.lastTimestamp > “${OUT}/events.txt”
kubectl get pvc -n “${NS}” -o yaml > “${OUT}/pvcs.yaml”
./smoke-test-finance.sh > “${OUT}/smoke-test.txt”

tar -czf “${OUT}.tar.gz” “${OUT}”
echo “Evidence archived to ${OUT}.tar.gz”
“`

Store this evidence somewhere separate from the cluster. If your organization has compliance requirements, map the evidence to your control framework. For example, HIPAA, PCI DSS, SOC 2, and cyber insurance questionnaires all care about backup protection and recovery testing, even if they use different language.

## Set a Practical Testing Frequency

Not every application needs a full restore drill every week. A reasonable schedule for many organizations is:

– **Monthly:** verify backup job success, storage immutability, and alerting.
– **Quarterly:** restore at least one high-value application into an isolated environment.
– **Semiannually:** perform a clean-cluster recovery test for a critical workload.
– **Annually:** run a tabletop exercise that includes leadership, communications, legal, and vendors.
– **After major changes:** retest when migrating storage, changing identity providers, replacing ingress controllers, or moving cloud accounts.

The key is consistency. A recovery test performed once and forgotten is not a program.

## What Executives Should Ask IT Teams

Technically inclined business owners and nonprofit executives do not need to inspect every YAML file, but they should ask direct questions:

– Which applications have documented RTO and RPO targets?
– When was the last successful restore test for our most critical system?
– Were backups restored into a clean environment or only the original cluster?
– Can ransomware operators delete or encrypt our backups?
– Do we have evidence of restore validation, not just backup completion?
– Who can perform a restore if the primary Kubernetes engineer is unavailable?
– Are container images, secrets, DNS, and external dependencies included in the plan?

These questions turn backup from a technical assumption into a managed business risk.

## Practical Summary and Key Takeaways

Kubernetes backup is not a single product feature. It is an engineering process that connects application design, storage, identity, security, automation, and business continuity planning.

The most important takeaways are:

– A successful backup job does not prove recoverability.
– Define RTO and RPO per application before choosing schedules.
– Combine GitOps, Kubernetes API backups, volume snapshots, and application-native backups.
– Store backups in immutable or deletion-resistant storage outside the normal blast radius.
– Test restores into isolated or clean environments, especially for ransomware scenarios.
– Validate real business transactions, not only pod readiness.
– Include secrets, images, DNS, certificates, operators, and external dependencies in the runbook.
– Capture evidence from every restore drill for audits, insurance, and continuous improvement.

For organizations running Kubernetes in production, the goal is not simply to own a backup tool. The goal is to know, with evidence, that the business can recover when the cluster, the cloud account, or the application data is under pressure. That confidence only comes from tested restores.

Posted in

author

Leave a Comment





Scroll To Top