Nomad Architecture¶
Nomad is a simple, flexible workload orchestrator. A single binary runs in two modes (server or client) and coordinates to schedule tasks across the cluster. Understanding the architecture is the foundation for every other topic.
Agent: Server or Client¶
Nomad's single binary (nomad) runs in two roles:
- Server: part of the control plane. Participates in Raft consensus. Stores cluster state.
- Client: part of the data plane. Runs allocations. Reports status.
A single agent can run in either mode, or both (not recommended for production).
# Server config
server {
enabled = true
bootstrap_expect = 3
}
# Client config
client {
enabled = true
servers = ["server1:4647", "server2:4647", "server3:4647"]
}
Cluster Topology¶
ββββββββββββββββββββββββββββββββββββββ
β Nomad Servers (3 or 5) β
β Raft consensus β
βββββββββββββββ¬βββββββββββββββββββββββ
β RPC (4647)
β Serf gossip (4648)
βΌ
ββββββββββββββββββββββββββββββββββ
β Nomad Clients (many) β
β Run allocations (tasks) β
ββββββββββββββββββββββββββββββββββ
Servers form a Raft cluster for strong consistency. Clients connect to any server and register.
Raft Consensus¶
Raft ensures server cluster agreement on state. Requirements:
- Quorum: (N/2)+1 servers must be available for writes
- Odd numbers preferred (3, 5, 7)
- 3 servers: quorum 2, tolerates 1 failure
- 5 servers: quorum 3, tolerates 2 failures
Leader election happens automatically when the leader fails. A new leader is chosen within seconds.
Gossip (Serf)¶
Servers and clients use Serf for membership discovery and failure detection. Two gossip pools:
- LAN gossip: within a region (fast, tight)
- WAN gossip: across regions, only between servers (for federation)
Port 4648 by default, UDP and TCP.
Regions and Datacenters¶
- Region: independent Nomad cluster with its own servers. Regions federate via WAN gossip.
- Datacenter: a logical partition within a region (e.g., physical DC or AZ).
- Nodes: Nomad client agents.
A job can target:
- One or more datacenters (
datacenters = ["dc1", "dc2"]) - A specific region (
region = "us-west")
Federation allows cross-region job submissions with -region flag but scheduling is per-region.
Scheduler¶
The scheduler runs on the server leader. Its job: for each submitted job, produce an allocation plan.
Scheduler flow:
- Job submitted
- Server creates an evaluation
- Evaluation consumed by scheduler
- Scheduler computes placements (bin-packing, spread, etc.)
- Allocations created and dispatched to clients
- Clients start the tasks
Nomad has specialized schedulers:
- service: optimizes for long-running with bin-packing
- batch: similar, but more forgiving
- system: runs on every node
- sysbatch: runs to completion on every node
Allocation Lifecycle¶
pending -> running -> complete
\-> failed -> restarting / rescheduled
- pending: scheduled but not yet running
- running: task(s) healthy
- complete: batch job finished
- failed: task failed beyond restart limits
Tasks, Groups, Jobs¶
- Task: single unit of work (a container, a JVM, a process)
- Group: one or more tasks that share network, volumes, placement
- Job: one or more groups
Allocations are per-group: each group's count determines how many allocations exist.
State Storage¶
Servers store state in Raft (in-memory with persistent log). Clients cache their own allocation state in the data directory for resilience.
Back up by snapshotting the leader:
nomad operator snapshot save backup.snap
nomad operator snapshot restore backup.snap
Networking¶
Server-to-server: RPC on port 4647, encrypted via TLS if configured.
Client-to-server: RPC on 4647.
Gossip: 4648 UDP/TCP.
HTTP API and UI: 4646, TLS optional.
HCP Nomad (in beta)¶
HashiCorp's managed Nomad offering. Servers in HCP; clients in your VPC. Reduces operational burden for small teams. Feature parity continues to evolve.
Enterprise Features¶
- Namespaces: multi-tenancy (now in OSS 1.0+)
- Resource Quotas: caps on CPU/memory per namespace
- Sentinel: policy as code
- Multi-Cluster: unified view of multiple clusters
- Audit Logging: detailed compliance logs
- Preemption: higher-priority jobs can evict lower
Bootstrap¶
Starting a new Nomad cluster:
- Configure 3 (or 5) server nodes with
bootstrap_expect = 3 - Start them; they elect a leader via Raft
- Configure clients with
servers = [...] - Clients register; leader assigns them
- If ACLs enabled:
nomad acl bootstrap
Configuration File Layout¶
Nomad supports both HCL and JSON config. Typical layout:
/etc/nomad.d/
βββ nomad.hcl
βββ server.hcl
Agent reads all .hcl / .json files recursively from -config directory.
Example Server Config¶
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
advertise {
http = "10.0.0.1:4646"
rpc = "10.0.0.1:4647"
serf = "10.0.0.1:4648"
}
server {
enabled = true
bootstrap_expect = 3
encrypt = "base64-key"
server_join {
retry_join = ["server1:4648", "server2:4648", "server3:4648"]
}
}
acl {
enabled = true
}
telemetry {
prometheus_metrics = true
disable_hostname = true
collection_interval = "10s"
publish_allocation_metrics = true
publish_node_metrics = true
}
Example Client Config¶
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
client {
enabled = true
servers = ["server1:4647", "server2:4647", "server3:4647"]
meta {
environment = "production"
rack = "rack-1"
}
host_volume "data" {
path = "/opt/data"
read_only = false
}
node_class = "compute"
}
plugin "docker" {
config {
allow_privileged = false
}
}
CLI Discovery¶
nomad server members # see cluster members
nomad node status # see client nodes
nomad operator raft list-peers # inspect Raft cluster
nomad operator api /v1/status/leader # who is leader
Leader Election and Failure¶
If the leader crashes, Raft elects a new one within seconds. During election, writes block momentarily; reads can still serve from any server (eventually consistent).
Clients talking to a crashed server reconnect to another server automatically (they try the full list).
TLS for Agent Communication¶
Production deployments enable TLS on all ports:
tls {
http = true
rpc = true
ca_file = "/etc/nomad.d/ca.pem"
cert_file = "/etc/nomad.d/cert.pem"
key_file = "/etc/nomad.d/key.pem"
verify_server_hostname = true
verify_https_client = true
}
Use consul-terraform-sync or consul-template to rotate certs.
Exam-Ready Checklist¶
- Can describe servers vs clients vs agents
- Know Raft quorum math
- Understand regions, datacenters, nodes
- Know default ports 4646 / 4647 / 4648
- Can read and author a basic agent config
- Understand allocation lifecycle
- Know federation between regions via WAN gossip