Einrichten eines Nomad-Clusters mit Consul und Integration in GitLab

EinfĂŒhrung

In letzter Zeit wĂ€chst die Beliebtheit von Kubernetes rasant – immer mehr Projekte setzen es ein. Ich möchte jedoch einen anderen Orchestrator, nĂ€mlich Nomad, ansprechen: Er eignet sich hervorragend fĂŒr Projekte, die bereits andere Lösungen von HashiCorp, wie Vault und Consul, nutzen, und bei denen die Infrastruktur nicht besonders komplex ist. In diesem Material finden Sie eine Anleitung zur Installation von Nomad, zur Bildung eines Clusters aus zwei Knoten sowie zur Integration von Nomad mit GitLab.

Einrichten eines Nomad-Clusters mit Consul und Integration in GitLab

Teststand

Ein wenig zum Teststand: Es werden drei virtuelle Server mit den Eigenschaften 2 CPU, 4 RAM, 50 Gb SSD verwendet, die in einem gemeinsamen lokalen Netzwerk verbunden sind. Ihre Namen und IP-Adressen lauten:

  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, Consul. Erstellung eines Nomad-Clusters

Lassen Sie uns mit der grundlegenden Installation beginnen. Trotz der Einfachheit der Installation werde ich sie hier zur VollstĂ€ndigkeit des Artikels beschreiben: Im Grunde wurde sie aus EntwĂŒrfen und Notizen fĂŒr den schnellen Zugriff bei Bedarf erstellt.

Bevor wir zur praktischen Anwendung ĂŒbergehen, lassen Sie uns den theoretischen Teil besprechen, denn in diesem Stadium ist es wichtig, die zukĂŒnftige Struktur zu verstehen.

Wir haben zwei Nomad-Knoten und möchten diese zu einem Cluster zusammenfassen. Zudem benötigen wir in Zukunft eine automatische Skalierung des Clusters – dafĂŒr brauchen wir Consul. Mit diesem Tool wird die Clusterbildung und das HinzufĂŒgen neuer Knoten zu einer sehr einfachen Aufgabe: Der erstellte Nomad-Knoten verbindet sich mit dem Consul-Agenten und anschließend mit dem bestehenden Nomad-Cluster. Daher installieren wir zunĂ€chst den Consul-Server, konfigurieren eine grundlegende HTTP-Authentifizierung fĂŒr das Web-Panel (das standardmĂ€ĂŸig ohne Authentifizierung zugĂ€nglich ist und ĂŒber eine externe Adresse erreichbar sein kann) und setzen die Consul-Agents auf den Nomad-Servern auf, bevor wir mit Nomad fortfahren.

Die Installation der Werkzeuge von HashiCorp ist sehr einfach: Wir verschieben im Grunde die BinÀrdatei in das Verzeichnis bin, konfigurieren die Konfigurationsdatei des Tools und erstellen die Dienstdatei.

Laden Sie die BinÀrdatei von Consul herunter und entpacken Sie sie im 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 die BinĂ€rdatei consul bereit fĂŒr die weitere Konfiguration.

Um mit Consul zu arbeiten, mĂŒssen wir mit dem Befehl keygen einen eindeutigen SchlĂŒssel erstellen:

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

Nun gehen wir zur Konfiguration von Consul ĂŒber und erstellen das Verzeichnis /etc/consul.d/ mit der folgenden Struktur:

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

Im Verzeichnis bootstrap befindet sich die Konfigurationsdatei config.json, in der wir die Einstellungen fĂŒr Consul festlegen. Ihr Inhalt ist:

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

Lassen Sie uns die wichtigsten Direktiven und deren Bedeutungen einzeln durchgehen:

  • bootstrap: true. Wir aktivieren die automatische HinzufĂŒgung neuer Knoten beim Verbinden. Ich möchte darauf hinweisen, dass wir hier keine genaue Anzahl erwarteter Knoten angeben.
  • server: true. Wir aktivieren den Servermodus. Consul wird derzeit auf dieser virtuellen Maschine als einziger Server und Master fungieren, wĂ€hrend die VMs von Nomad Clients sein werden.
  • datacenter: dc1. Wir geben den Namen des Rechenzentrums an, um einen Cluster zu erstellen. Dieser muss sowohl bei den Clients als auch bei den Servern identisch sein.
  • encrypt: your-key. Ein SchlĂŒssel, der ebenfalls einzigartig sein und auf allen Clients und Servern ĂŒbereinstimmen muss. Er wird mit dem Befehl consul keygen generiert.
  • start_joinIn dieser Liste geben wir die IP-Adressen an, zu denen eine Verbindung hergestellt wird. Momentan lassen wir nur unsere eigene Adresse stehen.

