Vous cherchez à orchestrer vos workloads sans la complexité de Kubernetes ? HashiCorp Nomad est un orchestrateur léger, distribué sous forme d'un seul binaire, capable de gérer aussi bien des conteneurs Docker que des binaires natifs, des machines virtuelles ou des jobs batch. Là où Kubernetes exige plusieurs composants (etcd, API server, scheduler, kubelet…), Nomad s'installe en une commande et devient opérationnel en quelques minutes. Ce guide s'adresse aux développeurs et ops qui veulent déployer rapidement des workloads variés sur un ou plusieurs datacenters.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer Nomad et lancer un cluster de développement en une commande
- Écrire des fichiers de jobs en HCL pour déployer des conteneurs Docker
- Différencier les types de jobs : service (continu), batch (ponctuel), system (chaque nœud) et periodic (cron)
- Configurer des rolling updates avec rollback automatique
- Utiliser les templates pour générer dynamiquement des fichiers de configuration
- Diagnostiquer les problèmes courants avec les commandes CLI essentielles
Qu'est-ce que Nomad ?
Section intitulée « Qu'est-ce que Nomad ? »Nomad est un orchestrateur de workloads développé par HashiCorp (les créateurs de Terraform). Là où Kubernetes se concentre sur les conteneurs, Nomad peut orchestrer tout type de charge de travail : conteneurs Docker, applications Java, binaires natifs, machines virtuelles QEMU, et même des GPU Nvidia.
Cette polyvalence tient à son architecture : Nomad délègue l'exécution à des task drivers interchangeables. Le planificateur décide où placer une charge de travail, puis le driver correspondant sait la démarrer, qu'il s'agisse d'appeler l'API Docker, de lancer un processus dans des cgroups ou de démarrer une machine virtuelle QEMU. Kubernetes, lui, suppose partout un conteneur conforme à l'interface CRI.
Nomad vs Kubernetes : quand choisir quoi ?
Section intitulée « Nomad vs Kubernetes : quand choisir quoi ? »Le comparatif ci-dessous n'oppose pas un gagnant à un perdant : il oppose un coût d'exploitation à une richesse d'écosystème. Nomad demande moins de composants à opérer et accepte des charges de travail que Kubernetes ne sait pas prendre, mais il n'a ni Helm, ni opérateurs, ni la profondeur d'outillage cloud-native. Lisez chaque ligne en vous demandant ce que votre équipe devra maintenir dans un an.
| Critère | Nomad | Kubernetes |
|---|---|---|
| Complexité d'installation | Un seul binaire, opérationnel en minutes | Plusieurs composants (etcd, API server, scheduler...) |
| Types de workloads | Conteneurs, binaires, VMs, batchs, GPU | Principalement conteneurs |
| Courbe d'apprentissage | Douce, HCL lisible | Plus raide, YAML verbeux |
| Écosystème | Plus restreint, intégration HashiCorp | Très vaste (Helm, operators, CRDs...) |
| Cas d'usage idéal | Infra mixte, équipes réduites, multi-datacenter | Microservices à grande échelle, cloud-native |
| Découverte de services | Via Consul ou intégrée (Nomad natif) | DNS interne + Services natifs |
Architecture et concepts clés
Section intitulée « Architecture et concepts clés »Avant de passer à la pratique, voici les concepts fondamentaux de Nomad. Chacun a un rôle précis dans le cycle de vie de vos déploiements.
Les composants du cluster
Section intitulée « Les composants du cluster »Nomad est distribué sous la forme d'un seul binaire qui peut jouer deux rôles :
- Server (master) : prend les décisions de planification, maintient l'état du cluster. On en déploie 3 ou 5 pour la haute disponibilité en production.
- Client (worker) : exécute les tâches planifiées par les servers. Chaque client remonte ses ressources disponibles (CPU, mémoire, disque) au server.
Un même nœud peut être server et client à la fois, ce qui est pratique pour le développement ou les petits clusters.
La hiérarchie Job > Group > Task
Section intitulée « La hiérarchie Job > Group > Task »Tout fichier de job respecte trois niveaux d'imbrication, et chacun correspond à
une décision différente de Nomad. Le Job est ce que vous soumettez et ce que
vous versionnez. Le Group est l'unité de placement : c'est lui que le
planificateur pose sur un nœud, et c'est lui qu'on réplique avec count. La
Task est l'unité d'exécution, celle qu'un driver démarre réellement.
Confondre Group et Task conduit à l'erreur classique du count placé au mauvais
niveau.
Job (le déploiement complet)└── Group (ensemble de tâches co-localisées) ├── Task (une unité de travail) └── Task (une autre unité de travail)- Job : l'objet de plus haut niveau. Il définit ce que vous voulez déployer et où (datacenter, région). Un fichier de job est écrit en HCL (HashiCorp Configuration Language), le même langage que Terraform.
- Task Group : un ensemble de tâches qui doivent tourner sur le même nœud. Les tâches d'un même groupe partagent le réseau et le stockage. C'est l'équivalent d'un Pod dans Kubernetes.
- Task : la plus petite unité de travail. C'est ce qui s'exécute réellement : un conteneur Docker, un binaire, une commande.
Les types de jobs
Section intitulée « Les types de jobs »Le champ type du job décide du comportement du planificateur, en particulier
de ce qu'il fait quand la tâche se termine. Un service qui s'arrête est
considéré en panne et redémarré ; un batch qui s'arrête est considéré comme
réussi. Choisir le mauvais type produit donc soit une boucle de redémarrage, soit
un traitement qui ne se relance jamais.
| Type | Description | Exemple d'usage |
|---|---|---|
| service | Tourne en continu, redémarré automatiquement | Application web, API REST |
| batch | S'exécute une fois puis se termine | Migration de données, génération de rapport |
| system | Déployé sur chaque nœud du cluster | Collecteur de logs, agent de monitoring |
| sysbatch | Batch exécuté une fois sur chaque nœud | Mise à jour de configuration système |
Les task drivers
Section intitulée « Les task drivers »Un task driver (pilote de tâche) indique à Nomad comment exécuter une task. Nomad en intègre plusieurs nativement :
| Driver | Ce qu'il exécute |
|---|---|
| docker | Conteneurs Docker |
| exec | Binaires isolés (avec cgroups) |
| raw_exec | Binaires sans isolation |
| java | Applications Java (JARs) |
| qemu | Machines virtuelles QEMU |
| podman | Conteneurs via Podman (plugin) |
Évaluations et allocations
Section intitulée « Évaluations et allocations »Ces deux mots reviennent en permanence dans la sortie des commandes, et les confondre rend le dépannage impossible. Une évaluation est une décision en cours d'instruction ; une allocation est le résultat de cette décision, un groupe de tâches attribué à un nœud précis. Quand un déploiement ne démarre pas, c'est presque toujours l'évaluation qu'il faut inspecter, pas l'allocation, qui n'existe pas encore.
-
Évaluation : Nomad compare l'état souhaité (votre fichier de job) avec l'état actuel du cluster et décide ce qui doit changer.
-
Planification : le scheduler détermine sur quel nœud placer chaque groupe de tâches, en fonction des ressources disponibles et des contraintes.
-
Allocation : une allocation est la correspondance entre un groupe de tâches et un nœud client. C'est l'unité d'exécution concrète.
Prérequis
Section intitulée « Prérequis »Pour suivre ce guide, vous avez besoin de :
- Linux (Ubuntu 22.04+ ou équivalent)
- Docker installé et fonctionnel (
docker run hello-worlddoit fonctionner) - wget et unzip pour l'installation
- Droits sudo pour lancer Nomad en mode dev
Installer Nomad
Section intitulée « Installer Nomad »Nomad est distribué sous forme d'un binaire unique. Pas de dépendances, pas de base de données externe, pas de composants multiples à configurer.
cd /tmpwget https://releases.hashicorp.com/nomad/2.0.4/nomad_2.0.4_linux_amd64.zipunzip nomad_2.0.4_linux_amd64.zipsudo mv nomad /usr/local/bin/rm nomad_2.0.4_linux_amd64.zipwget -O- https://apt.releases.hashicorp.com/gpg | \ sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpgecho "deb [arch=$(dpkg --print-architecture) \ signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \ https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \ sudo tee /etc/apt/sources.list.d/hashicorp.listsudo apt update && sudo apt install nomadbrew tap hashicorp/tapbrew install hashicorp/tap/nomadVérification : la commande suivante doit afficher la version installée :
nomad --versionNomad v2.0.4BuildDate 2026-07-07T17:20:59ZRevision 5b83b133998a1f514beb81019930fb673b5ed669Démarrer un cluster de développement
Section intitulée « Démarrer un cluster de développement »Le mode dev lance un agent Nomad qui fait office de server et de client sur la même machine. C'est parfait pour apprendre et tester.
sudo nomad agent -dev -bind 0.0.0.0Ouvrez un second terminal pour interagir avec le cluster. Vérifiez que tout fonctionne :
nomad server membersName Address Port Status Leader Raft Version Build Datacenter Regionguide-ubuntu.lab.global 10.10.40.12 4648 alive true 3 2.0.4 dc1 global
==> View and manage Nomad servers in the Web UI: http://127.0.0.1:4646/ui/serversLa ligne de renvoi vers l'interface web est ajoutée par Nomad 2.x en fin de plusieurs commandes de lecture. Elle n'indique aucune anomalie, c'est un simple rappel de navigation.
nomad node statusID Node Pool DC Name Class Drain Eligibility Statusc47c98a8 default dc1 guide-ubuntu.lab <none> false eligible readyL'interface web est accessible sur http://localhost:4646. Elle offre une vue complète des jobs, des nœuds, de la topologie et des allocations.
Déployer un premier job de type service
Section intitulée « Déployer un premier job de type service »Un job de type service tourne en continu. Si le conteneur s'arrête, Nomad le redémarre automatiquement. C'est le type le plus courant, équivalent à un Deployment dans Kubernetes.
Créez le fichier webapp.nomad.hcl :
job "webapp" { datacenters = ["dc1"] type = "service"
group "web" { count = 2
network { port "http" { to = 80 } }
service { name = "webapp" port = "http" provider = "nomad"
check { type = "http" path = "/" interval = "10s" timeout = "2s" } }
task "nginx" { driver = "docker"
config { image = "nginx:1.31.3-alpine3.24@sha256:4a73073bd557c65b759505da037898b61f1be6cbcc3c2c3aeac22d2a470c1752" ports = ["http"] }
shutdown_delay = "5s"
resources { cpu = 100 memory = 128 } } }}Ce fichier déclare :
- Un job nommé
webappsur le datacenterdc1 - Un group
webavec 2 instances (count = 2) - Un port dynamique mappé vers le port 80 du conteneur
- Un service avec un health check HTTP toutes les 10 secondes
- Une task qui utilise le driver Docker avec une image
nginxépinglée par digest - Des limites de ressources : 100 MHz de CPU et 128 MB de RAM
Déployez le job :
nomad job run webapp.nomad.hcl==> View this job in the Web UI: http://127.0.0.1:4646/ui/jobs/webapp@default
==> 2026-07-23T16:45:46Z: Monitoring evaluation "67e37192" 2026-07-23T16:45:46Z: Evaluation triggered by job "webapp" 2026-07-23T16:45:46Z: Allocation "899a2588" created: node "c47c98a8", group "web" 2026-07-23T16:45:46Z: Allocation "fa6f3a29" created: node "c47c98a8", group "web" 2026-07-23T16:45:47Z: Evaluation within deployment: "c1218e39"==> Deployment "c1218e39" successful
Deployed Task Group Desired Placed Healthy Unhealthy Progress Deadline web 2 2 2 0 2026-07-23T16:54:45ZNomad 2.x horodate chaque ligne de suivi et ouvre la sortie par un lien vers
l'interface web. Sans le shutdown_delay posé plus haut, il ajoute aussi un
avertissement au lancement :
Job Warnings:1 warning:
* group "web" defines services, but neither the group nor any of its tasks have shutdown_delay setCe n'est pas une erreur, le job démarre quand même. Nomad signale qu'à l'arrêt
d'une allocation, il retirera le service du catalogue et tuera la tâche
simultanément : les requêtes déjà routées vers l'instance se termineront par
une erreur. Le shutdown_delay intercale un délai entre la sortie du catalogue
et l'arrêt réel, le temps que les clients cessent de viser cette instance. C'est
le réflexe à prendre sur tout job de type service exposé.
Vérification : consultez le statut du job et de ses allocations :
nomad job status webappID = webappName = webappSubmit Date = 2026-07-23T16:44:20ZType = servicePriority = 50Datacenters = dc1Namespace = defaultNode Pool = defaultStatus = runningPeriodic = falseParameterized = false
SummaryTask Group Queued Starting Running Failed Complete Lost Unknownweb 0 0 2 0 0 0 0Pour voir les logs d'une allocation, utilisez les 8 premiers caractères de l'ID d'allocation :
nomad alloc logs 35d6fd42Pour accéder à l'application, consultez le port dynamique attribué :
nomad service info webappJob ID Address Tags Node ID Alloc IDwebapp 127.0.0.1:29808 [] c47c98a8 e96417f6webapp 127.0.0.1:31941 [] c47c98a8 f9594de9Testez avec curl en utilisant l'un des ports affichés :
curl http://127.0.0.1:29808Déployer un job batch (tâche ponctuelle)
Section intitulée « Déployer un job batch (tâche ponctuelle) »Un job batch s'exécute une seule fois puis se termine. C'est l'équivalent d'un Job Kubernetes. Idéal pour les migrations, les exports ou les traitements ponctuels.
Créez le fichier batch-job.nomad.hcl :
job "batch-exemple" { datacenters = ["dc1"] type = "batch"
group "traitement" { count = 1
task "generer-rapport" { driver = "docker"
config { image = "alpine:3.24.1@sha256:fd791d74b68913cbb027c6546007b3f0d3bc45125f797758156952bc2d6daf40" command = "/bin/sh" args = [ "-c", "echo 'Début du traitement...' && sleep 3 && echo 'Rapport généré avec succès' && echo 'Lignes traitées : 1542'" ] }
resources { cpu = 100 memory = 64 } } }}nomad job run batch-job.nomad.hclRécupérez les logs une fois le job terminé en utilisant l'ID d'allocation affiché lors du déploiement :
nomad alloc logs <ALLOC_ID>Début du traitement...Rapport généré avec succèsLignes traitées : 1542Le statut du job passe à dead une fois terminé, ce qui est le comportement attendu pour un batch :
nomad job status batch-exempleStatus = dead
SummaryTask Group Queued Starting Running Failed Complete Lost Unknowntraitement 0 0 0 0 1 0 0
AllocationsID Node ID Task Group Version Desired Status Created Modifiedf5ba0f6c c47c98a8 traitement 0 run complete 13s ago 6s agoProgrammer des jobs périodiques (cron)
Section intitulée « Programmer des jobs périodiques (cron) »Nomad intègre nativement un scheduler cron via le bloc periodic. Plus
besoin de crontab système ou de CronJob Kubernetes.
job "sauvegarde" { datacenters = ["dc1"] type = "batch"
periodic { crons = ["*/5 * * * *"] prohibit_overlap = true }
group "backup" { count = 1
task "dump-db" { driver = "docker"
config { image = "alpine:3.24.1@sha256:fd791d74b68913cbb027c6546007b3f0d3bc45125f797758156952bc2d6daf40" command = "/bin/sh" args = [ "-c", "echo '[INFO] Sauvegarde démarrée' && sleep 2 && echo '[OK] Sauvegarde terminée - taille: 42MB'" ] }
resources { cpu = 100 memory = 64 } } }}crons: syntaxe cron standard, ici toutes les 5 minutesprohibit_overlap: empêche le lancement d'une nouvelle exécution si la précédente n'est pas terminée
nomad job run sauvegarde.nomad.hclJob registration successfulApproximate next launch time: 2026-03-04T06:55:00Z (2m49s from now)Déployer un job system (sur chaque nœud)
Section intitulée « Déployer un job system (sur chaque nœud) »Un job system s'exécute sur chaque nœud client du cluster. C'est l'équivalent d'un DaemonSet dans Kubernetes. Cas d'usage typique : collecteur de logs, agent de monitoring, antivirus.
job "collecteur-logs" { datacenters = ["dc1"] type = "system"
group "logging" {
task "fluentbit" { driver = "docker"
config { image = "alpine:3.24.1@sha256:fd791d74b68913cbb027c6546007b3f0d3bc45125f797758156952bc2d6daf40" command = "/bin/sh" args = [ "-c", "echo 'Collecteur de logs démarré' && while true; do echo '[LOG] Collecte en cours...'; sleep 60; done" ] }
resources { cpu = 50 memory = 32 } } }}Quand vous ajoutez un nouveau nœud au cluster, Nomad y déploie automatiquement le job system sans intervention manuelle.
Variables d'environnement et configuration
Section intitulée « Variables d'environnement et configuration »Nomad permet d'injecter des variables d'environnement dans vos tâches via
le bloc env. Chaque variable est accessible par le processus lancé dans le
conteneur.
job "app-config" { datacenters = ["dc1"] type = "service"
group "api" { count = 1
network { port "http" { to = 8080 } }
task "api-server" { driver = "docker"
config { image = "hashicorp/http-echo" ports = ["http"] args = [ "-listen", ":8080", "-text", "API v1.2.0 - production" ] }
env { APP_ENV = "production" APP_VERSION = "1.2.0" LOG_LEVEL = "info" }
resources { cpu = 100 memory = 64 } } }}Utiliser les templates pour générer des fichiers
Section intitulée « Utiliser les templates pour générer des fichiers »Le système de templates de Nomad permet de générer des fichiers de configuration à la volée, en injectant des variables d'environnement Nomad. Les templates utilisent la syntaxe Go template (identique à Consul Template).
job "app-template" { datacenters = ["dc1"] type = "service"
group "web" { count = 1
network { port "http" { to = 80 } }
task "nginx" { driver = "docker"
config { image = "nginx:1.31.3-alpine3.24@sha256:4a73073bd557c65b759505da037898b61f1be6cbcc3c2c3aeac22d2a470c1752" ports = ["http"] volumes = [ "local/default.conf:/etc/nginx/conf.d/default.conf" ] }
template { data = <<-TPL server { listen 80; server_name _; location / { return 200 'App: {{ env "NOMAD_JOB_NAME" }}\nAllocation: {{ env "NOMAD_ALLOC_ID" }}\n'; add_header Content-Type text/plain; } location /health { return 200 'OK'; add_header Content-Type text/plain; } } TPL destination = "local/default.conf" change_mode = "restart" }
resources { cpu = 100 memory = 64 } } }}Le template génère une configuration Nginx personnalisée. La directive
change_mode = "restart" redémarre la task si le template change (par
exemple lors d'une mise à jour de variable).
Vérification : inspectez le fichier généré dans le conteneur :
nomad alloc exec <ALLOC_ID> cat /etc/nginx/conf.d/default.confserver { listen 80; server_name _; location / { return 200 'App: app-templateAllocation: 4a0699d1-3cba-7b6c-42a9-7d2c342cdb94'; add_header Content-Type text/plain; } location /health { return 200 'OK'; add_header Content-Type text/plain; }}Les variables NOMAD_JOB_NAME et NOMAD_ALLOC_ID ont été remplacées par
leurs valeurs réelles.
Configurer les rolling updates
Section intitulée « Configurer les rolling updates »Nomad gère nativement les mises à jour progressives (rolling updates)
via le bloc update. Cette stratégie permet de déployer une nouvelle version
sans interruption de service.
job "webapp" { datacenters = ["dc1"] type = "service"
update { max_parallel = 1 min_healthy_time = "10s" healthy_deadline = "3m" auto_revert = true }
group "web" { count = 3
network { port "http" { to = 80 } }
service { name = "webapp" port = "http" provider = "nomad"
check { type = "http" path = "/" interval = "10s" timeout = "2s" } }
task "nginx" { driver = "docker"
config { image = "nginx:1.31.3-alpine3.24@sha256:4a73073bd557c65b759505da037898b61f1be6cbcc3c2c3aeac22d2a470c1752" ports = ["http"] }
resources { cpu = 100 memory = 128 } } }}Les paramètres du bloc update :
| Paramètre | Rôle |
|---|---|
max_parallel | Nombre d'instances mises à jour simultanément |
min_healthy_time | Durée minimale pendant laquelle la nouvelle instance doit être saine |
healthy_deadline | Délai maximum pour qu'une instance devienne saine |
auto_revert | Revient automatiquement à la version précédente en cas d'échec |
Prévisualiser les changements avec plan
Section intitulée « Prévisualiser les changements avec plan »Avant d'appliquer une mise à jour, utilisez nomad job plan pour
visualiser les changements sans les appliquer (comme un terraform plan) :
nomad job plan webapp-v2.nomad.hcl+/- Job: "webapp"+/- Task Group: "web" (2 create, 3 ignore) +/- Count: "3" => "5" (forces create) +/- Task: "nginx" (forces create/destroy update) +/- Resources { +/- CPU: "100" => "200" +/- MemoryMB: "128" => "256" }
Scheduler dry-run:- All tasks successfully allocated.Nomad montre clairement les changements : nombre d'instances, ressources
CPU, mémoire. Si le résultat est conforme, appliquez avec nomad job run.
Les commandes CLI essentielles
Section intitulée « Les commandes CLI essentielles »Toute la CLI Nomad suit le même schéma : nomad <objet> <action>, où l'objet est
server, node, job, alloc ou service. Connaître ces cinq objets suffit à
deviner la commande sans consulter l'aide. Les sections ci-dessous les
parcourent dans l'ordre où vous en aurez besoin, du diagnostic du cluster
jusqu'au nettoyage.
Gestion du cluster
Section intitulée « Gestion du cluster »Ces commandes répondent à la question préalable à tout dépannage : le cluster
est-il en état de recevoir un job ? nomad server members doit montrer un
leader élu, et nomad node status au moins un nœud ready et eligible.
# Vérifier les serveurs du clusternomad server members
# Voir les nœuds clients et leur étatnomad node status
# Informations détaillées sur le clusternomad agent-info
# Installer l'autocomplétion (bash/zsh)nomad -autocomplete-installGestion des jobs
Section intitulée « Gestion des jobs »L'enchaînement validate, plan, run évite la majorité des déploiements
ratés : le premier contrôle la syntaxe HCL, le second simule le placement.
Attention à la dernière commande de la liste : nomad job stop conserve
l'historique et permet de relancer la même version, alors que l'option
-purge efface le job et ses versions sans confirmation.
# Valider la syntaxe d'un fichier de jobnomad job validate webapp.nomad.hcl
# Prévisualiser les changements (dry-run)nomad job plan webapp.nomad.hcl
# Déployer ou mettre à jour un jobnomad job run webapp.nomad.hcl
# Voir le statut d'un jobnomad job status webapp
# Lister tous les jobsnomad job status
# Voir l'historique des versions d'un jobnomad job history webapp
# Inspecter un job au format JSONnomad job inspect webapp
# Arrêter un job (conserve l'historique)nomad job stop webapp
# Arrêter et purger un job (supprime tout)nomad job stop -purge webappGestion des allocations
Section intitulée « Gestion des allocations »C'est au niveau de l'allocation que se trouvent les logs et le système de fichiers d'une tâche, pas au niveau du job. Toutes ces commandes acceptent le préfixe de l'identifiant, les huit premiers caractères suffisent tant qu'ils restent uniques.
# Voir les allocations d'un jobnomad job allocs webapp
# Consulter les logs d'une allocationnomad alloc logs <ALLOC_ID>
# Exécuter une commande dans un conteneurnomad alloc exec <ALLOC_ID> /bin/sh
# Récupérer des fichiers d'une allocationnomad alloc fs <ALLOC_ID> /alloc/logs/Gestion des services
Section intitulée « Gestion des services »Ces deux commandes n'affichent que les services déclarés avec
provider = "nomad", le registre interne utilisé dans les exemples de ce guide.
Si vos jobs s'enregistrent dans Consul, les instances se consultent côté
Consul et n'apparaissent pas ici.
# Lister les services enregistrésnomad service list
# Voir les instances d'un servicenomad service info webappNettoyage
Section intitulée « Nettoyage »Nomad conserve un temps les jobs arrêtés et les allocations terminées pour que
vous puissiez encore consulter leurs logs. nomad system gc force ce ménage
immédiatement, ce qui rend les journaux concernés définitivement
inaccessibles.
# Nettoyer les ressources orphelinesnomad system gcConfiguration d'un cluster de production
Section intitulée « Configuration d'un cluster de production »En mode dev, tout tourne sur un seul nœud. En production, vous séparez les rôles server et client.
Configuration du server (master)
Section intitulée « Configuration du server (master) »Ce fichier remplace les options passées en ligne de commande avec -dev. Le
répertoire data_dir est ici persistant : il contient le journal Raft, donc
l'état du cluster survit à un redémarrage, ce que le mode dev ne permettait pas.
data_dir = "/opt/nomad/data"datacenter = "dc1"
server { enabled = true bootstrap_expect = 3}Le paramètre bootstrap_expect indique le nombre de servers attendus avant
de démarrer l'élection du leader. Utilisez 3 ou 5 pour la haute
disponibilité.
Configuration du client (worker)
Section intitulée « Configuration du client (worker) »Le bloc client remplace le bloc server : un nœud de production n'endosse
généralement qu'un rôle. La liste servers est le seul point de contact avec
le cluster, et un client qui ne joint aucun de ces serveurs n'apparaît jamais
dans nomad node status.
data_dir = "/opt/nomad/data"datacenter = "dc1"
client { enabled = true servers = ["10.240.0.10", "10.240.0.11", "10.240.0.12"]}Le client doit connaître les adresses des servers pour s'y connecter.
Dépannage
Section intitulée « Dépannage »La plupart des blocages se lisent dans la sortie de nomad job status, qui
affiche l'évaluation en cause et la raison du non-placement. Réflexe utile avant
de parcourir le tableau : vérifiez que le leader est élu et qu'au moins un
nœud est eligible, car ces deux conditions expliquent à elles seules une
allocation qui reste en attente.
| Symptôme | Cause probable | Solution |
|---|---|---|
No cluster leader | Un seul server en mode non-dev | Lancez le nombre de servers indiqué dans bootstrap_expect |
Allocation pending | Ressources insuffisantes sur les clients | Vérifiez nomad node status -verbose et réduisez les resources |
Driver docker not found | Docker non installé ou non démarré | Installez Docker et vérifiez avec docker info |
Eval blocked | Aucun nœud ne satisfait les contraintes | Vérifiez le datacenter, le node pool et les ressources demandées |
Unhealthy allocation | Le health check échoue | Vérifiez que l'application est bien sur le bon port et que le path du check est correct |
Job submission error | Syntaxe HCL invalide | Validez avec nomad job validate fichier.nomad.hcl |
Permission denied | Droits insuffisants | Exécutez Nomad avec sudo ou configurez les permissions Docker |
À retenir
Section intitulée « À retenir »- Nomad est un seul binaire qui orchestre conteneurs, binaires, VMs et batchs sans la complexité de Kubernetes.
- La hiérarchie Job > Group > Task organise vos workloads. Un Group est l'équivalent d'un Pod Kubernetes.
- Les quatre types de jobs couvrent tous les cas : service (continu), batch (ponctuel), system (chaque nœud), periodic (cron).
- Le bloc
updateavecauto_revertassure des mises à jour progressives sans interruption. nomad job planvous montre les changements avant de les appliquer, exactement commeterraform plan.- Les templates génèrent des fichiers de configuration dynamiques en injectant les variables d'environnement Nomad.
- Nomad s'intègre naturellement avec Consul (découverte de services) et Vault (secrets), mais fonctionne parfaitement seul pour démarrer.
FAQ : questions fréquentes sur Nomad
Section intitulée « FAQ : questions fréquentes sur Nomad »Ces réponses courtes traitent les questions qui décident souvent de l'adoption de Nomad : son positionnement face à Kubernetes et Docker Swarm, sa gratuité et son mode d'installation. Elles complètent le guide sans le répéter.
Ce qu'il orchestre
Contrairement à Kubernetes centré sur les conteneurs, Nomad délègue l'exécution à des task drivers interchangeables :| Driver | Ce qu'il exécute |
|---|---|
| docker | Conteneurs Docker |
| exec | Binaires isolés (cgroups) |
| java | Applications Java (JAR) |
| qemu | Machines virtuelles |
Points forts
- Installation simple : un binaire, opérationnel en minutes.
- Workloads variés : conteneurs, binaires, VMs, batchs.
- Multi-datacenter natif.
nomad agent -dev.| Critère | Nomad | Kubernetes |
|---|---|---|
| Installation | Un binaire, minutes | Plusieurs composants |
| Workloads | Conteneurs, binaires, VMs, batchs | Surtout conteneurs |
| Courbe d'apprentissage | Douce (HCL) | Raide (YAML) |
| Écosystème | Restreint | Très vaste (Helm, opérateurs) |
Choisir Nomad
- Workloads hétérogènes (pas uniquement des conteneurs).
- Petite équipe DevOps.
- Besoin multi-datacenter simple à opérer.
Choisir Kubernetes
- Microservices à grande échelle.
- Besoin de l'écosystème cloud-native (opérateurs, CRD, service mesh).
Point de licence
Depuis août 2023, le code source de Nomad est sous Business Source License (BUSL-1.1) au lieu de la MPL 2.0. L'usage libre reste autorisé pour la quasi-totalité des cas ; seule la revente d'une offre concurrente est restreinte.CE ou Enterprise
| Nomad CE (gratuit) | Nomad Enterprise (payant) | |
|---|---|---|
| Orchestration complète | Oui | Oui |
| Multi-datacenter | Oui | Oui |
| Gouvernance multi-cluster | Non | Oui |
| Espaces de noms avancés, Sentinel | Non | Oui |
| Support commercial | Non | Oui |
Dépôt APT (Debian/Ubuntu)
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install nomad
Vérification
nomad --version
# Nomad v2.0.4
Cluster de test
sudo nomad agent -dev -bind 0.0.0.0
Le mode -dev lance un agent qui fait à la fois server et client. Il stocke tout en mémoire : à réserver à l'apprentissage, jamais à la production.type du job décide du comportement du planificateur.| Type | Comportement | Équivalent Kubernetes |
|---|---|---|
| service | Tourne en continu, redémarré si arrêt | Deployment |
| batch | S'exécute une fois puis se termine | Job |
| system | Déployé sur chaque nœud client | DaemonSet |
| periodic | Planifié via une expression cron | CronJob |
Piège classique
Un service qui s'arrête est considéré en panne et redémarré ; un batch qui s'arrête est considéré réussi. Choisir le mauvais type produit soit une boucle de redémarrage, soit un traitement qui ne se relance jamais.job "webapp" {
type = "service"
# ...
}
Job (le déploiement complet)
└── Group (tâches co-localisées sur un nœud)
├── Task (une unité d'exécution)
└── Task (une autre)
| Niveau | Rôle | Équivalent |
|---|---|---|
| Job | Ce que vous soumettez et versionnez | - |
| Group | Unité de placement, répliquée par count |
Pod Kubernetes |
| Task | Unité d'exécution réelle (driver) | Conteneur |
count. La Task est ce qu'un driver démarre réellement. Confondre les deux conduit à l'erreur classique du count placé au mauvais niveau.| Critère | Nomad | Docker Swarm |
|---|---|---|
| Workloads | Conteneurs, binaires, VMs, batchs | Conteneurs Docker seulement |
| Multi-datacenter | Natif | Limité |
| Écosystème | Consul, Vault | Intégré à Docker |
| Types de jobs | service, batch, system, periodic | services et tâches |
| Échelle | Milliers de nœuds | Petits à moyens clusters |
Découverte de services native
Depuis Nomad 1.3, un registre de services est intégré. Il suffit de déclarerprovider = "nomad" dans le bloc service :service {
name = "webapp"
port = "http"
provider = "nomad"
}
Vous consultez ensuite les instances avec nomad service list et nomad service info webapp.Quand ajouter Consul ?
Consul reste recommandé en production pour :- la découverte distribuée entre plusieurs clusters,
- les health checks partagés,
- le service mesh (mTLS entre services).