Ich hatte ja schonmal einen Artikel zum diesem Thema geschrieben. Dort wurde schon beschrieben, wie zwei Nomad/Consul-Installationen in zwei verschiedenen Cloud-Umgebungen (AWS und GCP) per Terraform installiert und "föderiert" wurden.
Voraussetzung für dieses Konstrukt war aber, dass beide Cloud-Umgebungen vorher per VPN verbunden werden mussten.
Jetzt ist der Plan, so ein Konstrukt ohne weitere Nutzung von Diensten der unterliegenden Cloud-Umgebungen aufzubauen.
Wie man zwei Consul-Installationen verbindet hatte ich schon in "Consul Datacenter Federation" beschrieben.
Leider (oder zum Glück) unterscheiden sich die verschiedenen Hashicorp Produkte an der ein oder anderen Stelle - deshalb waren die Erfahrungen bei Consul nicht 1:1 auf Nomad zu übertragen. Denn dort haben wir ähnliche Probleme wie bei Consul.
Auch bei Nomad müssen wir erzwingen, dass für die Kommunikation der Server untereinander die öffentliche Adresse verwendet wird. Bei Nomad wird dazu die advertise
Anweisung in der Server-Konfiguration benutzt. In meinem Template sieht das jetzt so aus:
advertise {
# Defaults to the first private IP address.
http = "{{ GetInterfaceIP \"ens3\" }}" # must be reachable by Nomad CLI clients
rpc = "{{ GetInterfaceIP \"ens3\" }}" # must be reachable by Nomad client nodes
serf = "${floatingip}" # must be reachable by Nomad server nodes
}
ports {
http = 4646
rpc = 4647
serf = 4648
}
Die ${floatingip}
wird dabei aus der entsprechenden Ressource von Terraform befüllt:
content = templatefile("${path.module}/templates/nomad.hcl.tpl", {
datacenter_name = var.config.datacenter_name,
domain_name = var.config.domain_name,
os_domain_name = var.config.os_domain_name,
node_name = "nomad-${count.index}",
bootstrap_expect = var.config.server_replicas,
# nomad_encryption_key = random_id.nomad_encryption_key.b64_std,
nomad_encryption_key = var.config.nomad_encryption_key,
upstream_dns_servers = var.config.dns_servers,
auth_url = "${var.auth_url}",
user_name = "${var.user_name}",
password = "${var.password}",
os_region = "${var.config.os_region}",
floatingip = "${element(openstack_networking_floatingip_v2.nomad_flip.*.address, count.index)}",
})
destination = "/etc/nomad/nomad.hcl"
Damit lassen sich die beteiligten Nomad Datacenter bzw. Regionen problemlos "verheiraten":
debian@nomad-2:~$ nomad server members
Name Address Port Status Leader Raft Version Build Datacenter Region
nomad-0.prod2 194.64.176.147 4648 alive false 3 1.7.2 prod2 prod2
nomad-1.prod2 194.64.176.22 4648 alive false 3 1.7.2 prod2 prod2
nomad-2.prod2 194.64.176.226 4648 alive true 3 1.7.2 prod2 prod2
nomad-0.prod3 194.64.177.186 4648 alive false 3 1.7.2 prod3 prod3
nomad-1.prod3 194.64.177.219 4648 alive true 3 1.7.2 prod3 prod3
nomad-2.prod3 194.64.177.44 4648 alive false 3 1.7.2 prod3 prod3
Jetzt fehlt noch das Aufsetzen des Consul Service Mesh ohne Kubernetes. Zum Glück gibt es auch dazu schon Informationen von Guy Barros, der dazu schon einen Medium-Artikel und ein Youtube-Video gemacht hat:
Er hat natürlich auch ein GitHub-Repository, in welchem sich dazu wertvolle Informationen finden. Mal sehen, ob wir es hinbekommen, damit eine sinnvolle Applikation in zwei unabhängigen Cloud-Umgebungen möglichst ausfallsicher auszurollen. Dazu dann mehr, sobald das auch läuft.