Nomad
- It has a client-server architecture. There is a main server and worker nodes (clients).
- Integrates with Consul for service discoverability
- Can integrate with other CNIs
Commands
https://developer.hashicorp.com/nomad/commands
nomad nodenomad node statusDisplay basic information about all the nodes.nomad node status 42635b82Display detailed information and resource usage about a node.nomad job statusnomad job status -verbose job-namenomad job scalenomad job scale job-name 2Set the number of instances (Horizontal scaling).nomad job stopnomad job allocs job-nameShow the allocation ID for a jobnomad alloc status <alloc-id>Show detailed info about the allocation (resources, ports, status, etc)nomad alloc exec -i -t <alloc-id> /bin/shRun command inside a container
Start agent
In dev mode
With a config file
Access the webui on port 4646.
Config file
Server and worker
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
server {
enabled = true
bootstrap_expect = 1
}
client {
enabled = true
servers = ["127.0.0.1"]
}
Worker
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
client {
enabled = true
servers = ["<Server_Node_IP>:4647"]
}
Jobs
Type of jobs
- Service jobs (default) are long-running tasks that should never go down.
- Batch jobs are short-lived and run to completion.
- System jobs are tasks that should be run on all clients matching certain criteria.
- Parameterized jobs are templates that can be triggered with specific parameters.
Job lifecycles
- Submission: initial step where you submit your job spec to Nomad using
nomad job run example.nomad - Planning: Nomad creates a plan for how and where to run the job.
- Allocation: Once the plan is approved, Nomad allocates resources and schedules the job.
- Execution: Finally, the job is executed. Nomad monitors its execution, ensuring it's restarted in case of failure according to the job's restart policy.
Scheduling Algorithms
Nomad uses sophisticated scheduling algorithms to optimize resource utilization and fault tolerance. It considers resource availability, job priority, and data locality, among other factors, to make scheduling decisions.
Bin Packing Nomad's bin packing algorithm aims to minimize resource fragmentation and maximize resource utilization by fitting jobs into the smallest number of clients.
Spread For fault tolerance, Nomad can also spread jobs across different clients to reduce the impact of a single client's failure.
Create a job
Create a job definition.
job "hello-world" {
type = "batch"
datacenters = ["dc1"]
group "hello-world-group" {
task "hello" {
driver = "exec"
config {
command = "/bin/echo"
args = ["Hello, Nomad!"]
}
resources {
cpu = 500 # MHz
memory = 256 # MB
}
}
}
}
job "fast-api" {
datacenters = ["dc1"]
group "api" {
network {
mode = "bridge"
port "http" {}
}
task "fastapi" {
driver = "docker"
config {
image = "tiangolo/uvicorn-gunicorn-fastapi"
ports = ["http"]
}
}
}
}
Execute it with nomad run example.nomad
Services
Connect the job with Consul. I have not tested this.
job "webapp" {
datacenters = ["dc1"]
group "backend" {
count = 1
task "redis" {
driver = "docker"
config {
image = "redis:latest"
}
service {
name = "redis"
port = "6379"
provider = "consul"
tags = ["redis", "db", "backend"]
check {
type = "tcp"
interval = "10s"
timeout = "2s"
}
}
}
}
group "frontend" {
network {
mode = "bridge"
port "http" {
static = 8080
to = 80
}
}
count = 2
task "frontend" {
driver = "docker"
config {
image = "nginx"
ports = ["http"]
}
env {
REDIS_ADDR = "redis.service.consul:80"
}
}
}
}
Secrets
Using Vault to store and retrieve secrets.
job "example-vault" {
datacenters = ["dc1"]
group "group1" {
task "task1" {
driver = "docker"
vault {
policies = ["my-policy"]
}
template {
data = <<EOH
MY_SECRET="{{ with secret "secret/myapp/config" }}{{ .Data.password }}{{ end }}"
EOH
destination = "secrets/file.env"
env = true
}
config {
image = "busybox"
}
}
}
}