Nomad Tutorials Teil-3: Nomad Services verstehen

5 min zu lesen.

Willkommen zurück zum dritten Teil unserer Nomad Tutorial-Reihe! Nachdem du in Teil eins Nomad erfolgreich installiert und in Teil zwei deinen ersten Nomad-Job erstellt hast, konzentrieren wir uns jetzt auf die Service Stanza. Die Service Stanza ist das Rückgrat für das Service-Management in Nomad, und du wirst lernen, wie du sie nutzt, um Service Discovery und Load Balancing nahtlos zu implementieren. Dieses Wissen ist entscheidend, um das volle Potenzial von Nomad auszuschöpfen und deine Deployments auf das nächste Level zu heben. Lass uns gemeinsam die Möglichkeiten erkunden, die Nomad für deine Services bereithält!

Was ist ein Service in Nomad?

In HashiCorp Nomad ist ein "Service" eine beschreibende Konfiguration, die angibt, dass eine bestimmte Aufgabe (Task) oder Gruppe von Aufgaben innerhalb eines Jobs einen langfristig laufenden Prozess darstellt, der Netzwerkanfragen beantwortet. Services in Nomad werden häufig für Anwendungen verwendet, die als Webserver, APIs, Datenbanken oder jede andere Art von Software fungieren, die kontinuierlich auf Anfragen reagieren muss.

Innerhalb einer Nomad-Jobkonfiguration wird ein Service durch die service Stanza definiert. Diese Stanza ermöglicht es dir, verschiedene Aspekte des Services zu konfigurieren, einschließlich:

hcl
service {
  provider = "consul"

  name = "test-service"
  port = "web"

  tags = [
  ]

  check {
    type     = "http"
    path     = "/"
    interval = "2s"
    timeout  = "2s"
  }
}
  • Provider: Es gibt in Hashicorp Nomad zwei mögliche Provider, Nomad und Consul für die Service-Discovery.
  • Name: Der eindeutige Name des Services, der in der Service-Discovery verwendet wird.
  • Tags: Eine Liste von Tags, die dem Service zugeordnet sind, die bei der Service-Discovery und -Organisation helfen können.
  • Port: Der Port, auf dem der Service läuft. Nomad kann dynamische Ports verwalten, was bedeutet, dass der Port bei der Ausführung der - Aufgabe zugewiesen wird.
  • Check: Health Checks, die verwendet werden, um die Verfügbarkeit und Gesundheit des Services zu überwachen. Diese können HTTP-, TCP- oder - Script-Checks sein, die in regelmäßigen Abständen ausgeführt werden.

Wenn du einen Service in Nomad definierst, arbeitet dieser oft mit HashiCorp Consul zusammen, einem Service-Discovery- und Health-Checking-Tool. Nomad registriert, sofern Consul installiert wurde, den Service automatisch bei Consul, wodurch andere Dienste oder Anwendungen den Service entdecken und mit ihm kommunizieren können. Consul kann auch die Healthchecks nutzen, um sicherzustellen, dass nur "gesunde" Instanzen des Services im Load Balancing berücksichtigt werden.

Es ist ebenfalls wichtig zu verstehen, dass die Tags, die du deinen Services in Nomad zuweist, weitreichende Anwendung finden können. Tags sind nicht nur innerhalb von Nomad selbst nützlich, sondern können auch von externen Anwendungen und Tools genutzt werden, um zusätzliche Konfigurationen und Verhaltensweisen zu steuern. Ein gängiges Beispiel hierfür ist ein Ingress-Controller, der die Tags deiner Services ausliest, um zu entscheiden, wie der Netzwerkverkehr zu diesen Services geleitet werden soll. Diese Tags ermöglichen eine flexible und dynamische Konfiguration, die sich an die sich ändernden Anforderungen deiner Infrastruktur anpassen kann. Indem du Tags klug einsetzt, kannst du die Interoperabilität zwischen Nomad und anderen Systemen wie Load Balancern, Monitoring-Tools und Service-Discovery-Mechanismen verbessern.

Wo kann die Service Stanza gesetzt werden?

