Skip to content

Velero

Kubernetes backup, restore, and migration tool. Velero saves cluster resource state (Deployments, Services, ConfigMaps, PVCs) and optionally PVC data to S3-compatible object storage. It supports recurring backup schedules, TTL-based expiration, and namespace-scoped or cluster-wide backup policies.

node-agent is required to back up PVC data

The default installation backs up Kubernetes resource manifests only. To include the contents of Persistent Volumes (databases, uploads, application data), you must enable nodeAgent.enabled: true and set configuration.defaultVolumesToFsBackup: true (or set defaultVolumesToFsBackup: true per schedule). Without node-agent, restoring from backup will recreate empty PVCs — no data included.

Key Features

  • Cluster-scoped backup — saves Kubernetes resources and optionally PVC data to S3
  • Kopia filesystem backupuploaderType: kopia (modern replacement for Restic)
  • Scheduled backupsSchedule resources rendered directly from chart values
  • TTL-based expiration — backups expire automatically (default 7 days)
  • Node-agent DaemonSet — optional filesystem backup for PVC data inclusion
  • S3-compatible storage — validated with the AWS plugin for MinIO and AWS S3
  • Restore-only mode — lock a cluster to restores only (useful for DR environments)
  • Prometheus metrics — metrics Service and optional ServiceMonitor enabled by default

Installation

Velero requires cluster-wide permissions and is typically deployed in a dedicated namespace:

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install velero helmforge/velero -n velero --create-namespace -f values.yaml

OCI registry:

helm install velero oci://ghcr.io/helmforgedev/helm/velero -n velero --create-namespace -f values.yaml

Deployment Examples

# values.yaml — Velero backing up Kubernetes resources only (no PVC data)
# This is the default behavior. PVC contents are NOT included.
credentials:
  existingSecret: velero-s3-credentials # must contain 'cloud' key with AWS-format credentials

configuration:
  defaultBackupTTL: 720h # 30 days
  backupStorageLocations:
    - name: default
      provider: aws
      bucket: my-velero-backups
      default: true
      config:
        region: minio
        s3Url: http://minio.minio.svc.cluster.local:9000
        s3ForcePathStyle: true
        insecureSkipTLSVerify: true
# values.yaml — Full cluster backup including PVC data via node-agent
# Requires node-agent DaemonSet and uses Kopia for filesystem-level backup.
credentials:
  existingSecret: velero-s3-credentials

configuration:
  defaultBackupTTL: 720h
  defaultVolumesToFsBackup: true # include PVC data in all backups by default
  uploaderType: kopia
  backupStorageLocations:
    - name: default
      provider: aws
      bucket: my-velero-backups
      default: true
      config:
        region: minio
        s3Url: http://minio.minio.svc.cluster.local:9000
        s3ForcePathStyle: true
        insecureSkipTLSVerify: true

nodeAgent:
  enabled: true
  resources:
    requests:
      memory: 128Mi
      cpu: 100m
    limits:
      memory: 512Mi
      cpu: 500m
# values.yaml — Scheduled daily and weekly backups with different TTLs
credentials:
  existingSecret: velero-s3-credentials

configuration:
  defaultBackupTTL: 168h # 7 days default
  backupStorageLocations:
    - name: default
      provider: aws
      bucket: my-velero-backups
      default: true
      config:
        region: us-east-1
        # s3Url not needed for real AWS S3

nodeAgent:
  enabled: true

schedules:
  - name: daily
    schedule: '0 3 * * *'
    template:
      ttl: 168h # 7 days
      includedNamespaces:
        - default
        - apps
      defaultVolumesToFsBackup: true
      snapshotVolumes: false

  - name: weekly
    schedule: '0 2 * * 0'
    template:
      ttl: 720h # 30 days
      includedNamespaces: [] # empty = all namespaces
      defaultVolumesToFsBackup: true
# values.yaml — DR environment: Velero locked to restore-only mode
# Use this on a secondary cluster that only receives restores, never creates backups.
credentials:
  existingSecret: velero-s3-credentials

