Einrichten eines Nomad-Clusters mit Consul und Integration mit Gitlab

Einführung

In letzter Zeit hat die Popularität von Kubernetes rasant zugenommen – immer mehr Projekte implementieren es. Ich wollte auf einen Orchestrator wie Nomad eingehen: Er eignet sich perfekt für Projekte, die bereits andere Lösungen von HashiCorp verwenden, zum Beispiel Vault und Consul, und die Projekte selbst sind in Bezug auf die Infrastruktur nicht komplex. Dieses Material enthält Anweisungen zur Installation von Nomad, zum Kombinieren von zwei Knoten zu einem Cluster sowie zur Integration von Nomad mit Gitlab.

Einrichten eines Nomad-Clusters mit Consul und Integration mit Gitlab

Prüfstand

Ein wenig zum Prüfstand: Zum Einsatz kommen drei virtuelle Server mit den Eigenschaften 2 CPU, 4 RAM, 50 GB SSD, vereint in einem gemeinsamen lokalen Netzwerk. Ihre Namen und IP-Adressen:

  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 von Nomad, Konsul. Erstellen eines Nomad-Clusters

Beginnen wir mit der Grundinstallation. Obwohl die Einrichtung einfach war, beschreibe ich sie aus Gründen der Integrität des Artikels: Sie wurde im Wesentlichen aus Entwürfen und Notizen erstellt, um bei Bedarf schnell darauf zugreifen zu können.

Bevor wir mit der Praxis beginnen, besprechen wir den theoretischen Teil, denn in dieser Phase ist es wichtig, die zukünftige Struktur zu verstehen.

Wir haben zwei Nomad-Knoten und wollen diese zu einem Cluster zusammenfassen, und in Zukunft brauchen wir auch eine automatische Cluster-Skalierung – dafür brauchen wir Consul. Mit diesem Tool wird das Clustering und Hinzufügen neuer Knoten zu einer sehr einfachen Aufgabe: Der erstellte Nomad-Knoten stellt eine Verbindung zum Consul-Agenten her und stellt dann eine Verbindung zum vorhandenen Nomad-Cluster her. Daher werden wir zu Beginn den Consul-Server installieren, die grundlegende HTTP-Autorisierung für das Webpanel konfigurieren (es ist standardmäßig ohne Autorisierung und kann über eine externe Adresse aufgerufen werden) sowie die Consul-Agenten selbst auf Nomad-Servern und anschließend Wir werden nur zu Nomad übergehen.

Die Installation der Tools von HashiCorp ist sehr einfach: Im Wesentlichen verschieben wir einfach die Binärdatei in das bin-Verzeichnis, richten die Konfigurationsdatei des Tools ein und erstellen seine Servicedatei.

Laden Sie die Consul-Binärdatei herunter und entpacken Sie sie in das Home-Verzeichnis des Benutzers:

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/

Jetzt haben wir eine fertige Consul-Binärdatei für die weitere Konfiguration.

Um mit Consul arbeiten zu können, müssen wir mit dem Befehl keygen einen eindeutigen Schlüssel erstellen:

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

Fahren wir mit dem Einrichten der Consul-Konfiguration fort und erstellen ein Verzeichnis /etc/consul.d/ mit der folgenden Struktur:

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

Das Bootstrap-Verzeichnis enthält eine Konfigurationsdatei config.json – darin legen wir die Consul-Einstellungen fest. Sein Inhalt:

{
"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"]
}

Schauen wir uns die wichtigsten Anweisungen und ihre Bedeutung separat an:

  • bootstrap: WAHR. Wir ermöglichen das automatische Hinzufügen neuer Knoten, wenn diese verbunden sind. Ich stelle fest, dass wir hier nicht die genaue Anzahl der erwarteten Knoten angeben.
  • Server: WAHR. Aktivieren Sie den Servermodus. Consul auf dieser virtuellen Maschine wird im Moment als einziger Server und Master fungieren, Nomads VM wird die Clients sein.
  • Rechenzentrum: dc1. Geben Sie den Namen des Rechenzentrums an, um den Cluster zu erstellen. Es muss sowohl auf Clients als auch auf Servern identisch sein.
  • verschlüsseln: dein Schlüssel. Der Schlüssel muss ebenfalls eindeutig sein und auf allen Clients und Servern übereinstimmen. Wird mit dem Befehl consul keygen generiert.
  • start_join. In dieser Liste geben wir eine Liste der IP-Adressen an, zu denen die Verbindung hergestellt wird. Im Moment hinterlassen wir nur unsere eigene Adresse.

