Backblaze B2
The B2 backend stores the kopia repository in a Backblaze B2 bucket, using B2’s native API and an application key. B2 also exposes an S3-compatible API. If you prefer that, use the S3 backend with B2’s S3 endpoint instead.
Provider prerequisites
Section titled “Provider prerequisites”- A B2 bucket. Kopiur does not create it.
- An application key, meaning a
keyIDandapplicationKeypair. Prefer a key scoped to the one bucket over the master key. Create it in the B2 console under App Keys.
The Secret shape
Section titled “The Secret shape”The mover loads this Secret with envFrom, so the keys reach kopia as environment variables.
| Secret key | Required | What it is |
|---|---|---|
B2_KEY_ID |
yes | The application key ID. |
B2_KEY |
yes | The application key paired with the ID. |
KOPIA_PASSWORD |
yes | The repository encryption password. |
stringData: B2_KEY_ID: "REPLACE_ME" B2_KEY: "REPLACE_ME" KOPIA_PASSWORD: "choose-something-long-and-random"The Repository
Section titled “The Repository”---apiVersion: v1kind: Secretmetadata: name: b2-repo-creds namespace: backupstype: OpaquestringData: # A Backblaze application key (keyID + key). Prefer a key scoped to the one # bucket, not the master key. B2_KEY_ID: "REPLACE_ME" B2_KEY: "REPLACE_ME" KOPIA_PASSWORD: "choose-something-long-and-random"---apiVersion: kopiur.home-operations.com/v1alpha1kind: Repositorymetadata: name: b2-primary namespace: backupsspec: backend: b2: bucket: my-kopia-backups # the B2 bucket holding the repository prefix: prod/ # optional object-name prefix within the bucket auth: secretRef: name: b2-repo-creds encryption: passwordSecretRef: name: b2-repo-creds key: KOPIA_PASSWORD create: enabled: trueFields reference (backend.b2)
Section titled “Fields reference (backend.b2)”| Field | Required | Default | Example | What it controls |
|---|---|---|---|---|
bucket |
yes | — | my-kopia-backups |
The B2 bucket holding the repository. B2 bucket names are globally unique, as in S3. |
prefix |
no | bucket root | clusters/prod/ |
Object-name prefix so several repos can share one bucket. End it with /. |
auth.secretRef |
no | — | { name: b2-repo-creds } |
Names the credential Secret above. Same namespace as the Repository; a ClusterRepository adds namespace:. |
B2 has no cloud IAM to federate with, so its auth is Secret-only. There is no workloadIdentity here, unlike S3, Azure, and GCS.
A stray auth.workloadIdentity on a B2 backend is not rejected. The API server silently prunes it, because it isn’t in the schema.
Customization — the values you actually change
Section titled “Customization — the values you actually change”bucketandprefixset where snapshots land.create.enabledinitializes the repository if it’s missing. The creation-time algorithms are fixed forever. See creation.moverDefaults.cachesizes the mover cache. See movers.
As a ClusterRepository
Section titled “As a ClusterRepository”The same backend.b2 stanza works on a cluster-scoped ClusterRepository, with two requirements. Every Secret reference must carry an explicit namespace:, and the Secret must exist in the namespaces the movers run in. See Movers.
Try it end-to-end
Section titled “Try it end-to-end”Prove this backend really takes a backup. The same example file carries a tiny smoke-test: a throwaway PVC, a SnapshotPolicy, and a Snapshot, all pointed at the b2-primary repository above. It takes you from “applied” to “a snapshot in my bucket” in one go.
1. Apply the bundle. That is the backups namespace, the Secret, the Repository, and the smoke-test objects:
$ kubectl apply -f deploy/examples/backends/b2.yaml2. Wait for the repository to be Ready. Everything else waits on this:
$ kubectl -n backups wait --for=condition=Ready repository/b2-primary --timeout=2mrepository.kopiur.home-operations.com/b2-primary condition met3. Take the smoke backup. The Snapshot uses generateName, so create it rather than apply it. The namespace, Secret, Repository, PVC, and policy already exist and report unchanged. The Snapshot is the one new object:
$ kubectl create -f deploy/examples/backends/b2.yamlsnapshot.kopiur.home-operations.com/smoke-now-abc12 created4. Watch it succeed:
$ kubectl -n backups get snapshots -wNAME PHASE ORIGIN SNAPSHOT AGEsmoke-now-abc12 Pending manual 2ssmoke-now-abc12 Running manual 7ssmoke-now-abc12 Succeeded manual k1f1ec0a8 38sThe output above is illustrative. The Snapshot has no fixed Succeeded condition, so to wait on it in a script, key on the phase:
$ kubectl -n backups wait --for=jsonpath='{.status.phase}'=Succeeded \ snapshot/smoke-now-abc12 --timeout=5m5. Prove the data really moved. status.stats shows non-zero bytesNew and filesNew, and status.snapshot.kopiaSnapshotID is the kopia snapshot ID in your bucket:
$ kubectl -n backups get snapshot smoke-now-abc12 -o jsonpath='{.status.stats}'{"sizeBytes":4096,"bytesNew":1280,"filesNew":2,"filesUnchanged":0}
$ kubectl -n backups get snapshot smoke-now-abc12 -o jsonpath='{.status.snapshot.kopiaSnapshotID}'k1f1ec0a8Both outputs are illustrative; sizes and the ID vary. Non-zero bytesNew proves the backup uploaded real content to B2.
6. Clean up the smoke-test when you’re done:
$ kubectl -n backups delete snapshot --all # finalizer also deletes the kopia snapshot$ kubectl -n backups delete snapshotpolicy smoke$ kubectl -n backups delete pvc smoke-dataFrom here the rest of the lifecycle is the same on every backend. Only the Repository differs. Put it on a cron with a SnapshotSchedule, described in Backups & schedules and Example 01. Restore by picking a Snapshot, described in Restores and Example 03.
Troubleshooting
Section titled “Troubleshooting”unauthorizedor401. EitherB2_KEY_IDandB2_KEYare wrong, or the key isn’t scoped to this bucket. Regenerate a key for this bucket. The ID and key must be a matching pair; a fresh key under the old key ID fails the same way.- Maintenance fails, backups work. The application key is missing
deleteFiles, orlistBuckets. Recreate it with the full capability list above.
See also
Section titled “See also”- Repositories & backends: the concepts, meaning scope, encryption, and creation.
- Movers, RBAC & credentials: where the credential Secret must live.
- Sibling backends: S3, which also covers B2’s S3 API · Azure · GCS.