configuration:
  restoreOnlyMode: true
  backupStorageLocations:
    - name: default
      provider: aws
      bucket: my-velero-backups
      default: true
      accessMode: ReadOnly # read-only on DR side
      config:
        region: minio
        s3Url: http://minio.minio.svc.cluster.local:9000
        s3ForcePathStyle: true
        insecureSkipTLSVerify: true

S3 Credentials Format

Velero uses an AWS credentials file format regardless of the S3 provider (including MinIO). The credentials.secretContents field contains the full file content:

[default]
aws_access_key_id=your-access-key
aws_secret_access_key=your-secret-key

For production, store credentials in a pre-created Kubernetes Secret and reference it with credentials.existingSecret:

kubectl create secret generic velero-s3-credentials \
  --from-literal=cloud='[default]
aws_access_key_id=your-access-key
aws_secret_access_key=your-secret-key' \
  -n velero

Configuration Reference

Core

ParameterTypeDefaultDescription
nameOverridestring""Override the chart name.
fullnameOverridestring""Override the full release name.
commonLabelsobject{}Extra labels added to all resources.

Image

ParameterTypeDefaultDescription
image.repositorystringdocker.io/velero/veleroVelero server image.
image.tagstring"v1.18.0"Image tag.
image.pullPolicystringIfNotPresentImage pull policy.
imagePullSecretsarray[]Pull secrets for private registries.

Plugins

ParameterTypeDefaultDescription
plugins.enabledbooleantrueEnable the default AWS/S3-compatible plugin.
plugins.aws.namestringvelero-plugin-for-awsInit container name.
plugins.aws.repositorystringdocker.io/velero/velero-plugin-for-awsAWS plugin image repository.
plugins.aws.tagstringv1.14.0AWS plugin image tag.
plugins.extraarray[]Extra plugin init containers.

Credentials

ParameterTypeDefaultDescription
credentials.useSecretbooleantrueMount credentials into the Velero pods.
credentials.existingSecretstring""Existing secret containing the credentials file (key: cloud).
credentials.namestring""Name for the Secret created by the chart when existingSecret is empty.
credentials.keystringcloudKey inside the credentials secret.
credentials.secretContentsstring""Full AWS credentials file content for inline secret creation.

RBAC

ParameterTypeDefaultDescription
rbac.createbooleantrueCreate a ClusterRoleBinding for the Velero service account.
rbac.clusterAdministratorbooleantrueBind to cluster-admin. Required for full cluster backup.
rbac.clusterAdministratorNamestringcluster-adminClusterRole name to bind.

Configuration

ParameterTypeDefaultDescription
configuration.uploaderTypestringkopiaFilesystem backup engine. kopia is the current default (replaces Restic).
configuration.defaultBackupTTLstring168hDefault backup expiration TTL (7 days). Expired backups are deleted from S3.
configuration.defaultItemOperationTimeoutstring4hDefault timeout for item-level operations.
configuration.logLevelstringinfoServer log verbosity.
configuration.logFormatstringtextLog format: text or json.
configuration.restoreOnlyModebooleanfalseLock the server to restore operations only (useful for DR clusters).
configuration.defaultVolumesToFsBackupbooleanfalseInclude PVC data in backups by default. Requires nodeAgent.enabled: true.
configuration.featuresstring""Comma-separated Velero feature flags.
configuration.extraArgsarray[]Extra server arguments.
configuration.extraEnvVarsarray[]Extra environment variables for the Velero server and node-agent.

Backup Storage Locations

The default entry uses the AWS plugin in S3-compatible mode. For real AWS S3, omit s3Url.

