Weil es bei nebula ja etwas nervt, die Hosts zu verwalten und händisch dem Overlaynetzwerk hinzuzufügen, war ich froh, als ich auf defined networking gestossen bin, die hinter nebula stehen und das Ganze auch "managed" anbieten.
Der Clou dabei ist, dass sie eine API bereithalten, mit der man Hosts automatisch dem Netz hinzufügen kann. Sie haben einen Guide dafür, der Automating Host Creation with the API heißt.
Netterweise gibt es bei defined einen "free tier", in dem man üben kann, wie das funktioniert. Mit einem API-Key bewaffnet, reicht es, sich mit einem Curl-Aufruf den Enrollment-Code zu generieren
curl -L 'https://api.defined.net/v1/host-and-enrollment-code' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer dnkey-grzlbrmpf' \
-d '{
"name": "My new host",
"networkID": "network-grzlbrmpf",
"roleID": "role-grzlbrmpf"
}'
NetworkID und role-ID werden benötigt (wobei "role" hier nichts mit RBAC zu tun hat sondern die Rolle des Hosts beschreibt – insbesondere im Bezug auf die Firewallregeln, die dieser "Host-Rolle" zugewiesen werden sollen).
Mit dem Enrollment-Code kann man dann die folgenden Schritte (automatisiert) auf dem frischen Client durchführen:

Danach läuft auf dem Host der dnclient als systemd-Service. Die Konfiguration "entsteht" während des Enrollments in /etc/defined
. Das Netzwerkinterface zum Overlaynetzwerk heisst dann defined1
und könnte dann z. B. in einer Nomad-Konfiguration entsprechend berücksichtigt werden:
[...]
host_network "overlay" {
interface = "defined1"
}
host_network "internal" {
interface = "ens3"
}
host_network "local" {
interface = "lo"
}
}
advertise {
# Defaults to the first private IP address.
http = "{{ GetInterfaceIP \"defined1\" }}" # must be reachable by Nomad CLI clients
rpc = "{{ GetInterfaceIP \"defined1\" }}" # must be reachable by Nomad client nodes
serf = "{{ GetInterfaceIP \"defined1\" }}" # must be reachable by Nomad server nodes
}
[...]
Das jetzt noch richtig in die Startsequenz eingebaut und dem Autoscaling auch im Overlaynetzwerk steht nicht mehr viel im Wege.
Offenbar hat sich da schonmal jemand Gedanken gemacht:
Leider hat das Skript "dnctl" einen kleinen Bug beim "unenroll". Den habe ich in meiner Version behoben. In
wird nur das obige Repository gezogen und mit sudo ./install
installiert. Danach wird noch eine /etc/defined/dnctl
Datei erstellt. Für mit Autoscaling erstellte Clients lässt man den Namen einfach weg. Genauso wie in der nomad.hcl
. Damit bekommt der Client einen "zufälligen" Namen. Der Dienst dnctl
wird nur enabled aber nicht gestartet – genauso wie bei Nomad.
Mit dem obigen Terraform wird dann einfach eine Instanz in der jeweiligen Umgebung erzeugt, abgeschaltet und ein Snapshot davon erzeugt. Diesen Snapshot verwendet dann der Autoscaler, um bei Scaling-Events neue Instanzen zu erzeugen.
Damit Nomad nach dem Start dann auch die richtige IP-Adresse "advertisen" kann, sollte man die Reihenfolge beim Start der Dienste festlegen:
[Unit]
Description=Nomad
Documentation=https://www.nomadproject.io/docs/
Wants=network-online.target dnctl.service
After=network-online.target dnctl.service
[...]
Wenn alles läuft wie es soll, kann es dann z. B. so aussehen:
root@triton-nomad1:~# nomad server members
Name Address Port Status Leader Raft Version Build Datacenter Region
triton-nomad1.de-west 100.102.0.10 4648 alive false 3 1.9.7 de-gt-2 de-west
nomad-prod1-0.de-west 100.102.0.11 4648 alive false 3 1.9.7 prod1 de-west
nomad-prod4-0.de-west 100.102.0.12 4648 alive true 3 1.9.7 prod4 de-west
Eine hoch ausfallsichere Control Plane, die über drei komplett unabhängige Datacenter verteilt ist. Diese Datacenter können von ganz unterschiedlichen Anbietern betrieben werden. Da als Nomad Client und Nomad Server jede Plattform verwendet werden kann, auf der Nomad läuft, könnten das z. B. VMs oder auch bare metal Server sein - oder eine Mischung aus beidem.
ID Node Pool DC Name Class OS Drain Eligibility Status Running Allocs
692be17d nom-pool prod1 nom-10ceffd6-bbe1 dynamic debian false eligible ready 0
62074377 nom-pool prod4 nom-0e83c376-560c dynamic debian false eligible ready 0
e37a5586 default prod4 nomad-client-prod4-0 <none> debian false eligible ready 2
25edb72f default prod1 nomad-client-prod1-0 <none> debian false eligible ready 3
ed492175 default de-gt-2 nomad-client-triton-0 <none> debian false eligible ready 0
4828a13c default de-gt-2 nomad-client-triton-1 <none> debian false eligible ready 1
Dazu kommen über die Datacenter verteilte Clients, wobei die, die von den Autoscalern bereitgestellt werden, in ihrem eigenen Node-Pool landen. Es könnten noch weitere Clients in beliebigen anderen Datacentern (wieder VMs, bare metal Server, etc.) oder auch andere, föderierte Nomad-Cluster an diesen Cluster angehängt werden, da hier die Anforderungen an die Netzwerklatenz nicht so hoch sind wie innerhalb eines Clusters. Auch die Datacenter müssen nicht auf derselben Technologie aufsetzen. Hier sind nur zwei der Umgebungen auf OpenStack aufgebaut während eine auf Triton Datacenter basiert.