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.

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:
- nomad-livelinux-01: 172.30.0.5
- nomad-livelinux-02: 172.30.0.10
- 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.jsonIm 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 -uiDas 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.targetWir 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 dc1NĂ€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.jsonInhalt 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.targetWir 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.dNach 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.serviceFĂŒ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.targetWir 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.hclDie 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:

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:

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:

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: manuellHier 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.jsonJetzt, 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
