Mise en place d'un cluster Nomad à l'aide de Consul et intégration avec Gitlab

introduction

Récemment, la popularité de Kubernetes a augmenté rapidement - de plus en plus de projets le mettent en œuvre. Je voulais aborder un orchestrateur comme Nomad : il est parfait pour les projets qui utilisent déjà d'autres solutions de HashiCorp, par exemple Vault et Consul, et les projets eux-mêmes ne sont pas complexes en termes d'infrastructure. Ce matériel contiendra des instructions pour installer Nomad, combiner deux nœuds dans un cluster, ainsi que pour intégrer Nomad avec Gitlab.

Mise en place d'un cluster Nomad à l'aide de Consul et intégration avec Gitlab

banc d'essai

Un peu sur le banc de test : trois serveurs virtuels sont utilisés avec les caractéristiques de 2 CPU, 4 RAM, 50 Go SSD, réunis dans un réseau local commun. Leurs noms et adresses IP :

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

Installation de Nomad, Consul. Créer un cluster Nomad

Commençons par l'installation de base. Bien que la configuration soit simple, je la décrirai dans un souci d'intégrité de l'article : elle a été essentiellement créée à partir de brouillons et de notes pour un accès rapide en cas de besoin.

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

Nous avons deux nœuds nomades et nous voulons les combiner dans un cluster, et à l'avenir, nous aurons également besoin d'une mise à l'échelle automatique du cluster - pour cela, nous aurons besoin de Consul. Avec cet outil, le clustering et l'ajout de nouveaux nœuds deviennent une tâche très simple : le nœud Nomad créé se connecte à l'agent Consul, puis se connecte au cluster Nomad existant. Par conséquent, au début, nous installerons le serveur Consul, configurerons l'autorisation http de base pour le panneau Web (il est sans autorisation par défaut et accessible à une adresse externe), ainsi que les agents Consul eux-mêmes sur les serveurs Nomad, après quoi nous procéderons uniquement à Nomad.

L'installation des outils de HashiCorp est très simple : essentiellement, il suffit de déplacer le fichier binaire vers le répertoire bin, de configurer le fichier de configuration de l'outil et de créer son fichier de service.

Téléchargez le fichier binaire Consul et décompressez-le 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 binaire consul prêt à l'emploi 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, en créant un répertoire /etc/consul.d/ avec la structure suivante :

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

Le répertoire d'amorçage contiendra un fichier de configuration config.json - dans lequel nous définirons les paramètres 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 leurs significations :

  • bootstrap: vrai. Nous permettons l'ajout automatique de nouveaux nœuds s'ils sont connectés. Je constate que nous n'indiquons pas ici le nombre exact de nœuds attendus.
  • serveur: vrai. Activez le mode serveur. Consul sur cette machine virtuelle fera office de seul serveur et maître pour le moment, la VM de Nomad sera les clients.
  • datacenter: cc1. Spécifiez le nom du centre de données pour créer le cluster. Il doit être identique sur les clients et les serveurs.
  • crypter: ta clé. La clé, qui doit également être unique et correspondre sur tous les clients et serveurs. Généré à l'aide de la commande consul keygen.
  • start_join. Dans cette liste nous indiquons une liste d'adresses IP auxquelles la connexion sera établie. Pour le moment, nous ne laissons que notre propre adresse.

À ce stade, nous pouvons exécuter consul en utilisant 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éboguer maintenant, cependant, vous ne pourrez pas utiliser cette méthode de manière continue 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

Contenu du fichier consul.service :

[Unit]
Description=Consul Startup process
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

Lancez 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  <all>

Étape suivante : installer Nginx et configurer le proxy et l'autorisation http. Nous installons nginx via le gestionnaire de packages et dans le répertoire /etc/nginx/sites-enabled nous créons un 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 "Password-protected Area";
    }
}

N'oubliez pas de créer un fichier .htpasswd et de générer un nom d'utilisateur et un mot de passe pour celui-ci. Cet élément est obligatoire pour que le panneau Web ne soit pas accessible à tous ceux qui connaissent notre domaine. Cependant, lors de la configuration de Gitlab, nous devrons abandonner cela - sinon nous ne pourrons pas déployer notre application sur Nomad. Dans mon projet, Gitlab et Nomad sont uniquement sur le Web gris, il n'y a donc pas de problème de ce type ici.

Sur les deux serveurs restants, nous installons les agents Consul selon les instructions suivantes. Nous répétons les étapes 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/

Par analogie avec le serveur précédent, nous créons un 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", # локальный адрес вм
    "start_join": ["172.30.0.15"], # удаленный адрес консул сервера
    "ports": {
      "dns": 53
     }

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

/etc/systemd/system/consul.service :

[Unit]
Description="HashiCorp Consul - A service mesh solution"
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 lancement, nous devrions voir le service configuré dans les membres nsul. Cela signifie qu'il s'est connecté avec succès au cluster en tant que client. Répétez la même chose sur le deuxième serveur et nous pourrons ensuite commencer à installer et configurer Nomad.

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

