Table des matières
Nomad Orchestrateur
Personnellement, j'ai choisi Nomad pour gérer les conteneurs sur mon Homelab. Il me permets une gestion simple et centralisée des conteneurs et processus.
Présentation
Site officiel: https://www.nomadproject.io/
Un orchestateur simple et flexible pour déployer et gérer des conteneurs et des binaires sur un cluster on-prem ou dans le cloud, à l'échelle.
Gratuit, Automanagé, Autohebergé et Opensource !
Parfait pour la gestiuon de Conteneurs (Docker & Podman), Processus, Fichiers Jar, VM Qemu, Conteneurs LXC, …
Se reporter à la documentation pour la liste complète des éxécuteurs supportés : https://developer.hashicorp.com/nomad/docs/drivers
Installation
Dans cette installation pas-a-pas, nous serons sous Ubuntu. Cette procédure peut-etre dérivé pour Debian ou autres systèmes Linux.
Note : Lors de mon installation, seul Docker était supporté. Podman est maintenant compatible mais pas encore complètement intégré : https://developer.hashicorp.com/nomad/plugins/drivers/podman
Commencons par l'installation des différents pré-requis pour Docker et Nomad.
sudo apt-get update sudo apt-get install software-properties-common curl ca-certificates curl gnupg lsb-release
Maintenant, importer le repository des binaires Nomad.
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
Ensuite, nous pouvons installer les packages Nomad.
sudo apt-get update && sudo apt-get install nomad
Ajouter le Repository Docker.
sudo mkdir -m 0755 -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Et installer les packages pour Docker.
sudo apt-get update && sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Activer les services pour démarrage automatique.
sudo systemctl enable nomad && sudo systemctl enable docker
Dernière étape, redémarrer le service Nomad pour découverte des services Docker.
sudo systemctl restart nomad
Vous pouvez ensuite accéder à l'interface web de gestion du cluster Nomad sur le port 4646 de la machine: http://127.0.0.1:4646/
Interface Administration
Configuration
L'emplacement du fichier principal de configuration est le suivant : '/etc/nomad.d/nomad.hcl'
Voici pour exemple mon fichier de configuration:
data_dir = "/opt/nomad/data" bind_addr = "192.168.1.101" datacenter = "home" # Nom du Datacenter region = "fr" # Code Regional du datacenter name = "nomad-main" # Nom du serveur server { # Définit l'instance comme gestionnaire du cluster, avec interface web et API enabled = true bootstrap_expect = 1 } client { # Définit l'instance comme Runner, autorisé à éxécuter des jobs enabled = true servers = ["127.0.0.1"] network_interface = "enp0s25" # Déclarer les interfaces réseaux ici meta { # Attributs customisées pour ciblage des jobs usage = "LAN" specific = "MAIN" } } plugin "docker" { config { # options Docker allow_privileged = true volumes { enabled = true } } } plugin "raw_exec" { config { enabled = true # Activation du raw_exec sur l'hôte } }
Vous pouvez égalementy vous reporter à la documentation sur la configuration : https://www.nomadproject.io/docs/configuration
Ne pas oublier de redémarrer le service Nomad après modification pour prise en compte.
Utilisation
A titre d'exemple, nous allons lancer un conteneur 'uptime-kuma' sur le port 8080 de l'hôte sans volume persistant.
Première étape, cliquer sur le bouton 'Run Job' en haut de l'interface web de votre cluster Nomad.
Bouton Run job sur interface web Nomad
Puis, coller le job suivant:
job "Monitoring" { region = "fr" datacenters = ["home"] type = "service" group "uptime-service" { count = 1 network { port "web" { static = 8080 to = 3001 } } restart { attempts = 5 delay = "1m" } task "uptimekuma" { driver = "docker" config { image = "louislam/uptime-kuma:alpine" ports = ["web"] } resources { cpu = 50 memory = 128 } } } }
En bas de la page, cliquer sur 'Plan', puis sur 'Run'.
Le job va se déclencher, vous pouvez ensuite accéder au service via le port 8080 : http://127.0.0.1:8080
Optimisation: Memory Oversubscription
Pour activer l'autorisation de dépassement mémoire, il faut déjà installer JQ.
sudo apt-get install jq
Ensuite, vous pouvez-vérifier le status du 'MemoryOversubscriptionEnabled' dans la confiuguration du scheduler Nomad :
curl -s http://127.0.0.1:4646/v1/operator/scheduler/configuration | jq . { "SchedulerConfig": { "SchedulerAlgorithm": "binpack", "PreemptionConfig": { "SystemSchedulerEnabled": true, "SysBatchSchedulerEnabled": false, "BatchSchedulerEnabled": false, "ServiceSchedulerEnabled": false }, "**MemoryOversubscriptionEnabled**": false, "RejectJobRegistration": false, "PauseEvalBroker": false, "CreateIndex": 5, "ModifyIndex": 5 }, "Index": 5, "LastContact": 0, "KnownLeader": true, "NextToken": "" }
Vouc pouvez l'activer avec la commande suivante:
curl -s http://127.0.0.1:4646/v1/operator/scheduler/configuration | \ jq '.SchedulerConfig | .MemoryOversubscriptionEnabled=true' | \ curl -X PUT http://127.0.0.1:4646/v1/operator/scheduler/configuration -d @-
Modèles de jobs
Voici quelques exemples de jobs pour référence.
Site Web Wordpress
Dans cet exemple, l'éxécution de Wordpress avec une base de données MariaDB, exposant sur le port 8080. Les ressources mémoire allouées sont limités avec une autorisation de dépassement pour le serveur SQL
job "Wordpress" { region = "fr" datacenters = ["home"] type = "service" constraint { # Restricted to run on a specific host group with label 'usage = LAN' attribute = "${meta.usage}" value = "LAN" } group "wordpress-service" { count = 1 network { port "frontend" { static = 8080 to = 80 } port "backend" { to = 3306 } } restart { attempts = 5 delay = "1m" } task "web-front" { driver = "docker" config { image = "wordpress:latest" ports = ["frontend"] volumes = [ # Use a custom folder here into host "/application-data/wordpress-data:/var/www/html" ] } env { WORDPRESS_DB_HOST = "${NOMAD_IP_backend}:${NOMAD_HOST_PORT_backend}" WORDPRESS_DB_USER = "user" WORDPRESS_DB_PASSWORD = "password" WORDPRESS_DB_NAME = "wordpress" } resources { cpu = 500 memory = 512 } } task "web-db" { driver = "docker" config { image = "mariadb:10.11" ports = ["backend"] volumes = [ "/application-data/wordpress-db:/var/lib/mysql" ] } user = 1000 env { MYSQL_ROOT_PASSWORD = "rootpassword" MYSQL_USER = "user" MYSQL_PASSWORD = "password" MYSQL_DATABASE = "wordpress" } resources { cpu = 300 memory = 256 } } } }
Batch et Prestart
Dans cet exemple, nous avons plusieurs points intéressants, le type Batch, le raw exec et le prestart.
L'objectif principal est le lancement d'un binaire sur l'hôte avec du 'raw exec'. Le job permets ainsi l'éxécution d'une commande sur l'hôte et lis le code retour ainsi que les sorties.
Le mode 'Batch' permets un lancement périodique de la commande.
La fonction de 'prestart' permets l'éxécution d'une tâche avant le processus principal. Par exemple ici, la copie d'un fichier.
job "DHCP" { region = "fr" datacenters = ["home"] type = "batch" priority = 90 periodic { // Launch every 24 hours cron = "@daily" // Do not allow overlapping runs. prohibit_overlap = true } group "dhcp-service" { count = 1 constraint { # Restricted to run on a specific host with label 'specific = MAIN' attribute = "${meta.specific}" value = "MAIN" } restart { attempts = 10 delay = "1m" } task "dhcpd-restart" { driver = "raw_exec" config { command = "systemctl" args = [ "restart", "isc-dhcp-server" ] } } # Prestart task partially updating conf task "dhcpd-conf" { lifecycle { hook = "prestart" sidecar = false } driver = "docker" config { image = "alpine:latest" command = "cp" args = [ "/tmpsource/dhcpd.conf", "/tmpdest/dhcpd.conf" ] volumes = [ "/etc/dhcp:/tmpdest" ] mounts = [ { type = "bind" source = "local/conf/dhcpd.conf" target = "/tmpsource/dhcpd.conf" } ] } template { data = <<EOH default-lease-time 86400; # Bail de 24H max-lease-time 172800; # Bail maxi de 48H # Déclaration d'un réseau subnet 192.168.1.0 netmask 255.255.255.0 { pool { range 192.168.1.100 192.168.1.199; allow unknown-clients; } # Plage IP option domain-name-servers 192.168.1.1; # DNS option domain-name "potatokingdom.fr"; # Domain option routers 192.168.1.1; # Passerelle } EOH destination = "local/conf/dhcpd.conf" env = false change_mode = "signal" change_signal = "SIGUSR2" } resources { cpu = 100 memory = 128 } } } }
Sources externes
Documentation officielle Nomad: https://developer.hashicorp.com/nomad/docs/install
Documentation officielle Docker: https://docs.docker.com/engine/install/ubuntu