User Guide LINSTOR
User Guide LINSTOR
This guide assumes, throughout, that you are using the latest version of LINSTOR and related tools.
• An Introduction to LINSTOR is a foundational overview of LINSTOR and provides explanations for LINSTOR
concepts and terms.
• Basic Administrative Tasks and System Setup deals with LINSTOR’s basic functionality and gives you insight into
using common administrative tasks. You can also use this chapter as a step-by-step instruction guide to deploy
LINSTOR with a basic, minimal setup.
• Further LINSTOR Tasks shows a variety of advanced and important LINSTOR tasks as well as configurations, so
that you can use LINSTOR in more complex ways.
• Administering LINSTOR by GUI deals with the graphical client approach to managing LINSTOR clusters that is
available to LINBIT® customers.
• LINSTOR Integrations has chapters that deal with how to implement a LINSTOR based storage solution with
various platforms and technologies, such as Kubernetes, Proxmox VE, OpenNebula, Docker, OpenStack, and
others, by using the LINSTOR API.
1
The LINSTOR User’s Guide:
Introduction to LINSTOR
2
The LINSTOR User’s Guide: 1.1. An Overview of LINSTOR
LINSTOR can be used on its own or you can integrate it with other platforms, such as Kubernetes, OpenShift,
OpenNebula, OpenStack, Proxmox VE, and others. LINSTOR runs on bare-metal on-premise hardware, or you can use
it within virtual machines (VMs), containers, clouds, or hybrid environments.
By using LINSTOR, you can work with these technologies on their own or else in various meaningful combinations.
The setup also requires one or more satellite nodes that run the LINSTOR satellite software as a systemd service,
linstor-satellite.service. The LINSTOR satellite service facilitates storage and related actions on the node,
for example creating storage volumes to provide data storage to users and applications. However, satellite nodes do
not have to provide physical storage to the cluster. For example, you can have diskless satellite nodes that participate
in the LINSTOR cluster for DRBD quorum purposes.
3
The LINSTOR User’s Guide: 1.2. How LINSTOR Works
It is also possible for a node to run both the LINSTOR controller and satellite services and act in a
Combined role.
You can think of the storage technologies as implemented on LINSTOR satellite nodes, for example, DRBD replication,
as the data plane. With LINSTOR, the control and data planes are separate and can function independently. This means,
for example, that you can update the LINSTOR controller node or the LINSTOR controller software while your LINSTOR
satellite nodes continue to provide (and replicate if using DRBD) storage to users and applications without interruption.
For convenience, a LINSTOR setup is often called a LINSTOR cluster in this guide, even though a valid LINSTOR setup
can exist as an integration within another platform, such as Kubernetes.
Users can interact with LINSTOR by using either a CLI-based client or a graphical user interface (GUI). Both of these
interfaces make use of the LINSTOR REST API. LINSTOR can integrate with other platforms and applications by using
plugins or drivers that also make use of this API.
Communication between the LINSTOR controller and the REST API happens via TCP/IP and can be secured by using
SSL/TLS.
The southbound drivers that LINSTOR uses to interface with physical storage are LVM, thinLVM and ZFS.
4
The LINSTOR User’s Guide: 1.2. How LINSTOR Works
5
The LINSTOR User’s Guide: 1.3. Installable Components
• LINSTOR controller
• LINSTOR satellite
• LINSTOR user interfaces (LINSTOR client and LINBIT SDS GUI)
These installable components are either source code that you can compile, or else prebuilt packages, that you can use
to install and run the software.
Multiple controllers can be used for LINSTOR, for example, when setting up a highly available LINSTOR cluster, but only
one controller can be active.
As mentioned earlier, the LINSTOR controller operates on a separate plane from the data plane that it manages. You
can stop the controller service, update or reboot the controller node, and still have access to your data hosted on the
LINSTOR satellite nodes. While you can still access and serve the data on your LINSTOR satellite nodes, without a
running controller node, you will not be able to perform any LINSTOR status or management tasks on the satellite
nodes.
LINSTOR Client
The LINSTOR client, linstor, is a command line utility that you can use to issue commands to the active LINSTOR
controller node. These commands can be action-oriented, such as commands that create or modify storage resources
in your cluster, or they can be status commands to glean information about the current state of your LINSTOR cluster.
You can use the LINSTOR client either by entering linstor followed by valid commands and arguments, or in the
client’s interactive mode, by entering linstor on its own.
You can find more information about using the LINSTOR client in the Using the LINSTOR Client section in this user’s
guide.
6
The LINSTOR User’s Guide: 1.3. Installable Components
# linstor
Use "help <command>" to get help for a specific command.
Available commands:
- advise (adv)
- backup (b)
- controller (c)
- drbd-proxy (proxy)
- encryption (e)
- error-reports (err)
- exos
- file (f)
- help
- interactive
- key-value-store (kv)
- list-commands (commands, list)
- node (n)
- node-connection (nc)
- physical-storage (ps)
- remote
- resource (r)
- resource-connection (rc)
- resource-definition (rd)
- resource-group (rg)
- schedule (sched)
- snapshot (s)
- sos-report (sos)
- space-reporting (spr)
- storage-pool (sp)
- volume (v)
- volume-definition (vd)
- volume-group (vg)
LINSTOR ==>
You can find more information about using the GUI interface in the LINBIT SDS GUI chapter in this user’s guide.
7
The LINSTOR User’s Guide: 1.4. Internal Components
Along the way, this section also introduces and explains core concepts and terms that you will need to familiarize
yourself with to understand how LINSTOR works and how to use it.
The most commonly used LINSTOR objects are explained below and a full list of objects follows.
Resource
A resource is the LINSTOR object that represents consumable storage that is presented to applications and end users. If
LINSTOR is a factory, then a resource is the finished product that it produces. Often, a resource is a DRBD replicated
block device but it does not have to be. For example, a resource could be diskless to satisfy DRBD quorum
requirements, or it could be an NVMe-oF or EBS initiator.
8
The LINSTOR User’s Guide: 1.4. Internal Components
Volume
A volume is the closest LINSTOR internal component to physical storage and is a subset of a resource. A resource can
have multiple volumes. For example, you might want to have a database stored on slower storage than its transaction
log in a MySQL cluster. To accomplish this by using LINSTOR, you could have one volume for the faster transaction log
storage media and another for the slower database storage media, and have both under a single "MySQL" resource. By
keeping multiple volumes under a single resource you are essentially creating a consistency group.
An attribute that you specify for a volume takes precedence over the same attribute if it is also specified "higher up" in
the LINSTOR object hierarchy. This is because, again, a volume is the closest internal LINSTOR object to physical
storage.
Node
A Node is a server or container that participates in a LINSTOR cluster. The node object has the following attributes:
• Name
• IP address
• TCP port
• Node type (controller, satellite, combined, auxiliary)
• Communication type (plain or SSL/TLS)
• Network interface type
• Network interface name
Storage Pool
A storage pool identifies storage that is assignable to other LINSTOR objects, such as LINSTOR resources, resource
definitions, or resource groups, and can be consumed by LINSTOR volumes.
• The storage back-end driver to use for the storage pool on the cluster node, for example, LVM, thin-
provisioned LVM, ZFS, and others
• The node that the storage pool exists on
• The storage pool name
• Configuration properties of the storage pool
• Additional parameters to pass to the storage pool’s back-end driver (LVM, ZFS, and others)
9
The LINSTOR User’s Guide: 1.4. Internal Components
Definitions
Definitions define the attributes of an object. Objects created from a definition will inherit the configuration attributes
defined in the definition. A definition must be created before you can create an associated child object. For example,
you must create a resource definition prior to creating the corresponding resource.
There are two LINSTOR definition objects that you can create directly, by using the LINSTOR client: resource definitions
and volume definitions.
Resource definition
Resource definitions can define the following attributes of a resource:
In addition to these definitions, LINSTOR has some indirect definitions: the storage pool definition, the snapshot
definition, and the snapshot volume definition. LINSTOR creates these automatically when you create the respective
object.
Groups
Groups are similar to definitions in that they are like profiles or templates. Where definitions apply to LINSTOR object
instances, groups apply to object definitions. As the name implies, a group can apply to multiple object definitions, just
as a definition can apply to multiple object instances. For example, you can have a resource group that defines resource
attributes for a frequently needed storage use case. You can then use the resource group to easily spawn (create)
multiple resources that need to have those attributes, without having to specify the attributes every time you create a
resource.
Resource group
A resource group is a parent object of a resource definition where all property changes made on a resource
group will be inherited by its resource definition children[1]. The resource group also stores settings for
automatic placement rules and can spawn a resource definition depending on the stored rules.
A resource group defines characteristics of its resource definition child objects. A resource spawned from the
resource group, or created from a resource definition that belongs to the resource group, will be a "grandchild"
object of a resource group and the "child" of a resource definition. Every resource definition that you create will
be a member of the default LINSTOR resource group, DfltRscGrp, unless you specify another resource group
when creating the resource definition.
10
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
Changes to a resource group will be applied to all resources or resource definitions that were created from the
resource group, retroactively, unless the same characteristic has been set on a child object, for example, a
resource definition or resource that was created from the resource group.
All of this makes using resource groups a powerful tool to efficiently manage a large number of storage
resources. Rather than creating or modifying individual resources, you can simply configure a resource group
parent, and all the child resource objects will receive the configuration.
Volume group
Similarly, volume groups are like profiles or templates for volume definitions. A volume group must always
reference a specific resource group. In addition, a volume group can define a volume number, and a "gross"
volume size.
A child object will inherit attributes that are defined on its parent objects, so long as the same attributes are not
already defined on the child object. Similarly, a lower object will receive attributes that are set on higher objects, so
long as the same attributes are not already defined on the lower object.
• A LINSTOR object can only receive or inherit attributes that can be set on that object.
• Lower objects receive attributes set on higher objects.
• An attribute set on a lower object takes precedence over the same attribute set on higher objects.
• Child objects inherit attributes set on parent objects.
• An attribute set on a child object takes precedence over the same attribute set on parent objects.
11
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
12
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
The next diagram shows the relationships between LINSTOR group objects on a single satellite node.
Figure 4. The hierarchical relationships between common LINSTOR group objects on a controller node
While the two preceding diagrams show higher-lower relationships between common LINSTOR objects, you can also
think of some LINSTOR objects as having parent-child relationships. The next diagram introduces this kind of
relationship between LINSTOR objects by using a storage pool definition (parent object) and a storage pool (child
object) as an example. A parent object can have multiple child objects, as shown in the following diagram.
13
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
14
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
Having introduced the concept of parent-child relationships in a conceptual diagram, the next diagram is a modified
version of the second diagram with some of those relationships added for groups and definitions. This modified
diagram also incorporates some of the higher-lower relationships that were shown in the first diagram.
15
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
Figure 6. The hierarchical relationships between LINSTOR group and definition objects
16
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
The next diagram synthesizes the relationship concepts of the preceding diagrams while also introducing new LINSTOR
objects related to snapshots and connections. With the many objects and criss-crossing lines, the reason for building
up to this diagram should be apparent.
17
The LINSTOR User’s Guide: 1.5. LINSTOR Object Hierarchy
18
The LINSTOR User’s Guide: 1.6. Using LINSTOR
Even with its seeming complexity, the preceding diagram is still a simplification and not an all-encompassing
representation of the possible relationships between LINSTOR objects. As listed earlier, there are more LINSTOR objects
than are shown in the diagram[3].
The good news is that you do not need to memorize the preceding diagram to work with LINSTOR. It could be useful to
refer to though if you are trying to troubleshoot attributes that you have set on LINSTOR objects and their inheritance
and effects on other LINSTOR objects in your cluster.
[1] Property changes made on a resource group will be inherited by its resource definition children and you will see the changes
reflected in the corresponding .res resource files. However, property changes made on the parent are not copied to the child
objects (either the resource definition or resource LINSTOR objects), that is, the child objects do not carry the property themselves.
The change affects the object children, but the property itself remains on the parent.
[2] Physical storage might not exist on a particular node, for example, a diskless node. Here, the "physical storage" layer is
imaginary, for the purposes of conceptualizing object hierarchy in LINSTOR.
[3] Also, because LINSTOR is evolving software, for some special use cases and contexts, it might be the case that certain object
property hierarchies are different from the general rules. When these cases occur in documentation, there will be mention of any
exceptions to the general rules.
19
The LINSTOR User’s Guide:
Administering LINSTOR
20
The LINSTOR User’s Guide: 2.1. Before Installing LINSTOR
2.1.1. Packages
LINSTOR is packaged in both the RPM and the DEB variants:
1. linstor-client contains the command line client program. It depends on Python which is usually already installed.
In RHEL 8 systems you will need to symlink python.
2. linstor-controller and linstor-satellite Both contain systemd unit files for the services. They depend on Java
runtime environment (JRE) version 1.8 (headless) or higher.
For further details about these packages see the Installable Components section above.
If you have a LINBIT® support subscription, you will have access to certified binaries through
LINBIT customer-only repositories.
You can configure LINSTOR to encrypt storage volumes, by using LUKS (dm-crypt), as detailed in the Encrypted
Volumes section of this user’s guide. Refer to the LUKS and dm-crypt projects for FIPS compliance status.
You can also configure LINSTOR to encrypt communication traffic between a LINSTOR satellite and a LINSTOR
controller, by using SSL/TLS, as detailed in the Secure Satellite Connections section of this user’s guide.
LINSTOR can also interface with Self-Encrypting Drives (SEDs) and you can use LINSTOR to initialize an SED drive.
LINSTOR stores the drive’s password as a property that applies to the storage pool associated with the drive. LINSTOR
encrypts the SED drive password by using the LINSTOR master passphrase that you must create first.
• HMAC-SHA2-512
• PBKDF2
• AES-128
A FIPS compliant version of LINSTOR is available for the use cases mentioned in this section. If you or your organization
require FIPS compliance at this level, please contact [email protected] for details.
If you want to use LINSTOR in containers, skip this section and use the Containers section below
for the installation.
21
The LINSTOR User’s Guide: 2.2. Installing LINSTOR
Enabling LINBIT package repositories will give you access to LINBIT software packages, DRBD kernel modules, and
other related software such as cluster managers and OCF scripts. You can then use a package manager to fetch, install,
and manage updating installed packages.
# curl -O https://my.linbit.com/linbit-manage-node.py
# chmod +x ./linbit-manage-node.py
# ./linbit-manage-node.py
The script will prompt you for your LINBIT customer portal username and password. After entering your credentials,
the script will list cluster nodes associated with your account (none at first).
Before it closes, the script will show a message that suggests different packages that you can install for different use
cases.
On DEB based systems you can install a precompiled DRBD kernel module package, drbd-
module-$(uname -r), or a source version of the kernel module, drbd-dkms. Install one or
the other package but not both.
22
The LINSTOR User’s Guide: 2.3. Upgrading LINSTOR
If you are using a DEB based package manager, refresh your package repositories list by entering:
apt update, before proceeding.
If you will be using LINSTOR without DRBD, you can skip installing theses packages.
If you want to be able to use LINSTOR to create DRBD replicated storage, you will need to install the required DRBD
packages. Depending on the Linux distribution that you are running on your node, install the DRBD-related packages
that the helper script suggested. If you need to review the script’s suggested packages and installation commands, you
can enter:
# ./linbit-manage-node.py --hints
To install LINSTOR on a satellite node, use your package manager to install the linbit-sds-satellite package.
Install both packages if your node will be both a satellite and controller (Combined role).
LINBIT also has downloadable archived files of source code for LINSTOR, DRBD, and more, available here:
https://linbit.com/linbit-software-download-page-for-linstor-and-drbd-linux-driver/.
If you are using the embedded default H2 database and the linstor-controller package is upgraded an automatic backup
file of the database will be created in the default /var/lib/linstor directory. This file is a good restore point if for
any reason a linstor-controller database migration should fail, then it is recommended to report the error to LINBIT and
restore the old database file and roll back to your previous controller version.
If you use any external database or etcd, it is recommended to do a manual backup of your current database to have a
restore point.
First, upgrade the linstor-controller and linstor-client packages on your controller host and then restart
the linstor-controller. The controller should start and all of its clients should show
OFFLINE(VERSION_MISMATCH). After that you can continue upgrading the linstor-satellite package on all
satellite nodes and restart them, after a short reconnection time they should all show ONLINE again and your upgrade
is finished.
2.4. Containers
LINSTOR and related software are also available as containers. The base images are available in LINBIT’s container
registry, drbd.io.
23
The LINSTOR User’s Guide: 2.4. Containers
through LINBIT customer trial accounts. Contact LINBIT for information on pricing or to begin a
trial. Alternatively, you may use LINSTOR SDS' upstream project named Piraeus, without being a
LINBIT customer.
To access the images, you first have to login to the registry using your LINBIT Customer Portal credentials.
• drbd.io/drbd9-rhel8
• drbd.io/drbd9-rhel7
• drbd.io/drbd9-sles15sp1
• drbd.io/drbd9-bionic
• drbd.io/drbd9-focal
• drbd.io/linstor-csi
• drbd.io/linstor-controller
• drbd.io/linstor-satellite
• drbd.io/linstor-client
An up-to-date list of available images with versions can be retrieved by opening http://drbd.io in your browser. Be
sure to browse the image repository through HTTP, although the registry’s images themselves are pulled through
HTTPS, using the associated docker pull command.
To load the kernel module, needed only for LINSTOR satellites, you’ll need to run a drbd9-$dist container in
privileged mode. The kernel module containers either retrieve an official LINBIT package from a customer repository,
use shipped packages, or they try to build the kernel modules from source. If you intend to build from source, you need
to have the according kernel headers (e.g., kernel-devel) installed on the host. There are four ways to execute
such a module load container:
Example using a module shipped with the container, which is enabled by not bind-mounting /usr/src:
24
The LINSTOR User’s Guide: 2.5. Initializing Your Cluster
-e LB_DIST=rhel7.7 -e LB_HASH=ThisIsMyNodeHash \
drbd.io/drbd9-rhel7
In both cases (hash + distribution, as well as bind-mounting a repo) the hash or repo configuration
has to be from a node that has a special property set. Feel free to contact our support, and we will
set this property.
For now (i.e., pre DRBD 9 version "9.0.17"), you must use the containerized DRBD kernel module,
as opposed to loading a kernel module onto the host system. If you intend to use the containers
you should not install the DRBD kernel module on your host systems. For DRBD version 9.0.17 or
greater, you can install the kernel module as usual on the host system, but you need to load the
module with the usermode_helper=disabled parameter (e.g., modprobe drbd
usermode_helper=disabled).
net=host is required for the containerized drbd-utils to be able to communicate with the
host-kernel through Netlink.
To run the LINSTOR controller container as a daemon, mapping TCP port 3370 on the host to the container, enter the
following command:
To interact with the containerized LINSTOR cluster, you can either use a LINSTOR client installed on a system using
repository packages, or using the containerized LINSTOR client. To use the LINSTOR client container:
From this point you would use the LINSTOR client to initialize your cluster and begin creating resources using the
typical LINSTOR patterns.
25
The LINSTOR User’s Guide: 2.6. Using the LINSTOR Client
Enable and also start the linstor-controller service on the host where it has been installed:
The linstor-satellite requires TCP ports 3366 and 3367. The linstor-controller
requires TCP port 3370. Verify that you have this port allowed on your firewall.
Output from this command should show you an empty list and not an error message.
You can use the linstor command on any other machine, but then you need to tell the client how to find the linstor-
controller. As shown, this can be specified as a command line option, an environment variable, or in a global file:
Alternatively you can create the /etc/linstor/linstor-client.conf file and populate it like below.
[global]
controllers=alice
If you have multiple linstor-controllers configured you can simply specify them all in a comma separated list. The
linstor-client will simply try them in the order listed.
The linstor-client commands can also be used in a much faster and convenient way by only writing
the starting letters of the parameters e.g.: linstor node list → linstor n l
If the IP is omitted, the client will try to resolve the given node-name as host-name by itself.
LINSTOR will automatically detect the node’s local uname -n which is later used for the DRBD-resource.
26
The LINSTOR User’s Guide: 2.8. Storage Pools
When you use linstor node list you will see that the new node is marked as offline. Now start and enable the
linstor-satellite on that node so that the service comes up on reboot as well:
You can also use systemctl start linstor-satellite if you are sure that the service is already enabled as
default and comes up on reboot.
About 10 seconds later you will see the status in linstor node list becoming online. Of course the satellite
process may be started before the controller knows about the existence of the satellite node.
In case the node which hosts your controller should also contribute storage to the LINSTOR cluster,
you have to add it as a node and start the linstor-satellite as well.
If you want to have other services wait until the linstor-satellite had a chance to create the necessary devices (that is,
after a boot), you can update the corresponding .service file and change Type=simple to Type=notify.
This will cause the satellite to delay sending the READY=1 message to systemd until the controller connects, sends all
required data to the satellite and the satellite at least tried once to get the devices up and running.
After creating a volume group on each of your nodes, you can create a storage pool that is backed by the volume
group on each of your nodes, by entering the following commands:
# linstor sp l
27
The LINSTOR User’s Guide: 2.8. Storage Pools
Exos pools will use the Exos pool serial number by default for the shared-space identifier.
Will give you a list of available disks grouped by size and rotational(SSD/Magnetic Disk).
With the create-device-pool command you can create a LVM pool on a disk and also directly add it as a storage
pool in LINSTOR.
If the --storage-pool option was provided, LINSTOR will create a storage pool with the given name.
For more options and exact command usage please check the linstor-client help.
28
The LINSTOR User’s Guide: 2.9. Using Resource Groups to Deploy LINSTOR Provisioned Volumes
Even if you choose not to create and use resource-groups in your LINSTOR cluster, all resources
created from resource-definitions and volume-definitions will exist in the 'DfltRscGrp' resource-
group.
A simple pattern for deploying resources using resource groups would look like this:
The commands above would result in a resource named 'my_ssd_res' with a 20GB volume replicated twice being
automatically provisioned from nodes who participate in the storage pool named 'pool_ssd'.
A more useful pattern could be to create a resource group with settings you’ve determined are optimal for your use
case. Perhaps you have to run nightly online verifications of your volumes' consistency, in that case, you could create a
resource group with the 'verify-alg' of your choice already set so that resources spawned from the group are pre-
configured with 'verify-alg' set:
The commands above result in twenty 10GiB resources being created each with the 'crc32c' 'verify-alg' pre-configured.
You can tune the settings of individual resources or volumes spawned from resource groups by setting options on the
respective resource-definition or volume-definition. For example, if 'res11' from the example above is used by a very
active database receiving many small random writes, you might want to increase the 'al-extents' for that specific
resource:
If you configure a setting in a resource-definition that is already configured on the resource-group it was spawned
from, the value set in the resource-definition will override the value set on the parent resource-group. For example,
if the same 'res11' was required to use the slower but more secure 'sha256' hash algorithm in its verifications, setting
the 'verify-alg' on the resource-definition for 'res11' would override the value set on the resource-group:
A guiding rule for the hierarchy in which settings are inherited is that the value "closer" to the
resource or volume wins: volume-definition settings take precedence over volume-group settings,
and resource-definition settings take precedence over resource-group settings.
29
The LINSTOR User’s Guide: 2.10. Configuring a Cluster
• Thick LVM
• Thin LVM with a single thin pool
• Thick ZFS
• Thin ZFS
In the following example scenario, assume that you have a goal of creating a resource named 'backups' with a size of
'500GiB' that is replicated among three cluster nodes.
If you want to resize (grow or shrink) the volume definition you can do that by specifying a new size with the set-
size command:
The size of a volume definition can only be decreased if it has no associated resource. However,
you can freely increase the size of a volume definition, even one having a deployed resource.
The parameter 0 is the number of the volume in the resource backups. You have to provide this parameter because
resources can have multiple volumes that are identified by a so-called volume number. You can find this number by
listing the volume definitions (linstor vd l). The list table will show volume numbers for the listed resources.
So far you have only created definition objects in LINSTOR’s database. However, not a single logical volume (LV) has
been created on the satellite nodes. Now you have the choice of delegating the task of deploying resources to LINSTOR
or else doing it yourself.
30
The LINSTOR User’s Guide: 2.11. Creating and Deploying Resources and Volumes
later deploy (spawn) resources. However, you can use the arguments described in this section that
accompany the --auto-place option with the resource-group create command. When
used this way, when you spawn a resource from a resource group, LINSTOR will deploy the
resource as if you had used the resource create --auto-place command.
If the nodes (or storage pools) in your cluster cannot fulfill the constraints of your --auto
-place command arguments, then LINSTOR will reject your command with an error message.
In the following example, the value after the --auto-place option tells LINSTOR how many replicas you want to
have. The --storage-pool option should be obvious.
Maybe not so obvious is that you may omit the --storage-pool option, then LINSTOR may select a storage pool on
its own. The selection follows these rules:
• Ignore all nodes and storage pools the current user has no access to
• Ignore all diskless storage pools
• Ignore all storage pools not having enough free space
The remaining storage pools will be rated by different strategies. LINSTOR has currently three strategies:
• MaxFreeSpace: This strategy maps the rating 1:1 to the remaining free space of the storage pool. However,
this strategy only considers the actually allocated space (in case of thin-provisioned storage pool this might
grow with time without creating new resources)
• MinReservedSpace: Unlike the "MaxFreeSpace", this strategy considers the reserved space. That is the
space that a thin volume can grow to before reaching its limit. The sum of reserved spaces might exceed the
storage pool’s capacity, which is as overprovisioning.
• MinRscCount: Simply the count of resources already deployed in a given storage pool
• MaxThroughput: For this strategy, the storage pool’s Autoplacer/MaxThroughput property is the base
of the score, or 0 if the property is not present. Every Volume deployed in the given storage pool will subtract
its defined sys/fs/blkio_throttle_read and sys/fs/blkio_throttle_write property- value
from the storage pool’s max throughput. The resulting score might be negative.
The scores of the strategies will be normalized, weighted and summed up, where the scores of minimizing strategies
will be converted first to allow an overall maximization of the resulting score.
The weights of the strategies can be configured with the following command:
The strategy names are listed above and the weight can be an arbitrary decimal.
To keep the behavior of the Autoplacer compatible with previous LINSTOR versions, all strategies
have a default-weight of 0, except the MaxFreeSpace which has a weight of 1.
31
The LINSTOR User’s Guide: 2.11. Creating and Deploying Resources and Volumes
Neither 0 nor a negative score will prevent a storage pool from getting selected. A storage pool
with these scores will just be considered later.
Finally, LINSTOR tries to find the best matching group of storage pools meeting all requirements. This step also
considers other auto-placement restrictions such as --replicas-on-same, --replicas-on-different,
--do-not-place-with, --do-not-place-with-regex, --layer-list, and --providers.
This ability can be particularly useful if you are trying to constrain resource placement within
Kubernetes environments that use LINSTOR managed storage. For example, you might set an
auxiliary node property that corresponds to a Kubernetes label. See the "replicasOnSame" section
within the "LINSTOR Volumes in Kubernetes" LINSTOR User’s Guide chapter for more details about
this use case.
The arguments, --replicas-on-same and --replicas-on-different expect the name of a property within
the Aux/ namespace.
The following example shows setting an auxiliary node property, testProperty, on three LINSTOR satellite nodes.
Next, you create a resource group, testRscGrp, with a place count of two and a constraint to place spawned
resources on nodes that have a testProperty value of 1. After creating a volume group, you can spawn a resource
from the resource group. For simplicity, output from the following commands is not shown.
You can verify the placement of the spawned resource by using the following command:
Because of the --replicas-on-same constraint, LINSTOR did not place the spawned resource on satellite node
node-1, because the value of its auxiliary node property, testProperty was 0 and not 1.
32
The LINSTOR User’s Guide: 2.11. Creating and Deploying Resources and Volumes
You can verify the node properties of node-1, by using the list-properties command:
For example, you can use the +1 auto-place value to deploy an additional replica of the testResource resource
used in the previous example. You will first need to set the auxiliary node property, testProperty to 1 on node-1.
Otherwise, LINSTOR will not be able to deploy the replica because of the previously configured --replicas-on
-same constraint. For simplicity, not all output from the commands below is shown.
The +1 value is not valid for the resource-group create --place-count command. This
is because the command does not deploy resources, it only creates templates from which to deploy
them later.
This command would create a resource deployed across three nodes having storage pools backed by a DRBD layer
backed by a LUKS layer (and implicitly backed by a "storage" layer). The order of layers that you specify in your CSV
list is "top-down", where a layer on the left in the list is above a layer on its right.
The --providers argument can be used to constrain automatic resource placement to only storage pools that match
those in a specified CSV list. You can use this argument to have explicit control over which storage pools will back your
deployed resource. If for example, you had a mixed environment of ZFS, LVM, and LVM_THIN storage pools in your
33
The LINSTOR User’s Guide: 2.12. Deleting Resources, Resource Definitions, and Resource Groups
cluster, by using the --providers LVM,LVM_THIN argument, you can specify that a resource only gets backed by
either an LVM or LVM_THIN storage pool, when using the --auto-place option.
The --providers argument’s CSV list does not specify an order of priority for the list elements.
Instead, LINSTOR will use factors like additional --auto-place constraints, available free space,
and LINSTOR’s storage pool selection strategies that were previously described, when placing a
resource.
This will remove the named resource definition from the entire LINSTOR cluster. The resource is removed from all
nodes and the resource entry is marked for removal from LINSTOR’s database tables. After LINSTOR has removed the
resource from all the nodes, the resource entry is removed from LINSTOR’s database tables.
If your resource definition has existing snapshots, you will not be able to delete the resource
definition until you delete its snapshots. See the Removing a Snapshot section in this guide.
Unlike deleting a resource definition, this command will only delete a LINSTOR resource from the node (or nodes) that
you specify. The resource is removed from the node and the resource entry is marked for removal from LINSTOR’s
database tables. After LINSTOR has removed the resource from the node, the resource entry is removed from
LINSTOR’s database tables.
Deleting a LINSTOR resource may have implications for a cluster, beyond just removing the resource. For example, if
the resource is backed by a DRBD layer, removing a resource from one node in a three node cluster could also remove
certain quorum related DRBD options, if any existed for the resource. After removing such a resource from a node in a
three node cluster, the resource would no longer have quorum as it would now only be deployed on two nodes in the
three node cluster.
After running a linstor resource delete command to remove a resource from a single node, you might see
informational messages such as:
INFO:
Resource-definition property 'DrbdOptions/Resource/quorum' was removed as there are not enough
resources for quorum
INFO:
Resource-definition property 'DrbdOptions/Resource/on-no-quorum' was removed as there are not
34
The LINSTOR User’s Guide: 2.13. Backup and Restore Database
Also unlike deleting a resource definition, you can delete a resource while there are existing snapshots of the resource’s
storage pool. Any existing snapshots for the resource’s storage pool will persist.
As you might expect, this command deletes the named resource group. You can only delete a resource group if it has
no associated resource definitions, otherwise LINSTOR will present an error message, such as:
ERROR:
Description:
Cannot delete resource group 'my_rg' because it has existing resource definitions.
To resolve this error so that you can delete the resource group, you can either delete the associated resource
definitions, or your can move the resource definitions to another (existing) resource group:
You can find which resource definitions are associated with your resource group by entering the following command:
To ensure a consistent database backup, take the controller offline by stopping the controller
service as shown in the commands below, before creating a backup of the LINSTOR database.
You can use the --config-directory argument with the linstor-database utility to
specify a LINSTOR configuration directory if needed. If you omit this argument, the utility uses the
35
The LINSTOR User’s Guide: 2.13. Backup and Restore Database
After backing up the database, you can copy the backup file to a safe place.
The resulting database backup is a plain JSON document, containing not just the actual data, but also some metadata
about when the backup was created, from which database, and other information.
For example, to restore the previously made backup from the db_export file, enter the following commands:
You can only import a database from a previous backup if the currently installed version of LINSTOR is the same (or
higher) version as the version that you created the backup from. If the currently installed LINSTOR version is higher
than the version that the database backup was created from, when you import the backup the data will be restored
with the same database scheme of the version used during the export. Then, the next time that the controller starts,
the controller will detect that the database has an old scheme and it will automatically migrate the data to the scheme
of the current version.
This allows the user to convert, for example, from an etcd setup to an SQL based setup. There is no special command
for converting the database format. You only have to specify the correct linstor.toml configuration file by using
the --config-directory argument (or updating the default /etc/linstor/linstor.toml and specifying
the database type that you want to use before importing). See the LINSTOR User’s Guide for more information about
specifying a database type. Regardless of the type of database that the backup was created from, it will be imported in
the database type that is specified in the linstor.toml configuration file.
36
The LINSTOR User’s Guide: 3.1. Creating a Highly Available LINSTOR Cluster
First, create a new resource that is 200MiB in size and set the necessary DRBD options, as shown in the example
commands below. You will need to adapt the storage pool name to match an existing storage pool in your environment.
It is crucial that your cluster qualifies for auto-quorum and uses the io-error policy (see Section Auto-Quorum
Policies), and that auto-promote is disabled.
From now on it is assumed that the resource’s name is linstor_db. After creating the linstor_db resource, you
can move the LINSTOR database to the new storage and create a systemd mount service. First, stop the current
controller service and disable it, as it will be managed by DRBD Reactor later.
[Mount]
# you can use the minor like /dev/drbdX or the udev symlink
What=/dev/drbd/by-res/linstor_db/0
Where=/var/lib/linstor
EOF
# mv /var/lib/linstor{,.orig}
# mkdir /var/lib/linstor
# chattr +i /var/lib/linstor # only if on LINSTOR >= 1.14.0
# drbdadm primary linstor_db
# mkfs.ext4 /dev/drbd/by-res/linstor_db/0
# systemctl start var-lib-linstor.mount
# cp -r /var/lib/linstor.orig/* /var/lib/linstor
# systemctl start linstor-controller
37
The LINSTOR User’s Guide: 3.1. Creating a Highly Available LINSTOR Cluster
Copy the /etc/systemd/system/var-lib-linstor.mount mount file to all the cluster nodes that you want
to have the potential to run the LINSTOR controller service (standby controller nodes). Again, do not systemctl
enable any of these services because DRBD Reactor will manage them.
[[promoter]]
id = "linstor_db"
[promoter.resources.linstor_db]
start = ["var-lib-linstor.mount", "linstor-controller.service"]
Depending on your requirements you might also want to set an on-stop-failure action and set stop-
services-on-exit.
After that restart drbd-reactor and enable it on all the nodes you configured it.
Check that there are no warnings from drbd-reactor service in the logs by running systemctl status drbd-
reactor. As there is already an active LINSTOR controller things will just stay the way they are. Run drbd-
reactorctl status linstor_db to check the health of the linstor_db target unit.
The last but nevertheless important step is to configure the LINSTOR satellite services to not delete (and then
regenerate) the resource file for the LINSTOR controller DB at its startup. Do not edit the service files directly, but use
systemctl edit. Edit the service file on all nodes that could become a LINSTOR controller and that are also
LINSTOR satellites.
After this change you should execute systemctl restart linstor-satellite on all satellite nodes.
Be sure to configure your LINSTOR client for use with multiple controllers as described in the
section titled, Using the LINSTOR Client and verify that you also configured your integration plug-
ins (for example, the Proxmox plug-in) to be ready for multiple LINSTOR controllers.
38
The LINSTOR User’s Guide: 3.2. DRBD Clients
The option --diskless was deprecated. Please use --drbd-diskless or --nvme
-initiator instead.
This means that changes on different volumes from one resource are getting replicated in the same chronological order
on the other Satellites.
Therefore you don’t have to worry about the timing if you have interdependent data on different volumes in a
resource.
To deploy more than one volume in a LINSTOR-resource you have to create two volume-definitions with the same
name.
Since the volume-definition create command is used without the --vlmnr option
LINSTOR assigned the volume numbers starting at 0. In the following two lines the 0 and 1 refer to
these automatically assigned volume numbers.
Here the 'resource create' commands do not need a --storage-pool option. In this case LINSTOR uses a 'fallback'
storage pool. Finding that storage pool, LINSTOR queries the properties of the following objects in the following order:
• Volume definition
• Resource
39
The LINSTOR User’s Guide: 3.5. Using LINSTOR Without DRBD
• Resource definition
• Node
If none of those objects contain a StorPoolName property, the controller falls back to a hard-coded 'DfltStorPool'
string as a storage pool.
This also means that if you forgot to define a storage pool prior deploying a resource, you will get an error message
that LINSTOR could not find the storage pool named 'DfltStorPool'.
Currently LINSTOR supports the creation of LVM and ZFS volumes with the option of layering some combinations of
LUKS, DRBD, or NVMe-oF/NVMe-TCP on top of those volumes.
For example, assume we have a Thin LVM backed storage pool defined in our LINSTOR cluster named, thin-lvm:
We could use LINSTOR to create a Thin LVM on linstor-d that’s 100GiB in size using the following commands:
You should then see you have a new Thin LVM on linstor-d. You can extract the device path from LINSTOR by
listing your linstor resources with the --machine-readable flag set:
If you wanted to layer DRBD on top of this volume, which is the default --layer-list option in LINSTOR for ZFS or
LVM backed volumes, you would use the following resource creation pattern instead:
You would then see that you have a new Thin LVM backing a DRBD volume on linstor-d:
40
The LINSTOR User’s Guide: 3.5. Using LINSTOR Without DRBD
"backing_disk": "/dev/drbdpool/rsc-1_00000",
The following table shows which layer can be followed by which child-layer:
For information about the prerequisites for the LUKS layer, refer to the Encrypted Volumes section
of this User’s Guide.
NVMe-oF only works on RDMA-capable networks and NVMe-TCP on networks that can carry IP
traffic. You can use tools such as lshw or ethtool to verify the capabilities of your network
adapters.
To use NVMe-oF/NVMe-TCP with LINSTOR the package nvme-cli needs to be installed on every node which acts as
a satellite and will use NVMe-oF/NVMe-TCP for a resource. For example, on a DEB-based system, to install the
package, enter the following command:
If you are not on a DEB-based system, use the suitable command for installing packages on your
operating system, for example, on SLES: zypper; on RPM-based systems: dnf.
To make a resource which uses NVMe-oF/NVMe-TCP an additional parameter has to be given as you create the
resource-definition:
As default the -l (layer-stack) parameter is set to drbd, storage when DRBD is used. If you
want to create LINSTOR resources with neither NVMe nor DRBD you have to set the -l parameter
to only storage.
To use NVMe-TCP rather than the default NVMe-oF, the following property needs to be set:
41
The LINSTOR User’s Guide: 3.5. Using LINSTOR Without DRBD
Before you create the resource on your nodes you have to know where the data will be stored locally and which node
accesses it over the network.
First we create the resource on the node where our data will be stored:
On the nodes where the resource-data will be accessed over the network, the resource has to be defined as diskless:
Now you can mount the resource nvmedata on one of your nodes.
If your nodes have more than one NIC you should force the route between them for NVMe-
of/NVME-TCP, otherwise multiple NICs could cause troubles.
As OpenFlex combines concepts of LINSTOR’s storage as well as NVMe-layer, LINSTOR was added both, a new storage
driver for the storage pools as well as a dedicated openflex layer which uses the mentioned REST API.
In order for LINSTOR to communicate with the OpenFlex-API, LINSTOR needs some additional properties, which can be
set once on controller level to take LINSTOR-cluster wide effect:
Once that is configured, we can now create LINSTOR objects to represent the OpenFlex architecture. The theoretical
mapping of LINSTOR objects to OpenFlex objects are as follows: Obviously an OpenFlex storage pool is represented by
a LINSTOR storage pool. As the next thing above a LINSTOR storage pool is already the node, a LINSTOR node
represents an OpenFlex storage device. The OpenFlex objects above storage device are not mapped by LINSTOR.
When using NVMe, LINSTOR was designed to run on both sides, the NVMe target as well as on the NVMe initiator side.
In the case of OpenFlex, LINSTOR cannot (or even should not) run on the NVMe target side as that is completely
managed by OpenFlex. As LINSTOR still needs nodes and storage pools to represent the OpenFlex counterparts, the
LINSTOR client was extended with special node create commands since 1.0.14. These commands not only accept
additionally needed configuration data, but also starts a "special satellite" besides the already running controller
instance. These special satellites are completely LINSTOR managed. They will shut down when the controller shuts
down and will be started again when the controller starts.
The new client command for creating a "special satellite" representing an OpenFlex storage device is:
42
The LINSTOR User’s Guide: 3.5. Using LINSTOR Without DRBD
• ofNode1 is the node name which is also used by the standard linstor node create command
• 192.168.166.7 is the address on which the provided NVMe devices can be accessed. As the NVMe devices
are accessed by a dedicated network interface, this address differs from the address specified with the
property StorDriver/Openflex/ApiHost. The latter is used for the management / REST API.
• 000af795789d is the identifier for the OpenFlex storage device.
The last step of the configuration is the creation of LINSTOR storage pools:
• ofNode1 and sp0 are the node name and storage pool name, respectively, just as usual for the LINSTOR’s
create storage pool command
• The last 0 is the identifier of the OpenFlex storage pool within the previously defined storage device
Once all necessary storage pools are created in LINSTOR, the next steps are similar to the usage of using an NVMe
resource with LINSTOR. Here is a complete example:
# create a storage pool for openflex storage pool "0" within storage device "000af795789d"
linstor storage-pool create openflex ofNode1 sp0 0
In case a node should access the OpenFlex REST API through a different host than specified with
linstor controller set-property StorDriver/Openflex/ApiHost
10.43.7.185 you can always use LINSTOR’s inheritance mechanism for properties. That means
simply define the same property on the node-level you need it, i.e.
linstor node set-property ofNode1 StorDriver/Openflex/ApiHost
10.43.8.185
43
The LINSTOR User’s Guide: 3.5. Using LINSTOR Without DRBD
The two properties set in the examples are mandatory, but can also be set on controller level which would act as a
default for all resources with WRITECACHE in their --layer-list. However, please note that the
Writecache/PoolName refers to the corresponding node. If the node does not have a storage pool named
pmempool you will get an error message.
The 4 mandatory parameters required by DM-Writecache are either configured through a property or figured out by
LINSTOR. The optional properties listed in the mentioned link can also be set through a property. Please see linstor
controller set-property --help for a list of Writecache/* property-keys.
Using --layer-list DRBD,WRITECACHE,STORAGE while having DRBD configured to use external metadata,
only the backing device will use a writecache, not the device holding the external metadata.
Rather than Writecache/PoolName (as when configuring the Writecache layer) the Cache
layer’s only required property is called Cache/CachePool. The reason for this is that the Cache
layer also has a Cache/MetaPool which can be configured separately or it defaults to the value
of Cache/CachePool.
Please see linstor controller set-property --help for a list of Cache/* property-keys and default
values for omitted properties.
Using --layer-list DRBD,CACHE,STORAGE while having DRBD configured to use external metadata, only the
backing device will use a cache, not the device holding the external metadata.
44
The LINSTOR User’s Guide: 3.6. Storage Providers
For a list of providers with their properties please see Storage Providers.
• Diskless: This provider type is mostly required to have a storage pool that can be configured with LINSTOR
properties like PrefNic as described in Managing Network Interface Cards.
• LVM / LVM-Thin: The adminstrator is expected to specify the LVM volume group or the thin-pool (in form of
"LV/thinpool") to use the corresponding storage type. These drivers support following properties for fine-
tuning:
◦ StorDriver/LvcreateOptions: The value of this property is appended to every lvcreate … call
LINSTOR executes.
• ZFS / ZFS-Thin: The administrator is expected to specify the ZPool that LINSTOR should use. These drivers
support following properties for fine-tuning:
◦ StorDriver/ZfscreateOptions: The value of this property is appended to every zfs create
… call LINSTOR executes.
• File / FileThin: Mostly used for demonstration / experiments. LINSTOR will basically reserve a file in a given
directory and will configure a loop device on top of that file.
• OpenFlex: This special storage provider currently requires to be run on a "special satellite". Please see
OpenFlex™ Layer for more details.
• EXOS: This special storage provider is currently required to be run on a "special satellite". Please see the EXOS
Integration chapter.
• SPDK: The administrator is expected to specify the logical volume store which LINSTOR should use. The usage
of this storage provider implies the usage of the NVME Layer.
◦ Remote-SPDK: This special storage provider currently requires to be run on a "special satellite". Please
see Remote SPDK Provider for more details.
This will start a new satellite instance running on the same machine as the controller. This special satellite will do all the
REST based RPC communication towards the remote SPDK proxy. As the help message of the LINSTOR command
45
The LINSTOR User’s Guide: 3.7. Managing Network Interface Cards
shows, the administrator might want to use additional settings when creating this special satellite:
The difference between the --api-* and their corresponding --api-\*-env versions is that the version with the
-env ending will look for an environment variable containing the actual value to use whereas the --api-\* version
directly take the value which is stored in the LINSTOR property. Administrators might not want to save the --api-pw
in plain text, which would be clearly visible using commands like linstor node list-property <nodeName>.
Once that special satellite is up and running the actual storage pool can be created:
Whereas node_name is self-explanatory, name is the name of the LINSTOR storage pool and driver_pool_name
refers to the SPDK logical volume store.
Once this remotespdk storage pool is created the remaining procedure is quite similar as using NVMe: First the target
has to be created by creating a simple "diskful" resource followed by a second resource having the --nvme
-initiator option enabled.
When a satellite node is created a first net interface gets created implicitly with the name
default. You can use the --interface-name option of the node create command to give
it a different name, when you create the satellite node.
For existing nodes, additional net interfaces are created like this:
Net interfaces are identified by the IP address only, the name is arbitrary and is not related to the NIC name used by
Linux. You can then assign the net interface to a node so that the node’s DRBD traffic will be routed through the
corresponding NIC.
It is also possible to set the PrefNic property on a storage pool. DRBD traffic from resources
using the storage pool will be routed through the corresponding NIC. However, you need to be
careful here. Any DRBD resource that requires Diskless storage, for example, diskless storage
acting in a tiebreaker role for DRBD quorum purposes, will go through the default satellite node
net interface, until you also set the PrefNic property for the default net interface. Setups can
46
The LINSTOR User’s Guide: 3.7. Managing Network Interface Cards
become complex. It is far easier and safer, if you can get away with it, to set the PrefNic
property at the node level. This way, all storage pools on the node, including Diskless storage
pools, will use your preferred NIC.
If you need to add an interface for only controller-satellite traffic, you can add an interface using the above node
interface create command. Then you modify the connection to make it the active controller-satellite
connection. For example, if you added an interface named 1G-satconn on all nodes, after adding the interface, you
can then tell LINSTOR to use this interface for controller-satellite traffic by entering the following command:
You can verify this change by using the linstor node interface list node-0 command. Output from the
command should show that the StltCon label applies to the 1G-satconn interface.
While this method routes DRBD traffic through a specified NIC, it is not possible through linstor commands only, to
route LINSTOR controller-client traffic through a specific NIC, for example, commands that you issue from a LINSTOR
client to the controller. To achieve this, you can either:
• Specify a LINSTOR controller by using methods outlined in Using the LINSTOR Client and have the only route to
the controller as specified be through the NIC that you want to use for controller-client traffic.
• Use Linux tools such as ip route and iptables to filter LINSTOR client-controller traffic, port number
3370, and route it through a specific NIC.
# linstor resource-connection path create alpha bravo myResource path1 nic1 nic1
# linstor resource-connection path create alpha bravo myResource path2 nic2 nic2
The first four commands in the example define a network interface (nic1 and nic2) for each node (alpha and
bravo) by specifying the network interface’s IP address. The last two commands create network path entries in the
DRBD .res file that LINSTOR generates. This is the relevant part of the resulting .res file:
resource myResource {
...
connection {
path {
host alpha address 192.168.43.221:7000;
host bravo address 192.168.43.222:7000;
}
path {
host alpha address 192.168.44.221:7000;
host bravo address 192.168.44.222:7000;
}
}
}
While it is possible to specify a port number to be used for LINSTOR satellite traffic when creating
a node interface, this port number is ignored when creating a DRBD resource connection path.
47
The LINSTOR User’s Guide: 3.8. Encrypted Volumes
Instead, the command will assign a port number dynamically, starting from port number 7000 and
incrementing up.
When you add a resource connection path between two nodes for a DRBD-backed resource, DRBD traffic between the
two nodes will use this new path only, although a default network interface will still exist on each node. This may be
significant if your new path uses different NICs than the implicit default path.
To use the default path again, in addition to any new paths, you will need to explicitly add it. For example:
# linstor resource-connection path create alpha bravo myResource path3 default default
Although the newly created path3 uses net interfaces that are named default on the two nodes, the path itself is
not a default path because other paths exist, namely path1 and path2. The new path, path3, will just act as a third
possible path, and DRBD traffic and path selection behavior will be as described in the next section.
"The TCP transport uses one path at a time. If the backing TCP connections get dropped, or show timeouts, the TCP
transport implementation tries to establish a connection over the next path. It goes over all paths in a round-robin
fashion until a connection gets established.
"The RDMA transport uses all paths of a connection concurrently and it balances the network traffic between the
paths evenly."
To use dm-crypt please verify that cryptsetup is installed before you start the satellite.
Before LINSTOR can encrypt any volume a master passphrase needs to be created. This can be done with the linstor-
client.
48
The LINSTOR User’s Guide: 3.9. Checking Cluster State
crypt-create-passphrase will wait for the user to input the initial master passphrase (as all other crypt
commands will with no arguments).
If you ever want to change the master passphrase this can be done with:
The luks layer can be added when creating the resource-definition or the resource itself, whereas the former method
is recommended since it will be automatically applied to all resource created from that resource-definition.
To enter the master passphrase (after controller restart) use the following command:
Whenever the linstor-controller is restarted, the user has to send the master passphrase to the
controller, otherwise LINSTOR is unable to reopen or create encrypted volumes.
[encrypt]
passphrase="example"
If either one of these is set, then every time the controller starts it will check whether a master passphrase already
exists. If there is none, it will create a new master passphrase as specified. Otherwise, the controller enters the
passphrase.
If a master passphrase is already configured, and it is not the same one as specified in the
environment variable or linstor.toml, the controller will be unable to re-enter the master
passphrase and react as if the user had entered a wrong passphrase. This can only be resolved
through manual input from the user, using the same commands as if the controller was started
without the automatic passphrase.
In case the master passphrase is set in both an environment variable and the linstor.toml, only
the master passphrase from the linstor.toml will be used.
49
The LINSTOR User’s Guide: 3.10. Evacuating a Node
If you are evacuating a node where LINSTOR is deployed within another environment, such as
Kubernetes, or OpenNebula, you need to move the node’s LINSTOR-backed workload to another
node in your cluster before evacuating its resources. For special actions and considerations within a
Kubernetes environment, see the Evacuating a Node in Kubernetes section. For a LINSTOR node in
OpenNebula, you need to perform a live migration of the OpenNebula LINSTOR-backed virtual
machines that your node hosts, to another node in your cluster, before evacuating the node’s
resources.
1. Determine if any resources on the node that you want to evacuate are "InUse". The "InUse" status corresponds
to a resource being in a DRBD Primary state. Before you can evacuate a node successfully, none of the
resources on the node should be "InUse", otherwise LINSTOR will fail to remove the "InUse" resources from the
node as part of the evacuation process.
2. Run linstor node evacuate <node_name>. You will get a warning if there is no suitable replacement
node for a resource on the evacuating node. For example, if you have three nodes and you want to evacuate
one, but your resource group sets a placement count of three, you will get a warning that will prevent the node
from removing the resources from the evacuating node.
3. Verify that the status of linstor node list for your node is "EVACUATE" rather than "Online".
4. Check the "State" status of resources on your node, by using the linstor resource list command. You
should see syncing activity that will last for sometime, depending on the size of the data sets in your node’s
resources.
5. List the remaining resources on the node by using the command linstor resource list --nodes
<node_name>. If any are left, verify whether they are just waiting for the sync to complete.
6. Verify that there are no resources on the node, by using the linstor resource list command.
7. Remove the node from the cluster by using the command linstor node delete <node_name>.
This ensures that LINSTOR will not place resources from a node that you are evacuating onto another node that you
plan on evacuating.
50
The LINSTOR User’s Guide: 3.11. Managing Snapshots
After restoring the node, you should use the node set-property <node_name> AutoplaceTarget true
command, if you previously set the AutoplaceTarget property to "false". This way, LINSTOR can again place
resources onto the node automatically, to fulfill placement count properties that you might have set for resources in
your cluster.
If LINSTOR has already evacuated resources when running a node restore command,
evacuated resources will not automatically return to the node. If LINSTOR is still in the process of
evacuating resources, this process will continue until LINSTOR has placed the resources on other
nodes. You will need to manually "move" the resources that were formerly on the restored node.
You can do this by first creating the resources on the restored node and then deleting the
resources from another node where LINSTOR may have placed them. You can use the resource
list command to show you on which nodes your resources are placed.
This will create snapshots on all nodes where the resource is present. LINSTOR will ensure that consistent snapshots are
taken even when the resource is in active use.
Setting the resource-definition property AutoSnapshot/RunEvery LINSTOR will automatically create snapshots
every X minute. The optional property AutoSnapshot/Keep can be used to clean-up old snapshots which were
created automatically. No manually created snapshot will be cleaned-up / deleted. If AutoSnapshot/Keep is
omitted (or ⇐ 0), LINSTOR will keep the last 10 snapshots by default.
First define the new resource with volumes matching those from the snapshot:
At this point, additional configuration can be applied if necessary. Then, when ready, create resources based on the
snapshots:
51
The LINSTOR User’s Guide: 3.11. Managing Snapshots
This will place the new resource on all nodes where the snapshot is present. The nodes on which to place the resource
can also be selected explicitly; see the help (linstor snapshot resource restore -h).
A resource can only be rolled back to the most recent snapshot. To roll back to an older snapshot, first delete the
intermediate snapshots.
The following tools need to be installed on the satellites that are going to send or receive snapshots:
The satellite needs to be restarted after installing these tools, otherwise LINSTOR will not be able
to use them.
Remotes
In a LINSTOR cluster, the definition of a shipping target is called a remote. Currently, there are two different types of
remotes: LINSTOR remotes and S3 remotes. LINSTOR remotes are used to ship snapshots to a different LINSTOR
cluster, while S3 remotes are needed to ship snapshots to AWS S3, min.io or any other service using S3 compatible
object storage.
Since a remote needs to store sensitive data, such as passwords, it is neccessary to have
encryption enabled whenever you want to use a remote in any way. How to set up LINSTOR’s
encryption is described here.
To create an S3 remote, LINSTOR will need to know the endpoint (that is, the URL of the target S3 server), the name of
the target bucket, the region the S3 server is in, as well as the access-key and secret-key used to access the bucket. If
the command is sent without adding the secret-key, a prompt will pop up to enter it in. The command should look like
this:
52
The LINSTOR User’s Guide: 3.11. Managing Snapshots
Usually, LINSTOR uses the endpoint and bucket to create an URL using the virtual-hosted-style for
its access to the given bucket (for example my-bucket.s3.us-west-2.amazonaws.com). Should
your setup not allow access this way, change the remote to path-style access (for example s3.us-
west-2.amazonaws.com/my-bucket) by adding the --use-path-style argument to make
LINSTOR combine the parameters accordingly.
To create a LINSTOR remote, only the URL or IP address of the controller of the target cluster is needed. The command
goes as follows:
Additionally, to ship LUKS-based (encrypted) backups, it is necessary to add the --passphrase and --cluster
-id arguments to the command. This is used to save the passphrase and cluster ID of the target cluster to the remote
respectively. For more details on shipping LUKS-based backups between two LINSTOR clusters, see this chapter.
To see all the remotes known to the local cluster, use linstor remote list. To delete a remote, use linstor
remote delete myRemoteName. Should an existing remote need altering, use linstor remote modify to
change it.
Shipping Snapshots to S3
All that is needed to ship a snapshot to S3 is to create an S3-remote that the current cluster can reach as well as the
resource that should be shipped. Then, simply use the following command to ship it there:
This command will create a snapshot of your resource and ship it to the given remote. If this isn’t the first time you
shipped a backup of this resource (to that remote) and the snapshot of the previous backup hasn’t been deleted yet,
an incremental backup will be shipped. To force the creation of a full backup, add the --full argument to the
command. Getting a specific node to ship the backup is also possible by using --node myNode, but if the specified
node is not available or only has the resource diskless, a different node will be chosen.
To see which backups exist in a specific remote, use linstor backup list myRemote. A resource-name can be
added to the command as a filter to only show backups of that specific resource by using the argument --resource
myRsc. If you use the --other argument, only entries in the bucket that LINSTOR does not recognize as a backup
will be shown. LINSTOR always names backups in a certain way, and as long as an item in the remote is named
according to this schema, it is assumed that it is a backup created by LINSTOR - so this list will show everything else.
• linstor backup delete all myRemote: This command deletes ALL S3-objects on the given remote,
provided that they are recognized to be backups, that is, fit the expected naming schema. There is the option
--cluster to only delete backups that were created by the current cluster.
• linstor backup delete id myRemote my-rsc_back_20210824_072543: This command deletes
a single backup from the given remote - namely the one with the given id, which consists of the resource-
name, the automatically generated snapshot-name (back_timestamp) and, if set, the backup-suffix. The option
--prefix lets you delete all backups starting with the given id. The option --cascade deletes not only the
specified backup, but all other incremental backups depending on it.
• linstor backup delete filter myRemote …: This command has a few different arguments to
specify a selection of backups to delete. -t 20210914_120000 will delete all backups made before 12
o’clock on the 14th of September, 2021. -n myNode will delete all backups uploaded by the given node. -r
myRsc will delete all backups with the given resource name. These filters can be combined as needed. Finally,
53
The LINSTOR User’s Guide: 3.11. Managing Snapshots
--cascade deletes not only the selected backup(s), but all other incremental backups depending on any of
the selected backups.
• linstor backup delete s3key myRemote randomPictureInWrongBucket: This command will
find the object with the given S3-key and delete it - without considering anything else. This should only be used
to either delete non-backup items from the remote, or to clean up a broken backup that is no longer deleteable
by other means. Using this command to delete a regular, working backup will break that backup, so beware!
All commands that have the --cascade option will NOT delete a backup that has incremental
backups depending on it unless you explicitly add that option.
All linstor backup delete … commands have the --dry-run option, which will give you a
list of all the S3-objects that will be deleted. This can be used to ensure nothing that should not be
deleted is accidentally deleted.
Maybe the most important task after creating a backup is restoring it. To do so, only the remote is needed - but it is
also possible to restore into an existing resource definition with no existing snapshots nor resources. There are two
options for the command:
Either --resource (-r) or --id must be used, but you cannot use both of them together. -r is used to restore
the latest backup of the resource specified with this option, while --id restores the exact backup specified by the
given id, and can therefore be used to restore backups other than the most recent.
If the backup to be restored includes a LUKS layer, the --passphrase argument is required. With it, the passphrase
of the original cluster of the backup needs to be set so that LINSTOR can decrypt the volumes after download and re-
encrypt them with the local passphrase.
The backup restore will download all the snapshots from the last full backup up to the specified backup. Afterwards, it
restores the snapshots into a new resource. If that last step should be skipped, the --download-only option needs
to be added to the command.
Backups can be downloaded from any cluster, not just the one that uploaded them, provided that the setup is correct.
Specifically, the target resource cannot have any existing resources or snapshots, and the storage pool(s) used need to
have the same storage providers. If the storage pool(s) on the target node have the exact same names as on the
cluster the backup was created on, no extra action is necessary. Should they have different names, the option
--storpool-rename needs to be used. It expects at least one oldname=newname pair. For every storage pool of
the original backup that is not named in that list, it will be assumed that its name is exactly the same on the target
node.
To find out exactly which storage pools need to be renamed, as well as how big the download and the restored
resource will be, the command linstor backup info myRemote … can be used. Similar to the restore
command, either -r or --id need to be given, which add the same restrictions as with that command. To see how
much space will be left over in the local storage pools after a restore, the argument -n myNode needs to be added.
Just like with a restore, it assumes the storage pool names are exactly the same on the given node as with the backup.
Should that not be the case, again, just like with the restore command, --storpool-rename should be used.
54
The LINSTOR User’s Guide: 3.11. Managing Snapshots
If you do not specify the cluster ID of your source cluster when you create a LINSTOR remote on
your target cluster, you will receive an "Unknown Cluster" error when you try to ship a backup. To
get the cluster ID of your source cluster, you can enter the command linstor controller
list-properties|grep -i cluster from the source cluster.
In the remote create command shown above, <NAME> is an arbitrary name that you specify to identify the
remote. <URL> is either the IP address of the source (remote) LINSTOR controller or its resolvable hostname. If you
have configured a highly available LINSTOR controller, use its virtual IP address (VIP) or the VIP’s resolvable name.
For LINSTOR to LINSTOR snapshot shipping, you must also create a LINSTOR remote on the source cluster. For
simplicity sake, although not strictly necessary, you can specify the target cluster’s LINSTOR passphrase when you
create a LINSTOR remote for the target cluster on the source cluster, before you ship backups or snapshots. On the
source cluster, enter:
If you are specifying a LINSTOR controller node (perhaps because you have a highly available
controller), when creating a remote, you can specify the controller either by an IP address or a
resolvable hostname.
Additionally, you can use --source-node and --target-node to specify which node should send and receive the
backup respectively. In case those nodes are not available, a different one will be chosen automatically.
If targetRsc is already a deployed resource on the remote cluster, snapshots in the backup shipping for localRsc
will ship to the remote cluster but they will not be restored to the remote cluster. The same is true if you specify the
--download-only option with the linstor backup ship command.
55
The LINSTOR User’s Guide: 3.11. Managing Snapshots
In a case like this the solution is to reduce the amount of shipments that can happen at the same time on the same
node. This is done by using the property BackupShipping/MaxConcurrentBackupsPerNode. This property
can be set either on the controller or on a specific node.
The expected value for this property is a number. Setting it to any negative number will be interpreted as "no limit",
while setting it to zero will result in this specific node not being eligible to ship any backups - or completely disabling
backup shipping if the property is set to 0 on the controller.
Any other positive number is treated as a limit of concurrently active shippings per node. To determine which node will
send a backup shipment, LINSTOR uses the following logic in the order shown:
1. The node specified in the command (--source-node for shippings to another cluster, --node for shipping
to S3 compatible storage) will ship the backup.
2. The node that has the most available backup slots will ship the backup.
3. If no node has an available backup slot, the shipment will be added to a queue and started as soon as a different
shipment has finished which leads to a backup slot becoming available.
Deactivating a resource with DRBD in its layer-list can NOT be reactivated again. However, a
successfully shipped snapshot of a DRBD resource can still be restored into a new resource.
The snapshot ship command is considered deprecated and any bugs found with it will not be
fixed. Instead, use the backup ship command with a remote pointing to your local controller.
For more details, see the previous section.
By default, the snapshot-shipping uses TCP ports from the range 12000-12999. To change this range, the property
SnapshotShipping/TcpPortRange, which accepts a to-from range, can be set on the controller:
A resource can also be periodically shipped. To accomplish this, it is mandatory to set the properties
SnapshotShipping/TargetNode as well as SnapshotShipping/RunEvery on the resource-definition.
SnapshotShipping/SourceNode can also be set, but if omitted LINSTOR will choose an active resource of the
same resource-definition.
To allow incremental snapshot-shipping, LINSTOR has to keep at least the last shipped snapshot on the target node.
The property SnapshotShipping/Keep can be used to specify how many snapshots LINSTOR should keep. If the
property is not set (or ⇐ 0) LINSTOR will keep the last 10 shipped snapshots by default.
56
The LINSTOR User’s Guide: 3.12. Scheduled Backup Shipping
• A data set that consists of one or more deployed LINSTOR resources that you want to backup and ship
• A remote destination to ship backups to (another LINSTOR cluster or an S3 instance)
• A schedule that defines when the backups should ship
LINSTOR backup shipping only works for deployed LINSTOR resources that are backed by LVM and
ZFS storage pools, because these are the storage pool types with snapshot support in LINSTOR.
At a minimum, the command needs a schedule name and a full backup cron schema to create a backup shipping
schedule. An example command would look like this:
① If specified, the incremental cron schema describes how frequently to create and ship incremental backups. New
incremental backups are based on the most recent full backup.
② The --keep-local option allows you to specify how many snapshots that a full backup is based upon should be
kept at the local backup source. If unspecified, all snapshots will be kept. [OPTIONAL]
③ The --keep-remote option allows you to specify how many full backups should be kept at the remote
destination. This option only works with S3 remote backup destinations, because you would not want to allow a
cluster node to delete backups from a node in another cluster. All incremental backups based on a deleted full
backup will also be deleted at the remote destination. If unspecified, the --keep-remote option defaults to "all".
[OPTIONAL]
④ Specifies whether to "RETRY" or "SKIP" the scheduled backup shipping if it fails. If "SKIP" is specified, LINSTOR will
ignore the failure and continue with the next scheduled backup shipping. If "RETRY" is specified, LINSTOR will wait
60 seconds and then try the backup shipping again. The LINSTOR schedule create command defaults to "SKIP"
if no --on-failure option is given. [OPTIONAL]
⑤ The number of times to retry the backup shipping if a scheduled backup shipping fails and the --on-failure
RETRY option has been given. Without this option, the LINSTOR controller will retry the scheduled backup shipping
indefinitely, until it is successful. [OPTIONAL]
⑥ The name that you give the backup schedule so that you can reference it later with the schedule list, modify,
delete, enable, or disable commands. [REQUIRED]
⑦ This cron schema describes how frequently LINSTOR creates snapshots and ships full backups.
57
The LINSTOR User’s Guide: 3.12. Scheduled Backup Shipping
If you specify an incremental cron schema that has overlap with the full cron schema that you
specify, at the times when both types of backup shipping would occur simultaneously, LINSTOR
will only make and ship a full backup. For example, if you specify that a full backup be made every
three hours, and an incremental backup be made every hour, then every third hour, LINSTOR will
only make and ship a full backup. For this reason, specifying the same cron schema for both your
incremental and full backup shipping schedules would be useless, because incremental backups will
never be made.
Both the --keep-remote and --keep-local options deserve special mention as they have implications beyond
what may be obvious. Using these options, you specify how many snapshots or full backups should be kept, either on
the local source or the remote destination.
If there are local snapshots remaining from failed shipments, these will be deleted first, even if
they were created later.
If you have enabled a backup shipping schedule and then later manually delete a LINSTOR snapshot, LINSTOR may not
be able to delete everything it was supposed to. For example, if you delete a full backup snapshot definition, on a later
full backup scheduled shipping, there may be incremental snapshots based on the manually deleted full backup
snapshot that will not be deleted.
This option only deletes backups at the remote destination. It does not delete snapshots that the
58
The LINSTOR User’s Guide: 3.12. Scheduled Backup Shipping
For example:
This command does not affect previously created snapshots or successfully shipped backups. These will be retained
until they are manually deleted.
① This is a special option that allows you to specify the controller node that will be used as a source for scheduled
backup shipments, if possible. If you omit this option from the command, then LINSTOR will choose a source node
at the time a scheduled shipping is made. [OPTIONAL]
② You can set here either the resource group or the resource definition (but not both) that you want to enable the
backup shipping schedule for. If you omit this option from the command, then the command enables scheduled
backup shipping for all deployed LINSTOR resources that can make snapshots. [OPTIONAL]
③ The name of the remote destination that you want to ship backups to. [REQUIRED]
④ The name of a previously created backup shipping schedule. [REQUIRED]
59
The LINSTOR User’s Guide: 3.12. Scheduled Backup Shipping
If you include the option specifying either a resource group or resource definition, as described in the backup
schedule enable command example above, then you disable the schedule only for that resource group or resource
definition.
For example, if you omitted specifying a resource group or resource definition in an earlier backup schedule
enable command, LINSTOR would schedule backup shipping for all its deployed resources that can make snapshots.
Your disable command would then only affect the resource group or resource definition that you specify with the
command. The backup shipping schedule would still apply to any deployed LINSTOR resources besides the specified
resource group or resource definition.
The same as for the backup schedule enable command, if you specify neither a resource group nor a resource
definition, then LINSTOR disables the backup shipping schedule at the controller level for all deployed LINSTOR
resources.
It may be helpful to think about the backup schedule delete command as a way that you can remove a backup
shipping schedule-remote pair from a specified LINSTOR object level, either a resource definition, a resource group, or
at the controller level if neither is specified.
The backup schedule delete command does not affect previously created snapshots or successfully shipped
backups. These will be retained until they are manually deleted, or until they are removed by the effects of a still
applicable keep-local or keep-remote option.
You might want to use this command when you have disabled a backup schedule for multiple LINSTOR object levels and
later want to affect a granular change, where a backup schedule enable command might have unintended
consequences.
For example, consider a scenario where you have a backup schedule-remote pair that you enabled at a controller level.
This controller has a resource group, myresgroup that has several resource definitions, resdef1 through resdef9,
under it. For maintenance reasons perhaps, you disable the schedule for two resource definitions, resdef1 and
resdef2. You then realize that further maintenance requires that you disable the backup shipping schedule at the
resource group level, for your myresgroup resource group.
After completing some maintenance, you are able to enable the backup shipping schedule for resdef3 through
resdef9, but you are not yet ready to resume (enable) backup shipping for resdef1 and resdef2. You can enable
backup shipping for each resource definition individually, resdef3 through resdef9, or you can use the backup
schedule delete command to delete the backup shipping schedule from the resource group, myresgroup. If you
use the backup schedule delete command, backups of resdef3 through resdef9 will ship again because the
backup shipping schedule is enabled at the controller level, but resdef1 and resdef2 will not ship because the backup
shipping schedule is still disabled for them at the resource definition level.
When you complete your maintenance and are again ready to ship backups for resdef1 and resdef2, you can delete
the backup shipping schedule for those two resource definitions to return to your starting state: backup shipping
scheduled for all LINSTOR deployed resources at the controller level. To visualize this it may be helpful to refer to the
decision tree diagram for how LINSTOR decides whether or not to ship a backup in the How the LINSTOR Controller
Determines Scheduled Backup Shipping subsection.
In the example scenario above, you might have enabled backup shipping on the resource group,
after completing some maintenance. In this case, backup shipping would resume for resource
definitions resdef3 through resdef9 but continue not to ship for resource definitions resdef1 and
resdef2 because backup shipping was still disabled for those resource definitions. After you
completed all maintenance, you could delete the backup shipping schedule on resdef1 and
resdef2. Then all of your resource definitions would be shipping backups, as they were prior to
your maintenance, because the schedule-remote pair was enabled at the resource group level.
However, this would remove your option to globally stop all scheduled shipping at some later point
60
The LINSTOR User’s Guide: 3.12. Scheduled Backup Shipping
in time at the controller level because the enabled schedule at the resource group level would
override any schedule disable command applied at the controller level.
If resources have schedule-remote-pairs and are being shipped, the command output will show when the last backup
was shipped and when the next backup is scheduled to ship. It will also show whether the next and last backup
shipments were full or incremental backups. Finally, the command will show when the next planned incremental (if
any) and full backup shipping will occur.
You can use the --active-only flag with the schedule list-by-resource command to filter out all
resources that are not being shipped.
As the diagram shows, enabled or disabled backup shipping schedules have effect in the following order:
A backup shipping schedule-remote pair that is enabled or disabled at a preceding level will override the enabled or
disabled status for the same schedule-remote pair at a later level.
The command will output a table that shows on what LINSTOR object level a backup shipping schedule is either not set
(empty cell), enabled, or disabled.
By using this command, you can determine on which level you need to make a change to enable, disable, or delete
scheduled backup shipping for a resource.
61
The LINSTOR User’s Guide: 3.13. Setting DRBD Options for LINSTOR Objects
In the syntax above, <LINSTOR_ object_identifiers> is a placeholder for identifiers such as a node name,
node names, or a resource name, or a combination of these identifiers.
For example, to set the DRBD replication protocol for a resource definition named backups, enter:
You can enter a LINSTOR object along with drbd-options and the --help, or -h, flag to show the command
usage, available options, and the default value for each option. For example:
For example, to set the DRBD maximum buffer size to 8192 at a connection level, for a resource named backups,
between two nodes, node-0 and node-1, enter:
Indeed, when using the linstor --curl command to examine the two commands actions on the LINSTOR REST
API, the output is identical:
62
The LINSTOR User’s Guide: 3.13. Setting DRBD Options for LINSTOR Objects
The connection section of the LINSTOR-generated resource file backups.res on node-0 will look something like
this:
connection {
_peer_node_id 1;
path {
_this_host ipv4 192.168.222.10:7000;
_remote_host ipv4 192.168.222.11:7000;
}
path {
_this_host ipv4 192.168.121.46:7000;
_remote_host ipv4 192.168.121.220:7000;
}
net {
[...]
max-buffers 8192;
_name "node-1";
}
}
If there are multiple paths between the two nodes, as in the example above, DRBD options that
you set using the resource drbd-peer-options command will apply to all of them.
The preceding command would set the DRBD ping-timeout option to 29.9 seconds at a connection level between
two nodes, node-0 and node-1.
63
The LINSTOR User’s Guide: 3.14. Adding and Removing Disks
The same syntax applies to any drbd-peer-options set either on a LINSTOR resource, resource connection, or
node connection. For example:
Removing a DRBD option or DRBD peer option will return the option to its default value. Refer to the linstor
<LINSTOR_object> drbd-options --help (or drbd-peer-options --help) command output for the
default values of options. You can also refer to the drbd.conf-9.0 man page to get information about DRBD
options.
Suppose our cluster consists of nodes 'alpha' and 'bravo' in a local network and 'charlie' at a remote site, with a
resource definition named backups deployed to each of the nodes. Then DRBD Proxy can be enabled for the
connections to 'charlie' as follows:
64
The LINSTOR User’s Guide: 3.16. External Database Providers
The DRBD Proxy configuration can be tailored with commands such as:
LINSTOR does not automatically optimize the DRBD configuration for long-distance replication, so you will probably
want to set some configuration options such as the protocol:
As the Site property might also be used for other site-based decisions in future features, the
DrbdProxy/AutoEnable also has to be set to true:
This property can also be set on node, resource-definition, resource and resource-connection level (from left to right
in increasing priority, whereas the controller is the left-most, that is, the least prioritized level).
Once this initialization steps are completed, every newly created resource will automatically check if it has to enable
DRBD proxy to any of its peer-resources.
To use an external database there are a few additional steps to configure. You have to create a DB/Schema and user to
use for linstor, and configure this in the /etc/linstor/linstor.toml.
3.16.1. PostgreSQL
A sample PostgreSQL linstor.toml looks like this:
[db]
user = "linstor"
password = "linstor"
connection_url = "jdbc:postgresql://localhost/linstor"
65
The LINSTOR User’s Guide: 3.17. Configuring the LINSTOR Controller
[db]
user = "linstor"
password = "linstor"
connection_url = "jdbc:mariadb://localhost/LINSTOR?createDatabaseIfNotExist=true"
The LINSTOR schema/database is created as LINSTOR so verify that the MariaDB connection
string refers to the LINSTOR schema, as in the example above.
3.16.3. etcd
etcd is a distributed key-value store that makes it easy to keep your LINSTOR database distributed in a HA-setup. The
etcd driver is already included in the LINSTOR-controller package and only needs to be configured in the
linstor.toml.
More information about how to install and configure etcd can be found here: etcd docs
[db]
## only set user/password if you want to use authentication, only since LINSTOR 1.2.1
# user = "linstor"
# password = "linstor"
## for etcd
## do not set user field if no authentication required
connection_url = "etcd://etcdhost1:2379,etcdhost2:2379,etcdhost3:2379"
## if you want to use client TLS authentication too, only since LINSTOR 1.2.1
# client_key_pkcs8_pem = "client-key.pkcs8"
## set client_key_password if private key has a password
# client_key_password = "mysecret"
[http]
enabled = true
66
The LINSTOR User’s Guide: 3.17. Configuring the LINSTOR Controller
port = 3370
listen_addr = "127.0.0.1" # to disable remote access
If you want to use the REST API the current documentation can be found on the following link:
https://app.swaggerhub.com/apis-docs/Linstor/Linstor/
Here is a simple example on how you can create a self signed certificate with the keytool that is included in the Java
Runtime:
keytool will ask for a password to secure the generated keystore file and is needed for the LINSTOR Controller
configuration. In your linstor.toml file you have to add the following section:
[https]
keystore = "/path/to/keystore_linstor.jks"
keystore_password = "linstor"
Now (re)start the linstor-controller and the HTTPS REST API should be available on port 3371.
More information about how to import other certificates can be found here: https://docs.oracle.com/javase/8/docs/
technotes/tools/unix/keytool.html
When HTTPS is enabled, all requests to the HTTP /v1/ REST API will be redirected to the HTTPS
redirect.
keytool -importkeystore\
-srcstorepass linstor -deststorepass linstor -keypass linstor\
-srckeystore client.jks -destkeystore trustore_client.jks
67
The LINSTOR User’s Guide: 3.18. Configuring LINSTOR Satellite
[https]
keystore = "/path/to/keystore_linstor.jks"
keystore_password = "linstor"
truststore = "/path/to/trustore_client.jks"
truststore_password = "linstor"
Now restart the Controller and it will no longer be possible to access the controller API without a correct certificate.
The LINSTOR client needs the certificate in PEM format, so before we can use it we have to convert the java keystore
certificate to the PEM format.
# Convert to pkcs12
keytool -importkeystore -srckeystore client.jks -destkeystore client.p12\
-storepass linstor -keypass linstor\
-srcalias client1 -srcstoretype jks -deststoretype pkcs12
To avoid entering the PEM file password all the time it might be convenient to remove the password.
The --certfile parameter can also added to the client configuration file, see Using the LINSTOR Client for more
details.
3.19. Logging
LINSTOR uses SLF4J with Logback as binding. This gives LINSTOR the possibility to distinguish between the log levels
ERROR, WARN, INFO, DEBUG and TRACE (in order of increasing verbosity). The following are the different ways that
you can set the logging level, ordered by priority (first has highest priority):
1. Since LINSTOR client version 1.20.1, you can use the command controller set-log-level to change the
log level used by LINSTOR’s running configuration. Various arguments can be used with this command. Refer to
the command’s --help text for details. For example, to set the log level to TRACE on the LINSTOR controller
and all satellites, enter the following command:
To change the LINSTOR log level on a particular node, you can use the LINSTOR client (since version 1.20.1)
command node set-log-level.
68
The LINSTOR User’s Guide: 3.19. Logging
Changes that you make to the log level by using the LINSTOR client will not persist LINSTOR
service restarts, for example, if a node reboots.
3. When starting the controller or satellite a command line argument can be passed:
4. The recommended place is the logging section in the configuration file. The default configuration file location
is /etc/linstor/linstor.toml for the controller and /etc/linstor/linstor_satellite.toml
for the satellite. Configure the logging level as follows:
[logging]
level="TRACE"
69
The LINSTOR User’s Guide: 3.20. Monitoring
When none of the configuration methods above is used LINSTOR will default to INFO log level.
3.20. Monitoring
Since LINSTOR 1.8.0, a Prometheus /metrics HTTP path is provided with LINSTOR and JVM specific exports.
The /metrics path also supports three GET arguments to reduce LINSTOR’s reported data:
• resource
• storage_pools
• error_reports
These all default to true. To disable, for example error report data:
http://localhost:3370/metrics?error_reports=false
Node alpha is the just the controller. Node bravo and node charlie are just satellites.
Here are the commands to generate such a keystore setup, values should of course be edited for your environment.
70
The LINSTOR User’s Guide: 3.21. Secure Satellite Connections
keytool -importkeystore\
-srcstorepass linstor -deststorepass linstor -keypass linstor\
-srckeystore charlie/keystore.jks -destkeystore alpha/certificates.jks
keytool -importkeystore\
-srcstorepass linstor -deststorepass linstor -keypass linstor\
-srckeystore alpha/keystore.jks -destkeystore charlie/certificates.jks
echo '[netcom]
type="ssl"
port=3367
server_certificate="ssl/keystore.jks"
trusted_certificates="ssl/certificates.jks"
key_password="linstor"
keystore_password="linstor"
truststore_password="linstor"
ssl_protocol="TLSv1.2"
' | ssh root@charlie "cat > /etc/linstor/linstor_satellite.toml"
Now just start controller and satellites and add the nodes with --communication-type SSL.
71
The LINSTOR User’s Guide: 3.22. Configuring LDAP Authentication
[ldap]
enabled = true ①
# distinguished name: {user} can be used as template for the user name
dn = "uid={user}" ③
dn = "uid={user},ou=storage-services,o=ha,dc=example"
④ search_base is a string value where you can specify the starting point in the LDAP directory tree for the
authentication query, for example:
search_base = "ou=storage-services"
⑤ search_filter is a string value where you can specify an LDAP object restriction for authentication, such as
user and group membership, for example:
search_filter = "(&(uid={user})(memberof=ou=storage-services,dc=example,dc=com))"
It is highly recommended that you configure LINSTOR REST API HTTPS and LDAPS to protect
potentially sensitive traffic passing between the LINSTOR Controller and an LDAP server.
72
The LINSTOR User’s Guide: 3.23. Automatisms for DRBD Resources
If you have configured LDAP authentication without also configuring LINSTOR REST API HTTPS, you will need to
explicitly enable password authentication over HTTP, by using the --allow-insecure-path flag with your
linstor commands. This is not recommended outside of a secured and isolated LAN, as you will be sending
credentials in plain text.
The LINSTOR Controller will prompt you for the user’s password, in each of the above examples. You may optionally
use the --password argument to supply the user’s password on the command line, with all the warnings of caution
that would go along with doing so.
Inversely, LINSTOR will automatically disable quorum policies whenever there are less than the minimum required
resource assignments to achieve quorum.
This is controlled through the, DrbdOptions/auto-quorum, property which can be applied to the linstor-
controller, resource-group, and resource-definition. Accepted values for the DrbdOptions/auto-quorum
property are disabled, suspend-io, and io-error.
Setting the DrbdOptions/auto-quorum property to disabled will allow you to manually, or more granularly,
control the quorum policies of your resources should you want to.
The default policies for DrbdOptions/auto-quorum are quorum majority, and on-no-
quorum io-error. For more information about DRBD’s quorum features and their behavior,
please refer to the quorum section of the DRBD user’s guide.
The DrbdOptions/auto-quorum policies will override any manually configured properties if
DrbdOptions/auto-quorum is not disabled.
For example, to manually set the quorum policies of a resource-group named my_ssd_group, you would use the
following commands:
You may want to disable DRBD’s quorum features completely. To do that, you would need to first disable
DrbdOptions/auto-quorum on the appropriate LINSTOR object, and then set the DRBD quorum features
accordingly. For example, use the following commands to disable quorum entirely on the my_ssd_group resource-
group:
73
The LINSTOR User’s Guide: 3.23. Automatisms for DRBD Resources
Setting DrbdOptions/Resource/on-no-quorum to an empty value in the commands above
deletes the property from the object entirely.
3.23.2. Auto-Evict
If a satellite is offline for a prolonged period of time, LINSTOR can be configured to declare that node as evicted. This
triggers an automated reassignment of the affected DRBD resources to other nodes to ensure a minimum replica count
is kept.
After the linstor-controller loses the connection to a satellite, aside from trying to reconnect, it starts a timer for that
satellite. As soon as that timer exceeds DrbdOptions/AutoEvictAfterTime and all of the DRBD-connections to
the DRBD-resources on that satellite are broken, the controller will check whether or not
DrbdOptions/AutoEvictMaxDisconnectedNodes has been met. If it hasn’t, and
DrbdOptions/AutoEvictAllowEviction is true for the node in question, the satellite will be marked as
EVICTED. At the same time, the controller will check for every DRBD-resource whether the number of resources is still
above DrbdOptions/AutoEvictMinReplicaCount. If it is, the resource in question will be marked as DELETED.
If it isn’t, an auto-place with the settings from the corresponding resource-group will be started. Should the auto-
place fail, the controller will try again later when changes that might allow a different result, such as adding a new
node, have happened. Resources where an auto-place is necessary will only be marked as DELETED if the
corresponding auto-place was successful.
The evicted satellite itself will not be able to reestablish connection with the controller. Even if the node is up and
running, a manual reconnect will fail. It is also not possible to delete the satellite, even if it is working as it should be.
The satellite can, however, be restored. This will remove the EVICTED-flag from the satellite and allow you to use it
again. Previously configured network interfaces, storage pools, properties and similar entities as well as non-DRBD-
related resources and resources that could not be autoplaced somewhere else will still be on the satellite. To restore a
satellite, use
Should you want to instead throw everything that once was on that node, including the node itself, away, you need to
74
The LINSTOR User’s Guide: 3.23. Automatisms for DRBD Resources
This is useful when a Diskless node has been in a Primary state for a DRBD resource for more than a specified number
of minutes. This could happen in cases where you integrate LINSTOR managed storage with other orchestrating and
scheduling platforms, such as OpenStack, OpenNebula, and others. On some platforms that you integrate LINSTOR
with, you might not have a way to influence where in your cluster a storage volume will be used.
The auto-diskful options give you a way to use LINSTOR to sensibly delegate the roles of your storage nodes in
response to an integrated platform’s actions that are beyond your control.
To set this property, for example, on a LINSTOR resource definition named myres with a threshold of five minutes,
enter the command:
Setting the option on a LINSTOR resource group will affect all resource definitions that are spawned from the group,
unless a resource definition has the option set on it.
The order of priority, from highest to lowest, for the effect of setting the auto-diskful option is:
• Resource definition
• Resource group
• Controller
75
The LINSTOR User’s Guide: QoS Settings
You can set this option on the following LINSTOR objects: node, resource, resource definition, or resource group. The
default value for this option is True, but the option has no effect unless the auto-diskful option has also been
set.
After LINSTOR has toggled a resource to Diskful, because the threshold number of minutes has passed where a
Diskless node was in the Primary role for a resource, and after DRBD has synchronized the data to this previously
Diskless and now Primary node, LINSTOR will remove the resource from any Secondary nodes when that action is
necessary to fulfill a replica count constraint that the resource might have. This could be the case, for example, if you
have specified a number of replicas for a resource by using the --auto-place option.
QoS Settings
LINSTOR implements QoS for managed resources by using sysfs properties that correspond to kernel variables related
to block I/O operations. These sysfs properties can be limits on either bandwidth (bytes per second), or IOPS, or both.
The sysfs files and their corresponding LINSTOR properties are as follows:
Settings made to a group or definition will affect both existing and new resources created from the
group or definition.
The following example shows creating a resource group, then creating a volume group, then applying QoS settings to
the volume group, and then spawning resources from the resource group. A verification command will show that the
spawned resources inherit the QoS settings. The example uses an assumed previously created LINSTOR storage pool
named pool1. You will need to replace this name with a storage pool name that exists in your environment.
To verify that the spawned resources inherited the QoS setting, you can show the contents of the corresponding sysfs
file, on a node that contributes storage to the storage pool.
# cat /sys/fs/cgroup/blkio/blkio.throttle.write_bps_device
252:4 1048576
As the QoS properties are inherited and not copied, you will not see the property listed in any
"child" objects that have been spawned from the "parent" group or definition.
76
The LINSTOR User’s Guide: 3.24. Getting Help
Further information about subcommands (e.g., list-nodes) can be retrieved in two ways:
Using the 'help' subcommand is especially helpful when LINSTOR is executed in interactive mode (linstor
interactive).
One of the most helpful features of LINSTOR is its rich tab-completion, which can be used to complete basically every
object LINSTOR knows about (e.g., node names, IP addresses, resource names, …). In the following examples, we show
some possible completions, and their results:
# linstor node create alpha 1<tab> # completes the IP address if hostname can be resolved
# linstor resource create b<tab> c<tab> # linstor assign-resource backups charlie
If tab-completion does not work out of the box, please try to source the appropriate file:
# source /etc/bash_completion.d/linstor # or
# source /usr/share/bash_completion/completions/linstor
For zsh shell users, the linstor-client command can generate a zsh compilation file, that has basic support for
command and argument completion.
3.24.2. SOS-Report
If something goes wrong and you need help finding the cause of the issue, you can use
77
The LINSTOR User’s Guide: 3.24. Getting Help
The command above will create a new sos-report in /var/log/linstor/controller/ on the controller node.
Alternatively you can use
which will create a new sos-report and additionally downloads that report to the local machine into your current
working directory.
This sos-report contains logs and useful debug-information from several sources (Linstor-logs, dmesg, versions of
external tools used by LINSTOR, ip a, database dump and many more). These information are stored for each node in
plain text in the resulting .tar.gz file.
3.24.4. GitHub
To file bug or feature request please check out our GitHub page https://github.com/linbit
[1] https://linbit.com/drbd-user-guide/drbd-guide-9_0-en/#s-configuring-multiple-paths
78
The LINSTOR User’s Guide:
79
The LINSTOR User’s Guide: 4.1. Prerequisites
4.1. Prerequisites
• Access to LINBIT’s customer repositories.
• Running and working LINSTOR controller instance.
On yum/dnf based distributions you can install the software by entering the command:
On apt based distributions you install the software by entering the command:
4.3. Administering the LINSTOR Cluster by Using the LINBIT SDS GUI
You can access the LINBIT SDS GUI by opening an HTTP connection with the active LINSTOR controller node via TCP
port 3370. For example, if your LINSTOR controller’s IP address is 192.168.222.250, you would enter
http://192.168.222.250:3370 into your web browser’s address bar to use the LINBIT SDS GUI.
80
The LINSTOR User’s Guide:
LINSTOR Integrations
81
The LINSTOR User’s Guide: 5.1. Kubernetes Introduction
This chapter goes into great detail regarding all the install time options and various configurations possible with
LINSTOR and Kubernetes. The chapter begins with some explanatory remarks and then moves onto deployment
instructions. After that, there are instructions for getting started with LINSTOR to configure storage within a
Kubernetes deployment. Following that, more advanced topics and configurations, such as snapshots and monitoring,
are covered.
LINBIT’s container image repository (https://drbd.io), used by LINSTOR Operator, is only available
to LINBIT customers or through LINBIT customer trial accounts. Contact LINBIT for information on
pricing or to begin a trial. Alternatively, you can use the LINSTOR SDS upstream project named
Piraeus, without being a LINBIT customer.
LINSTOR Operator v2 is the recommended way of deploying LINBIT SDS for Kubernetes on new clusters. Users of
existing Operator v1 deployments should continue to use their Helm deployments and skip to the, Operator v1
deployment instructions.
Listing 2. kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: linbit-sds
resources:
- https://charts.linstor.io/static/v2.2.0.yaml ①
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: drbdio-pull-secret
type: kubernetes.io/dockerconfigjson
literals:
-
.dockerconfigjson={"auths":{"drbd.io":{"username":"MY_LINBIT_USER","password":"MY_LINBIT_PASSWORD"}}
82
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
} ②
Then, apply the kustomization.yaml file, by using kubectl command, and wait for the Operator to start:
$ kubectl apply -k .
namespace/linbit-sds created
...
$ kubectl -n linbit-sds wait pod --for=condition=Ready --all
pod/linstor-operator-controller-manager-6d9847d857-zc985 condition met
5.3.2. Deploying LINBIT SDS for Kubernetes by Using the Command Line Tool
Deploying LINBIT SDS for Kubernetes with the Operator v2 is as simple as creating a new LinstorCluster resource
and waiting for the Operator to complete the setup:
Output should eventually show that the wait condition has been met and the LINBIT SDS pods are up and running.
$ MY_LINBIT_USER=<my-linbit-customer-username>
$ MY_LINBIT_PASSWORD=<my-linbit-customer-password>
$ helm repo add linstor https://charts.linstor.io
Next, enter the following command to install the LINSTOR Operator v2:
83
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
--wait
Output from this final helm install command should show a success message.
[...]
LinstorCluster: linbit-sds
Successfully deployed!
[...]
The following example creates a simple FILE_THIN pool and it does not require any additional set up on the host:
Other types of storage pools can be configured as well. Refer to the examples upstream.
This method requires a working cert-manager deployment in your cluster. For an alternative way to provision keys and
certificates, see the OpenSSL section below.
84
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
The LINSTOR controller and satellite only need to trust each other. For that reason, you should only have a certificate
authority (CA) for those components. Apply the following YAML configuration to your deployment to create a new
cert-manager Issuer resource:
Listing 3. linstor-cert-manager.yaml
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-bootstrapper
namespace: linbit-sds
spec:
selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linstor-internal-ca
namespace: linbit-sds
spec:
commonName: linstor-internal-ca
secretName: linstor-internal-ca
duration: 87600h # 10 years
isCA: true
usages:
- signing
- key encipherment
- cert sign
issuerRef:
name: ca-bootstrapper
kind: Issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: linstor-internal-ca
namespace: linbit-sds
spec:
ca:
secretName: linstor-internal-ca
Next, configure the new issuer resource to let the LINSTOR Operator provision the certificates needed to encrypt the
controller and satellite traffic, by applying the following YAML configuration:
Listing 4. linstor-ca-issuer.yaml
---
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
internalTLS:
certManager:
name: linstor-internal-ca
kind: Issuer
---
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: internal-tls
spec:
85
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
internalTLS:
certManager:
name: linstor-internal-ca
kind: Issuer
After applying the configurations above to your deployment, you can verify that TLS traffic encryption is working.
If you completed the Provisioning Keys and Certificates By Using cert-manager section above, you can skip this
section and go to the Verifying TLS Configuration section.
First, create a new CA by using a new key and a self-signed certificate. You can change options such as the encryption
algorithm and expiry time to suit the requirements of your deployment.
Next, create two new keys, one for the LINSTOR controller, one for all satellites:
Next, create a certificate for each key, valid for 10 years, signed by the CA that you created earlier:
# openssl req -new -sha256 -key controller.key -subj "/CN=linstor-controller" -out controller.csr
# openssl req -new -sha256 -key satellite.key -subj "/CN=linstor-satellite" -out satellite.csr
# openssl x509 -req -in controller.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out controller.crt -days 3650 -sha256
# openssl x509 -req -in satellite.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out satellite.crt -days 3650 -sha256
Next, create Kubernetes secrets from the created keys and certificates:
Finally, configure the Operator resources to reference the newly created secrets, by applying the following YAML
configuration to your deployment:
Listing 5. linstor-internal-tls-secret.yaml
---
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
86
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
internalTLS:
secretName: linstor-controller-internal-tls
---
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: internal-tls
spec:
internalTLS:
secretName: linstor-satellite-internal-tls
After configuring LINSTOR controller and satellite traffic encryption, you can next verify the secure TLS connection
between the LINSTOR controller and a satellite by examining the output of a kubectl linstor node list
command. If TLS is enabled, the output will show (SSL) next to an active satellite address.
The above command relies on the kubectl-linstor command to simplify entering LINSTOR
client commands in Kubernetes. You can install the tool by following the instructions in Simplifying
LINSTOR Client Command Entry.
If the output shows (PLAIN) rather than (SSL), this indicates that the TLS configuration was not applied
successfully. Check the status of the LinstorCluster and LinstorSatellite resources.
If the output shows (SSL), but the node remains offline, this usually indicates that a certificate is not trusted by the
other party. Verify that the controller’s tls.crt is trusted by the satellite’s ca.crt and vice versa. The following
shell function provides a quick way to verify that one TLS certificate is trusted by another:
function k8s_secret_trusted_by() {
kubectl get secret -n linbit-sds \
-ogo-template='{{ index .data "tls.crt" | base64decode }}' \
"$1" > $1.tls.crt
kubectl get secret -n linbit-sds \
-ogo-template='{{ index .data "ca.crt" | base64decode }}' \
"$2" > $2.ca.crt
openssl verify -CAfile $2.ca.crt $1.tls.crt
}
# k8s_secret_trusted_by satellite-tls controller-tls
If TLS encryption was properly configured, output from running the above function should be:
satellite-tls.tls.crt: OK
The upstream Piraeus project’s reference documentation shows all available LinstorCluster and
LinstorSatelliteConfiguration resources options related to TLS.
87
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
This method requires a working cert-manager deployment in your cluster. For an alternative way to provision keys and
certificates, see the OpenSSL section below.
When using TLS, the LINSTOR API uses client certificates for authentication. It is good practice to have a separate CA
just for these certificates. To do this, first apply the following YAML configuration to your deployment to create a
certificate issuer.
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-bootstrapper
namespace: linbit-sds
spec:
selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linstor-api-ca
namespace: linbit-sds
spec:
commonName: linstor-api-ca
secretName: linstor-api-ca
duration: 87600h # 10 years
isCA: true
usages:
- signing
- key encipherment
- cert sign
issuerRef:
name: ca-bootstrapper
kind: Issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: linstor-api-ca
namespace: linbit-sds
spec:
ca:
secretName: linstor-api-ca
Next, configure this issuer to let the Operator provision the needed certificates, by applying the following
configuration.
---
apiVersion: piraeus.io/v1
88
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
apiTLS:
certManager:
name: linstor-api-ca
kind: Issuer
This completes the necessary steps for securing the LINSTOR API with TLS by using cert-manager. Skip to the
Verifying LINSTOR API TLS Configuration section to verify that TLS is working.
This method requires the openssl program on the command line. For an alternative way to provision keys and
certificates, see the cert-manager section above.
First, create a new certificate authority (CA) by using a new key and a self-signed certificate. You can change options
such as the encryption algorithm and expiry time to suit the requirements of your deployment.
Next, create two new keys, one for the LINSTOR API server, and one for all LINSTOR API clients:
Next, create a certificate for the server. Because the clients might use different shortened service names, you need to
specify multiple subject names:
89
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
Next, create Kubernetes secrets from the created keys and certificates.
Finally, configure the Operator resources to reference the newly created secrets. For simplicity, you can configure the
same client secret for all components.
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
apiTLS:
apiSecretName: linstor-api-tls
clientSecretName: linstor-client-tls
csiControllerSecretName: linstor-client-tls
csiNodeSecretName: linstor-client-tls
You can verify that the API is running, secured by TLS, by manually connecting to the HTTPS endpoint using a curl
command.
If the command is successful, the API is using HTTPS, clients are able to connect to the controller with their
certificates, and the command output should show something similar to this:
{"version":"1.20.2","git_hash":"58a983a5c2f49eb8d22c89b277272e6c4299457a","build_time":"2022-12-
14T14:21:28+00:00","rest_api_version":"1.16.0"}%
If the command output shows an error, verify that the client certificates are trusted by the API secret, and vice versa.
The following shell function provides a quick way to verify that one TLS certificate is trusted by another:
function k8s_secret_trusted_by() {
kubectl get secret -n linbit-sds \
-ogo-template='{{ index .data "tls.crt" | base64decode }}' \
"$1" > $1.tls.crt
kubectl get secret -n linbit-sds \
-ogo-template='{{ index .data "ca.crt" | base64decode }}' \
"$2" > $2.ca.crt
openssl verify -CAfile $2.ca.crt $1.tls.crt
}
90
The LINSTOR User’s Guide: 5.3. Deploying LINSTOR Operator v2
If TLS encryption was properly configured, output from running the above function should be:
satellite-tls.tls.crt: OK
Another issue might be the API endpoint using a certificate that is not using the expected service name. A typical error
message for this issue would be:
curl: (60) SSL: no alternative certificate subject name matches target host name 'linstor-controller.piraeus-datastore.svc'
In this case, make sure you have specified the right subject names when provisioning the certificates.
All available options are documented in the upstream Piraeus project’s reference documentation for
LinstorCluster.
To configure a LINSTOR passphrase in a Kubernetes deployment, the referenced secret must exist in the same
namespace as the operator (by default linbit-sds), and have a MASTER_PASSPHRASE entry.
The following example YAML configuration for the .spec.linstorPassphraseSecret configures a passphrase
example-passphrase.
---
apiVersion: v1
kind: Secret
metadata:
name: linstor-passphrase
namespace: linbit-sds
data:
# CHANGE THIS TO USE YOUR OWN PASSPHRASE!
# Created by: echo -n "example-passphrase" | base64
MASTER_PASSPHRASE: ZXhhbXBsZS1wYXNzcGhyYXNl
---
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
linstorPassphraseSecret: linstor-passphrase
LinstorCluster
This resource controls the state of the LINSTOR cluster and integration with Kubernetes.
91
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
LinstorSatelliteConfiguration
This resource controls the state of the LINSTOR satellites, optionally applying it to only a subset of nodes.
LinstorSatellite
This resource controls the state of a single LINSTOR satellite. This resource is not intended to be changed
directly, rather it is created by the LINSTOR Operator by merging all matching
LinstorSatelliteConfiguration resources.
LinstorNodeConnection
This resource controls the state of the LINSTOR node connections.
The name of this secret must match the one specified in the Helm values, by default drbdiocred.
• Configure the LINSTOR database back end. By default, the chart configures etcd as database back end. The
Operator can also configure LINSTOR to use Kubernetes as datastore directly. If you go the etcd route, you
should configure persistent storage for it:
◦ Use an existing storage provisioner with a default StorageClass.
◦ Use hostPath volumes.
◦ Disable persistence, for basic testing only. This can be done by adding --set
etcd.persistentVolume.enabled=false to the helm install command below.
• Read the storage guide and configure a basic storage setup for LINSTOR
• Read the section on securing the deployment and configure as needed.
• Select the appropriate kernel module injector using --set with the helm install command in the final
step.
◦ Choose the injector according to the distribution you are using. Select the latest version from one of
drbd9-rhel7, drbd9-rhel8,… from http://drbd.io/ as appropriate. The drbd9-rhel8 image should
also be used for RHCOS (OpenShift). For the SUSE CaaS Platform use the SLES injector that matches the
base system of the CaaS Platform you are using (e.g., drbd9-sles15sp1). For example:
operator.satelliteSet.kernelModuleInjectionImage=drbd.io/drbd9-rhel8:v9.1.8
92
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
◦ Only inject modules that are already present on the host machine. If a module is not found, it will be
skipped.
operator.satelliteSet.kernelModuleInjectionMode=DepsOnly
◦ Disable kernel module injection if you are installing DRBD by other means. Deprecated by DepsOnly
operator.satelliteSet.kernelModuleInjectionMode=None
• Finally create a Helm deployment named linstor-op that will set up everything.
Listing 6. k8s-backend.yaml
etcd:
enabled: false
operator:
controller:
dbConnectionURL: k8s
It is NOT possible to migrate from an existing cluster with etcd back end to the Kubernetes back
end.
Create the hostPath persistent volumes, substituting cluster node names accordingly in the nodes= option:
By default, a PV is created on every control-plane node. You can manually select the storage nodes by passing
--set "nodes={<NODE0>,<NODE1>,<NODE2>}" to the install command.
The correct value to reference the node is the value of the kubernetes.io/hostname label.
You can list the value for all nodes by running kubectl get nodes -o custom-
columns="Name:{.metadata.name},NodeName:{.metadata.labels['kubernetes
\.io/hostname']}"
93
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
POSTGRES_DB: postgresdb
POSTGRES_USER: postgresadmin
POSTGRES_PASSWORD: admin123
The Helm chart can be configured to use this database rather than deploying an etcd cluster, by adding the following to
the Helm install command:
operator:
satelliteSet:
storagePools:
lvmPools:
94
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
- name: lvm-thick
volumeGroup: drbdpool
This file can be passed to the Helm installation by entering the following command:
To enable automatic configuration of devices, set the devicePaths key on storagePools entries:
storagePools:
lvmPools:
- name: lvm-thick
volumeGroup: drbdpool
devicePaths:
- /dev/vdb
lvmThinPools:
- name: lvm-thin
thinVolume: thinpool
volumeGroup: linstor_thinpool
devicePaths:
- /dev/vdc
- /dev/vdd
Currently, this method supports creation of LVM and LVMTHIN storage pools.
95
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
[VDO]: https://www.redhat.com/en/blog/look-vdo-new-linux-compression-layer
The volume group created by LINSTOR for LVM thin pools will always follow the scheme
"linstor_$THINPOOL".
The secret can then be passed to the controller by passing the following argument to helm install
96
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
--set operator.controller.dbUseClientCert=true
If this option is active, the secret specified in the above section must contain two additional keys:
linstorSslMethod: cert-manager
linstorHttpsMethod: cert-manager
linstorSslMethod: helm
linstorHttpsMethod: helm
openssl req -new -newkey rsa:2048 -days 5000 -nodes -x509 -keyout ca.key \
-out ca.crt -subj "/CN=linstor-system"
openssl req -new -newkey rsa:2048 -days 5000 -nodes -x509 -keyout client-ca.key \
-out client-ca.crt -subj "/CN=linstor-client-ca"
Create private keys, two for the controller, one for all nodes and one for all clients:
97
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
linstor-op-cs.default.svc in the last command needs to match create service name. With
Helm, this is always <release-name>-cs.<namespace>.svc.
Create Kubernetes secrets that can be passed to the controller and node pods:
linstorHttpsControllerSecret: linstor-api
linstorHttpsClientSecret: linstor-client
operator:
controller:
sslSecret: linstor-control
satelliteSet:
sslSecret: linstor-satellite
98
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
--set operator.controller.luksSecret=linstor-pass
operator:
satelliteSet:
storagePools:
lvmThinPools:
- name: lvm-thin
thinVolume: thinpool
volumeGroup: ""
devicePaths:
- /dev/sdb
Default install. This does not setup any persistence for the backing etcd key-value store.
LINBIT’s container image repository (http://drbd.io), used in the previous and upcoming kubectl
create commands, is only available to LINBIT customers or through LINBIT customer trial
accounts. Contact LINBIT for information on pricing or to begin a trial. Alternatively, you can use
the LINSTOR SDS upstream project named Piraeus, without being a LINBIT customer.
Install with LINSTOR storage-pools defined at install through sp-values.yaml, persistent hostPath volumes,
three etcd replicas, and by compiling the DRBD kernel modules for the host kernels.
This should be adequate for most basic deployments. Note that this deployment is not using the pre-compiled DRBD
kernel modules just to make this command more portable. Using the pre-compiled binaries will make for a much faster
install and deployment. Using the Compile option would not be suggested for use in a large Kubernetes clusters.
99
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
Install with LINSTOR storage-pools defined at install through sp-values.yaml, use an already created PostgreSQL
DB (preferably clustered), rather than etcd, and use already compiled kernel modules for DRBD.
The PostgreSQL database in this particular example is reachable through a service endpoint named postgres.
PostgreSQL itself is configured with POSTGRES_DB=postgresdb, POSTGRES_USER=postgresadmin, and
POSTGRES_PASSWORD=admin123
1. Delete all volume claims managed by LINSTOR components. You can use the following command to get a list of
volume claims managed by LINSTOR. After checking that none of the listed volumes still hold needed data, you
can delete them using the generated kubectl delete command.
After a short wait, the controller and satellite pods should terminate. If they continue to run, you can check the
above resources for errors (they are only removed after all associated pods have terminated).
If you removed all PVCs and all LINSTOR pods have terminated, you can uninstall the Helm deployment
Due to the Helm’s current policy, the Custom Resource Definitions named
LinstorController and LinstorSatelliteSet will not be deleted by the
100
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
command. More information regarding Helm’s current position on CRDs can be found here.
LINBIT’s container image repository (http://drbd.io), used in the Helm chart below, is only available
to LINBIT customers or through LINBIT customer trial accounts. Contact LINBIT for information on
pricing or to begin a trial. Alternatively, you can use the LINSTOR SDS upstream project named
Piraeus, without being a LINBIT customer.
global:
imagePullPolicy: IfNotPresent # empty pull policy means k8s default is used ("always" if tag ==
":latest", "ifnotpresent" else) ①
setSecurityContext: true # Force non-privileged containers to run as non-root users
# Dependency charts
etcd:
enabled: true
persistentVolume:
enabled: true
storage: 1Gi
replicas: 1 # How many instances of etcd will be added to the initial cluster. ②
resources: {} # resource requirements for etcd containers ③
image:
repository: gcr.io/etcd-development/etcd
tag: v3.4.15
stork:
enabled: false
storkImage: docker.io/openstorage/stork:2.8.2
schedulerImage: registry.k8s.io/kube-scheduler
schedulerTag: ""
replicas: 1 ②
storkResources: {} # resources requirements for the stork plugin containers ③
schedulerResources: {} # resource requirements for the kube-scheduler containers ③
podsecuritycontext: {}
csi:
enabled: true
pluginImage: "drbd.io/linstor-csi:v1.1.0"
csiAttacherImage: registry.k8s.io/sig-storage/csi-attacher:v4.3.0
csiLivenessProbeImage: registry.k8s.io/sig-storage/livenessprobe:v2.10.0
csiNodeDriverRegistrarImage: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.8.0
csiProvisionerImage: registry.k8s.io/sig-storage/csi-provisioner:v3.5.0
csiSnapshotterImage: registry.k8s.io/sig-storage/csi-snapshotter:v6.2.1
csiResizerImage: registry.k8s.io/sig-storage/csi-resizer:v1.8.0
csiAttacherWorkerThreads: 10 ⑨
csiProvisionerWorkerThreads: 10 ⑨
csiSnapshotterWorkerThreads: 10 ⑨
csiResizerWorkerThreads: 10 ⑨
controllerReplicas: 1 ②
nodeAffinity: {} ④
nodeTolerations: [] ④
controllerAffinity: {} ④
controllerTolerations: [] ④
enableTopology: true
resources: {} ③
customLabels: {}
customAnnotations: {}
kubeletPath: /var/lib/kubelet ⑦
controllerSidecars: []
controllerExtraVolumes: []
nodeSidecars: []
101
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
nodeExtraVolumes: []
priorityClassName: ""
drbdRepoCred: drbdiocred
linstorSslMethod: "manual" # <- If set to 'helm' or 'cert-manager' the certificates will be
generated automatically
linstorHttpsMethod: "manual" # <- If set to 'helm' or 'cert-manager' the certificates will be
generated automatically
linstorHttpsControllerSecret: "" # <- name of secret containing linstor server certificates+key. See
docs/security.md
linstorHttpsClientSecret: "" # <- name of secret containing linstor client certificates+key. See
docs/security.md
controllerEndpoint: "" # <- override to the generated controller endpoint. use if controller is not
deployed via operator
psp:
privilegedRole: ""
unprivilegedRole: ""
operator:
replicas: 1 # <- number of replicas for the operator deployment ②
image: "drbd.io/linstor-operator:v1.10.4"
affinity: {} ④
tolerations: [] ④
resources: {} ③
customLabels: {}
customAnnotations: {}
podsecuritycontext: {}
args:
createBackups: true
createMonitoring: true
sidecars: []
extraVolumes: []
controller:
enabled: true
controllerImage: "drbd.io/linstor-controller:v1.23.0"
dbConnectionURL: ""
luksSecret: ""
dbCertSecret: ""
dbUseClientCert: false
sslSecret: ""
affinity: {} ④
httpBindAddress: ""
httpsBindAddress: ""
tolerations: ④
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
resources: {} ③
replicas: 1 ②
additionalEnv: [] ⑤
additionalProperties: {} ⑥
sidecars: []
extraVolumes: []
customLabels: {}
customAnnotations: {}
satelliteSet:
enabled: true
satelliteImage: "drbd.io/linstor-satellite:v1.23.0"
storagePools: {}
sslSecret: ""
automaticStorageType: None
affinity: {} ④
tolerations: [] ④
102
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
resources: {} ③
monitoringImage: "drbd.io/drbd-reactor:v1.2.0"
monitoringBindAddress: ""
kernelModuleInjectionImage: "drbd.io/drbd9-rhel7:v9.1.14"
kernelModuleInjectionMode: ShippedModules
kernelModuleInjectionAdditionalSourceDirectory: "" ⑧
kernelModuleInjectionResources: {} ③
kernelModuleInjectionExtraVolumeMounts: []
mountDrbdResourceDirectoriesFromHost: "" ⑩
additionalEnv: [] ⑤
sidecars: []
extraVolumes: []
customLabels: {}
customAnnotations: {}
haController:
enabled: false
image: drbd.io/linstor-k8s-ha-controller:v0.3.0
affinity: {} ④
tolerations: [] ④
resources: {} ③
replicas: 1 ②
customLabels: {}
customAnnotations: {}
103
The LINSTOR User’s Guide: 5.4. Deploying LINSTOR Operator v1
• /var/lib/linstor.d (directory)
If you have deployed LINBIT SDS in Kubernetes by using the LINSTOR Operator v2, high availability
is built into the deployment by default.
The LINSTOR High Availability Controller (HA Controller) speeds up the failover process for stateful workloads using
LINSTOR for storage. It monitors and manages any Pod that is attached to at least one DRBD resource.
For the HA Controller to work properly, you need quorum, that is at least three replicas (or two replicas + one diskless
tiebreaker). If using lower replica counts, attached Pods will be ignored and are not eligible for faster failover.
If you are using the HA Controller in your cluster you can set additional parameters in all StorageClasses. These
parameters ensure that the volume is not accidentally remounted as read-only, leading to degraded Pods.
parameters:
property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: suspend-io
property.linstor.csi.linbit.com/DrbdOptions/Resource/on-no-data-accessible: suspend-io
property.linstor.csi.linbit.com/DrbdOptions/Resource/on-suspended-primary-outdated: force-
secondary
property.linstor.csi.linbit.com/DrbdOptions/Net/rr-conflict: retry-connect
To exempt a Pod from management by the HA Controller, add the following annotation to the Pod:
These commands will create a file save.db on the machine you are running kubectl from.
104
The LINSTOR User’s Guide: 5.5. Deploying with an External LINSTOR Controller
To follow the steps in this section you should be familiar with editing LinstorCluster resources.
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec:
externalController:
url: http://linstor-controller.example.com:3370
You can also specify an IP address rather than a hostname and domain for the controller.
To use host networking, deploy a LinstorSatelliteConfiguration resource by applying the following YAML
configuration to your deployment:
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: host-network
spec:
patches:
- target:
kind: Pod
name: satellite
patch: |
apiVersion: v1
kind: Pod
metadata:
name: satellite
spec:
hostNetwork: true
105
The LINSTOR User’s Guide: 5.5. Deploying with an External LINSTOR Controller
• The Available condition on the LinstorCluster resource reports the expected URL for the external
LINSTOR controller:
• The Kubernetes nodes are registered as satellite nodes on the LINSTOR controller:
After getting the node names from the output of the above command, verify that the node names are also
LINSTOR satellites by entering a LINSTOR node list command on your LINSTOR controller node.
After all pods are ready, you should see the Kubernetes cluster nodes as satellites in your LINSTOR setup.
106
The LINSTOR User’s Guide: 5.6. Interacting with LINSTOR in Kubernetes
Your Kubernetes nodes must be reachable using their IP by the controller and storage nodes.
Create a storage class referencing an existing storage pool on your storage nodes.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor-on-k8s
provisioner: linstor.csi.linbit.com
parameters:
autoPlace: "3"
storagePool: existing-storage-pool
resourceGroup: linstor-on-k8s
You can provision new volumes by creating PVCs using your storage class. The volumes will first be placed only on
nodes with the given storage pool, that is, your storage infrastructure. Once you want to use the volume in a pod,
LINSTOR CSI will create a diskless resource on the Kubernetes node and attach over the network to the diskful
resource.
# KL_VERS=0.2.1 ①
# KL_ARCH=linux-amd64 ②
# curl -L -O \
https://github.com/piraeusdatastore/kubectl-linstor/releases/download/v$KL_VERS/kubectl-linstor-v$KL_VERS-$KL_ARCH.tar.gz
① Set the shell variable KL_VERS to the latest release version of the kubectl-linstor utility, as shown on the
kubectl-linstor releases page.
② Set the shell variable KL_ARCH to the architecture appropriate to your deployment and supported by the utility’s
available releases.
If your deployment uses the LINSTOR Operator v2, you must use version 0.2.0 or higher of the
kubectl-linstor utility.
To install the utility, first extract it and then move the extracted executable file to a directory in your $PATH, for
example, /usr/bin. Then you can use kubectl-linstor to get access to the complete LINSTOR CLI.
107
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
╰────────────────────────────────────────────────────────────────────────────────────╯
It also expands references of the form pod:[<namespace>/]<podname> into a list resources in use by the pod.
This should only be necessary for investigating problems and accessing advanced functionality. Regular operation such
as creating volumes should be achieved through the Kubernetes integration.
Configuring the behavior and properties of LINSTOR volumes deployed through Kubernetes is accomplished using
Kubernetes StorageClass objects.
The resourceGroup parameter is mandatory. Usually you want it to be unique and the same as
the storage class name.
Here below is the simplest practical StorageClass that can be used to deploy volumes:
Listing 7. linstor-basic-sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
# The name used to identify this StorageClass.
name: linstor-basic-storage-class
# The name used to match this StorageClass with a provisioner.
# linstor.csi.linbit.com is the name that the LINSTOR CSI plugin uses to identify itself
provisioner: linstor.csi.linbit.com
volumeBindingMode: WaitForFirstConsumer
parameters:
# LINSTOR will provision volumes from the drbdpool storage pool configured
# On the satellite nodes in the LINSTOR cluster specified in the plugin's deployment
storagePool: "lvm-thin"
resourceGroup: "linstor-basic-storage-class"
# Setting a fstype is required for "fsGroup" permissions to work correctly.
# Currently supported: xfs/ext4
csi.storage.k8s.io/fstype: xfs
The storagePool value, lvm-thin in the example YAML configuration file above, must match
an available LINSTOR StoragePool. You can list storage pool information using the linstor
storage-pool list command, executed within the running linstor-op-cs-controller
pod, or by using the kubectl linstor storage-pool list command if you have installed
the kubectl-linstor utility.
108
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
You can create the storage class with the following command:
Now that your storage class is created, you can now create a persistent volume claim (PVC) which can be used to
provision volumes known both to Kubernetes and LINSTOR:
Listing 8. my-first-linstor-volume-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-first-linstor-volume
spec:
storageClassName: linstor-basic-storage-class
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
This will create a PersistentVolumeClaim, but no volume will be created just yet. The storage class we used specified
volumeBindingMode: WaitForFirstConsumer, which means that the volume is only created once a workload
starts using it. This ensures that the volume is placed on the same node as the workload.
For our example, we create a simple Pod, which mounts or volume by referencing the PersistentVolumeClaim. .my-
first-linstor-volume-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: fedora
namespace: default
spec:
containers:
- name: fedora
image: fedora
command: [/bin/bash]
args: ["-c", "while true; do sleep 10; done"]
volumeMounts:
- name: my-first-linstor-volume
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: my-first-linstor-volume
persistentVolumeClaim:
claimName: "my-first-linstor-volume"
109
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
Running kubectl describe pod fedora can be used to confirm that Pod scheduling and volume attachment
succeeded. Examining the PersistentVolumeClaim, we can see that it is now bound to a volume.
To remove a volume, verify that no pod is using it and then delete the PersistentVolumeClaim using the kubectl
command. For example, to remove the volume that we just made, run the following two commands, noting that the
Pod must be unscheduled before the PersistentVolumeClaim will be removed:
linstor.csi.linbit.com/ is an optional, but recommended prefix for LINSTOR CSI specific
parameters.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: full-example
provisioner: linstor.csi.linbit.com
parameters:
# CSI related parameters
csi.storage.k8s.io/fstype: xfs
# LINSTOR parameters
linstor.csi.linbit.com/autoPlace: "2"
linstor.csi.linbit.com/placementCount: "2"
linstor.csi.linbit.com/resourceGroup: "full-example"
linstor.csi.linbit.com/storagePool: "my-storage-pool"
linstor.csi.linbit.com/disklessStoragePool: "DfltDisklessStorPool"
linstor.csi.linbit.com/layerList: "drbd storage"
linstor.csi.linbit.com/placementPolicy: "AutoPlaceTopology"
linstor.csi.linbit.com/allowRemoteVolumeAccess: "true"
linstor.csi.linbit.com/encryption: "true"
linstor.csi.linbit.com/nodeList: "diskful-a diskful-b"
linstor.csi.linbit.com/clientList: "diskless-a diskless-b"
linstor.csi.linbit.com/replicasOnSame: "zone=a"
linstor.csi.linbit.com/replicasOnDifferent: "rack"
linstor.csi.linbit.com/disklessOnRemaining: "false"
linstor.csi.linbit.com/doNotPlaceWithRegex: "tainted.*"
linstor.csi.linbit.com/fsOpts: "-E nodiscard"
linstor.csi.linbit.com/mountOpts: "noatime"
linstor.csi.linbit.com/postMountXfsOpts: "extsize 2m"
# Linstor properties
property.linstor.csi.linbit.com/*: <x>
# DRBD parameters
DrbdOptions/*: <x>
5.7.2. csi.storage.k8s.io/fstype
The csi.storage.k8s.io/fstype parameter sets the file system type to create for volumeMode:
FileSystem PVCs. Currently supported are:
110
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
• ext4 (default)
• xfs
5.7.3. autoPlace
autoPlace is an integer that determines the amount of replicas a volume of this StorageClass will have. For
instance, autoPlace: "3" will produce volumes with three-way replication. If neither autoPlace nor nodeList
are set, volumes will be automatically placed on one node.
You have to use quotes, otherwise Kubernetes will complain about a malformed StorageClass.
This option (and all options which affect auto-placement behavior) modifies the number of
LINSTOR nodes on which the underlying storage for volumes will be provisioned and is orthogonal
to which kubelets those volumes will be accessible from.
5.7.4. placementCount
placementCount is an alias for autoPlace
5.7.5. resourceGroup
The LINSTOR Resource Group (RG) to associate with this StorageClass. If not set, a new RG will be created for each
new PVC.
5.7.6. storagePool
storagePool is the name of the LINSTOR storage pool that will be used to provide storage to the newly-created
volumes.
Only nodes configured with this same storage pool with be considered for auto-placement.
Likewise, for StorageClasses using nodeList all nodes specified in that list must have this
storage pool configured on them.
5.7.7. disklessStoragePool
disklessStoragePool is an optional parameter that only affects LINSTOR volumes that are assigned as "diskless"
to kubelets, that is, as clients. If you have a custom diskless storage pool defined in LINSTOR, you will specify that
here.
5.7.8. layerList
A comma-separated list of layers to use for the created volumes. The available layers and their order are described
towards the end of this section. Defaults to drbd,storage
5.7.9. placementPolicy
Select from one of the available volume schedulers:
• AutoPlaceTopology, the default: Use topology information from Kubernetes together with user provided
constraints (see replicasOnSame and replicasOnDifferent).
• AutoPlace Use the LINSTOR auto-placement feature, influenced by replicasOnSame and
111
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
replicasOnDifferent
• FollowTopology: Use CSI Topology information to place at least one volume in each "preferred" zone. Only
usable if CSI Topology is enabled.
• Manual: Use only the nodes listed in nodeList and clientList.
• Balanced: EXPERIMENTAL Place volumes across failure domains, using the least used storage pool on each
selected node.
5.7.10. allowRemoteVolumeAccess
Control on which nodes a volume is accessible. The value for this option can take two different forms:
• A simple "true" or "false" allows access from all nodes, or only those nodes with diskful resources.
• Advanced rules, which allow more granular rules on which nodes can access the volume.
The current implementation can grant access to the volume for nodes that share the same labels. For example,
if you want to allow access from all nodes in the same region and zone as a diskful resource, you could use:
parameters:
linstor.csi.linbit.com/allowRemoteVolumeAccess: |
- fromSame:
- topology.kubernetes.io/region
- topology.kubernetes.io/zone
You can specify multiple rules. The rules are additive, a node only need to match one rule to be assignable.
5.7.11. encryption
encryption is an optional parameter that determines whether to encrypt volumes. LINSTOR must be configured for
encryption for this to work properly.
5.7.12. nodeList
nodeList is a list of nodes for volumes to be assigned to. This will assign the volume to each node and it will be
replicated among all of them. This can also be used to select a single node by hostname, but it’s more flexible to use
replicasOnSame to select a single node.
This option determines on which LINSTOR nodes the underlying storage for volumes will be
provisioned and is orthogonal from which kubelets these volumes will be accessible.
5.7.13. clientList
clientList is a list of nodes for diskless volumes to be assigned to. Use in conjunction with nodeList.
5.7.14. replicasOnSame
replicasOnSame is a list of key or key=value items used as auto-placement selection labels when autoPlace is
used to determine where to provision storage. These labels correspond to LINSTOR node properties.
The operator periodically synchronizes all labels from Kubernetes Nodes, so you can use them as
keys for scheduling constraints.
112
The LINSTOR User’s Guide: 5.7. Getting Started with LINBIT SDS Storage in Kubernetes
Let’s explore this behavior with examples assuming a LINSTOR cluster such that node-a is configured with the
following auxiliary property zone=z1 and role=backups, while node-b is configured with only zone=z1.
This guide assumes LINSTOR CSI version 0.10.0 or newer. All properties referenced in
replicasOnSame and replicasOnDifferent are interpreted as auxiliary properties. If you
are using an older version of LINSTOR CSI, you need to add the Aux/ prefix to all property names.
So replicasOnSame: "zone=z1" would be replicasOnSame: "Aux/zone=z1" Using
Aux/ manually will continue to work on newer LINSTOR CSI versions.
If we configure a StorageClass with autoPlace: "1" and replicasOnSame: "zone=z1", then volumes will
be provisioned on either node-a or node-b as they both have the zone=z1 aux prop.
If we configure a StorageClass with autoPlace: "2" and replicasOnSame: "zone=z1", then volumes will
be provisioned on both node-a and node-b as they both have the zone=z1 aux prop.
You can also use a property key without providing a value to ensure all replicas are placed on nodes with the same
property value, with caring about the particular value. Assuming there are 4 nodes, node-a1 and node-a2 are
configured with zone=a. node-b1 and node-b2 are configured with zone=b. Using autoPlace: "2" and
replicasOnSame: "zone" will place on either node-a1 and node-a2 OR on node-b1 and node-b2.
5.7.15. replicasOnDifferent
replicasOnDifferent takes a list of properties to consider, same as replicasOnSame. There are two modes of
using replicasOnDifferent:
If a value is given for the property, the nodes which have that property-value pair assigned will be considered
last.
• Distribute volumes across nodes with different values for the same key:
If no property value is given, LINSTOR will place the volumes across nodes with different values for that
property if possible.
Example: Assuming there are 4 nodes, node-a1 and node-a2 are configured with zone=a. node-b1 and
node-b2 are configured with zone=b. Using a StorageClass with autoPlace: "2" and
replicasOnDifferent: "zone", LINSTOR will create one replica on either node-a1 or node-a2 and
one replica on either node-b1 or node-b2.
5.7.16. disklessOnRemaining
Create a diskless resource on all nodes that were not assigned a diskful resource.
5.7.17. doNotPlaceWithRegex
Do not place the resource on a node which has a resource with a name matching the regular expression.
113
The LINSTOR User’s Guide: 5.8. Snapshots
5.7.18. fsOpts
fsOpts is an optional parameter that passes options to the volume’s file system at creation time.
5.7.19. mountOpts
mountOpts is an optional parameter that passes options to the volume’s file system at mount time.
5.7.20. postMountXfsOpts
Extra arguments to pass to xfs_io, which gets called before right before first use of the volume.
5.7.21. property.linstor.csi.linbit.com/*
Parameters starting with property.linstor.csi.linbit.com/ are translated to LINSTOR properties that are
set on the Resource Group associated with the StorageClass.
property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: disabled
This option is deprecated, use the more general property.linstor.csi.linbit.com/*
form.
Advanced DRBD options to pass to LINSTOR. For example, to change the replication protocol, use
DrbdOptions/Net/protocol: "A".
5.8. Snapshots
Snapshots create a copy of the volume content at a particular point in time. This copy remains untouched when you
make modifications to the volume content. This, for example, enables you to create backups of your data before
performing modifications or deletions on your data.
Because a backup is useless unless you have a way to restore it, this section describes how to create a snapshot, and
how to restore it, for example, in the case of accidental deletion of your data.
The next subsection contains instructions around snapshots within Operator v2 deployments. If you have deployed
LINBIT SDS in Kubernetes by using Operator v1, skip ahead to the [s-kubernetes-add-snaphot-support-v1] subsection.
• Your cluster has a storage pool supporting snapshots. LINSTOR supports snapshots for LVM_THIN,
FILE_THIN, ZFS and ZFS_THIN pools.
• You have a StorageClass, PersistentVolumeClaim, and Deployment that uses a storage pool that
supports snapshots.
114
The LINSTOR User’s Guide: 5.8. Snapshots
• Your cluster has a CSI snapshotter (snapshot-controller) deployed. To verify if it is already deployed,
you can enter the following command:
volumesnapshotclasses.snapshot.storage.k8s.io
volumesnapshotcontents.snapshot.storage.k8s.io
volumesnapshots.snapshot.storage.k8s.io
If output from the command is empty, you can deploy a snapshot controller by entering the following
commands:
Creating a Snapshot
To create a volume snapshot, you first need to create a volume snapshot class (VolumeSnapshotClass). This
volume snapshot class will specify the linstor.csi.linbit.com provisioner, and sets the clean-up policy for the
snapshots to Delete. This means that deleting the Kubernetes resources will also delete the snapshots in LINSTOR.
You can create a volume snapshot class by entering the following command:
To create a snapshot, you create a VolumeSnapshot resource. The VolumeSnapshot resource needs to reference
a snapshot-compatible PersistentVolumeClaim resource, and the VolumeSnapshotClass that you just
created. For example, you could create a snapshot (named data-volume-snapshot-1) of a PVC named data-
volume by entering the following command:
115
The LINSTOR User’s Guide: 5.8. Snapshots
Output should show a table of information about the volume snapshot resource, similar to the following:
You can further verify the snapshot in LINSTOR, by entering the following command:
+-----------------------------------------------------------------------------------------+
| ResourceName | SnapshotName | NodeNames | Volumes | CreatedOn | State |
|=========================================================================================|
| pvc-[...] | snapshot-[...] | kube-0 | 0: 1 GiB | 2023-02-13 15:36:18 | Successful |
+-----------------------------------------------------------------------------------------+
Restoring a Snapshot
To restore a snapshot, you will need to create a new PVC to recover the volume snapshot to. You will replace the
existing PVC, named data-volume in this example, with a new version based on the snapshot.
First, stop the deployment that uses the data-volume PVC. In this example, the deployment is named volume-
logger.
Next, remove the PVC. You still have the snapshot resource, so this is a safe operation.
Next, create a new PVC by referencing a previously created snapshot. This will create a volume which uses the data
from the referenced snapshot.
116
The LINSTOR User’s Guide: 5.8. Snapshots
dataSource:
apiGroup: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: data-volume-snapshot-1
accessModes:
- ReadWriteOnce
EOF
Because you named the new volume, data-volume, the same as the previous volume, you can just scale up the
Deployment again, and the new pod will start using the restored volume.
---
kind: VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
metadata:
name: linstor-csi-snapshot-class-s3
driver: linstor.csi.linbit.com
deletionPolicy: Retain
parameters:
snap.linstor.csi.linbit.com/type: S3
snap.linstor.csi.linbit.com/remote-name: backup-remote
snap.linstor.csi.linbit.com/allow-incremental: "false"
snap.linstor.csi.linbit.com/s3-bucket: snapshot-bucket
snap.linstor.csi.linbit.com/s3-endpoint: s3.us-west-1.amazonaws.com
snap.linstor.csi.linbit.com/s3-signing-region: us-west-1
snap.linstor.csi.linbit.com/s3-use-path-style: "false"
# Refer here to the secret that holds access and secret key for the S3 endpoint.
# See below for an example.
csi.storage.k8s.io/snapshotter-secret-name: linstor-csi-s3-access
csi.storage.k8s.io/snapshotter-secret-namespace: storage
---
kind: Secret
apiVersion: v1
metadata:
name: linstor-csi-s3-access
namespace: storage
immutable: true
type: linstor.csi.linbit.com/s3-credentials.v1
stringData:
access-key: access-key
secret-key: secret-key
Check the LINSTOR snapshot guide on the exact meaning of the snap.linstor.csi.linbit.com/ parameters.
The credentials used to log in are stored in a separate secret, as show in the example above.
Referencing the above storage class when creating snapshots causes the snapshots to be automatically uploaded to the
configured S3 storage.
117
The LINSTOR User’s Guide: 5.9. Volume Accessibility and Locality
If the snapshot that should be restored is part of a backup to S3, the LINSTOR "remote" needs to be configured first.
The snapshot you want to register needs to be one of the listed snapshots.
To register the snapshot with Kubernetes, you need to create two resources, one VolumeSnapshotContent referencing
the ID of the snapshot and one VolumeSnapshot, referencing the content.
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: example-backup-from-s3
namespace: project
spec:
source:
volumeSnapshotContentName: restored-snap-content-from-s3
volumeSnapshotClassName: linstor-csi-snapshot-class-s3
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: restored-snap-content-from-s3
spec:
deletionPolicy: Delete
driver: linstor.csi.linbit.com
source:
snapshotHandle: snapshot-id
volumeSnapshotClassName: linstor-csi-snapshot-class-s3
volumeSnapshotRef:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
name: example-backup-from-s3
namespace: project
Once applied, the VolumeSnapshot should be shown as ready, at which point you can reference it as a dataSource
in a PVC.
Volume locality is achieved by setting volumeBindingMode: WaitForFirstConsumer in the storage class. This
tell Kubernetes and the CSI driver to wait until the first consumer (Pod) referencing the PVC is scheduled. The CSI
driver then provisions the volume with backing data on the same node as the consumer. In case a node without
appropriate storage pool was selected, a replacement node in the set of accessible nodes is chosen (see below).
Volume accessibility is controlled by the allowRemoteVolumeAccess parameter. Whenever the CSI plugin needs
118
The LINSTOR User’s Guide: 5.9. Volume Accessibility and Locality
to place a volume, this parameter is consulted to get the set of "accessible" nodes. This means they can share volumes
placed on them through the network. This information is also propagated to Kubernetes using label selectors on the PV.
Listing 9. example-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor-storage
provisioner: linstor.csi.linbit.com
volumeBindingMode: WaitForFirstConsumer ①
parameters:
linstor.csi.linbit.com/storagePool: linstor-pool ②
linstor.csi.linbit.com/placementCount: "2" ③
linstor.csi.linbit.com/allowRemoteVolumeAccess: "true" ④
① Enable late volume binding. This places one replica on the same node as the first consuming pod, if possible.
② Set the storage pool(s) to use.
③ Ensure that the data is replicated, so that at least 2 nodes store the data.
④ Allow using the volume even on nodes without replica. Since all nodes are connected equally, performance impact
should be manageable.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor-storage
provisioner: linstor.csi.linbit.com
volumeBindingMode: WaitForFirstConsumer ①
parameters:
linstor.csi.linbit.com/storagePool: linstor-pool ②
linstor.csi.linbit.com/placementCount: "2" ③
linstor.csi.linbit.com/allowRemoteVolumeAccess: | ④
- fromSame:
- topology.kubernetes.io/zone
linstor.csi.linbit.com/replicasOnDifferent: topology.kubernetes.io/zone ⑤
① Enable late volume binding. This places one replica on the same node as the first consuming pod, if possible.
② Set the storage pool(s) to use.
③ Ensure that the data is replicated, so that at least 2 nodes store the data.
119
The LINSTOR User’s Guide: 5.10. LINSTOR Affinity Controller
④ Allow using the volume on nodes in the same zone as a replica, under the assumption that zone internal networking
is fast and low latency.
⑤ Spread the replicas across different zones.
Multi-Region Clusters
If your cluster spans multiple regions, you do not want to incur the latency penalty to replicate your data across
regions. To accomplish this, you can configure your storage class to just replicate data in the same zone.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor-storage
provisioner: linstor.csi.linbit.com
volumeBindingMode: WaitForFirstConsumer ①
parameters:
linstor.csi.linbit.com/storagePool: linstor-pool ②
linstor.csi.linbit.com/placementCount: "2" ③
linstor.csi.linbit.com/allowRemoteVolumeAccess: | ④
- fromSame:
- topology.kubernetes.io/zone
linstor.csi.linbit.com/replicasOnSame: topology.kubernetes.io/region ⑤
① Enable late volume binding. This places one replica on the same node as the first consuming pod, if possible.
② Set the storage pool(s) to use.
③ Ensure that the data is replicated, so that at least 2 nodes store the data.
④ Allow using the volume on nodes in the same zone as a replica, under the assumption that zone internal networking
is fast and low latency.
⑤ Restrict replicas to only a single region.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linstor-storage
provisioner: linstor.csi.linbit.com
parameters:
linstor.csi.linbit.com/storagePool: linstor-pool ①
linstor.csi.linbit.com/placementCount: "1" ②
linstor.csi.linbit.com/allowRemoteVolumeAccess: "true" ③
120
The LINSTOR User’s Guide: 5.11. Volume Locality Optimization Using LINSTOR Scheduler
This can be an issue if you want to use a strict affinity: Your PV is pinned to specific nodes, but you might want to
remove or add nodes. While LINSTOR can move the volume (for example: this happens automatically if you remove a
node in Kubernetes), the PV affinity is not updated to reflect this.
This is where the LINSTOR Affinity Controller comes in: it watches PVs and compares their affinity with the volumes'
states in LINSTOR. If they go out of sync, the PV is replaced with an updated version.
The LINSTOR Affinity Controller is packaged in a Helm chart. If you install it in the same namespace as the Operator,
simply run:
Additional options for the chart are available at the upstream project.
The scheduler is available as a separate chart from artifacthub.io. The chart will deploy a new scheduler, which you can
later use when creating pod resources:
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
schedulerName: linstor-scheduler ①
containers:
- name: busybox
image: busybox
command: ["tail", "-f", "/dev/null"]
volumeMounts:
- name: my-first-linstor-volume
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: my-first-linstor-volume
persistentVolumeClaim:
claimName: "test-volume"
To follow the steps in this section, you should be familiar with editing
LinstorSatelliteConfiguration resources.
The DRBD module loader is the component responsible for making the DRBD kernel module available, in addition to
loading other useful kernel modules for LINBIT SDS in Kubernetes. This section describes how you can configure
various aspects of the DRBD kernel module loader, within a LINSTOR Operator v2 deployment.
Besides the DRBD kernel module, these modules are also loaded if available:
121
The LINSTOR User’s Guide: 5.12. Configuring the DRBD Module Loader in Operator v2 Deployments
Module Purpose
libcrc32c dependency for DRBD
nvmet_rdma, nvme_rdma LINSTOR NVME layer
loop LINSTOR when using loop devices as backing disks
dm_writecache LINSTOR writecache layer
dm_cache LINSTOR cache layer
dm_thin_pool LINSTOR thin-provisioned storage
dm_snapshot LINSTOR Snapshots
dm_crypt LINSTOR encrypted volumes
To disable the DRBD module loader completely, apply the following YAML configuration to your deployment:
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: no-loader
spec:
patches:
- target:
kind: Pod
name: satellite
patch: |
apiVersion: v1
kind: Pod
metadata:
name: satellite
spec:
initContainers:
- name: drbd-module-loader
$patch: delete
The following YAML configuration overrides the chosen DRBD module loader image with a user-defined image
example.com/drbd-loader:v9:
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: custom-drbd-module-loader-image
spec:
patches:
- target:
kind: Pod
name: satellite
122
The LINSTOR User’s Guide: 5.12. Configuring the DRBD Module Loader in Operator v2 Deployments
patch: |
apiVersion: v1
kind: Pod
metadata:
name: satellite
spec:
initContainers:
- name: drbd-module-loader
image: example.com/drbd-loader:v9
drbd.io, available to LINBIT customers only, maintains the following module loader container images:
Image Distribution
drbd.io/drbd9-amzn2:v9.2.5 Amazon Linux 2
drbd.io/drbd9-bionic:v9.2.5 Ubuntu 18.04
drbd.io/drbd9-focal:v9.2.5 Ubuntu 20.04
drbd.io/drbd9-jammy:v9.2.5 Ubuntu 22.04
drbd.io/drbd9-rhel7:v9.2.5 Red Hat Enterprise Linux 7
drbd.io/drbd9-rhel8:v9.2.5 Red Hat Enterprise Linux 8
drbd.io/drbd9-rhel9:v9.2.5 Red Hat Enterprise Linux 9
If you need to create a module loader image for your own distribution, you can refer to the container source files
which are available in the upstream Piraeus project.
5.12.3. Changing How the Module Loader Loads the DRBD Kernel Module
By default, the DRBD module loader will try to build the kernel module from source. The module loader can also be
configured to load the module from a DEB or RPM package included in the image, or skip loading DRBD entirely.
To change the behavior of the DRBD module loader, set the LB_HOW environment variable to an appropriate value
shown in the following table:
After setting the LB_HOW environment variable, apply the following YAML configuration to your deployment. Based
on the name within the metadata section, the example below would be used with an LB_HOW environment variable
that was set to deps_only.
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: no-drbd-module-loader
spec:
patches:
- target:
kind: Pod
name: satellite
patch: |
123
The LINSTOR User’s Guide: 5.13. Using the Host Network for DRBD Replication in Operator v2 Deployments
apiVersion: v1
kind: Pod
metadata:
name: satellite
spec:
initContainers:
- name: drbd-module-loader
env:
- name: LB_HOW
value: deps_only
By default, DRBD will use the container network to replicate volume data. This ensures replication works on a wide
range of clusters without further configuration. It also enables use of NetworkPolicy to block unauthorized access
to DRBD traffic. Since the network interface of the pod is tied to the lifecycle of the pod, it also means DRBD will
temporarily disrupt replication when the LINSTOR satellite pod is restarted.
In contrast, using the host network for DRBD replication will cause replication to work independently of the LINSTOR
satellite pod. The host network might also offer better performance than the container network. As a downside, you
will have to manually ensure connectivity between nodes on the relevant ports.
To follow the steps in this section, you should be familiar with editing
LinstorSatelliteConfiguration resources.
To configure the host network for the LINSTOR satellite, apply the following YAML configuration to your deployment:
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
name: host-network
spec:
patches:
- target:
kind: Pod
name: satellite
patch: |
apiVersion: v1
kind: Pod
metadata:
name: satellite
spec:
hostNetwork: true
After the satellite pods are recreated, they will use the host network. Any existing DRBD resources are reconfigured to
use a new IP address on the host network rather than an IP address on the container network.
124
The LINSTOR User’s Guide: 5.13. Using the Host Network for DRBD Replication in Operator v2 Deployments
First, you need to remove the LinstorSatelliteConfiguration that set hostNetwork: true. You can do
this by entering the following kubectl command:
Next, reboot each cluster node, either serially, one by one, or else all at once. In general, replication will not work
between rebooted nodes and non-rebooted nodes. The non-rebooted nodes will continue to use the host network
addresses, which are generally not reachable from the container network.
After all nodes have restarted, all resources will be configured to use the container network, and all DRBD connections
should be connected again.
During this procedure, ensure that no new volumes or snapshots are created, otherwise the
migration to the container network might not be applied to all resources.
First, you need to temporarily stop all DRBD replication and suspend all DRBD volume I/O operations by using the
drbdadm suspend-io all command. Enter the command once on each LINSTOR satellite pod.
Next, you can safely reset all DRBD connection paths. This frees the connection on each node to be moved to the
container network.
Finally, remove the LinstorSatelliteConfiguration resource configuration that set hostNetwork: true.
This will result in the creation of new LINSTOR satellite pods that use the container network.
125
The LINSTOR User’s Guide: 5.14. Evacuating a Node in Kubernetes
After the pods are recreated and the LINSTOR satellites are Online, the DRBD resource will be reconfigured and
resume I/O operations.
First move the node’s workload to another node. You can do this by entering the command:
After verifying that your cluster is running as expected, you can continue to follow the steps in Evacuating a Node.
If you are planning on evacuating more than one node, enter the following command on all the nodes that you will be
evacuating:
This ensures that LINSTOR will not place resources from a node that you are evacuating onto another node that you
plan on evacuating.
If you use the Prometheus Operator, the LINSTOR Operator will also set up the ServiceMonitor instances. The
metrics will automatically be collected by the Prometheus instance associated to the operator, assuming watching the
Piraeus namespace is enabled.
If you want to disable the monitoring container, set monitoringImage to "" in your LinstorSatelliteSet
resource.
126
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
During the upgrade process, attaching, detaching or provisioning of volumes will be paused. Existing volumes and
volumes already in use by a pod will continue to work.
During the upgrade process, the LINSTOR satellite pods will restart. This will stop replication of
DRBD devices, freezing any writes on volumes, until the satellite pods are online again.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: linbit-sds
resources:
- https://charts.linstor.io/static/v2.2.0.yaml
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: drbdio-pull-secret
type: kubernetes.io/dockerconfigjson
literals:
-
.dockerconfigjson={"auths":{"drbd.io":{"username":"MY_LINBIT_USER","password":"MY_LINBIT_PASSWORD"}}
}
Then, apply the kustomization.yaml file, by using the following kubectl command, and wait for the upgrade to
complete:
$ kubectl apply -k .
namespace/linbit-sds created
[...]
$ kubectl -n linbit-sds wait pod --for=condition=Ready --all
Upgrades using the LINSTOR etcd deployment require etcd to use persistent storage. Only follow
these steps if etcd was deployed using etcd.persistentVolume.enabled=true
127
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
Some versions require special steps, refer to instructions here The main command to upgrade to a new LINSTOR
Operator version is:
If you used any customizations on the initial install, pass the same options to helm upgrade. The options currently in
use can be retrieved from Helm.
This triggers the rollout of new pods. After a short wait, all pods should be running and ready. Check that no errors are
listed in the status section of LinstorControllers, LinstorSatelliteSets and LinstorCSIDrivers.
There are situations in which the Operator can’t create the backup automatically. This might be because:
• The base version of the chart or operator is too old. Automatic backups are available starting with version 1.8.0
If upgrading from a version before 1.8.0, follow the manual steps in the next section.
• The backup is too large to fit into a Kubernetes secret. In this case an error is reported in the status field of the
LinstorController resources. Follow the instructions by copying the created backup to a safe location and
creating the necessary secret.
kubectl cp <linstor-operator-pod>:/run/linstor-backups/linstor-backup-<some-hash>.tar.gz
<destination-path>
kubectl create secret linstor-backup-<same-hash>
128
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
2. The following command will create a file crds.yaml, which stores the current state of all LINSTOR Custom
Resource Definitions:
1. Fetch the backup (skip if the backup is already available on your local machine):
129
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
Upgrading to 1.10
Version 1.10 introduces an option to share DRBD configuration between host and container. If you need this option, you
have to update the CRDs. Because Helm does not upgrade CRDs on chart upgrade, instead enter the following
commands:
Upgrading to 1.9
Version 1.9 disables the LINSTOR HA Controller deployment by default. The deployment has moved out of the LINSTOR
Operator chart. If you want to keep using the old version, enable it again using this Helm command:
If you are upgrading to v1.9 from v1.6 or earlier, you need to either:
2. Or, upgrade to v1.7 first, and Helm will create a master passphrase for you automatically. You can view this
passphrase later, by entering:
130
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
Upgrading to v1.8
This upgrade requires a complete rebuild of the K8s database, so upgrades might take longer than
normal.
Version 1.8 introduces new options to centrally set the log level and number of worker threads for the CSI driver. If you
need these options, you have to update the CRDs. As Helm does not upgrade CRDs on chart upgrade, instead enter the
following commands:
In addition, 1.8 reworks the way SSL/TLS setups work. Refer to the Securing Operator v1 Deployment section and work
through these steps again.
If you are upgrading to v1.8 from v1.6 or earlier, you need to either:
2. Or, upgrade to v1.7 first, and Helm will create a master passphrase for you automatically. You can view this
passphrase later, by entering:
Upgrading to v1.7
No additional steps necessary.
Upgrading to v1.6
This versions introduces a new option to support Kubernetes distributions which use different state directories than
the default of /var/lib/kubelet. A notable example is microk8s, which uses
/var/snap/microk8s/common/var/lib/kubelet. To support this, a small addition to the
LinstorCSIDriver CRD was necessary. As Helm does not upgrade CRDs on chart upgrade, instead enter the
following commands:
If you do not apply the new CRDs, you will get errors such as the following:
131
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
If you previously used the included snapshot-controller to process VolumeSnapshot resources, you should replace it
with the new charts provided by the Piraeus project. The section on snapshots has been updated to include
instructions on how you can add the snapshot-controller to your cluster.
Upgrading to v1.5
This version introduces a monitoring component for DRBD resources. This requires a new image and a replacement of
the existing LinstorSatelliteSet CRD. Helm does not upgrade the CRDs on a chart upgrade, instead enter the
following commands:
If you do not plan to use the provided monitoring you still need to apply the above steps, otherwise you will get an
error such as the following:
Some Helm versions fail to set the monitoring image even after replacing the CRDs. In that case,
the in-cluster LinstorSatelliteSet will show an empty monitoringImage value. Edit the resource
using kubectl edit linstorsatellitesets and set the value to drbd.io/drbd-
reactor:v0.3.0 to enable monitoring.
Upgrading to v1.4
This version introduces a new default version for the etcd image, so take extra care that etcd is using persistent
storage. Upgrading the etcd image without persistent storage will corrupt the cluster.
If you are upgrading an existing cluster without making use of new Helm options, no additional steps are necessary.
If you plan to use the newly introduced additionalProperties and additionalEnv settings, you have to
replace the installed CustomResourceDefinitions with newer versions. Helm does not upgrade the CRDs on a chart
upgrade
Upgrading to v1.3
No additional steps necessary.
132
The LINSTOR User’s Guide: 5.16. Upgrading a LINSTOR Deployment on Kubernetes
Upgrading to v1.2
LINSTOR Operator v1.2 is supported on Kubernetes 1.17+. If you are using an older Kubernetes distribution, you might
need to change the default settings, for example [the CSI provisioner](https://kubernetes-csi.github.io/docs/
external-provisioner.html).
There is a known issue when updating the CSI components: the pods will not be updated to the newest image and the
errors section of the LinstorCSIDrivers resource shows an error updating the DaemonSet. In this case, manually
delete deployment/linstor-op-csi-controller and daemonset/linstor-op-csi-node. They will be
re-created by the Operator.
133
The LINSTOR User’s Guide: 6.1. Deploying LINBIT SDS on OpenShift
OpenShift is the official Red Hat developed and supported distribution of Kubernetes. The value of OpenShift is the
strong integration of otherwise optional components, like network ingress and monitoring, all tied together with a Web
UI to manage it all. LINSTOR Operator integrates with these components where possible.
through LINBIT customer trial accounts. Contact LINBIT for information on pricing or to begin a
trial. Alternatively, you can use the LINSTOR SDS upstream project, named Piraeus, without being a
LINBIT customer.
First, create a new OpenShift project for LINBIT SDS which will also create a namespace for LINBIT SDS deployment:
$ oc new-project linbit-sds
Now using project "linbit-sds" on server ...
Next, create a file named kustomization.yaml to customize some of the deployment’s default values:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: linbit-sds
resources:
- https://charts.linstor.io/static/v2.1.1.yaml
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: drbdio-pull-secret
type: kubernetes.io/dockerconfigjson
literals:
-
.dockerconfigjson={"auths":{"drbd.io":{"username":"MY_LINBIT_USER","password":"MY_LINBIT_PASSWORD"}}
} ①
① Replace MY_LINBIT_USER and MY_LINBIT_PASSWORD with your LINBIT customer portal credentials.
The YAML configuration manifest above is current at the time of writing. Refer to
https://charts.linstor.io for the most up-to-date version or previous versions if needed.
You can make additional modifications to the kustomizaion.yaml file based on your preferences and needs.
Possible options are discussed in the Kubernetes advanced deployment section.
Finally, deploy LINBIT SDS by applying the customized configuration, and wait until all pods are ready, by entering the
following commands in the same directory as your kustomization.yaml:
134
The LINSTOR User’s Guide: 6.1. Deploying LINBIT SDS on OpenShift
$ oc apply -k . && \
oc wait --for=condition=ready pod --all -n linbit-sds --timeout=5m && \
oc get pods -n linbit-sds
Output should eventually show that a LINSTOR controller pod is up and running.
After deploying the LINSTOR controller pod, enter the following command to complete the deployment of your LINBIT
SDS in OpenShift cluster:
# oc apply -f - <<EOF
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
name: linstorcluster
spec: {}
EOF
# oc wait pod --for=condition=Ready -n linbit-sds --timeout=5m --all
Output should eventually show that your LINBIT SDS cluster pods are up and running.
① These pods are the LINSTOR satellite node pods. The pod name reflects each node’s hostname.
135
The LINSTOR User’s Guide: 6.2. Interacting with LINBIT SDS in OpenShift
TERMINATION WILDCARD
linstor-op-cs linstor-op-cs-storage.apps.oc.example.com linstor-op-cs linstor-op-cs edge
None
This might enable external access to LINBIT GUI and LINSTOR API. Ensure that only authorized
users can access it, for example, by requiring client side TLS certificates on the route.
First, ensure that monitoring of user-defined projects is enabled in OpenShift by following the steps in Red Hat
documentation.
Once monitoring for user-defined projects is enabled, the LINSTOR Operator automatically detects the presence of
OpenShift’s Prometheus-based monitoring stack and configures the ServiceMonitor resources. The Prometheus
instance will scrape metrics for DRBD and LINSTOR from all Cluster nodes.
This should only be necessary for investigating problems and accessing advanced functionality. Regular operation such
as creating volumes should be achieved through the Kubernetes integration.
136
The LINSTOR User’s Guide: 7.1. Introduction to Nomad
This chapter describes using LINSTOR and DRBD to provision volumes in Nomad.
Nomad supports provisioning storage volumes using plug-ins conforming to the Container Storage Interface (CSI).
LINBIT distributes a CSI plug-in in the form of container images from drbd.io. The plug-in can be configured to work
with a LINSTOR cluster that is deployed along or inside a Nomad cluster.
through LINBIT customer trial accounts. Contact LINBIT for information on pricing or to begin a
trial. Alternatively, you may use LINSTOR SDS' upstream project named Piraeus, without being a
LINBIT customer.
If you want to install LINSTOR directly on your nodes, check out the guide on installing LINSTOR.
You can skip this section and jump directly to deploying the CSI driver.
To allow running privileged containers, add the following snippet to your Nomad agent configuration and restart
Nomad
plugin "docker" {
config {
allow_privileged = true
}
}
• Support for container networking. If you don’t have the Container Network Interface plug-ins installed, you will
only be able to use mode = "host" in your job networks. For most production setups, we recommend
installing the default plug-ins:
Head to the plug-in release page, select the release archive appropriate for your distribution and unpack them
in /opt/cni/bin. You might need to create the directory before unpacking.
• Provide a host volume, allowing a container access to the hosts /dev directory
To create a host volume, add the following snippet to your Nomad agent configuration and restart Nomad.
137
The LINSTOR User’s Guide: 7.2. Deploying LINSTOR on Nomad
client {
host_volume "dev" {
path = "/dev"
}
}
The following example will create a Nomad job starting a single LINSTOR Controller in datacenter dc1 and connect to
an external database.
job "linstor-controller" {
datacenters = ["dc1"] ①
type = "service"
group "linstor-controller" {
network {
mode = "bridge"
# port "linstor-api" { ②
# static = 3370
# to = 3370
# }
}
service { ③
name = "linstor-api"
port = "3370"
connect {
sidecar_service {}
}
check {
expose = true
type = "http"
name = "api-health"
path = "/health"
interval = "30s"
timeout = "5s"
}
}
task "linstor-controller" {
driver = "docker"
config {
image = "drbd.io/linstor-controller:v1.13.0" ④
auth { ⑤
username = "example"
password = "example"
server_address = "drbd.io"
}
mount {
type = "bind"
138
The LINSTOR User’s Guide: 7.2. Deploying LINSTOR on Nomad
source = "local"
target = "/etc/linstor"
}
}
# template { ⑥
# destination = "local/linstor.toml"
# data = <<EOH
# [db]
# user = "example"
# password = "example"
# connection_url = "jdbc:postgresql://postgres.internal.example.com/linstor"
# EOH
# }
resources {
cpu = 500 # 500 MHz
memory = 700 # 700MB
}
}
}
}
Uncomment this section if your cluster is not configured with Consul Connect.
③ The service block is used to expose the LINSTOR API to other jobs through the service mesh.
If your cluster is not configured for Consul Connect you can remove this section.
④ This sets the LINSTOR Controller image to run. The latest images are available from drbd.io.
The use of the :latest tag is strongly discouraged, as it can quickly lead to version
mismatches and unintended upgrades.
⑤ Sets the authentication to use when pulling the image. If pulling from drbd.io, you need to use your LINBIT
customer login here. Read more about pulling from a private repo here.
⑥ This template can be used to set arbitrary configuration options for LINSTOR. This example configures an external
database for LINSTOR. You can find a more detailed explanation of LINSTOR’s database options here and more on
Nomad templates here.
139
The LINSTOR User’s Guide: 7.2. Deploying LINSTOR on Nomad
Using a host volume means that only a single node is able to run the LINSTOR Controller. If the
node is unavailable, the LINSTOR Cluster will also be unavailable. For alternatives, use an external
(highly available) database or deploy the LINSTOR cluster directly on the hosts.
To create a host volume for the LINSTOR database, first create the directory on the host with the expected
permissions
$ mkdir -p /var/lib/linstor
$ chown -R 1000:0 /var/lib/linstor
Then add the following snippet to your Nomad agent configuration and restart Nomad
client {
host_volume "linstor-db" {
path = "/var/lib/linstor"
}
}
Then, add the following snippets to the linstor-controller.hcl example from above and adapt the
connection_url option from the configuration template.
volume "linstor-db" {
type = "host"
source = "linstor-db"
}
volume_mount {
volume = "linstor-db"
destination = "/var/lib/linstor"
}
template {
destination = "local/linstor.toml"
data = <<EOH
[db]
user = "linstor"
password = "linstor"
connection_url = "jdbc:h2:/var/lib/linstor/linstordb"
EOH
}
The following example will create a Nomad job starting a LINSTOR satellite on every node in data center dc1.
job "linstor-satellite" {
140
The LINSTOR User’s Guide: 7.2. Deploying LINSTOR on Nomad
datacenters = ["dc1"] ①
type = "system"
group "satellite" {
network {
mode = "host"
}
volume "dev" { ②
type = "host"
source = "dev"
}
task "linstor-satellite" {
driver = "docker"
config {
image = "drbd.io/linstor-satellite:v1.13.0" ③
auth { ④
username = "example"
password = "example"
server_address = "drbd.io"
}
privileged = true ⑤
network_mode = "host" ⑥
}
volume_mount { ②
volume = "dev"
destination = "/dev"
}
resources {
cpu = 500 # 500 MHz
memory = 500 # 500MB
}
}
task "drbd-loader" {
driver = "docker"
lifecycle {
hook = "prestart" ⑦
}
config {
image = "drbd.io/drbd9-rhel8:v9.0.29" ⑧
privileged = true ⑤
auth { ④
username = "example"
password = "example"
server_address = "drbd.io"
}
}
env {
LB_HOW = "shipped_modules" ⑨
}
volume_mount { ⑩
volume = "kernel-src"
destination = "/usr/src"
}
141
The LINSTOR User’s Guide: 7.2. Deploying LINSTOR on Nomad
volume_mount { ⑩
volume = "modules"
destination = "/lib/modules"
}
}
volume "modules" { ⑩
type = "host"
source = "modules"
read_only = true
}
volume "kernel-src" { ⑩
type = "host"
source = "kernel-src"
read_only = true
}
}
}
The use of the :latest tag is strongly discouraged, as it can quickly lead to version
mismatches and unintended upgrades.
④ Sets the authentication to use when pulling the image. If pulling from drbd.io, you need to use your LINBIT
customer login here. Read more about pulling from a private repo here.
⑤ To configure storage devices, DRBD and load kernel modules, the containers need to be running in privileged mode.
⑥ The satellite needs to communicate with DRBD, which requires access to the netlink interface running in the hosts
network.
⑦ The drbd-loader task will be executed once at the start of the satellite and load DRBD and other useful kernel
modules.
⑧ The drbd-loader is specific to the distribution you are using. Available options are:
• drbd.io/drbd9-bionic for Ubuntu 18.04 (Bionic Beaver)
• drbd.io/drbd9-focal for Ubuntu 20.04 (Focal Fossa)
• drbd.io/drbd9-rhel8 for RHEL 8
• drbd.io/drbd9-rhel7 for RHEL 7
⑨ The drbd-loader container can be configured using environment variables. LB_HOW tells the container how to
insert the DRBD kernel module. Available options are:
shipped_modules
Uses the prepackaged RPMs or DEBs delivered with the container.
compile
Compile DRBD from source. Requires access to the kernel headers (see below).
deps_only
Only try to load existing modules used by the LINSTOR satellite (for example dm_thin_pool and
dm_cache).
⑩ In order for the drbd-loader container to build DRBD or load existing modules, it needs access to a hosts
/usr/src and /lib/modules respectively.
142
The LINSTOR User’s Guide: 7.3. Deploying the LINSTOR CSI Driver in Nomad
This requires setting up additional host volumes on every node. The following snippet needs to be added to every
Nomad agent confiration, then Nomad needs to be restarted.
client {
host_volume "modules" {
path = "/lib/modules"
read_only = true
}
host_volume "kernel-src" {
path = "/usr/src"
read_only = true
}
}
In all cases, you need to add the satellites to your cluster and create some storage pools. For example, to add the node
nomad-01.example.com and configure a LVM Thin storage pool, you would run:
The CSI driver requires your satellites to be named after their hostname. To be precise, the satellite
name needs to match Nomads attr.unique.hostname attribute on the node.
The following example will create a Nomad job starting a LINSTOR CSI Driver on every node in data center dc1.
143
The LINSTOR User’s Guide: 7.3. Deploying the LINSTOR CSI Driver in Nomad
job "linstor-csi" {
datacenters = ["dc1"] ①
type = "system"
group "csi" {
network {
mode = "bridge"
}
service {
connect {
sidecar_service { ②
proxy {
upstreams {
destination_name = "linstor-api"
local_bind_port = 8080
}
}
}
}
}
task "csi-plugin" {
driver = "docker"
config {
image = "drbd.io/linstor-csi:v0.13.1" ③
auth { ④
username = "example"
password = "example"
server_address = "drbd.io"
}
args = [
"--csi-endpoint=unix://csi/csi.sock",
"--node=${attr.unique.hostname}", ⑤
"--linstor-endpoint=http://${NOMAD_UPSTREAM_ADDR_linstor_api}", ⑥
"--log-level=info"
]
privileged = true ⑦
}
csi_plugin { ⑧
id = "linstor.csi.linbit.com"
type = "monolith"
mount_dir = "/csi"
}
resources {
cpu = 100 # 100 MHz
memory = 200 # 200MB
}
}
}
}
144
The LINSTOR User’s Guide: 7.4. Using LINSTOR Volumes in Nomad
③ This sets the LINSTOR CSI Driver image to run. The latest images are available from drbd.io.
The use of the :latest tag is strongly discouraged, as it can quickly lead to version
mismatches and unintended upgrades.
④ Sets the authentication to use when pulling the image. If pulling from drbd.io, you need to use your LINBIT
customer login here. Read more about pulling from a private repo here.
⑤ This argument sets the node name used by the CSI driver to identify itself in the LINSTOR API. By default, this is set
to the node’s hostname.
⑥ This argument sets the LINSTOR API endpoint. If you are not using the consul service mesh (see Nr. 2 above), this
needs to be set to the Controllers API endpoint. The endpoint needs to be reachable from every node this is
deployed on.
⑦ The CSI driver needs to execute mount commands, requiring privileged containers.
⑧ The csi_plugin stanza informs Nomad that this task is a CSI plug-in. The Nomad agent will forward requests for
volumes to one of the jobs containers.
As an example, the following specification requests a 1GiB volume with 2 replicas from the LINSTOR storage pool
thinpool.
id = "vol1" ①
name = "vol1" ②
type = "csi"
plugin_id = "linstor.csi.linbit.com"
capacity_min = "1GiB"
capacity_max = "1GiB"
capability {
access_mode = "single-node-writer" ③
attachment_mode = "file-system" ④
}
mount_options {
fs_type = "ext4" ⑤
}
parameters { ⑥
"resourceGroup" = "default-resource",
"storagePool" = "thinpool",
"autoPlace" = "2"
}
145
The LINSTOR User’s Guide: 7.4. Using LINSTOR Volumes in Nomad
① The id is used to reference this volume in Nomad. Used in the volume.source field of a job specification.
② The name is used when creating the volume in the back end (that is, LINSTOR). Ideally this matches the id and is a
valid LINSTOR resource name. If the name would not be valid, LINSTOR CSI will generate a random compatible
name.
③ What kind of access the volume should support. LINSTOR CSI supports:
single-node-reader-only
Allow read only access on one node at a time.
single-node-writer
Allow read and write access on one node at a time.
multi-node-reader-only
Allow read only access from multiple nodes.
job "example" {
...
group "example" {
volume "example-vol" {
type = "csi"
source = "vol1"
attachment_mode = "file-system"
access_mode = "single-node-writer"
}
task "mount-example" {
volume_mount {
volume = "example-vol"
destination = "/data"
}
146
The LINSTOR User’s Guide: 7.4. Using LINSTOR Volumes in Nomad
...
}
}
}
The following command creates a snapshot named snap1 of the volume vol1.
You can use a snapshot to pre-populate an existing volume with data from the snapshot
$ cat vol2.hcl
id = "vol2"
name = "vol2"
snapshot_id = "snap1"
type = "csi"
plugin_id = "linstor.csi.linbit.com"
...
147
The LINSTOR User’s Guide: 8.1. Introduction to Proxmox VE
'linstor-proxmox' is a Perl plugin for Proxmox that, in combination with LINSTOR, allows you to replicate VM disks on
several Proxmox VE nodes. This allows to live-migrate active VMs within a few seconds and with no downtime without
needing a central SAN, as the data is already replicated to multiple nodes.
The controllervm setting, which was intended for executing a LINSTOR controller in a VM manged by LINSTOR is
gone. Using drbd-reactor to realize a highly available LINSTOR controller is what we suggest.
148
The LINSTOR User’s Guide: 8.3. Installing the LINSTOR Proxmox Plug-in
If you do not plan to install the latest Proxmox kernel, you have to install kernel headers matching your current running
kernel (for example, pve-headers-$(uname -r)). If you missed this step, then you can still rebuild the drbd-
dkms package against your current kernel (so long as you have installed kernel headers in advance) by entering the
apt install --reinstall drbd-dkms command.
You will need to add the Proxmox PVE repository to your APT sources list,
/etc/apt/sources.list, and then enter apt update, before you can install the pve-
headers package. Refer to the Proxmox wiki for instructions.
You can then install the DRBD kernel module, DRBD utilities, and the LINSTOR Proxmox plugin by entering:
Refer to the Using a Script to Manage LINBIT Cluster Nodes for instructions on registering a node
with LINBIT and enabling LINBIT repositories.
You can add LINBIT’s public repository by entering the commands below, setting $PVERS to your Proxmox VE major
version (for example, "7", not "7.1"):
# wget -O /tmp/package-signing-pubkey.asc \
https://packages.linbit.com/package-signing-pubkey.asc
# gpg --yes -o /etc/apt/trusted.gpg.d/linbit-keyring.gpg --dearmor \
/tmp/package-signing-pubkey.asc
# PVERS=7 && echo "deb [signed-by=/etc/apt/trusted.gpg.d/linbit-keyring.gpg] \
http://packages.linbit.com/public/ proxmox-$PVERS drbd-9" > /etc/apt/sources.list.d/linbit.list
After adding the LINBIT package repository, you can install the Proxmox plugin and other necessary components
(DRBD kernel module and utilities), by entering the following command:
149
The LINSTOR User’s Guide: 8.4. Configuring LINSTOR
[Service]
Type=notify
TimeoutStartSec=infinity
The preferred way to use the plugin, starting from version 4.1.0, is through LINSTOR resource groups and a single
volume group within every resource group. LINSTOR resource groups are described in Using Resource Groups to
Deploy LINSTOR Provisioned Volumes. All the required LINSTOR configuration (e.g., redundancy count) has to be set on
the resource group.
drbd: drbdstorage
content images,rootdir
controller 10.11.12.13
resourcegroup defaultpool
The "drbd" entry is fixed and you are not allowed to modify it, as it tells to Proxmox to use DRBD as storage back end.
The "drbdstorage" entry can be modified and is used as a friendly name that will be shown in the PVE web GUI to locate
the DRBD storage. The "content" entry is also fixed, so do not change it. The redundancy (specified in the resource
group) specifies how many replicas of the data will be stored in the cluster. The recommendation is to set it to 2 or 3
depending on your setup. The data is accessible from all nodes, even if some of them do not have local copies of the
data. For example, in a 5 node cluster, all nodes will be able to access 3 copies of the data, no matter where they are
stored in. The "controller" parameter must be set to the IP of the node that runs the LINSTOR controller service. Only
one node can be set to run as LINSTOR controller at the same time. If that node fails, start the LINSTOR controller on
another node and change that value to its IP address.
A configuration using different storage pools in different resource groups would look like this:
drbd: drbdstorage
content images,rootdir
controller 10.11.12.13
resourcegroup defaultpool
drbd: fastdrbd
content images,rootdir
controller 10.11.12.13
resourcegroup ssd
drbd: slowdrbd
content images,rootdir
controller 10.11.12.13
resourcegroup backup
By now, you should be able to create VMs using Proxmox’s web GUI by selecting "drbdstorage", or any other of the
defined pools as storage location.
Starting from version 5 of the plugin, you can set the option "preferlocal yes". If it is set, the plugin tries to create a
diskful assignment on the node that issued the storage create command. With this option you can ensure that the VM
150
The LINSTOR User’s Guide: 8.6. Making the Controller Highly Available (Optional Configuration)
gets local storage if possible. Without that option LINSTOR might place the storage on nodes 'B' and 'C', while the VM is
initially started on node 'A'. This would still work as node 'A' then would get a diskless assignment, but having local
storage might be preferred.
NOTE: DRBD supports only the raw disk format at the moment.
At this point you can try to live migrate the VM - as all data is accessible on all nodes (even on Diskless nodes) - it will
take just a few seconds. The overall process might take a bit longer if the VM is under load and if there is a significant
amount of RAM being dirtied all the time. But in any case, the downtime should be minimal and you will see no
interruption at all.
The last — but crucial — step is to configure the Proxmox plugin to be able to connect to multiple LINSTOR
controllers. It will use the first one it receives an answer from. This is done by adding a comma-separated list of
controllers in the controller section of the plugin like this:
drbd: drbdstorage
content images,rootdir
controller 10.11.12.13,10.11.12.14,10.11.12.15
resourcegroup defaultpool
151
The LINSTOR User’s Guide: 9.1. Introduction to OpenNebula
Detailed installation and configuration instructions and be found in the README.md file of the driver’s source.
The LINSTOR add-on allows the deployment of virtual machines with highly available images backed by DRBD and
attached across the network through DRBD’s own transport protocol.
With access to LINBIT’s customer repositories you can install the linstor-opennebula package with:
or
Without access to LINBIT’s prepared packages you need to fall back to instructions on the OpenNebula LINSTOR Add-
on GitHub page.
A DRBD cluster with LINSTOR can be installed and configured by following the instructions in this guide, see Initializing
Your Cluster.
The OpenNebula and DRBD clusters can be somewhat independent of one another with the following exception:
OpenNebula’s Front-End and Host nodes must be included in both clusters.
Host nodes do not need a local LINSTOR storage pool, as virtual machine images are attached to them across the
network [1].
Add linstor to the list of drivers in the TM_MAD and DATASTORE_MAD sections:
TM_MAD = [
152
The LINSTOR User’s Guide: 9.4. Configuring the OpenNebula Add-on
EXECUTABLE = "one_tm",
ARGUMENTS = "-t 15 -d dummy,lvm,shared,fs_lvm,qcow2,ssh,vmfs,ceph,linstor"
]
DATASTORE_MAD = [
EXECUTABLE = "one_datastore",
ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,dev,iscsi_libvirt,vcenter,linstor -s
shared,ssh,ceph,fs_lvm,qcow2,linstor"
]
TM_MAD_CONF = [
NAME = "linstor", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "yes",
ALLOW_ORPHANS="yes",
TM_MAD_SYSTEM = "ssh,shared", LN_TARGET_SSH = "NONE", CLONE_TARGET_SSH = "SELF", DISK_TYPE_SSH =
"BLOCK",
LN_TARGET_SHARED = "NONE", CLONE_TARGET_SHARED = "SELF", DISK_TYPE_SHARED = "BLOCK"
]
DS_MAD_CONF = [
NAME = "linstor", REQUIRED_ATTRS = "BRIDGE_LIST", PERSISTENT_ONLY = "NO",
MARKETPLACE_ACTIONS = "export"
]
Host nodes are responsible for running instantiated VMs and typically have the storage for the images they need
attached across the network through LINSTOR diskless mode.
All nodes must have DRBD9 and LINSTOR installed. This process is detailed in the User’s Guide for DRBD9
It is possible to have Front-End and Host nodes act as storage nodes in addition to their primary role provided that
they the meet all the requirements for both roles.
153
The LINSTOR User’s Guide: 9.4. Configuring the OpenNebula Add-on
The storage nodes must use storage pools created with a driver that’s capable of making snapshots, such as the thin
LVM plug-in.
In this example preparation of thin-provisioned storage using LVM for LINSTOR, you must create a volume group and
thinLV using LVM on each storage node.
The following is an example of this process using two physical volumes (/dev/sdX and /dev/sdY) and generic names for
the volume group and thinpool. Take care to set the thinLV’s metadata volume to a reasonable size. once it becomes full
it can be difficult to resize.
Then you’ll create storage pool(s) on LINSTOR using this as the backing storage.
If you are using ZFS storage pools or thick-LVM, please use LINSTOR_CLONE_MODE copy
otherwise you will have problems deleting linstor resources, because of ZFS parent-child snapshot
relationships.
Groups
Be sure to consider the groups that oneadmin should be added to to gain access to the devices and programs needed
to access storage and instantiate VMs. For this add-on, the oneadmin user must belong to the disk group on all
nodes to access the DRBD devices where images are held.
Create a resource group and volume group for your datastore, it is mandatory to specify a storage-pool within the
154
The LINSTOR User’s Guide: 9.4. Configuring the OpenNebula Add-on
resource group, otherwise monitoring space for OpenNebula will not work. Here we create one with 2 node
redundancy and use a created opennebula-storagepool:
LINSTOR_CONTROLLERS
LINSTOR_CONTROLLERS can be used to pass a comma separated list of controller ips and ports to the LINSTOR
client in the case where a LINSTOR controller process is not running locally on the Front-End, e.g.:
LINSTOR_CONTROLLERS = "192.168.1.10:8080,192.168.1.11:6000"
LINSTOR_RESOURCE_GROUP
LINSTOR_RESOURCE_GROUP attribute is used to associate an OpenNebula datastore with a LINSTOR resource group.
LINSTOR_CLONE_MODE
LINSTOR now automatically decides which clone mode it should use.
LINSTOR supports two different clone modes: snapshot and copy. These modes are set through the
LINSTOR_CLONE_MODE attribute.
The default mode is snapshot. It uses a linstor snapshot and restores a new resource from this snapshot, which is
then a clone of the image. This mode is usually faster than using the copy mode as snapshots are cheap copies.
The second mode is copy. It creates a new resource with the same size as the original and copies the data with dd to
the new resource. This mode will be slower than snapshot, but is more robust as it doesn’t rely on any snapshot
mechanism. It is also used if you are cloning an image into a different LINSTOR datastore.
LINSTOR_STORAGE_POOL
LINSTOR_STORAGE_POOL attribute is used to select the LINSTOR storage pool your datastore should use. If resource
groups are used this attribute isn’t needed as the storage pool can be select by the auto select filter options.
155
The LINSTOR User’s Guide: 9.5. Live Migration
LINSTOR_AUTO_PLACE
The LINSTOR_AUTO_PLACE option takes a level of redundancy which is a number between one and the total number
of storage nodes. Resources are assigned to storage nodes automatically based on the level of redundancy.
LINSTOR_DEPLOYMENT_NODES
Using LINSTOR_DEPLOYMENT_NODES allows you to select a group of nodes that resources will always be assigned
to. Please note that the bridge list still contains all of the storage nodes in the LINSTOR cluster.
Also add the new sys datastore id to the COMPATIBLE_SYS_DS to your image datastores (COMMA separated),
otherwise the scheduler will ignore them.
If you want live migration with volatile disks you need to enable the --unsafe option for KVM, see: opennebula-doc
For datastores which place per node, free space is reported based on the most restrictive storage pools from all nodes
where resources are being deployed. For example, the capacity of the node with the smallest amount of total storage
space is used to determine the total size of the datastore and the node with the least free space is used to determine
the remaining space in the datastore.
For a datastore which uses automatic placement, size and remaining space are determined based on the aggregate
storage pool used by the datastore as reported by LINSTOR.
[1] If a host is also a storage node, it will use a local copy of an image if that is available
156
The LINSTOR User’s Guide: 10.1. Introduction to OpenStack
LINSTOR can integrate with Cinder using a volume driver. The volume driver translates calls to the Cinder API to
LINSTOR commands. For example: requesting a volume from Cinder will create new resources in LINSTOR, Cinder
Volume snapshots translate to snapshots in LINSTOR and so on.
At this point you should be able to list your storage cluster nodes using the LINSTOR client:
You should configure one or more storage pools per node. This guide assumes the storage pool is named
cinderpool. LINSTOR should list the storage pool for each node, including the diskless storage pool created by
default.
157
The LINSTOR User’s Guide: 10.2. Installing LINSTOR for OpenStack
LINBIT maintains a fork of the Cinder repository with all improvements to the LINSTOR driver backported to the
supported stable versions. Currently, these are:
158
The LINSTOR User’s Guide: 10.2. Installing LINSTOR for OpenStack
The exact steps to enable the LINSTOR Driver depend on your OpenStack distribution. In general, the python-
linstor package needs to be installed on all hosts running the Cinder volume service. The next section will cover the
installation process for common OpenStack distributions.
Installing on DevStack
DevStack is a great way to try out OpenStack in a lab environment. To use the most recent driver use the following
DevStack configuration:
# This ensures the LINSTOR Driver has access to the 'python-linstor' package.
#
# This is needed even if using the included driver!
USE_VENV=True
ADDITIONAL_VENV_PACKAGES=python-linstor
Installing on Kolla
Kolla packages OpenStack components in containers. They can then be deployed, for example using Kolla Ansible You
can take advantage of the available customisation options for kolla containers to set up the LINSTOR driver.
To ensure that the required python-linstor package is installed, use the following override file:
{% extends parent_template %}
# Cinder
{% set cinder_base_pip_packages_append = ['python-linstor'] %}
[cinder-base]
type = git
location = https://github.com/LINBIT/openstack-cinder.git
# Replace linstor/stable/victoria with the reference matching your OpenStack release.
reference = linstor/stable/victoria
159
The LINSTOR User’s Guide: 10.2. Installing LINSTOR for OpenStack
• the custom Cinder images, created in the section above, are used deployment of Cinder services is enabled.
You can place the LINSTOR driver configuration in one of the override directories for kolla-ansible. For more details on
the available configuration options, see the section below.
[linstor-drbd]
volume_backend_name = linstor-drbd
volume_driver = cinder.volume.drivers.linstordrv.LinstorDrbdDriver
linstor_uris = linstor://cinder-01.openstack.test,linstor://cinder-02.openstack.test
cinder_git_repo: https://github.com/LINBIT/openstack-cinder.git
cinder_git_install_branch: linstor/stable/victoria
cinder_user_pip_packages:
- python-linstor
cinder_backends: ①
linstor-drbd:
160
The LINSTOR User’s Guide: 10.3. Configuring a LINSTOR Back End for Cinder
volume_backend_name: linstor-drbd
volume_driver: cinder.volume.drivers.linstordrv.LinstorDrbdDriver
linstor_uris: linstor://cinder-01.openstack.test,linstor://cinder-02.openstack.test
① A detailed description of the available back end parameters can be found in the section below.
To update the LINSTOR driver version, find your Cinder installation. Some likely paths are:
/usr/lib/python*/dist-packages/cinder/
/usr/lib/python*/site-packages/cinder/
The LINSTOR driver consists of a single file called linstordrv.py, located in the Cinder directory:
$CINDER_PATH/volume/drivers/linstordrv.py
To update the driver, replace the file with one from the LINBIT repository
RELEASE=linstor/stable/victoria
curl -fL "https://raw.githubusercontent.com/LINBIT/openstack-
cinder/$RELEASE/cinder/volume/drivers/linstordrv.py" > $CINDER_PATH/volume/drivers/linstordrv.py
You might also need to remove the Python cache for the update to be registered:
rm -rf $CINDER_PATH/volume/drivers/__pycache__
Most of the time, the Cinder configuration file is located at /etc/cinder/cinder.conf. Some deployment
options allow manipulating this file in advance. See the section above for specifics.
To configure a new volume back end using LINSTOR, add the following section to cinder.conf
[linstor-drbd]
volume_backend_name = linstor-drbd ①
volume_driver = cinder.volume.drivers.linstordrv.LinstorDrbdDriver ②
linstor_uris = linstor://cinder-01.openstack.test,linstor://cinder-02.openstack.test ③
linstor_trusted_ca = /path/to/trusted/ca.cert ④
linstor_client_key = /path/to/client.key ⑤
linstor_client_cert = /path/to/client.cert ⑤
# Deprecated or removed in 2.0.0
linstor_default_storage_pool_name = cinderpool ⑥
linstor_autoplace_count = 2 ⑦
linstor_controller_diskless = true ⑧
# non-linstor-specific options
... ⑨
161
The LINSTOR User’s Guide: 10.3. Configuring a LINSTOR Back End for Cinder
The parameters described here are based on the latest release provided by LINBIT. The driver
included in OpenStack might not support all of these parameters. Consult the OpenStack driver
documentation to learn more.
① The name of the volume back end. Needs to be unique in the Cinder configuration. The whole section should share
the same name. This name is referenced again in cinder.conf in the enabled_backends setting and when
creating a new volume type.
② The version of the LINSTOR driver to use. There are two options:
• cinder.volume.drivers.linstordrv.LinstorDrbdDriver
• cinder.volume.drivers.linstordrv.LinstorIscsiDriver
Which driver you should use depends on your LINSTOR set up and requirements. Details on each choice are
documented in the section below.
③ The URL(s) of the LINSTOR Controller(s). Multiple Controllers can be specified to make use of Linstor High
Availability. If not set, defaults to linstor://localhost.
④ If HTTPS is enabled the referenced certificate is used to verify the LINSTOR Controller authenticity.
⑤ If HTTPS is enabled the referenced key and certificate will be presented to the LINSTOR Controller for
authentication.
⑥ Deprecated in 2.0.0, use volume types instead. The storage pools to use when placing resources. Applies to all
diskfull resources created. Defaults to DfltStorPool.
⑦ Removed in 2.0.0, use volume types instead. The number of replicas to create for the given volume. A value of 0
will create a replica on all nodes. Defaults to 0.
⑧ Removed in 2.0.0, volumes are created on demand by the driver. If set to true, ensures that at least one
(diskless) replica is deployed on the Cinder Controller host. This is useful for ISCSI transports. Defaults to true.
⑨ You can specify more generic Cinder options here, for example target_helper = tgtadm for the ISCSI
connector.
You can also configure multiple LINSTOR back ends, choosing a different name and configuration
options for each.
After configuring the LINSTOR back end, it should also be enabled. Add it to the list of enabled back ends in
cinder.conf, and optionally set is as the default back end:
[DEFAULT]
...
default_volume_type = linstor-drbd-volume
enabled_backends = lvm,linstor-drbd
...
As a last step, if you changed the Cinder configuration or updated the driver itself, you need to restart the Cinder
service(s). Please check the documentation for your OpenStack Distribution on how to restart services.
162
The LINSTOR User’s Guide: 10.3. Configuring a LINSTOR Back End for Cinder
• Once set up, the Cinder host is no longer involved in the data path. All read and write to the volume are handled
by the local DRBD module, which will handle replication across its configured peers.
• Since the Cinder host is not involved in the data path, any disruptions to the Cinder service do not affect
volumes that are already attached.
Known limitations:
• Not all hosts and hypervisors support using DRBD volumes. This restricts deployment to Linux hosts and kvm
hypervisors.
• Resizing of attached and in-use volumes does not fully work. While the resize itself is successful, the compute
service will not propagate it to the VM until after a restart.
• Multi-attach (attaching the same volume on multiple VMs) is not supported.
• Encrypted volumes only work if udev rules for DRBD devices are in place.
udev rules are either part of the drbd-utils package or have their own drbd-udev
package.
The drawback is that all data has to be sent to a Cinder node, to be processed by an (userspace) iSCSI daemon; that
means that the data needs to pass the kernel/userspace border, and these transitions will cost some performance.
Another drawback is the introduction of a single point of failure. If a Cinder node running the iSCSI daemon crashes,
other nodes lose access to their volumes. There are ways to configure Cinder for automatic fail-over to mitigate this,
but it requires considerable effort.
In driver versions prior to 2.0.0, the Cinder host needs access to a local replica of every volume.
This can be achieved by either setting linstor_controller_diskless=True or using
linstor_autoplace_count=0. Newer driver versions will create such a volume on demand.
163
The LINSTOR User’s Guide: 10.4. Creating a New Volume Type for LINSTOR
10T12:24:35.000000 |
+------------------+----------------------------------------+------+---------+-------
+----------------------------+
If you have the Horizon GUI deployed, check Admin > System Information > Block Storage Service
instead.
In the above example all configured services are enabled and up. If there are any issues, please check the logs of the
Cinder Volume service.
Alternatively, you can create volume types using the Horizon GUI. Navigate to Admin > Volume > Volume
Types and click "Create Volume Type". You can assign it a back end by adding the volume_backend_name as "Extra
Specs" to it.
Alternatively, you can set the property using the GUI by navigating tp Admin > Volume > Volume Types. In the
Actions column, open the dropdown menu and click the View Extra Specs button. This opens a dialog you can
use to create, edit and delete properties.
164
The LINSTOR User’s Guide: 10.5. Using Volumes
linstor:do_not_place_with_regex
Do not place the resource on a node which has a resource with a name matching the regex.
linstor:layer_list
Comma-separated list of layers to apply for resources. If empty, defaults to DRBD,Storage.
linstor:provider_list
Comma-separated list of providers to use. If empty, LINSTOR will automatically choose a suitable provider.
linstor:redundancy
Number of replicas to create. Defaults to two.
linstor:replicas_on_different
A comma-separated list of key or key=value items used as autoplacement selection labels when autoplace is
used to determine where to provision storage.
linstor:replicas_on_same
A comma-separated list of key or key=value items used as autoplacement selection labels when autoplace is
used to determine where to provision storage.
linstor:storage_pool
Comma-separated list of storage pools to use when auto-placing.
linstor:property:<key>
If a <key> is prefixed by linstor:property:, it is interpreted as a LINSTOR property. The property gets set
on the Resource Group created for the volume type.
OpenStack does not allow for / in property names. If a LINSTOR property name contains a / replace it with a :.
For example: To change the quorum policy, DrbdOptions/auto-quorum needs to be set. This can be done
by setting the linstor:property:DrbdOptions:auto-quorum property in OpenStack.
For example, to create a simple 1Gb volume on the command line you can use:
10.6. Troubleshooting
This section describes what to do in case you encounter problems with using LINSTOR volumes and snapshots.
165
The LINSTOR User’s Guide: 10.6. Troubleshooting
This message shows that there was an error creating a new volume. Check the Cinder Volume service logs for more
details.
If this is the only error message, this means that the Cinder Scheduler could not find a volume back end suitable for
creating the volume. This is most likely because:
• The volume back end is offline. See Verifying the Status of LINSTOR Back Ends.
• The volume back end does not have enough free capacity to fulfil the request. Check the output of cinder
get-pools --detail and linstor storage-pool list to verify that the requested capacity is
available.
166
The LINSTOR User’s Guide: 11.1. Introduction to Docker
The LINSTOR Docker Volume Plugin is a volume driver that provisions persistent volumes from a LINSTOR cluster for
Docker containers.
The implicit :latest tag is the latest amd64 version. We currently also build for arm64 with the according tag.
Installing the arm64 plugin looks like this:
# cat /etc/linstor/docker-volume.conf
[global]
controllers = linstor://hostnameofcontroller
# cat /etc/linstor/docker-volume.conf
[global]
storagepool = thin-lvm
fs = ext4
fsopts = -E discard
size = 100MB
replicas = 2
167
The LINSTOR User’s Guide: 11.4. Using the LINSTOR Plug-in for Docker
On node bravo:
11.4.6. Using LINSTOR Volumes with Services from Docker Swarm Manager
Node
Docker services do not accept the -v or --volume syntax, you must use the --mount syntax.
Docker run will accept either syntax.
168
The LINSTOR User’s Guide: 12.1. LINSTOR Gateway Requirements
For NVMe-oF, iSCSI, and NFS, a LINSTOR storage-pool, resource-group, and volume-group for LINSTOR
Gateway need to be created before use. The following section provides example commands for setting up the
prerequisites in a three-node LINSTOR cluster.
Create a LVM backed storage-pool on each node using the physical device /dev/sdb:
Create resource-groups and volume-groups backed by the storage-pool created in the previous command:
LINSTOR Gateway requires modification of the LINSTOR Satellite’s configuration on each Satellite node. Edit or create
the following file using your preferred text editor:
# vim /etc/linstor/linstor_satellite.toml
[files]
allowExtFiles = [
"/etc/systemd/system",
"/etc/systemd/system/linstor-satellite.service.d",
"/etc/drbd-reactor.d"
169
The LINSTOR User’s Guide: 12.1. LINSTOR Gateway Requirements
Save the changes to the Satellite configuration and restart the satellite service on all nodes to load the changes.
DRBD Reactor’s main function could be summarized as such: each DRBD Reactor daemon tries to take over DRBD
Reactor managed services. The daemon that wins the race prevents other nodes from activating the services until the
original winner is no longer able to. When that happens, a new winner will take over DRBD Reactor managed services,
therefore achieving high-availability.
For details regarding DRBD Reactor’s installation and configuration options, refer to the DRBD Reactor GitHub page.
In addition to this, DRBD Reactor needs to be configured to automatically reload when its configuration changes. Run
this snippet on all nodes, as described in the DRBD Reactor README:
# cp examples/drbd-reactor-reload.{path,service} /etc/systemd/system/
# systemctl enable --now drbd-reactor-reload.path
DRBD Reactor uses Pacemaker’s resource agents when integrated with LINSTOR Gateway. You also need to install
resource agents on all nodes in the cluster. This package is named resource-agents in both RPM and DEB based
distributions:
The nvmetcli package can be installed on RPM based systems using the following command:
LINSTOR Gateway requires the LIO iSCSI implementation be installed on all nodes.
The targetcli package can be installed on RPM based systems using the following command:
For NFS support in LINSTOR Gateway, nfs-server utilities need to be installed on each node.
170
The LINSTOR User’s Guide: 12.2. Verifying Requirements are Satisfied
The nfs-utils package can be installed on RPM based systems using the following command:
The NFS server should not be enabled in systemd since that will conflict with DRBD Reactors ability to manage the
service. Disable the nfs-server service and check that it has been disabled using the following commands:
Ensure that the output of the command above lists the service as inactive and disabled:
In addition to the initialized LINSTOR cluster, the following tools need to be present on all nodes:
• linstor-client
• drbd-reactor
• nvmetcli
• targetcli
• nfs-utils (RPM) or nfs-common (DEB)
• nfs-server (RPM) or nfs-kernel-server (DEB)
• resource-agents
LINSTOR Gateway provides a utility to check that the prerequisite tools are present:
# linstor-gateway check-health
This command should print something similar to the output below if you installed all of the required components. If an
error is reported, you must resolve the error before proceeding.
[✓] LINSTOR
[✓] drbd-reactor
[✓] Resource Agents
[✓] iSCSI
[✓] NVMe-oF
[✓] NFS
171
The LINSTOR User’s Guide: 12.2. Verifying Requirements are Satisfied
Ensure all your LINSTOR nodes are listed as a Satellite or Combined type, and that you have 3 (or more) to support
quorum:
Check that LINSTOR’s storage-pool list includes an LVM or ZFS backed storage-pool:
Check that you’ve created at least one LINSTOR resource-group that uses your storage-pool. Also verify that each
resource-group has a corresponding volume-group:
172
The LINSTOR User’s Guide: 12.3. Creating iSCSI Targets
┊ 0 ┊ ┊
╰──────────────────╯
# linstor volume-group list nvmeof_group
╭──────────────────╮
┊ VolumeNr ┊ Flags ┊
╞══════════════════╡
┊ 0 ┊ ┊
╰──────────────────╯
Use linstor-gateway iscsi help for detailed information regarding the iscsi
subcommand.
The following command will create a new DRBD resource in the LINSTOR cluster with the specified name and resource-
group. This command also creates the DRBD Reactor configuration files to enable high availability of the iSCSI target.
After running the command above, you will have a 1GiB iSCSI target with CHAP authentication enabled using the
username and password provided. It will be discoverable on the IP address provided in the command. The target will be
backed by a DRBD device managed by LINSTOR. The DRBD resource was created by LINSTOR in the iscsi_group
resource-group. The DRBD Reactor configuration files created by the above command can be found in /etc/drbd-
reactor.d/.
You can list LINSTOR Gateway created iSCSI resources using the linstor-gateway iscsi list command:
You can check the DRBD Reactor status using the drbd-reactorctl status command.
173
The LINSTOR User’s Guide: 12.6. Deleting NFS Exports
You only need to set this once per resource-group, and only on the resource-group created
specifically for LINSTOR Gateway’s NFS exports.
Finally, the following command will create a HA NFS export in the cluster. This single command will create a new
resource within the LINSTOR cluster using the specified name and resource-group. This command also creates the
DRBD Reactor configuration files to enable high availability of the NFS export.
After running the command above, you will have a 1GiB NFS export with the specified allowed-ips able to mount
the export using the IP address specified as the --service-ip. The exports will be backed by a DRBD device
managed by LINSTOR. The DRBD resource was created by LINSTOR in the nfs_group resource-group. The DRBD
Reactor configuration files created by the above command can be found in /etc/drbd-reactor.d/.
You can list LINSTOR Gateway created NFS resources using the linstor-gateway nfs list command:
You can check the DRBD Reactor status using the drbd-reactorctl status command.
Use linstor-gateway nvme help for detailed information regarding the nvme
subcommand.
The following command will create a new DRBD resource in the LINSTOR cluster with the specified name and resource
group. This command also creates the DRBD Reactor configuration files to enable high availability of the NVMe-oF
target.
After running the command above, you will have a highly available 2GiB NVMe-oF target created in your cluster that is
discoverable on the IP address used in the command. The target will be backed by a DRBD device managed by
LINSTOR. The DRBD resource was created by LINSTOR in the nvmeof_group resource group. The DRBD Reactor
174
The LINSTOR User’s Guide: 12.8. Deleting NVMe-oF Targets
You can list the NVMe-oF resources that you created by using LINSTOR Gateway by entering the linstor-gateway
nvme list command:
You can check the DRBD Reactor status using the drbd-reactorctl status command.
175
The LINSTOR User’s Guide: Chapter 13. LINSTOR Exos Integration
LINSTOR integration with Exos enables multiple server nodes to allocate and connect to LINSTOR resources serviced by
the same Exos pool. Therefore all of the Exos storage management features such as SSD/HDD tiering, SSD caching,
snapshots, and thin provisioning are available for LINSTOR resources and Kubernetes Storage Classes.
After configuration, LINSTOR will dynamically map Resource replicas as LUNs presented to server nodes through one of
the two Exos controllers.
Since the Exos controllers are managed by a secure network API, LINSTOR must be configured with proper networking
and username/password combination. The diagram below is showing the relationship between LINSTOR cluster and
Exos Enclosures.
Multi-host setup allows up to eight LINSTOR nodes to be directly connected with 48Gbit SAS links
for low latency and high throughput.
Load balancing and server failover are managed & enabled by LINSTOR while volume creation is handled by the Exos
hardware RAID engine.
The Exos storage provider in LINSTOR offers native integration with Exos' REST-API.
This section will describe how to enable Exos integration and configure LINSTOR to manage storage backed by an Exos
enclosure.
Exos storage systems offer a feature rich set of configuration options to match any enterprise storage demand. To
maximize ease of use, this guide is based on the following defaults and assumptions:
1. Dual Controllers - Exos systems controllers are Active/Active with automatic failover. Both controllers IP
address must be configured also in the LINSTOR properties for full support.
2. Dual Exos Pools - Optimal performance is achieved when data from pool A is accessed through Controller A. If a
node is connected to both Controller A and B of same controller, LINSTOR will configure Linux multipath which
176
The LINSTOR User’s Guide: 13.1. Exos Properties as a LINSTOR Storage Provider
The information in the table below is needed from your Exos enclosures. This information will be used to populate the
appropriate LINSTOR Controller properties and LINSTOR objects in the sub-sections that follow.
Unique usernames and passwords For Exos controllers are set by:
177
The LINSTOR User’s Guide: 13.2. Configuring a LINSTOR and Exos Integration
Passwords entered in this fashion will show up as plain text when using get-defaults.
With the above command, LINSTOR will store your password in plain text in the LINSTOR properties and visible by a
simple linstor controller list-properties command. You can hide it under an environment variable, and
use the UsernameEnv and/or PasswordEnv properties. This tells LINSTOR to look in environment variable for the
actual username/password, as shown in the following example:
LINSTOR will not modify the environment variables, only read from them. Storage admin has to
verify that the environment variables are correctly set.
# echo $EXOS_PW
mySecretPassword
# linstor controller set-property \
StorDriver/Exos/<exos_encl_name>/PasswordEnv EXOS_PW
If both property-versions (i.e. Password and PasswordEnv) are set, the non-environment version is preferred.
If the satellite is started before the environment variable is set, the satellite needs to be restarted
to see the new environment variable.
If no special --username or --password is given, the above mentioned defaults are used.
If you want to use a hostname that is not DNS resolvable to reference your Exos enclosure within
LINSTOR, you may use any name in place of <exos_hostname>, but you will also have to supply
the enclosure’s IP address: linstor node create <desired_name> <enclosure_ip>
Use the following example to create and inspect the current controller settings:
For a more in-depth view, you can always ask the LINSTOR controller or the LINSTOR nodes for the Exos-related
properties:
178
The LINSTOR User’s Guide: 13.2. Configuring a LINSTOR and Exos Integration
The storage pool can also be created as usual in LINSTOR. Only the name of the previously registered Exos enclosure as
well as the serial number of the Exos pool needs to be specified:
the linstor_pool_name can be set to (almost) any unique string for the LINSTOR deployment.
Here is an example of mapping an Exos Pool in Exos enclosure Alpha to two Satellite nodes:
After creating an exos storage pool the LINSTOR Satellite will scan the given Exos enclosure for connected ports. If
cabled, these ports will be listed in the following command:
Detailed description of all the available Exos commands is found with built-in help.
# linstor exos -h
179
The LINSTOR User’s Guide: 13.3. Creating Resources Backed by Exos Storage Pools
180
The LINSTOR User’s Guide: 14.1. Introduction to CloudStack
Currently, the LINSTOR plug-in for CloudStack can only be used to provision volumes for use with
KVM hypervisors.
Setting up and deploying CloudStack can be a complex task. A production-ready deployment can take several weeks
to months before it is ready for users. A basic test deployment in a virtual environment can be set up in a few hours
perhaps. This chapter will deal only with aspects related to integrating LINSTOR in CloudStack and should be
considered a general overview. You should supplement instructions in this chapter with instructions and best practice
recommendations from the CloudStack documentation.
Attention should be paid to security, firewall, and resource provisioning instructions in the
CloudStack documentation, and in other chapters in the LINSTOR User’s Guide, before production
deployment.
In this chapter, as in other areas of the LINSTOR User’s Guide, the word node is used. In most cases,
you can think of a node as equivalent to a CloudStack host.
PermitRootLogin yes
181
The LINSTOR User’s Guide: 14.3. Installing and Preparing LINSTOR for CloudStack
One of the pull requests did not merge properly in CloudStack v4.17.0 which caused a CloudStack
UI bug in the CloudStack initialization wizard. More details are available here. If you need to be on
the v4.17 branch, it is recommended (at time of writing) that you install v4.17.1.
Follow the installation instructions in the LINSTOR User’s Guide to install LINSTOR on the storage providing nodes in
your cluster.
1. Install necessary packages for storage layers that you will be using, for example, ZFS or LVM. The steps below
use ZFS as a backing storage layer for LINSTOR.
2. Install the necessary LINSTOR packages (DRBD kernel module, linbit-sds-controller, and linbit-
sds-satellite packages) from LINBIT repositories if you are a LINBIT customer, otherwise, you will need to
build from source.
3. Restart the multipathd daemon.
4. Enable and start the LINSTOR Controller and LINSTOR Satellite services on your nodes.
6. Create a new LINSTOR storage pool on all of your participating nodes. For example, given a ZFS pool named
zfs_storage, enter the following to create a storage pool named DfltStorPool:
7. Create a LINSTOR resource group to be used for CloudStack. To create a resource group named cloudstack,
to be placed on two of your cluster nodes, enter:
8. Create a LINSTOR volume group from your resource group, by entering the command:
182
The LINSTOR User’s Guide: 14.4. Installing CloudStack
The CloudStack setup best practices recommend that a primary storage mount point (and
therefore the LINSTOR resource that backs it) "should not exceed 6TB in size."
Verify that LINSTOR created your resources by using a resource list command.
On Ubuntu, enter:
On RHEL, enter:
183
The LINSTOR User’s Guide: 14.5. Installing and Configuring CloudStack
[mysqld]
innodb_rollback_on_timeout=1
innodb_lock_wait_timeout=600
max_connections=350 ①
log-bin=mysql-bin
binlog-format = 'ROW'
① 350 is the max_connections value specified in the CloudStack installation guide. You can change this value
depending on your needs.
If you are on an Ubuntu 16.04 or later system, for binary logging, you need to specify a server_id in your .cnf
database configuration file, for example:
[mysqld]
server_id = 1
innodb_rollback_on_timeout=1
innodb_lock_wait_timeout=600
max_connections=350
log-bin=mysql-bin
binlog-format = 'ROW'
On RHEL, enter:
After installing the NFS server, create an NFS export for CloudStack’s secondary storage by entering the following
commands:
# mkdir -p /export/secondary
# echo "/export *(rw,async,no_root_squash,no_subtree_check)" >> /etc/exports
# exportfs -a
184
The LINSTOR User’s Guide: 14.6. Installing the CloudStack System Virtual Machine Image Template
You can follow the links above to find and download the packages that you need for your installation. Be sure to verify
the integrity of downloaded packages against CloudStack’s signing keys, as outlined in the instructions here.
Alternatively, you can follow instructions here to configure the CloudStack repository appropriate to your Linux
distribution and then pull and install packages by using your distribution’s package manager.
After adding the CloudStack repository, you may need to update the package manager’s repository list, before you can
install packages.
• cloudstack-management
• cloudstack-common
• cloudstack-ui
For your other cluster nodes that will be hosting VMs, install the cloudstack-agent package.
For testing purposes, you can enter the following command on your management node:
Here, the cloud after cloud: and nonsense are passwords that you can change as you see fit.
For production deployments, follow the more detailed instructions in the CloudStack Installation Guide.
# CS_VERSION=4.17
# CS_VERSION_PATCH=4.17.1
# wget https://download.cloudstack.org/systemvm/$CS_VERSION/systemvmtemplate-$CS_VERSION_PATCH-
kvm.qcow2.bz2
# /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt \
-m /export/secondary \
-f systemvmtemplate-$CS_VERSION_PATCH=-kvm.qcow2.bz2 \
-h kvm -o localhost -r cloud -d cloud
185
The LINSTOR User’s Guide: 14.7. Configuring KVM Hypervisor Hosts for Use in CloudStack
Enter the following command to add libvirt configurations to every node in your cluster that will host CloudStack
VMs:
# ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
# ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/
# apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
# apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper
You can follow the progress of CloudStack’s initial database setup by entering:
# journalctl -u cloudstack-management -f
Once you are greeted by the CloudStack UI’s portal login page, log into the portal by using the default user name
admin and the default password password.
After successfully logging in, the CloudStack UI will display the "Hello and Welcome to CloudStack" page.
186
The LINSTOR User’s Guide: 14.8. Taking Next Steps in CloudStack
The wizard will first prompt you to change the default password for the administrator user. After changing the
password, you can continue through the wizard steps to configure a zone, network, and resources details. Complete
the fields in each setup step according to your environment and needs. More details about initializing CloudStack can
be found here.
The following fields will be common to all LINSTOR use cases in CloudStack:
• Zone details:
◦ Hypervisor: KVM
• Add resources, IP Address step:
◦ Host Name: <host_name_of_cluster_node_that_will_host_VMs>
◦ Username: root
◦ Password: <root_password_that_you_configured_previously_for_the_host>
• Add resources, Primary Storage step:
◦ Protocol: Linstor
◦ Server: <IP_address_of_LINSTOR_controller_node>
◦ Resource Group: <LINSTOR_resource_group_name_that_you_configured_previously>
Based on configuring an NFS export for secondary storage earlier, complete the fields presented during the "Add
resources, Secondary Storage" step as follows:
• Provider: NFS
• IP Address: <IP_address_of_NFS_server> # should be the CloudStack management node
• Path: <NFS_mount_point> # /export/secondary, as configured previously
After completing entry fields in the "Add resources" fields and clicking the "Next" button, the wizard will display a
message indicating the "Zone is ready to launch." Click on the "Launch Zone" button.
The "Adding Host" step of the "Launch Zone" process may take a while.
After the zone is added, the wizard will show a "Zone creation complete" message. You can then click on the "Enable
Zone" button. After another "Success" notification you will be returned to the CloudStack UI dashboard.
187
The LINSTOR User’s Guide: 14.8. Taking Next Steps in CloudStack
LINBIT has also made available a video demonstrating deploying LINSTOR and CloudStack into a three-node VM cluster.
You can view the video here.
188
The LINSTOR User’s Guide: 15.1. Introduction to Oracle Linux Virtualization Manager
OLVM supports multiple storage technologies that can be integrated with LINSTOR:
• iSCSI or NFS storage are used for shared storage. In this setup, all OLVM nodes connect to a service host that
exports the storage volume, by using iSCSI or NFS. Here, LINSTOR Gateway can help you create and manage
iSCSI targets and NFS exports based on replicated DRBD volumes and make them highly available.
• Managed Block Storage is another feature available in OLVM. Disks for VMs are managed as separate
volumes, rather than from within a pool of storage on a service host. This makes it possible to directly attach a
volume to a VM while avoiding the performance overhead that a service host adds.
LINSTOR and LINSTOR Gateway don’t need to run on the same nodes as OLVM, provided that the
Gateway nodes are reachable from the OLVM hosts.
Use the linstor-gateway command to create iSCSI or NFS exports. Choose a service IP that is reachable from the
OLVM nodes. The following example creates an iSCSI export of 60GB reachable under 192.168.0.100 and a NFS
export of 50GB, available at 192.168.0.101:/srv/gateway-exports/nfs-data
To configure the storage domains, navigate to the OLVM Administration Portal and open the Storage > Domains
page. Click New Domain and choose a name for the new storage domain. Then, select the Domain function (either
Data or ISO) and the matching storage type (either iSCSI or NFS). Enter the required connection parameters to
complete the configuration.
189
The LINSTOR User’s Guide: 15.3. Using LINSTOR Cinder for Managed Block Storage
Use a separate data domain for the self-hosted engine to reduce the risk of adverse interference with your VMs.
Create a iSCSI target with at least 60GB to use for the management VM. The following example creates a 60GB
volume exported as iqn.2019-08.com.linbit:olvm-engine, available at the IP 192.168.0.200. Change
the IP and iSCSI target name to appropriate values for your setup.
While setting up the OLVM self-hosted engine, you will be asked to provide details for the storage of the Manager
virtual machine. You only need to provide the storage type iscsi and the IP address 192.168.0.200. All other
information will be discovered automatically.
Please specify the storage you would like to use (glusterfs, iscsi, fc,
nfs)[nfs]: iscsi
Please specify the iSCSI portal IP address: 192.168.0.200
Please specify the iSCSI portal port [3260]:
Please specify the iSCSI discover user:
Please specify the iSCSI discover password:
Please specify the iSCSI portal login user:
Please specify the iSCSI portal login password:
The following targets have been found:
[1] iqn.2019-08.com.linbit:engine-data
TPGT: 1, portals:
192.168.0.200:3260
Please select a target (1) [1]: 1
Please select the destination LUN (1) [1]:
After the setup completes, the iSCSI target is added as a data domain to OLVM. Use separate data domains for your
VMs to avoid interference with the self-hosted engine’s storage.
Using LINSTOR Cinder requires several additional steps to set up for OLVM:
• All OLVM hosts, including the engine host, need to be registered with LINBIT and the ovirt repository enabled:
# curl -O https://my.linbit.com/linbit-manage-node.py
# chmod +x ./linbit-manage-node.py
# ./linbit-manage-node.py
...
1) pacemaker-2(Disabled)
2) ovirt(Enabled)
3) drbd-9.0(Disabled)
4) drbd-9(Enabled)
...
• OLVM hosts as well as the management engine need to be part of the LINSTOR cluster. Ensure that the
linstor-satellite service is installed and configured on all hosts.
190
The LINSTOR User’s Guide: 15.3. Using LINSTOR Cinder for Managed Block Storage
• OLVM needs to have CinderLib support enabled. It is disabled by default. To enable it, run engine-setup
on the engine host:
$ engine-setup --reconfigure-optional-components
...
--== PRODUCT OPTIONS ==--
Configure Cinderlib integration (Currently in tech preview) (Yes, No) [No]: Yes
...
• The engine hosts need to have the LINBIT version of python3-cinder-common installed, which can be
identified by the linbit1 string in the version number:
• All OLVM hosts need to have the LINBIT version of vdsm and python3-osbrick installed, which can be
identified by the linbit1 string in the version number:
To configure LINSTOR Cinder for Managed Block Storage, navigate to the OLVM Administration Portal and open the
Storage > Domains page. Click New Domain and select Domain Function "Managed Block Storage". Choose a
name, and set the following driver options:
OLVM 4.4 does not support creating VMs using Managed Block Storage from the VM Portal, only
through the Administration Portal.
191