Application Management with Nomad

  • AM1: Applications can be deployed as binaries or docker container
  • AM2: Applications can be deployed on specific nodes
  • AM3: Applications can be deployed somewhere inside the cluster
  • AM4: An interface in which I see the status of each application (health, resource consumption, endpoints)

What is Nomad?

Installing Nomad

  • Determine the correct Linux distribution and hardware
  • Create nomad group, user and directories
  • Download and link the nomad binary
  • Copy configuration files
  • Enable nomad with systemd
>> /usr/local/bin/nomad agent -server -config /etc/nomad/nomad.conf.jso
>> nomad node statusID        DC                      Name       Class   Drain  Eligibility  Status
7be9e3ea infrastructure_at_home raspi-0 <none> false eligible ready
537de130 infrastructure_at_home raspi-4-1 <none> false eligible ready
899eab5d infrastructure_at_home raspi-3-2 <none> false eligible ready
c2a79d23 infrastructure_at_home raspi-3-1 <none> false eligible ready

Nomad Jobs: Execute a Binary

job "example" {
datacenters = ["infrastructure_at_home"],
group "exec" {
task "http_serve" {
driver = "exec"
artifact {
source = "https://github.com/m3ng9i/ran/releases/download/v0.1.4/ran_linux_arm64.zip"
}
config {
command = "ran_linux_arm64"
args = [
"-l",
"--debug",
"-p",
"${NOMAD_PORT_http}"
]
}
resources {
cpu = 200
memory = 200
network {
port "http" {}
}
}
}
}
}
  • It is structured into job, group and task sections
  • > Job is the top-level name for running applications, think of the file name
  • > A group defines a set of related tasks that will be placed on the same node
  • >A task defines which the application: which type, its configuration, its network ports and more
  • With datacenter identifies at which nomad cluster to run the program
  • Inside of task we define the application specific
  • > The driver can be
  • > exec Run command in a Shell
  • > Java Execute a JAR File
  • > docker Execute a docker container
  • With artifact we express to download and unzip a file to the application job
  • config provides the command and additional args that will be used to execute the application. Take special attention to the ${NOMAD_PORT_http} - this is the dynamic HTTP port that Nomad will assign to the running process.
  • Finally with resources you define the minimum required resources that a node needs to fulfill this task, and also how to assign ports, which is in this case dynamic
>> nomad job plan example.nomadJob: "example"
Task Group: "exec" (1 ignore)
Task: "http_serve"
Scheduler dry-run:
- All tasks successfully allocated.
>> nomad job run example.==> Monitoring evaluation "8eb3657a"
Evaluation triggered by job "example"
Evaluation within deployment: "f31e3269"
Evaluation status changed: "pending" -> "complete"
==> Evaluation "8eb3657a" finished with status "complete"
>> nomad status topID            = example
Name = example
Submit Date = 2020-03-09T19:25:38Z
Type = service
Priority = 50
Datacenters = infrastructure_at_home
Namespace = default
Status = running
Periodic = false
Parameterized = false
Summary
Task Group Queued Starting Running Failed Complete Lost
exec 0 0 1 2 1 0
Latest Deployment
ID = f31e3269
Status = successful
Description = Deployment completed successfully
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
exec 1 1 0 0 2020-03-09T19:35:38Z
Allocations
ID Node ID Task Group Version Desired Status Created Modified
21d08737 4b393cb6 exec 4 run running 7m49s ago 7m35s ago

Running a Docker Job

  • The driver is docker
  • inside config, you specify the image that will be loaded, and provide a port_map to specify which exposed ports of the Docker container will be exposed by the job. The declaration http = 80 means that the exposed port 80 will be bound to the variable http
  • In the resources.network part we map the exposed http port from the Docker container to static port 80
job "example2" {
datacenters = ["infrastructure_at_home"],
group "webserver" {
count = 3,
task "nginx" {
driver = "docker",
config {
image = "nginx:1.17.9"
port_map {
http = 80
}
}
resources {
cpu = 200,
memory = 200,
network {
port "http" {
static = 80
}
}
}
}
}
}

Controlling Application Allocation

job "example2" {
group "webserver" {
count = 2
task "nginx" {
affinity {
attribute = "${attr.memory.totalbytes}"
operator = ">"
value = "1048576"
weight = 100
}
...
}
}
}

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store