An dieser Stelle können wir consul über die Befehlszeile ausführen:

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

Dies ist jetzt eine gute Methode zum Debuggen. Aus offensichtlichen Gründen können Sie diese Methode jedoch nicht dauerhaft verwenden. Erstellen wir eine Servicedatei, um Consul über systemd zu verwalten:

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

Inhalt der Datei 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

Starten Sie Consul über systemctl:

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

Überprüfen wir: Unser Dienst muss ausgeführt werden, und wenn wir den Befehl „consul member“ ausführen, sollten wir unseren Server sehen:

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

Nächster Schritt: Nginx installieren und Proxying und HTTP-Autorisierung einrichten. Wir installieren nginx über den Paketmanager und erstellen im Verzeichnis /etc/nginx/sites-enabled eine Konfigurationsdatei consul.conf mit folgendem Inhalt:

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";
    }
}

Vergessen Sie nicht, eine .htpasswd-Datei zu erstellen und einen Benutzernamen und ein Passwort dafür zu generieren. Dieser Punkt ist erforderlich, damit das Webpanel nicht für jeden verfügbar ist, der unsere Domain kennt. Beim Einrichten von Gitlab müssen wir jedoch darauf verzichten, da wir unsere Anwendung sonst nicht auf Nomad bereitstellen können. In meinem Projekt sind sowohl Gitlab als auch Nomad nur im grauen Web verfügbar, daher gibt es hier kein solches Problem.

Auf den verbleibenden zwei Servern installieren wir Consul-Agenten gemäß der folgenden Anleitung. Wir wiederholen die Schritte mit der Binärdatei:

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/

Analog zum vorherigen Server erstellen wir ein Verzeichnis für Konfigurationsdateien /etc/consul.d mit folgender Struktur:

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

Inhalt der Datei 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
     }

Speichern Sie die Änderungen und fahren Sie mit der Einrichtung der Servicedatei fort. Ihr Inhalt:

/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

Wir starten Consul auf dem Server. Jetzt, nach dem Start, sollten wir den konfigurierten Dienst in den nsul-Mitgliedern sehen. Dies bedeutet, dass die Verbindung als Client erfolgreich mit dem Cluster hergestellt wurde. Wiederholen Sie dasselbe auf dem zweiten Server und danach können wir mit der Installation und Konfiguration von Nomad beginnen.

Eine detailliertere Installation von Nomad wird in der offiziellen Dokumentation beschrieben. Es gibt zwei traditionelle Installationsmethoden: Herunterladen einer Binärdatei und Kompilieren aus der Quelle. Ich werde die erste Methode wählen.

Beachten: Das Projekt entwickelt sich sehr schnell, oft werden neue Updates veröffentlicht. Möglicherweise wird bis zur Fertigstellung dieses Artikels eine neue Version veröffentlicht. Daher empfehle ich, vor dem Lesen die aktuell aktuelle Version von Nomad zu prüfen und herunterzuladen.

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

Nach dem Entpacken erhalten wir eine Nomad-Binärdatei mit einem Gewicht von 65 MB – diese muss nach /usr/local/bin verschoben werden.

Erstellen wir ein Datenverzeichnis für Nomad und bearbeiten dessen Servicedatei (diese wird am Anfang höchstwahrscheinlich noch nicht vorhanden sein):

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

Fügen Sie dort die folgenden Zeilen ein:

[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

Allerdings haben wir es nicht eilig, Nomad zu starten – wir haben seine Konfigurationsdatei noch nicht erstellt:

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

Die endgültige Verzeichnisstruktur sieht wie folgt aus:

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

Die Datei nomad.hcl sollte die folgende Konfiguration enthalten:

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

Inhalt der Datei 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
}

Vergessen Sie nicht, die Konfigurationsdatei auf dem zweiten Server zu ändern – dort müssen Sie den Wert der http-Direktive ändern.

Der letzte Schritt in dieser Phase besteht darin, Nginx für das Proxying zu konfigurieren und die HTTP-Autorisierung einzurichten. Inhalt der Datei 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";
        }
        
}

Jetzt können wir über ein externes Netzwerk auf das Webpanel zugreifen. Stellen Sie eine Verbindung her und rufen Sie die Serverseite auf:

Einrichten eines Nomad-Clusters mit Consul und Integration mit Gitlab
Bild 1. Liste der Server im Nomad-Cluster

