Dell PowerStore - powerstore¶
Dell PowerStore is a storage solution from Dell Technologies. It offers the consumption of block storage across the network.
LXD supports connecting to PowerStore storage through iSCSI (Internet Small Computer Systems Interface).
Ensure that the required kernel modules and the iSCSI CLI (iscsiadm) are installed on your host system.
Terminology¶
PowerStore does not have a concept of storage pools. Instead, LXD scopes its volumes to a storage pool by prefixing each volume name with a deterministic storage pool identifier. This prefix prevents name conflicts between volumes belonging to different LXD storage pools on the same PowerStore array.
LXD creates volumes on the PowerStore array and maps them to the respective LXD host. When the first volume needs to be mapped to a specific LXD host, LXD discovers and connects to the available targets provided by PowerStore.
The powerstore driver in LXD¶
The powerstore driver in LXD uses PowerStore volumes for custom storage volumes, instances, and snapshots.
All volumes created by LXD using the powerstore driver are thin-provisioned block volumes. If required (for example, for containers and custom file system volumes), LXD formats the volume with a desired file system.
LXD expects PowerStore to be pre-configured and accessible. When creating the LXD storage pool, the user must specify authentication credentials that allow LXD to connect to PowerStore. LXD also assumes that it has full control over the volumes it manages.
This driver provides remote storage. As a result, and depending on the internal network, storage access might be a bit slower compared to local storage. On the other hand, using remote storage has significant advantages in a cluster setup: all cluster members have access to the same storage pools with the exact same contents, without requiring the storage pools to be synchronized between members.
When a volume is first mapped to the LXD host, LXD discovers the available targets from the PowerStore array and connects to them.
Alternatively, you can specify the targets with powerstore.target.
Volume snapshots are supported by PowerStore. When a volume with at least one snapshot is copied, LXD sequentially copies snapshots into the destination volume, from which a new snapshot is created. Finally, once all snapshots are copied, the source volume is copied into the destination volume.
Volume names¶
The driver uses the volume’s volatile.uuid to generate a volume name.
The pool-scoped prefix lxd-<pool_name_hash>- is prepended to all volume names along with special identifiers, such as c_ or v_, to distinguish volume types.
Additional identifiers, such as .i or .b, may also be appended to further distinguish volume types.
Type |
Identifier |
Example |
|---|---|---|
Container |
|
|
Virtual machine |
|
|
Image (ISO) |
|
|
Custom volume |
|
|
Mountable snapshot clone |
|
|
Snapshots in PowerStore are native children of their parent volume. Each snapshot is named using the snapshot’s own UUID with the same type prefix as the parent volume.
Mountable snapshot clones are temporary volumes created by LXD when a snapshot needs to be directly accessed (for example, during export). The s prefix is prepended to the volume type identifier to distinguish them from regular volumes.
Limitations¶
The powerstore driver has the following limitations:
- Volume size constraints
The minimum volume size (quota) is
1MiBand must be a multiple of1MiB. The maximum volume size is256TiB.- Volume shrinking
The PowerStore driver does not allow shrinking volumes.
- Sharing custom volumes between instances
The PowerStore driver “simulates” volumes with content type
filesystemby putting a file system on top of a PowerStore volume. Therefore, custom storage volumes can only be assigned to a single instance at a time.- Sharing a PowerStore storage pool between multiple LXD installations
Sharing the same PowerStore storage pool between multiple LXD installations is not supported.
- Recovering PowerStore storage pools
Recovery of PowerStore storage pools using
lxd recoveris not supported.
Configuration options¶
The following configuration options are available for storage pools that use the powerstore driver, as well as storage volumes in these pools.
Storage pool configuration¶
| Key: | powerstore.gateway |
| Type: | string |
| Scope: | global |
| Key: | powerstore.gateway.verify |
| Type: | bool |
| Default: |
|
| Scope: | global |
| Key: | powerstore.mode |
| Type: | string |
| Default: | the discovered mode |
| Scope: | global |
The mode to use to map PowerStore volumes to the local server.
Supported value is iscsi.
| Key: | powerstore.target |
| Type: | string |
| Default: | target addresses |
A comma-separated list of target addresses. If empty, LXD discovers and connects to all available targets. Otherwise, it only connects to the specified addresses.
| Key: | powerstore.user.name |
| Type: | string |
| Default: |
|
| Scope: | global |
Name of the PowerStore user with an admin role that gives LXD full control over managed storage pools.
| Key: | powerstore.user.password |
| Type: | string |
| Scope: | global |
| Key: | rsync.bwlimit |
| Type: | string |
| Default: |
|
| Scope: | global |
When rsync must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.
| Key: | rsync.compression |
| Type: | bool |
| Default: |
|
| Scope: | global |
| Key: | volume.size |
| Type: | string |
| Default: |
|
| Scope: | global |
The size must be in multiples of 1 MiB. The minimum size is 1 MiB and maximum is 256 TiB.
Tip
In addition to these configurations, you can also set default values for the storage volume configurations. See Configure default values for storage volumes.
Storage volume configuration¶
| Key: | block.filesystem |
| Type: | string |
| Default: | same as |
| Condition: | block-based volume with content type |
| Scope: | global |
Valid options: btrfs, ext4, xfs
If not set, ext4 is assumed.
| Key: | block.mount_options |
| Type: | string |
| Default: | same as |
| Condition: | block-based volume with content type |
| Scope: | global |
| Key: | security.shifted |
| Type: | bool |
| Default: | same as |
| Condition: | custom volume |
| Scope: | global |
Enable this option to allow the volume to be attached to multiple isolated instances.
| Key: | security.unmapped |
| Type: | bool |
| Default: | same as |
| Condition: | custom volume |
| Scope: | global |
| Key: | size |
| Type: | string |
| Default: | same as |
| Scope: | global |
The size must be in multiples of 1 MiB. The minimum size is 1 MiB and maximum is 256 TiB.
| Key: | snapshots.expiry |
| Type: | string |
| Default: | same as |
| Condition: | custom volume |
| Scope: | global |
Specify an expression like 1M 2H 3d 4w 5m 6y.
| Key: | snapshots.pattern |
| Type: | string |
| Default: | same as |
| Condition: | custom volume |
| Scope: | global |
You can specify a naming template for scheduled snapshots and unnamed snapshots.
The snapshots.pattern option uses a Pongo2 template string to format the snapshot name.
To add a time stamp to the snapshot name, use the Pongo2 context variable creation_date.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set snapshots.pattern to {{ creation_date|date:'2006-01-02_15-04-05' }} to name the snapshots after their time of creation, down to the precision of a second.
Another way to avoid name collisions is to use the placeholder %d in the pattern.
If no matching snapshots exist, the placeholder is replaced with 0.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.
| Key: | snapshots.schedule |
| Type: | string |
| Default: | same as |
| Condition: | custom volume |
| Scope: | global |
Specify either a cron expression (<minute> <hour> <dom> <month> <dow>), a comma-separated list of schedule aliases (@hourly, @daily, @midnight, @weekly, @monthly, @annually, @yearly), or leave empty to disable automatic snapshots (the default).
| Key: | volatile.devlxd.owner |
| Type: | string |
| Default: | DevLXD owner identity ID |
| Scope: | global |
| Key: | volatile.idmap.last |
| Type: | string |
| Condition: | filesystem |
| Key: | volatile.idmap.next |
| Type: | string |
| Condition: | filesystem |