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_poolis 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"
}
// ...
}
}
}
