Jeedom avec Nomad

Bonjour :wave:

Je me permets de poster ce message à but informatif. Je passe sur une partie des explications techniques car je pars du principe que le lecteur à des connaissances dans le devops, mais des gens curieux peuvent poser des questions si quelque chose n’est pas clair.

J’utilise Nomad et ses potos Consul et Vault pour mes besoins professionnels. Et aussi pour mon petit homelab fait avec amour. J’appelle cette ensemble de logiciel une Hashistack qui est une Stack de logiciel de Hashicorp l’entreprise qui produit ces logiciels.

Nomad, c’est un orchestrateur au même titre que Kubernetes.

Et donc depuis quelques jours, j’ai cherché à mettre Jeedom en version Docker sous gestion de Nomad (on lui passe un job, c’est le terme pour dire fichier de définition).

J’ai été confronté à quelques difficultés, sinon ce n’est pas marrant! :sweat_smile:

Les principales étant:

  • Avoir le Docker sur le réseau LAN de chez moi, (192.168.10.0/24) et non le bridge Docker
  • Utiliser Traefik comme reverse proxy (jeedom.service.lan)

Je suis passé par diverses options jusqu’à arriver à cette configuration, qui me satisfait. Car je voulais que le Traefik qui est sur le host puisse communiquer avec le docker de Jeedom, avec le macvlan, ce n’est pas possible.

Sur le host où se trouve la hashistack il est nécessaire de mettre en place un bridge. J’utilise Ubuntu 22.04 et donc gère le réseau avec netplan.

Voici le fichier netplan
root@hashistack: cat /etc/netplan/50-cloud-init.yaml

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: false

    bridges:
      br-root:
        addresses: [ 192.168.10.12/24 ]
        routes:
          - to: default
            via: 192.168.10.1
        mtu: 1500
        nameservers:
            addresses: [192.168.10.1]
        interfaces:
          - eth0

Un petit netplan try et il est content pépère Ubuntu, aller hop!

Maintenant le CNI qui est nécessaire à Nomad pour gérer les réseaux des containers. Donc dans le répertoire par défaut de configuration de CNI /opt/cni/config j’ai créé ce fichier:

cat /opt/cni/config/jeedom.conflist

{
  "cniVersion": "1.0.0",
  "name": "jeedom",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "br-root",
      "ipam": {
          "type": "static",
          "addresses": [
              {
                  "address": "192.168.10.20/24",
                  "gateway": "192.168.10.1"
              }
          ],
          "routes": [
              {
                  "dst": "0.0.0.0/0"
              }
          ],
          "dns": {
                  "nameservers": ["192.168.10.1"]
          }
        }
    }
  ]
}

Donc dans ce fichier, j’indique tout simplement de devoir se connecter au bridge br-root et je lui mets une IP statique, car c’est comme cela et pas autrement, non mais! Jeedom, tu n’as pas le droit de changer!

Il faut penser à recharger Nomad pour que la configuration soit prise en compte.

Et finalement, le fichier job Nomad pour faire démarrer notre Jentee Jeedom:
(je précise qu’il s’agit d’un fichier minimal, il y a tellement d’options possibles)

cat jeedom.service.lan.hcl

job "jeedom.service.lan" {
  region = "global"
  datacenters = ["dc1"]
  type = "service"

  node_pool = "default"
  priority = 50
  all_at_once = false
  namespace = "default"

   update {
     max_parallel     = 1
     canary           = 1
     min_healthy_time = "10s"
     healthy_deadline = "5m"
     auto_revert      = true
     auto_promote     = true
     health_check     = "checks"
     stagger          = "30s"
   }

  group "jeedom" {

    count = 1

    restart {
      attempts = 10
      interval = "5m"
      delay = "10s"
      mode = "delay"
    }

    network {
      mode = "cni/jeedom"
    }

    service {
      name = "jeedom-service-lan-group-01"

      port = "80"

      address = "192.168.10.20"

      tags = [
        "traefik.enable=true",
        "traefik.consulcatalog.connect=false",
        "traefik.http.routers.jeedomservicelan.entrypoints=http",
        "traefik.http.routers.jeedomservicelan.rule=Host(`jeedom.service.lan`)",
        "traefik.http.routers.jeedomservicelan.service=jeedom-service-lan-group-01"
      ]
    }

    task "jeedom" {
      driver = "docker"

      config {
        image = "jeedom/jeedom:latest"

        privileged = true

        devices = [
          {
            host_path = "/dev/ttyUSB0"
            container_path = "/dev/ttyUSB0"
          }
        ]

        mount {
          type = "bind"
          target = "/var/www/html"
          source = "/data/jeedom.service.lan/data/var/www/html"
          readonly = false
          bind_options {
            propagation = "rshared"
          }
        }

        mount {
          type = "bind"
          target = "/var/lib/mysql"
          source = "/data/jeedom.service.lan/data/var/lib/mysql"
          readonly = false
          bind_options {
            propagation = "rshared"
          }
        }
      }

      resources {
        cpu    = 2048
        memory = 2048
      }
    }
  }
}

La structure d’un fichier Nomad pour résumer:
Conf Générale > Group > Network / Service / Tasks

Dans Network on indique donc le fichier CNI créé précédemment.
Dans Service, on indique des tags à passer à Traefik pour lui donner l’IP/Port et DNS à proxifier.
Dans Tasks, c’est le plus proche d’un docker-compose, on indique les appareils à connecter au docker, dans mon cas, la clé 4G USB pour les SMS. Les répertoires à monter pour avoir les données persistantes et finalement les ressources à affecter à ce container.

Un petit nomad run jeedom.service.lan.hcl dans le terminal (connecté en SSH sur le serveur) ou coller le contenu du job dans l’interface web de Nomad et ça va démarrer tranquillou!

Quelques secondes après, votre Jeedom sera joignable sur l’ip (avec le fichier d’exemple que j’ai donné): 192.168.10.20 ou par URL http://jeedom.service.lan .

Pour ma part, j’ai migré ma VM Jeedom vers ce Docker sous Nomad. Après quelques minutes, des réinstallations de dépendances, tout à bien redémarré, des petites corrections d’historiques dû à la coupure et c’est reparti!

J’utilise le plugin aTV Remote qui fonctionne ce qui était un problème si le docker n’avait pas été sur le LAN de chez moi. J’imagine que c’est pareil pour des plugin comme homebridge etc.

Pour informations complémentaires. J’utilise zigbee2mqtt et mosquitto aussi sous format job Nomad depuis quelques mois. Je conçois sous le format services indépendants pour l’exploitation.

J’imagine que l’on ne doit pas être vraiment beaucoup à utiliser Nomad, mais si cela peut aider des « collègues » à zapper quelques heures de recherches pour se concentrer sur Jeedom, c’est avec plaisir! :slightly_smiling_face:

Pour d’autres personnes qui ne connaissent pas Nomad, c’est bien sympa! Si vous avez envie de découvrir cette suite de logiciels (Nomad, Consul, Vault), j’ai créé une collection Ansible d’installation à récupérer sur mon GitHub.

Bon geekage!
Merci

Aller, petit EDIT avec des captures d’écrans de l’interface web de Nomad.

La liste de mes jobs qui tournent:

Et le job Jeedom:

2 « J'aime »

Salut,

Je connais (+/-) consul & vault, je ne connaissais pas nomad, maintenant j’en ai une vague idée.
Je n’utiliserai pas mais merci pour le retour d’expérience;

une question en fait: vault te sert à quoi dans le cas d’utilisation avec jeedom?

En l’occurrence, Vault ne me sert pas pour Jeedom.

Il aurait une fonction si on pouvait « preseed » le compte admin de Jeedom. Ca serait super, comme cela, en variables d’environnement de Docker utilisateur et mot de passe, qui serait des templates allant chercher dans Vault.

Par exemple avec Nomad associé à Vault pour Jeedom, cela pourrait rendre ressembler à ce fichier job:

      template {
        data = <<EOH
ANSIBLE_FORCE_COLOR=TRUE

{{ with secret "kv/data/jeedom" }}
ADMIN_LOGIN={{ .Data.data.admin_login }}
ADMIN_PASSWORD={{ .Data.data.admin_password }}
{{ end }}

EOH
        destination = "secrets/file_group_01.env"
        env         = true
      }

D’ailleurs j’ai hâte de voir arriver la version en 2 services de Jeedom, séparer MariaDB de Jeedom.

Où puis-je faire des suggestions pour le Docker Jeedom? Github?

Merci

ok c’est bien ce que j’avais en tête, je voulais juste être sur.

github semble un bon début