ParameterTypeDefaultDescription
configuration.backupStorageLocations[].namestringdefaultBSL name.
configuration.backupStorageLocations[].providerstringawsProvider plugin name.
configuration.backupStorageLocations[].bucketstring""S3 bucket name.
configuration.backupStorageLocations[].prefixstring""Optional key prefix within the bucket.
configuration.backupStorageLocations[].defaultbooleantrueMark as the default BSL.
configuration.backupStorageLocations[].accessModestringReadWriteReadWrite for primary, ReadOnly for DR.
configuration.backupStorageLocations[].config.regionstringus-east-1S3 region (use a custom string for MinIO).
configuration.backupStorageLocations[].config.s3Urlstring""S3-compatible endpoint. Empty = AWS S3.
configuration.backupStorageLocations[].config.s3ForcePathStylebooleantrueRequired for MinIO and most S3-compatible stores.
configuration.backupStorageLocations[].config.insecureSkipTLSVerifybooleanfalseSkip TLS verification (dev/MinIO HTTP only).

Schedules

Schedules are rendered as Velero Schedule CRDs. The template.ttl in each schedule overrides the server-level defaultBackupTTL.

ParameterTypeDescription
schedules[].namestringSchedule name.
schedules[].schedulestringCron expression for the backup schedule.
schedules[].template.ttlstringBackup TTL for this schedule (overrides server default).
schedules[].template.includedNamespacesarrayNamespaces to include. Empty = all namespaces.
schedules[].template.defaultVolumesToFsBackupbooleanInclude PVC data in this schedule’s backups.
schedules[].template.snapshotVolumesbooleanUse volume snapshots (requires cloud provider support).

Node Agent (Filesystem Backup)

node-agent runs as a DaemonSet on every node

The node-agent requires host path access to pod volume directories. It runs as root (runAsUser: 0) by design — this is necessary to read PVC mount paths on the node filesystem. Enabling node-agent is the only way to include PVC data in backups via filesystem copy.

ParameterTypeDefaultDescription
nodeAgent.enabledbooleanfalseDeploy the node-agent DaemonSet for filesystem backup.
nodeAgent.podVolumePathstring/var/lib/kubelet/podsHost path to pod volume directories.
nodeAgent.pluginVolumePathstring/var/lib/kubelet/pluginsHost path to kubelet plugin directories.
nodeAgent.useScratchEmptyDirbooleantrueMount an emptyDir scratch volume into the node-agent.
nodeAgent.resourcesobject{}Resources for node-agent containers.

Metrics

ParameterTypeDefaultDescription
metrics.enabledbooleantrueExpose Velero metrics on a Service.
metrics.service.typestringClusterIPMetrics service type.
metrics.service.portinteger8085Metrics service port.
metrics.serviceMonitor.enabledbooleanfalseCreate a Prometheus Operator ServiceMonitor.
metrics.serviceMonitor.intervalstring30sMetrics scrape interval.
metrics.serviceMonitor.scrapeTimeoutstring10sMetrics scrape timeout.
metrics.serviceMonitor.additionalLabelsobject{}Extra labels for the ServiceMonitor.

Resources and Security

ParameterTypeDefaultDescription
resourcesobject{}CPU and memory requests and limits for the Velero server.
terminationGracePeriodSecondsinteger3600Grace period (1 hour). Allows in-progress backups or restores to complete.
priorityClassNamestring""PriorityClass for the Velero server pod.
podSecurityContextobject{}Pod-level security context.

Service Account

ParameterTypeDefaultDescription
serviceAccount.server.createbooleantrueCreate the Velero service account.
serviceAccount.server.namestring""Override the service account name.
serviceAccount.server.annotationsobject{}Annotations for the service account (e.g. IRSA for AWS EKS).

Scheduling

ParameterTypeDefaultDescription
nodeSelectorobject{}Node selector for the server pod.
tolerationsarray[]Tolerations for the server pod.
affinityobject{}Affinity rules for the server pod.
priorityClassNamestring""PriorityClass for the server pod.

Extra

ParameterTypeDefaultDescription
extraVolumesarray[]Extra volumes for the server pod.
extraVolumeMountsarray[]Extra volume mounts for the server container.
extraObjectsarray[]Extra Kubernetes manifests rendered with tpl.

More Information