Noter: Le projet se développe très rapidement, de nouvelles mises à jour sont souvent publiées. Peut-être qu’une nouvelle version sera publiée au moment où cet article sera terminé. Par conséquent, avant de lire, je vous recommande de vérifier la version actuelle de Nomad pour le moment et de la télécharger.

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 déballage, nous recevrons un fichier binaire Nomad pesant 65 Mo - il doit être déplacé vers /usr/local/bin.

Créons un répertoire de données pour Nomad et éditons son fichier de service (il n'existera probablement pas au début) :

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

Collez-y 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, nous ne sommes pas pressés de 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 des répertoires 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 - vous devrez y modifier la valeur de la directive http.

La dernière chose à ce stade est de configurer Nginx pour le proxy et la configuration de 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 "Password-protected Area";
        }
        
}

Nous pouvons désormais accéder au panneau Web via un réseau externe. Connectez-vous et allez sur la page des serveurs :

Mise en place d'un cluster Nomad à l'aide de Consul et intégration avec Gitlab
Image 1. Liste des serveurs du cluster Nomad

Les deux serveurs sont affichés avec succès dans le panneau, nous verrons la même chose dans le résultat de la commande nomad node status :

Mise en place d'un cluster Nomad à l'aide de Consul et intégration avec Gitlab
Image 2. Sortie de la commande Nomad Node Status

Et le Consul ? Jetons un coup d'oeil. Rendez-vous dans le panneau de contrôle Consul, sur la page des nœuds :
Mise en place d'un cluster Nomad à l'aide de Consul et intégration avec Gitlab
Image 3. Liste des nœuds du cluster Consul

Nous avons maintenant un Nomad préparé qui travaille en collaboration avec Consul. Dans la dernière étape, nous passerons à la partie amusante : configurer la livraison des conteneurs Docker de Gitlab vers Nomad, et parler également de certaines de ses autres caractéristiques distinctives.

Création de Gitlab Runner

Pour déployer des images Docker sur Nomad, nous utiliserons un exécuteur séparé contenant le fichier binaire Nomad (ici, en passant, nous pouvons noter une autre fonctionnalité des applications Hashicorp - individuellement, il s'agit d'un seul fichier binaire). Téléchargez-le dans le répertoire du coureur. Créons un simple Dockerfile avec le contenu suivant :


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

Dans le même projet, nous créons .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 conséquence, nous aurons une image disponible du runner Nomad dans le registre Gitlab, nous pouvons désormais accéder directement au référentiel du projet, créer un Pipeline et configurer le travail nomade de Nomad.

Configuration du projet

Commençons par le fichier de travail 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}' < project.nomad > 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 s'effectue manuellement, mais vous pouvez le configurer pour modifier le contenu du répertoire du projet. Le pipeline se compose de deux étapes : l'assemblage de l'image et son déploiement sur Nomad. Dans un premier temps, nous assemblons une image Docker et la plaçons dans notre registre, et dans la seconde nous lançons notre travail dans Nomad.

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

    group "zhadan.ltd" {
        count = 1
        update {
            max_parallel      = 1
            min_healthy_time  = "30s"
            healthy_deadline  = "5m"
            progress_deadline = "10m"
            auto_revert       = true
        }
        task "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 connecter. La meilleure solution dans ce cas est de saisir un identifiant et un mot de passe dans Vault, puis de l'intégrer à Nomad. Nomad prend en charge nativement Vault. Mais d'abord, installons les politiques nécessaires pour Nomad dans Vault lui-même ; elles peuvent être téléchargées :

# 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 de tâches du fichier job.nomad :

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

J'utilise l'autorisation par token et je l'enregistre directement ici, il y a aussi la possibilité de spécifier le token comme variable au démarrage de l'agent nomade :

$ VAULT_TOKEN=<token> nomad agent -config /path/to/config

Nous pouvons maintenant utiliser les clés avec Vault. Le principe de fonctionnement est simple : on crée un fichier dans Nomad job qui va stocker 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 cette approche simple, vous pouvez configurer la livraison de conteneurs au cluster Nomad et travailler avec lui à l'avenir. Je dirai que dans une certaine mesure, je sympathise avec Nomad - il est plus adapté aux petits projets où Kubernetes peut entraîner une complexité supplémentaire et ne réalisera pas tout son potentiel. De plus, Nomad est parfait pour les débutants : il est facile à installer et à configurer. Cependant, lors des tests sur certains projets, je rencontre un problème avec ses premières versions : de nombreuses fonctions de base ne sont tout simplement pas là ou ne fonctionnent pas correctement. Cependant, je pense que Nomad continuera à se développer et qu'à l'avenir il acquerra les fonctions dont tout le monde a besoin.

Auteur : Ilya Andreev, édité par Alexey Zhadan et l'équipe Live Linux


Source: habr.com

Ajouter un commentaire