In diesem Schritt können wir Consul ĂŒber die Befehlszeile starten:

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

Das ist momentan eine gute Debugging-Methode, jedoch kann dieser Weg aus offensichtlichen GrĂŒnden nicht dauerhaft verwendet werden. Erstellen wir eine Service-Datei, 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-Prozess
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

Wir starten Consul ĂŒber systemctl:

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

Wir ĂŒberprĂŒfen: Der Dienst sollte gestartet sein, und wenn wir den Befehl consul members ausfĂŒhren, sehen wir unseren Server:

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

NĂ€chster Schritt: Installation von Nginx und Konfiguration des Proxys sowie der HTTP-Authentifizierung. Wir installieren nginx ĂŒber den Paketmanager und erstellen in dem Verzeichnis /etc/nginx/sites-enabled die 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 "PasswortgeschĂŒtzter Bereich";
    }
}

Vergessen Sie nicht, eine .htpasswd-Datei zu erstellen und einen Benutzernamen sowie ein Passwort dafĂŒr zu generieren. Dieser Schritt ist notwendig, um sicherzustellen, dass das Web-Panel nicht fĂŒr jeden zugĂ€nglich ist, der unsere Domain kennt. Beim Einrichten von GitLab mĂŒssen wir jedoch darauf verzichten — andernfalls können wir unsere Anwendung nicht in Nomad bereitstellen. In meinem Projekt befinden sich sowohl GitLab als auch Nomad nur im internen Netzwerk, daher gibt es hier kein solches Problem.

Auf den beiden anderen Servern installieren wir die Consul-Agenten gemĂ€ĂŸ den folgenden Anweisungen. Wiederholen Sie 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 das Verzeichnis fĂŒr die Konfigurationsdateien /etc/consul.d mit der folgenden 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", # lokale VM-Adresse
    "start_join": ["172.30.0.15"], # externe Adresse des Consul-Servers
    "ports": {
      "dns": 53
     }

Änderungen werden gespeichert und wir gehen zu den Service-Datei-Einstellungen ĂŒber, deren Inhalt ist:

/etc/systemd/system/consul.service:

[Unit]
Description="HashiCorp Consul - Eine Service-Mesh-Lösung"
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. Nach dem Start sollten wir in nsul members den konfigurierten Dienst sehen. Das bedeutet, dass er erfolgreich als Client mit dem Cluster verbunden ist. Wiederholen Sie dasselbe auf dem zweiten Server, und danach können wir mit der Installation und Konfiguration von Nomad beginnen.

Eine detaillierte Installation von Nomad ist in der offiziellen Dokumentation beschrieben. Es gibt zwei herkömmliche Installationsmethoden: den Download der BinÀrdatei und die Kompilierung aus den Quellen. Ich werde die erste Methode wÀhlen.

Hinweis: Das Projekt entwickelt sich sehr schnell, und es werden hĂ€ufig neue Updates veröffentlicht. Es ist möglich, dass zum Zeitpunkt des Abschlusses des Artikels eine neue Version herauskommt. Daher empfehle ich, vor dem Lesen die aktuelle Version von Nomad zu ĂŒberprĂŒfen und diese 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 die BinĂ€rdatei von Nomad mit einer GrĂ¶ĂŸe von 65 MB – sie muss in /usr/local/bin/ verschoben werden.

Lassen Sie uns ein Datenverzeichnis fĂŒr Nomad erstellen und die Service-Datei bearbeiten (die wahrscheinlich zu Beginn nicht vorhanden ist):

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

Wir eilen jedoch nicht, um Nomad zu starten – wir haben die 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 wird wie folgt aussehen:

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

Die Datei nomad.hcl sollte 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 muss der Wert der http-Direktive angepasst werden.

Als Letztes in diesem Schritt steht die Konfiguration von Nginx fĂŒr das Proxying und die Einrichtung der http-Authentifizierung an. 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 "PasswortgeschĂŒtzter Bereich";
        }
        
}

Jetzt können wir auf das Web-Panel ĂŒber das externe Netzwerk zugreifen. Wir verbinden uns und gehen auf die Seite servers:

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

Beide Server werden erfolgreich im Panel angezeigt, das gleiche sehen wir auch in der Ausgabe des Befehls nomad node status:

Einrichten eines Nomad-Clusters mit Consul und Integration in GitLab
Abbildung 2. Ausgabe des Befehls nomad node status

Wie sieht es auf der Seite von Consul aus? Lassen Sie uns einen Blick darauf werfen. Wir gehen zum Consul-Dashboard, zur Seite Knoten:
Einrichten eines Nomad-Clusters mit Consul und Integration in GitLab
Abbildung 3. Liste der Knoten im Consul-Cluster

