Configuration d'un cluster Nomad avec Consul et intégration avec GitLab

Introduction

Dernièrement, la popularité de Kubernetes augmente rapidement : de plus en plus de projets l'implémentent. Je souhaitais aborder l'orchestrateur Nomad : il est parfaitement adapté aux projets utilisant déjà d'autres solutions de HashiCorp, comme Vault et Consul, surtout si ces projets ne sont pas complexes en termes d'infrastructure. Ce document contient un guide d'installation de Nomad, l'union de deux nœuds en cluster, ainsi que l'intégration de Nomad avec Gitlab.

Configuration d'un cluster Nomad avec Consul et intégration avec GitLab

Stand de test

Un peu sur l'environnement de test : trois serveurs virtuels avec des caractéristiques de 2 CPU, 4 RAM, 50 Go SSD, sont réunis dans un réseau local commun. Leurs noms et adresses IP :

  1. nomad-livelinux-01: 172.30.0.5
  2. nomad-livelinux-02: 172.30.0.10
  3. consul-livelinux-01: 172.30.0.15

Installation de Nomad, Consul. Création du cluster Nomad

Commençons par l'installation de base. Malgré la simplicité de l'installation, je vais la décrire pour la cohérence de l'article : elle a été essentiellement créée à partir de brouillons et de notes pour un accès rapide si nécessaire.

Avant de passer à la pratique, discutons de la partie théorique, car à ce stade, il est important de comprendre la structure future.

Nous avons deux nœuds Nomad et nous voulons les unir en un cluster. De plus, à l'avenir, nous aurons besoin d'une montée en charge automatique du cluster — c'est ici qu'intervient Consul. Avec cet outil, la mise en cluster et l'ajout de nouveaux nœuds deviennent des tâches très simples : le nœud Nomad créé se connecte à l'agent Consul, après quoi il se connecte au cluster Nomad existant. Donc, au début, nous allons installer le serveur Consul, configurer l'authentification http de base pour le panneau web (qui est par défaut sans authentification et peut être accessible par adresse externe), ainsi que les agents Consul sur les serveurs Nomad, puis nous nous mettrons enfin à Nomad.

L'installation des outils de HashiCorp est très simple : en gros, nous déplaçons le fichier binaire dans le répertoire bin, configurons le fichier de configuration de l'outil et créons son fichier de service.

Nous téléchargeons le fichier binaire de Consul et le décompressons dans le répertoire personnel de l'utilisateur :

root@consul-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# mv consul /usr/local/bin/

Nous avons maintenant un fichier binaire consul prêt pour une configuration ultérieure.

Pour travailler avec Consul, nous devons créer une clé unique à l'aide de la commande keygen :

root@consul-livelinux-01:~# consul keygen

Passons à la configuration de Consul, créons le répertoire /etc/consul.d/ avec la structure suivante :

/etc/consul.d/
├── bootstrap
│   └── config.json

Dans le répertoire bootstrap se trouvera le fichier de configuration config.json — nous y définirons les paramètres de Consul. Son contenu :

{
"bootstrap": true,
"server": true,
"datacenter": "dc1",
"data_dir": "/var/consul",
"encrypt": "your-key",
"log_level": "INFO",
"enable_syslog": true,
"start_join": ["172.30.0.15"]
}

Examinons séparément les principales directives et leur signification :

  • bootstrap: true. Nous activons l'ajout automatique de nouveaux nœuds lors de leur connexion. Je souligne que nous ne spécifions pas ici le nombre exact de nœuds attendus.
  • serveur: true. Nous activons le mode serveur. Consul sur cette machine virtuelle sera pour le moment le seul serveur et maître, les VM de Nomad seront des clients.
  • datacenter: dc1. Nous spécifions le nom du datacenter pour créer le cluster. Il doit être identique à la fois sur les clients et sur les serveurs.
  • encrypt: your-key. La clé, qui doit également être unique et correspondre à la fois sur tous les clients et serveurs. Elle est générée à l'aide de la commande consul keygen.
  • start_join. Dans cette liste, nous spécifions les adresses IP auxquelles nous allons nous connecter. Pour l'instant, nous laissons seulement notre propre adresse.

À ce stade, nous pouvons lancer Consul à l'aide de la ligne de commande :

root@consul-livelinux-01:~# /usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui

C'est un bon moyen de débogage pour le moment, cependant, il n'est pas possible d'utiliser cette méthode de façon permanente pour des raisons évidentes. Créons un fichier de service pour gérer Consul via systemd :

root@consul-livelinux-01:~# nano /etc/systemd/system/consul.service

Le contenu du fichier consul.service :

[Unit]
Description=Processus de démarrage de Consul
After=network.target
 
[Service]
Type=simple
ExecStart=/bin/bash -c '/usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui'
TimeoutStartSec=0
 
[Install]
WantedBy=default.target

Démarrons Consul via systemctl :

root@consul-livelinux-01:~# systemctl start consul

Vérifions : notre service doit être en cours d'exécution, et en exécutant la commande consul members, nous devrions voir notre serveur :

root@consul-livelinux:/etc/consul.d# consul members
consul-livelinux    172.30.0.15:8301  alive   server  1.5.0  2         dc1

Étape suivante : installation de Nginx et configuration du proxy, de l'authentification http. Installons nginx via le gestionnaire de paquets et dans le répertoire /etc/nginx/sites-enabled, créons le fichier de configuration consul.conf avec le contenu suivant :

upstream consul-auth {
    server localhost:8500;
}

server {

    server_name consul.doman.name;
    
    location / {
      proxy_pass http://consul-auth;
      proxy_set_header Host $host;
      auth_basic_user_file /etc/nginx/.htpasswd;
      auth_basic "Zone protégée par mot de passe";
    }
}

N'oubliez pas de créer un fichier .htpasswd et de générer un identifiant et un mot de passe pour celui-ci. Cette étape est nécessaire pour que le panneau web ne soit pas accessible à tous ceux qui connaissent notre domaine. Cependant, lors de la configuration de Gitlab, nous devrons y renoncer; sinon, nous ne pourrons pas déployer notre application dans Nomad. Dans mon projet, à la fois Gitlab et Nomad se trouvent uniquement sur un réseau interne, donc ce problème n'existe pas ici.

Sur les deux autres serveurs, installons les agents Consul en suivant cette instruction. Nous répétons les actions avec le fichier binaire :

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# mv consul /usr/local/bin/

De la même manière que pour le serveur précédent, créons le répertoire pour les fichiers de configuration /etc/consul.d avec la structure suivante :

/etc/consul.d/
├── client
│   └── config.json

Contenu du fichier config.json :

{
    "datacenter": "dc1",
    "data_dir": "\/opt\/consul",
    "log_level": "DEBUG",
    "node_name": "nomad-livelinux-01",
    "server": false,
    "encrypt": "your-private-key",
    "domain": "livelinux",
    "addresses": {
      "dns": "127.0.0.1",
      "https": "0.0.0.0",
      "grpc": "127.0.0.1",
      "http": "127.0.0.1"
    },
    "bind_addr": "172.30.0.5", # adresse locale de la VM
    "start_join": ["172.30.0.15"], # adresse distante du serveur Consul
    "ports": {
      "dns": 53
     }

Enregistrez les modifications et passons à la configuration du fichier de service, son contenu :

/etc/systemd/system/consul.service:

[Unit]
Description="HashiCorp Consul - Une solution de maillage de services"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target

[Service]
User=root
Group=root
ExecStart=\/usr\/local\/bin\/consul agent -config-dir=\/etc\/consul.d\/client
ExecReload=\/usr\/local\/bin\/consul reload
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

Nous lançons consul sur le serveur. Maintenant, après le démarrage, nous devrions voir le service configuré dans nsul members. Cela indiquera qu'il a réussi à se connecter au cluster en tant que client. Répétez la même chose sur le deuxième serveur et après cela, nous pourrons commencer l'installation et la configuration de Nomad.

Une installation plus détaillée de Nomad est décrite dans sa documentation officielle. Il existe deux méthodes traditionnelles d'installation : le téléchargement du fichier binaire et la compilation à partir des sources. Je vais choisir la première méthode.

Remarque: le projet évolue très rapidement, de nouvelles mises à jour sont souvent publiées. Il est possible qu'à la fin de cet article, une nouvelle version soit disponible. Je recommande donc de vérifier la version actuelle de Nomad avant de lire et de télécharger celle-ci.

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/nomad/0.9.1/nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# unzip nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# mv nomad /usr/local/bin/
root@nomad-livelinux-01:~# nomad -autocomplete-install
root@nomad-livelinux-01:~# complete -C /usr/local/bin/nomad nomad
root@nomad-livelinux-01:~# mkdir /etc/nomad.d

Après avoir décompressé, nous obtiendrons un fichier binaire de Nomad de 65 Mo qu'il faudra déplacer dans /usr/local/bin.

Créons un répertoire data pour Nomad et modifions son fichier service (il n'existe probablement pas au départ) :

root@nomad-livelinux-01:~# mkdir --parents /opt/nomad
root@nomad-livelinux-01:~# nano /etc/systemd/system/nomad.service

Nous y insérons les lignes suivantes :

[Unit]
Description=Nomad
Documentation=https://nomadproject.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/nomad agent -config /etc/nomad.d
KillMode=process
KillSignal=SIGINT
LimitNOFILE=infinity
LimitNPROC=infinity
Restart=on-failure
RestartSec=2
StartLimitBurst=3
StartLimitIntervalSec=10
TasksMax=infinity

[Install]
WantedBy=multi-user.target

Cependant, ne nous précipitons pas à lancer nomad — nous n'avons pas encore créé son fichier de configuration :

root@nomad-livelinux-01:~# mkdir --parents /etc/nomad.d
root@nomad-livelinux-01:~# chmod 700 /etc/nomad.d
root@nomad-livelinux-01:~# nano /etc/nomad.d/nomad.hcl
root@nomad-livelinux-01:~# nano /etc/nomad.d/server.hcl

La structure finale du répertoire sera la suivante :

/etc/nomad.d/
├── nomad.hcl
└── server.hcl

Le fichier nomad.hcl doit contenir la configuration suivante :

datacenter = "dc1"
data_dir = "/opt/nomad"

Contenu du fichier server.hcl :

server {
  enabled = true
  bootstrap_expect = 1
}

consul {
  address = "127.0.0.1:8500"
  server_service_name = "nomad"
  client_service_name = "nomad-client"
  auto_advertise = true
  server_auto_join = true
  client_auto_join = true
}

bind_addr = "127.0.0.1" 

advertise {
  http = "172.30.0.5"
}

client {
  enabled = true
}

N'oubliez pas de modifier le fichier de configuration sur le deuxième serveur — il faudra changer la valeur de la directive http.

Dernièrement, il reste à configurer Nginx pour le proxy et à établir l'autorisation http. Contenu du fichier nomad.conf :

upstream nomad-auth {
        server 172.30.0.5:4646;
}

server {

        server_name nomad.domain.name;
        
        location / {
	        proxy_pass http://nomad-auth;
	        proxy_set_header Host $host;
	        auth_basic_user_file /etc/nginx/.htpasswd;
		   auth_basic "Zone protégée par mot de passe";
        }
        
}

Nous pouvons maintenant accéder au panneau Web via le réseau externe. Connectons-nous et accédons à la page servers :

Configuration d'un cluster Nomad avec Consul et intégration avec GitLab
Image 1. Liste des serveurs dans le cluster Nomad

Les deux serveurs s'affichent avec succès dans le panneau, et nous observerons la même chose dans la sortie de la commande nomad node status :

Configuration d'un cluster Nomad avec Consul et intégration avec GitLab
Image 2. Sortie de la commande nomad node status

Que se passe-t-il du côté de Consul ? Vérifions. Accédons au panneau de contrôle Consul, à la page nodes :
Configuration d'un cluster Nomad avec Consul et intégration avec GitLab
Image 3. Liste des nœuds dans le cluster Consul

Nous avons maintenant un Nomad configuré, fonctionnant en tandem avec Consul. Dans cette étape finale, nous allons passer à la partie la plus intéressante : configurer la livraison des conteneurs Docker depuis Gitlab vers Nomad, tout en discutant de certaines de ses autres caractéristiques distinctives.

Création d'un Gitlab Runner

Pour déployer des images Docker dans Nomad, nous allons utiliser un runner distinct avec le fichier binaire de Nomad à l'intérieur (il est à noter ici une autre caractéristique des applications Hashicorp : elles se présentent sous la forme d'un unique fichier binaire). Téléchargez-le dans le répertoire du runner. Pour cela, nous allons créer un Dockerfile très simple avec le contenu suivant :


FROM alpine:3.9
RUN apk add --update --no-cache libc6-compat gettext
COPY nomad /usr/local/bin/nomad

Dans ce même projet, créons un .gitlab-ci.yml :

variables:
  DOCKER_IMAGE: nomad/nomad-deploy
  DOCKER_REGISTRY: registry.domain.name

stages:
  - build

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:latest
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}

En fin de compte, nous aurons une image du runner Nomad disponible dans Gitlab Registry, et nous pouvons maintenant passer à la répertoire du projet pour créer un pipeline et configurer le job Nomad.

Configuration du projet

Commençons par le fichier de job pour Nomad. Mon projet dans cet article sera assez primitif : il consistera en une seule tâche. Le contenu de .gitlab-ci sera le suivant :

variables:
  NOMAD_ADDR: http://nomad.address.service:4646
  DOCKER_REGISTRY: registry.domain.name
  DOCKER_IMAGE: example/project

stages:
  - build
  - deploy

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad-runner/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA}
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}

deploy:
  stage: deploy
  image: registry.example.com/nomad/nomad-runner:latest
  script:
    - envsubst '${CI_COMMIT_SHORT_SHA}'  job.nomad
    - cat job.nomad
    - nomad validate job.nomad
    - nomad plan job.nomad || if [ $? -eq 255 ]; then exit 255; else echo "success"; fi
    - nomad run job.nomad
  environment:
    name: production
  allow_failure: false
  when: manual

Ici, le déploiement se fait manuellement, mais vous pouvez le configurer pour modifier le contenu du répertoire du projet. Le pipeline se compose de deux étapes : la construction de l'image et son déploiement dans Nomad. Lors de la première étape, nous construisons l'image Docker et la poussons dans notre Registry, puis, à la deuxième, nous lançons notre job dans Nomad.

travail "monitoring-status" {
    datacenters = ["dc1"]
    migrer {
        max_parallel = 3
        health_check = "checks"
        min_healthy_time = "15s"
        healthy_deadline = "5m"
    }

    groupe "zhadan.ltd" {
        count = 1
        mise à jour {
            max_parallel      = 1
            min_healthy_time  = "30s"
            healthy_deadline  = "5m"
            progress_deadline = "10m"
            auto_revert       = true
        }
        tâche "service-monitoring" {
            driver = "docker"

            config {
                image = "registry.domain.name/example/project:${CI_COMMIT_SHORT_SHA}"
                force_pull = true
                auth {
                    username = "gitlab_user"
                    password = "gitlab_password"
                }
                port_map {
                    http = 8000
                }
            }
            resources {
                network {
                    port "http" {}
                }
            }
        }
    }
}

Veuillez noter que j'ai un registre privé et que, pour réussir à extraire une image Docker, je dois m'y authentifier. La meilleure solution ici est de placer le nom d'utilisateur et le mot de passe dans Vault, puis d'intégrer cela avec Nomad. Nomad prend en charge Vault nativement. Mais d'abord, dans Vault, nous allons configurer les politiques nécessaires pour Nomad, que vous pouvez charger :

# Download the policy and token role
$ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
$ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L

# Write the policy to Vault
$ vault policy write nomad-server nomad-server-policy.hcl

# Create the token role with Vault
$ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json

Maintenant, après avoir créé les politiques nécessaires, nous allons ajouter l'intégration avec Vault dans le bloc tâche du fichier job.nomad :

vault {
  enabled = true
  address = "https://vault.domain.name:8200"
  token = "token"
}

J'utilise l'autorisation par token et je l'inscris directement ici, il existe également une option pour spécifier le token comme variable lors du lancement de l'agent nomad :

$ VAULT_TOKEN= nomad agent -config /path/to/config

Maintenant, nous pouvons utiliser les clés de Vault. Le principe est simple : nous créons un fichier dans le job Nomad qui contiendra les valeurs des variables, par exemple :

template {
                data = <<EOH
{{with secret "secrets/pipeline-keys"}}
REGISTRY_LOGIN="{{ .Data.REGISTRY_LOGIN }}"
REGISTRY_PASSWORD="{{ .Data.REGISTRY_LOGIN }}{{ end }}"

EOH
    destination = "secrets/service-name.env"
    env = true
}

Avec une approche aussi simple, nous pouvons configurer la livraison des conteneurs dans le cluster Nomad et travailler avec lui par la suite. Je dirai que, dans une certaine mesure, j'apprécie Nomad — il convient mieux aux petits projets où Kubernetes pourrait poser des problèmes supplémentaires et ne réaliserait pas pleinement son potentiel. De plus, Nomad est parfait pour les débutants — il s'installe et se configure facilement. Cependant, lors des tests sur certains projets, je me heurtais à des problèmes avec ses premières versions — de nombreuses fonctions de base sont simplement manquantes ou ne fonctionnent pas correctement. Néanmoins, je pense que Nomad continuera à se développer et, à l'avenir, il sera doté des fonctionnalités nécessaires à tous.

Auteur : Ilya Andreev, sous la direction d'Alexey Zhadan et de l'équipe « Live Linux »


Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster