4 min to read.
Welcome back to the third part of our Nomad tutorial series! After successfully installing Nomad in part one and creating your first Nomad job in part two, we will now focus on the Service Stanza. The Service Stanza is the backbone for service management in Nomad, and you'll learn how to use it to seamlessly implement service discovery and load balancing. This knowledge is critical to unlocking the full potential of Nomad and taking your deployments to the next level. Let's explore together the possibilities Nomad holds for your services!
In HashiCorp Nomad, a "service" is a descriptive configuration that specifies that a particular task or group of tasks within a job represents a long-term running process that responds to network requests. Services in Nomad are often used for applications that act as web servers, APIs, databases or any other type of software that needs to continuously respond to requests.
Within a Nomad job configuration, a service is defined by the service stanza. This stanza allows you to configure various aspects of the service, including:
service {
provider = "consul"
name = "jellyfin"
port = "web"
tags = [
]
check {
type = "http"
path = "/"
interval = "2s"
timeout = "2s"
}
}
When you define a service in Nomad, it often works with HashiCorp Consul, a service discovery and health checking tool. Nomad, if Consul is installed, will automatically register the service with Consul, allowing other services or applications to discover and communicate with the service. Consul can also use the health checks to ensure that only "healthy" instances of the service are included in load balancing.
It is also important to understand that the tags you assign to your services in Nomad can have far-reaching applications. Tags are not only useful within Nomad itself, but can also be used by external applications and tools to control additional configurations and behaviors. A common example of this is an ingress controller that reads the tags of your services to decide how network traffic should be routed to those services. These tags allow for a flexible and dynamic configuration that can adapt to the changing needs of your infrastructure. By using tags wisely, you can improve interoperability between Nomad and other systems such as load balancers, monitoring tools and service discovery mechanisms.
The service stanza in Nomad gives you the flexibility to define it either at the individual task level or at the task group level. The main difference between these two approaches is the order in which services are created and removed.
If you define a service at group level, the entire task group including the associated configuration is initialized first. The individual tasks within this group are only started once the group has been created. This means that a service defined at group level is already active even before all tasks have been fully set up. This can be advantageous if several tasks use the same service, as the service is already available as soon as the first tasks are ready. This means that these tasks can already be found and used by other components via Service Discovery, even if not all tasks in the group have been started up yet.
In contrast, a service that is defined at task level is set up at the exact moment when the specific task is started. The service is created and expires with the life cycle of the individual task. This gives you finer control over when exactly a service should be available, based on the status of the specific task.
This distinction can be particularly relevant for health checks. If a service is set up at group level, health checks may already happen for tasks that are operational while others are still being initialized. The timing and availability of services can therefore vary depending on the choice of configuration level and should be carefully considered in order to achieve the desired behavior in your service infrastructure.
In this HCL (HashiCorp Configuration Language) script, a Nomad job named "test" is defined, which contains a single group "demo". Within this group, a network is configured that provides a dynamic port for HTTP traffic. However, the focus is on the service stanza, which defines a service called "test-service" on the same dynamic HTTP port that the network provides.
job "test" {
group "demo" {
network {
port "http"{
}
}
service {
name = "test-service"
port = "http"
tags = [
]
check {
type = "http"
path = "/"
interval = "2s"
timeout = "2s"
}
}
task "server" {
env {
PORT = "${NOMAD_PORT_http}"
NODE_IP = "${NOMAD_IP_http}"
}
driver = "docker"
config {
image = "hashicorp/demo-webapp-lb-guide"
ports = ["http"]
}
}
}
}
The service Stanza is a powerful feature in Nomad that makes it possible to orchestrate complex applications and microservices and ensure their availability and discoverability in a dynamic infrastructure.