Die Service Stanza in Nomad bietet dir die Flexibilität, sie entweder auf der Ebene einzelner Tasks oder auf der Ebene der Task-Gruppe zu definieren. Der wesentliche Unterschied zwischen diesen beiden Ansätzen liegt in der Reihenfolge, in der Services erstellt und wieder entfernt werden.

Wenn du einen Service auf Gruppenebene definierst, wird zuerst die gesamte Task-Gruppe samt der zugehörigen Konfiguration initialisiert. Erst nachdem die Gruppe steht, werden die einzelnen Tasks innerhalb dieser Gruppe gestartet. Das bedeutet, dass ein auf Gruppenebene definierter Service bereits aktiv ist, noch bevor alle Tasks vollständig eingerichtet sind. Dies kann vorteilhaft sein, wenn mehrere Tasks denselben Service nutzen, da der Service schon verfügbar ist, sobald die ersten Tasks bereit sind. So können diese Tasks bereits über Service Discovery von anderen Komponenten gefunden und genutzt werden, auch wenn noch nicht alle Tasks der Gruppe hochgefahren sind.

Im Gegensatz dazu wird ein Service, der auf Task-Ebene definiert ist, genau in dem Moment eingerichtet, in dem der spezifische Task gestartet wird. Der Service entsteht und vergeht mit dem Lebenszyklus des einzelnen Tasks. Dies gibt dir feinere Kontrolle darüber, wann genau ein Service verfügbar sein soll, basierend auf dem Status des jeweiligen Tasks.

Diese Unterscheidung kann besonders bei Health Checks relevant sein. Wenn ein Service auf Gruppenebene eingerichtet ist, könnten Health Checks bereits für Tasks passieren, die betriebsbereit sind, während andere noch initialisiert werden. Das Timing und die Verfügbarkeit von Services können also je nach Wahl der Konfigurationsebene variieren und sollten sorgfältig bedacht werden, um das gewünschte Verhalten in deiner Service-Infrastruktur zu erzielen.

Beispiele mit der Service Stanza

In diesem HCL (HashiCorp Configuration Language) Skript wird ein Nomad-Job namens "test" definiert, der eine einzelne Gruppe "demo" enthält. Innerhalb dieser Gruppe wird ein Netzwerk konfiguriert, das einen dynamischen Port für HTTP-Verkehr bereitstellt. Der Fokus liegt jedoch auf der service Stanza, die einen Service namens "test-service" auf demselben dynamischen HTTP-Port definiert, den das Netzwerk bereitstellt.

hcl
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"]
      }      
    }
  }
}

Die service Stanza im Detail:

  • name: The name of the service is "test-service". This name is used for service discovery so that other services or applications can find this service and communicate with it.
  • port: The service is configured on the "http" port, which corresponds to the dynamic port defined by the network stanza.
  • tags: Tags (keywords) could be added here as a list to further describe or classify the service. In this script the list of tags is empty, but in practice entries such as Ingress configurations could be placed here.
  • check: This is a health check that ensures that the service is working properly. The type of the check is "http", which means that Nomad sends an HTTP request to the service to check the status. The path is "/", which is the root URL of the service. The health check is performed every 2 seconds (interval) and the service has 2 seconds (timeout) to respond before it is considered down.

Here is another example of what a declaration in a task could look like:

hcl
job "test" {

  group "demo" {

    network {
      port  "http"{

      }
    }

    task "server" {
      env {
        PORT    = "${NOMAD_PORT_http}"
        NODE_IP = "${NOMAD_IP_http}"
      }

      driver = "docker"

      config {
        image = "hashicorp/demo-webapp-lb-guide"
        ports = ["http"]
      }     

      service {
        name = "test-service"
        port = "http"

        tags = [
        ]

        check {
          type     = "http"
          path     = "/"
          interval = "2s"
          timeout  = "2s"
        }
      }
    }
  }
}

Die service Stanza ist ein mächtiges Feature in Nomad, das es ermöglicht, komplexe Anwendungen und Microservices zu orchestrieren und deren Verfügbarkeit und Entdeckbarkeit in einer dynamischen Infrastruktur sicherzustellen.