Jetzt haben wir Nomad eingerichtet, das zusammen mit Consul arbeitet. Im abschließenden Schritt kommen wir zu dem spannendsten Teil: Wir richten die Lieferung von Docker-Containern aus GitLab in Nomad ein und sprechen auch ĂŒber einige seiner anderen charakteristischen Merkmale.

Erstellung eines GitLab Runners

FĂŒr das Deployment von Docker-Images in Nomad werden wir einen separaten Runner mit der Nomad-BinĂ€rdatei darin verwenden (hierbei ist zu beachten, dass die Anwendungen von Hashicorp jeweils als einzelne BinĂ€rdatei auftreten). Laden Sie diese in das Verzeichnis des Runners hoch. FĂŒr ihn erstellen wir 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

In diesem Projekt erstellen wir .gitlab-ci.yml:

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

Phasen:
  - bauen

bauen:
  Phase: bauen
  Bild: ${DOCKER_REGISTRY}/nomad/alpine:3
  Skript:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:latest
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}

Am Ende haben wir ein verfĂŒgbares Image des Nomad-Runners im Gitlab-Registry. Jetzt können wir direkt zum Projekt-Repository ĂŒbergehen, einen Pipeline erstellen und den Nomad-Job konfigurieren.

Projekteinrichtung

Wir beginnen mit der Job-Datei fĂŒr Nomad. Mein Projekt in diesem Artikel wird ziemlich einfach sein: Es wird aus einer einzigen Aufgabe bestehen. Der Inhalt von .gitlab-ci wird wie folgt aussehen:

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

Phasen:
  - bauen
  - bereitstellen

bauen:
  Phase: bauen
  Bild: ${DOCKER_REGISTRY}/nomad-runner/alpine:3
  Skript:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA}
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}


bereitstellen:
  Phase: bereitstellen
  Bild: registry.example.com/nomad/nomad-runner:latest
  Skript:
    - 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 "Erfolg"; fi
    - nomad run job.nomad
  Umgebung:
    Name: Produktion
  Fehler zulassen: false
  Wann: manuell

Hier erfolgt das Deployment manuell, jedoch können Sie es so konfigurieren, dass der Inhalt des Projektverzeichnisses geÀndert wird. Die Pipeline besteht aus zwei Phasen: dem Erstellen des Images und dem Deployen in Nomad. In der ersten Phase erstellen wir das Docker-Image und pushen es in unser Registry, wÀhrend wir in der zweiten Phase unseren Job in Nomad starten.

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 ein geschlossenes Registry habe und zur erfolgreichen Abfrage des Docker-Images eine Authentifizierung notwendig ist. Die beste Lösung in diesem Fall ist es, ein Login und ein Passwort im Vault zu speichern und dieses anschließend mit Nomad zu integrieren. Nomad unterstĂŒtzt Vault nativ. ZunĂ€chst mĂŒssen wir jedoch im Vault die erforderlichen Policies fĂŒr Nomad einrichten, die Sie hier hochladen können:

# 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

Jetzt, da wir die notwendigen Policies erstellt haben, fĂŒgen wir im Abschnitt Task in der Datei job.nomad die Integration mit Vault hinzu:

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

Ich verwende die Authentifizierung ĂŒber ein Token und gebe dieses hier direkt an; es besteht zudem die Möglichkeit, das Token als Variable beim Start des Nomad-Agenten anzugeben:

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

Jetzt können wir die SchlĂŒssel aus dem Vault nutzen. Das Prinzip ist einfach: Wir erstellen eine Datei in dem Nomad Job, die die Werte der Variablen speichert, 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 unkomplizierten Ansatz können Sie die Bereitstellung von Containern im Nomad-Cluster einrichten und anschließend damit arbeiten. Ich persönlich bin Nomad gegenĂŒber positiv eingestellt – es eignet sich besser fĂŒr kleinere Projekte, wo Kubernetes zusĂ€tzliche Komplikationen verursachen könnte und nicht sein volles Potenzial entfalten kann. Zudem ist Nomad ideal fĂŒr AnfĂ€nger – die Installation und Konfiguration sind einfach. Allerdings habe ich bei Tests mit bestimmten Projekten auf Probleme mit Ă€lteren Versionen gestoßen – viele grundlegende Funktionen fehlen oder arbeiten nicht korrekt. Ich bin jedoch ĂŒberzeugt, dass Nomad sich weiterentwickeln wird und in Zukunft alle notwendigen Funktionen bieten wird.

Autor: Ilja Andrejew, redigiert von Alexei Schadan und dem Team von „Live Linux“


Quelle: habr.com

Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster