ACLs in föderierten Nomad-Clustern

Ich schreibe nur kurz die aktuellen Erkenntnisse zum Thema Access Control Lists (ACLs) in föderierten Nomad Clustern auf.

Mit ACLs werden in Nomad Role-Based Access Controls (RBAC) realisiert. Das ACL Subsystem ist standardmässig nicht eingeschaltet sondern wird aktiviert, wenn man in der Server Konfiguration

acl {
  enabled    = true
}

einträgt. Ist das geschehen, muß das System aber noch "eingeschaltet" werden. Mit nomad acl bootstrap. Das Kommando gibt als "Secret ID" das Management-Token aus, welches quasi das "Root"-Token für das Cluster ist. Damit kann man dann weitere Token und Policies erstellen.

Wenn man Nomad-Cluster aufsetzt, die man föderieren möchte, ist es nicht sinnvoll und auch nicht erwünscht, das ACL-System bei jedem Cluster einzeln zu aktivieren und einzuschalten. Stattdessen sollen sich alle Cluster wie ein großes Cluster verhalten und verwalten lassen.

Direkt nach dem Aufsetzen (z. B. mit terraform) kann man mit einem Cluster, in dem ACLs eingeschaltet aber noch nicht per nomad acl bootstrap eingeschaltet wurden, im Grunde kaum etwas tun. Fast alle Kommandos werden mit einem "403 - permission denied" beantwortet.

Man kann die Cluster aber mit nomad server join föderieren. Dazu ist offensichtlich kein eingeschaltetes ACL-System erforderlich.

Ob die Reihenfolge stimmt, weiß ich nicht genau. Aber nach dem join kann man dann im ersten Cluster mit nomad acl bootstrap das ACL-System einschalten. Nachdem man das Management-Token bekommen hat, erzeugt man damit ein Replication-Token:

$ nomad acl token create -type="management" -global=true \
  -name="prod2-replication-token" \
  -token="b1e55cc6-8289-6b6e-c779-9f0b0a30e96b"
Accessor ID  = d74642e7-2b8b-25c1-d4e9-169e18548788
Secret ID    = 6ca5eae5-adb9-1687-f2f3-214ab5c4f8c5

Mit diesen Informationen ändert man jetzt die Server-Konfiguration im zweiten Cluster ab:

server {
  ...
  authoritative_region = "prod2"  
  ...
}

acl {
  ...
  replication_token = "6ca5eae5-adb9-1687-f2f3-214ab5c4f8c5"
  ...
}

Unter authoritative_region wird das erste Cluster eingetragen und unter replication_token wird das gerade erzeugte Token eingetragen. Danach wird der Nomad Dienst im zweiten Cluster auf allen Server Nodes nacheinander durchgestartet.

Es ist ein bekannter Bug, dass das Cluster, welches sich die Konfiguration des authoritativen Clusters repliziert, Fehlermeldungen der Art

Jan 08 14:54:19 nomad-2 nomad[1670]:     2024-01-08T14:54:19.425Z [ERROR] nomad.fsm: DeleteNodePools failed: error="deleting node pool \"all\" is not allowed"
Jan 08 14:54:19 nomad-2 nomad[1670]: nomad.fsm: DeleteNodePools failed: error="deleting node pool \"all\" is not allowed"
Jan 08 14:54:19 nomad-2 nomad[1670]:     2024-01-08T14:54:19.425Z [ERROR] nomad.fsm: DeleteNamespaces failed: error="default namespace can not be deleted"
Jan 08 14:54:19 nomad-2 nomad[1670]:     2024-01-08T14:54:19.425Z [ERROR] nomad.fsm: DeleteNodePools failed: error="deleting node pool \"all\" is not allowed"

ausgibt.

Wenn das geschehen ist, kann man mit dem Management-Token vom ersten Cluster auch im zweiten Cluster arbeiten. Außerdem funktioniert der Zugriff in der Nomad-GUI auf alle Informationen der föderierten Regionen, wenn man das Management-Token verwendet.

Ganz wichtig: Im Gegensatz zu Consul hat Nomad das Konzept von "Regionen". Bei der Föderierung von Nomad Clustern werden "Regionen" föderiert - nicht "Datacenter" (wenn man die Regionen nicht genauso benennt wie die Datacenter).

Das geht auf das Setup vieler Hyperscaler zurück, die in einer Region in der Regel mindestens drei Availability Zonen (AZ) haben. In solchen Umgebungen kann man z. B. in jeder AZ einen Nomad-Server ausrollen, um damit einen Cluster aufzubauen. Der Cluster umfasst dann alle Ressourcen aller beteiligten AZ.

Unsere Regionen sind "de-north" und "de-west" - diese bestehen jeweils aus mindestens zwei AZ. Natürlich kann man auch in jeder AZ einen Cluster mit jeweils drei Nomad-Servern erzeugen. Beide Cluster sind aber trotzdem Teile einer Region - es ist keine Föderierung zwischen diesen Clustern zu konfigurieren. Es wird nur der Eintrag

server {
  enabled          = true
  authoritative_region = "de-north"
  ...
}

benötigt. Es wird kein replication_token benötigt. Das Cluster wird nur per nomad server join <ip-des-anderen-clusters-in-dieser-region> an das authoritative Cluster angedockt.

Damit sind dann alle Datacenter der fraglichen Region in der Nomad GUI (z. B. mit ihren gesammelten Clients) zu sehen:

Weitere Datacenter und Clients in derselben Region sind damit natürlich schnell hinzuzufügen. Weitere Regionen müssen mit den oben genannten Schritten angebunden werden.

Auf der Kommandozeile kann man auch schön sehen, dass es pro Region einen "Leader" gibt - und nicht pro Datacenter: