Skip to content

Commit

Permalink
Implement cinder volume driver as block storage (#9)
Browse files Browse the repository at this point in the history
Implement cinder volume driver as block storage

Unrelated changes:
- Use fmt.Sprintf to concatenate strings
- Rename plugin to common name velero.io/openstack
- Allow authenticating against swift with special env vars
- Allow Authenticate to specify which service is authenticating
- Log enhancements (lowercase the errors)
- Update README with installation, env vars usage, volume backups section, development section
  • Loading branch information
Lirt authored Mar 19, 2021
1 parent d8b6dab commit 910a379
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 28 deletions.
111 changes: 101 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
# Swift plugin for Velero
# Velero Plugin for Openstack

Openstack Swift plugin for [velero](https://github.com/vmware-tanzu/velero/) backups.
Openstack Cinder and Swift plugin for [velero](https://github.com/vmware-tanzu/velero/) backups.

## Configure
## Configuration

Configure velero container with swift authentication environment variables:
Configure velero container with your Openstack authentication environment variables:

```bash
# Keystone v2.0
export OS_AUTH_URL=<AUTH_URL /v2.0>
export OS_USERNAME=<USERNAME>
export OS_PASSWORD=<PASSWORD>
export OS_REGION_NAME=<REGION>

# Keystone v3
export OS_AUTH_URL=<AUTH_URL /v3>
export OS_PASSWORD=<PASSWORD>
export OS_USERNAME=<USERNAME>
export OS_PROJECT_ID=<PROJECT_ID>
export OS_PROJECT_NAME=<PROJECT_NAME>
export OS_REGION_NAME=<REGION_NAME>
export OS_DOMAIN_NAME=<DOMAIN_NAME OR OS_USER_DOMAIN_NAME>

# If you want to test with unsecure certificates
export OS_VERIFY="false"
```

If your Openstack cloud has separated Swift service (SwiftStack or different), you can specify special environment variables for Swift to authenticate it and keep the standard ones for Cinder:

```bash
# Swift with SwiftStack
export OS_SWIFT_AUTH_URL=<AUTH_URL /v2.0>
export OS_SWIFT_PASSWORD=<PASSWORD>
export OS_SWIFT_PROJECT_ID=<PROJECT_ID>
export OS_SWIFT_REGION_NAME=<REGION_NAME>
export OS_SWIFT_TENANT_NAME=<TENANT_NAME>
export OS_SWIFT_USERNAME=<USERNAME>
```

### Install Using Velero CLI

Initialize velero plugin

```bash
# Initialize velero from scratch:
velero install --provider swift --plugins lirt/velero-plugin-swift:v0.1.1 --bucket <BUCKET_NAME> --no-secret
velero install \
--provider "velero.io/openstack" \
--plugins lirt/velero-plugin-for-openstack:v0.2.0 \
--bucket <BUCKET_NAME> \
--no-secret

# Or add plugin to existing velero:
velero plugin add lirt/velero-plugin-swift:v0.1.1
velero plugin add lirt/velero-plugin-for-openstack:v0.2.0
```

Change configuration of `backupstoragelocations.velero.io`:
Expand All @@ -32,15 +60,68 @@ Change configuration of `backupstoragelocations.velero.io`:
spec:
objectStorage:
bucket: <BUCKET_NAME>
provider: swift
provider: velero.io/openstack
```
## Test
Change configuration of `volumesnapshotlocations.velero.io`:

```yaml
spec:
provider: velero.io/openstack
```

### Install Using Helm Chart

Alternative installation can be done using Helm Charts.

There is an [official helm chart for Velero](https://github.com/vmware-tanzu/helm-charts/) which can be used to install both velero and velero openstack plugin.

To use it, first create `values.yaml` file which will later be used in helm installation (here is just minimal necessary configuration):

```yaml
---
credentials:
extraSecretRef: "velero-credentials"
configuration:
provider: openstack
backupStorageLocation:
bucket: my-swift-bucket
initContainers:
- name: velero-plugin-openstack
image: lirt/velero-plugin-for-openstack:v0.2.0
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /target
name: plugins
snapshotsEnabled: true
backupsEnabled: true
# caCert: <CERT_CONTENTS_IN_BASE64>
```

Make sure that secret `velero-credentials` exists and has proper format and content.

Then install `velero` using command like this:

```bash
go test -v ./...
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
helm upgrade \
velero \
vmware-tanzu/velero \
--install \
--namespace velero \
--values values.yaml \
--version 2.15.0
```

## Volume Backups

Please note two things regarding volume backups:
1. The snapshots are done using flag `--force`. The reason is that volumes in state `in-use` cannot be snapshotted without it (they would need to be detached in advance). In some cases this can make snapshot contents inconsistent.
2. Snapshots in the cinder backend are not always supposed to be used as durable. In some cases for proper availability, the snapshot need to be backed up to off-site storage. Please consult if your cinder backend creates durable snapshots with your cloud provider.

Volume backups with Velero can also be done using [Restic](https://velero.io/docs/main/restic/).

## Build

```bash
Expand All @@ -49,5 +130,15 @@ go mod tidy
go build
# Build image
docker build --file docker/Dockerfile --tag velero-swift:my-test-tag .
docker build --file docker/Dockerfile --tag velero-plugin-for-openstack:my-test-tag .
```

## Test

```bash
go test -v ./...
```

## Development

The plugin interface is built based on the [official Velero plugin example](https://github.com/vmware-tanzu/velero-plugin-example).
10 changes: 8 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package main

import (
swift "github.com/Lirt/velero-plugin-swift/src/swift"
"github.com/Lirt/velero-plugin-swift/src/cinder"
"github.com/Lirt/velero-plugin-swift/src/swift"
"github.com/sirupsen/logrus"
veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework"
)

func main() {
veleroplugin.NewServer().
RegisterObjectStore("velero.io/swift", newSwiftObjectStore).
RegisterObjectStore("velero.io/openstack", newSwiftObjectStore).
RegisterVolumeSnapshotter("velero.io/openstack", newCinderBlockStore).
Serve()
}

func newSwiftObjectStore(logger logrus.FieldLogger) (interface{}, error) {
return swift.NewObjectStore(logger), nil
}

func newCinderBlockStore(logger logrus.FieldLogger) (interface{}, error) {
return cinder.NewBlockStore(logger), nil
}
Loading

0 comments on commit 910a379

Please sign in to comment.