Using Dynamic Host Volumes in Nomad
With the 1.10.0 release of Nomad, dynamic host volumes can now be managed without restarting a Nomad Client node to apply the configuration change.
You can use the volume create
and volume register
CLI commands and the equivalent API endpoints to register a new volume by defining its capabilities, mount options, and parameters. This works similarly for the Container Storage Interface (CSI) volumes and "new" dynamic host volumes.
First, let's write a volume.hcl
file to define the volume we want to create in our Nomad cluster:
name = "example"
type = "host"
plugin_id = "mkdir"
capability {
access_mode = "single-node-single-writer"
attachment_mode = "file-system"
}
The type defines the kind of volume you want to create. Set it either to host
for dynamic host volumes or csi
for CSI volumes.
In case of a dynamic host volume, you have to set the plugin_id to mkdir
, the default Nomad plugin to take care of how the volume is created and managed. You set the name to the plugin you want to use for a CSI volume. For example, we use SeaweedFS as CSI storage. In that case, the plugin_id is set to seaweedfs
.
The volume is created by running the following CLI command: nomad volume create ./volume.hcl
Since we haven't defined any host constraints, Nomad will choose an available node based on the following factors:
- the node cannot already have a host volume with the same name
- if
node_pool
is set, the selected node must be in that node pool - the node must meet all constraints defined by the constraint fields
For example, if we want to create a volume in the prod
node pool, we can use this volume configuration:
name = "example"
type = "host"
node_pool = "prod"
plugin_id = "mkdir"
capability {
access_mode = "single-node-single-writer"
attachment_mode = "file-system"
}
Once created, you can see the volume in the Storage section within the Nomad UI:
On the CLI, you can show your dynamic host volumes via this command:
nomad volume status -type host
To reference the created host volume in a Nomad job, add a volume
block in a job group and reference the volume
in a volume_mount
block inside your task definition:
job "my_job" {
group "job_group" {
volume "groupvol" {
type = "host"
source = "example"
access_mode = "single-node-single-writer"
attachment_mode = "file-system"
}
task "group_task" {
volume_mount {
volume = "groupvol"
destination = "/srv"
}
// ...
}
}
}