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.
Pensez à Nomad comme un chef d’orchestre polyvalent : au lieu de ne diriger que les violons (les conteneurs), il dirige l’orchestre entier — cuivres, bois, percussions et tout le reste.
Nomad vs Kubernetes : quand choisir quoi ?
Section intitulée « Nomad vs Kubernetes : quand choisir quoi ? »| 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 »Les workloads dans Nomad suivent une hiérarchie simple :
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 »| 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 »Quand vous soumettez un job, Nomad suit ce processus :
-
É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/1.11.2/nomad_1.11.2_linux_amd64.zipunzip nomad_1.11.2_linux_amd64.zipsudo mv nomad /usr/local/bin/rm nomad_1.11.2_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 v1.11.2BuildDate 2026-02-11T19:01:47ZDé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 Regionmaster1.global 192.168.20.103 4648 alive true 3 1.11.2 dc1 globalnomad node statusID Node Pool DC Name Class Drain Eligibility Status851cb730 default dc1 master1 <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:alpine" ports = ["http"] }
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 l’image
nginx:alpine - Des limites de ressources : 100 MHz de CPU et 128 MB de RAM
Déployez le job :
nomad job run webapp.nomad.hcl==> Monitoring evaluation "eac314ee" Evaluation triggered by job "webapp" Allocation "5847c171" created: node "851cb730", group "web" Allocation "35d6fd42" created: node "851cb730", group "web" Evaluation status changed: "pending" -> "complete"==> Evaluation "eac314ee" finished with status "complete"==> Monitoring deployment "11f3d442" ✓ Deployment "11f3d442" successful
Deployed Task Group Desired Placed Healthy Unhealthy Progress Deadline web 2 2 2 0 2026-03-04T07:59:08+01:00Vérification : consultez le statut du job et de ses allocations :
nomad job status webappID = webappName = webappType = serviceStatus = running
SummaryTask Group Queued Starting Running Failed Complete Lost Unknownweb 0 0 2 0 0 0 0
AllocationsID Node ID Task Group Version Desired Status Created Modified35d6fd42 851cb730 web 0 run running 1m41s ago 1m25s ago5847c171 851cb730 web 0 run running 1m41s ago 1m25s agoPour 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:31918 [] 851cb730 35d6fd42webapp 127.0.0.1:29580 [] 851cb730 493bee81Testez avec curl en utilisant l’un des ports affichés :
curl http://127.0.0.1:31918Dé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.19" 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 Modified286eeb2e 851cb730 traitement 0 run complete 17s ago 13s 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.19" 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.19" 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:alpine" 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:alpine" 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 »Voici les commandes que vous utiliserez au quotidien pour opérer un cluster Nomad :
Gestion du cluster
Section intitulée « Gestion du cluster »# 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 »# 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 »# 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 »# Lister les services enregistrésnomad service list
# Voir les instances d'un servicenomad service info webappNettoyage
Section intitulée « Nettoyage »# 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) »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) »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 »| 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.