Beide Server werden erfolgreich im Panel angezeigt. Wir werden dasselbe in der Ausgabe des Befehls „nomad node status“ sehen:

Einrichten eines Nomad-Clusters mit Consul und Integration mit Gitlab
Bild 2. Ausgabe des Nomad Node Status-Befehls

Was ist mit Konsul? Werfen wir einen Blick darauf. Gehen Sie zum Consul-Kontrollfeld zur Knotenseite:
Einrichten eines Nomad-Clusters mit Consul und Integration mit Gitlab
Bild 3. Liste der Knoten im Consul-Cluster

Jetzt haben wir einen vorbereiteten Nomad, der mit dem Konsul zusammenarbeitet. In der letzten Phase kommen wir zum unterhaltsamen Teil: der Einrichtung der Lieferung von Docker-Containern von Gitlab an Nomad und sprechen auch über einige seiner anderen Besonderheiten.

Gitlab Runner erstellen

Um Docker-Images auf Nomad bereitzustellen, verwenden wir einen separaten Runner mit der darin enthaltenen Nomad-Binärdatei (hier können wir übrigens ein weiteres Merkmal von Hashicorp-Anwendungen bemerken – einzeln handelt es sich um eine einzelne Binärdatei). Laden Sie es in das Läuferverzeichnis hoch. Erstellen wir dafür ein einfaches Dockerfile mit folgendem Inhalt:


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

Im selben Projekt erstellen wir .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}

Als Ergebnis verfügen wir über ein verfügbares Image des Nomad-Runners in der Gitlab-Registrierung. Jetzt können wir direkt zum Projekt-Repository gehen, eine Pipeline erstellen und den Nomad-Job von Nomad konfigurieren.

Projektaufbau

Beginnen wir mit der Jobdatei für Nomad. Mein Projekt in diesem Artikel wird recht primitiv sein: Es wird aus einer Aufgabe bestehen. Der Inhalt von .gitlab-ci wird wie folgt sein:

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

Hier erfolgt die Bereitstellung manuell, Sie können sie jedoch so konfigurieren, dass der Inhalt des Projektverzeichnisses geändert wird. Die Pipeline besteht aus zwei Phasen: der Image-Assemblierung und deren Bereitstellung für Nomad. Im ersten Schritt stellen wir ein Docker-Image zusammen und übertragen es in unsere Registry. Im zweiten Schritt starten wir unseren Job in 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" {}
                }
            }
        }
    }
}

Bitte beachten Sie, dass ich über eine private Registry verfüge und mich zum erfolgreichen Abrufen eines Docker-Images dort anmelden muss. Die beste Lösung besteht in diesem Fall darin, einen Benutzernamen und ein Passwort in Vault einzugeben und es dann in Nomad zu integrieren. Nomad unterstützt Vault nativ. Aber zuerst installieren wir die notwendigen Richtlinien für Nomad in Vault selbst; sie können heruntergeladen werden:

# 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

Nachdem wir nun die erforderlichen Richtlinien erstellt haben, fügen wir die Integration mit Vault im Aufgabenblock in der Datei job.nomad hinzu:

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

Ich nutze die Autorisierung per Token und registriere diese direkt hier, es besteht auch die Möglichkeit, den Token beim Start von Nomad Agent als Variable anzugeben:

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

Jetzt können wir die Schlüssel mit Vault verwenden. Das Funktionsprinzip ist einfach: Wir erstellen im Nomad-Job eine Datei, in der die Werte von Variablen gespeichert werden, zum Beispiel:

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
}

Mit diesem einfachen Ansatz können Sie die Bereitstellung von Containern an den Nomad-Cluster konfigurieren und in Zukunft damit arbeiten. Ich muss sagen, dass ich in gewisser Weise mit Nomad sympathisiere – es eignet sich eher für kleine Projekte, bei denen Kubernetes zusätzliche Komplexität verursachen kann und sein volles Potenzial nicht ausschöpft. Außerdem ist Nomad perfekt für Einsteiger geeignet – es ist einfach zu installieren und zu konfigurieren. Beim Testen einiger Projekte stoße ich jedoch auf ein Problem mit den frühen Versionen – viele Grundfunktionen sind einfach nicht vorhanden oder funktionieren nicht richtig. Ich glaube jedoch, dass sich Nomad weiterentwickeln wird und in Zukunft die Funktionen erhalten wird, die jeder braucht.

Autor: Ilya Andreev, herausgegeben von Alexey Zhadan und dem Live Linux-Team


Source: habr.com

Kommentar hinzufügen