Nomad Architecture Overview
+----------------------+
| CLI / API |
+----------+-----------+
|
HTTP / RPC
|
+-----------------------------------+
| Nomad Servers |
|-----------------------------------|
| Scheduler |
| Raft Consensus |
| State Store |
| Evaluations / Planning |
| Leader Election |
+----------------+------------------+
|
Gossip / RPC
|
-----------------------------------------
| | |
+-------------+ +-------------+ +-------------+
| Nomad Client| | Nomad Client| | Nomad Client|
| Node | | Node | | Node |
+-------------+ +-------------+ +-------------+
| Drivers | | Drivers | | Drivers |
| Docker | | Exec | | Podman |
| Java | | QEMU | | Raw_exec |
+-------------+ +-------------+ +-------------+
Main Components
Server Nodes
like k8s controlplane
equivalent to kube-apiserver, scheduler,etcd and control manager compressed into one system
Responsibilities
Servers handles:
cluster state
scheduling
consensus
leader election
evaluations
placement planning
health awarness
job state tracking
Internally they use
Raft Consensus
Raft Consensus
N = 2f + 1
This is quorum rule, where:N = total servers
f = failure tolerated
So:3 servers -> tolerate 1 server
5 servers -> tolerate 2 servers
Nomad server is the one that works on preemption, allocation logic and all that. There is a cluster of nomad server not a single server and nomad uses RAFT to decides which is the leader
Nomad embeds HashiCorp raft library and that replaces etcd
State Storage
Kubernetes:
etcd
Nomad:integrated Raft state store
No external DB.
Huge design difference.
The Raft log itself becomes the authoritative cluster state.
This is one reason Nomad is operationally lighter.Nomad Client is the one where the actual work is executed.
Leader Election
One server becomes:
authoritative scheduler leader
Others are followers.
If leader dies:Raft elects new leader.
Client Nodes
These are worker machines.
Equivalent to:
kubelet nodes
But simpler.
Responsibilities
Clients:
receive allocations
run workloads
report health
manage task lifecycle
expose resource availability
Allocations
k8s - Pods
nomad - allocations
an allocation is a scheduled instance of a task group on a client node.
Job Spec
↓
Scheduler Decision
↓
Allocation Created
↓
Runs on Client
Job Model
Nomad Hierarchy:
Job
└── Group
└── Task
Example
Job: ecommerce
Group: frontend
Task: nginx
Task: envoy
Group: backend
Task: api
Task: metrics
Why group exists?
Task in same group:
co located on same machine
share network namespace (Important)
share volumes
Scheduling Pipeline
Step 1 - Job submission
user submits: nomad job run app.nomad
server receives HCL/JSON spec
Step 2 - Evaluation
Evaluation (eval)
whenever cluster changes:
node added
node died
job updated
health failed
nomad creates an evaluation object: Think of eval as "cluster neds scheduling work"
similar to k8s reconcillation triggers
Scheduler
Scheduler consumes evaluation and computes
placements
constrants
affinities
resource fits
Step 4 - Plan
Scheduler creates a plan: Task X -> Node Y
Step 5 - Allocation
Plan gets committed
allocation created
client executes them