Foreman Logo

Wer kennt das nicht am besten soll alle nervige, wiederkehrende Arbeit automatisiert werden, damit man mehr Zeit für spaßige, neue Projekte hat? Es gibt nach Backups wohl kein Thema, mit dem man so wenig Ruhm ernten kann, wie Updates, oder? Also ein klarer Fall für Automatisierung! Oder doch nicht weil zu viel schief gehen kann? Nun ja, diese Entscheidung kann ich euch nicht abnehmen. Aber zumindest für eine häufige Fehlerquelle kann ich eine Lösung anbieten und zwar das zeitgleiche Update eines Clusters, was dann doch wieder zum Ausfall des eigentlich hochverfügbaren Service führt.

Bevor ich aber nun zu der von mir vorgeschlagen Lösung komme, will ich kurz erklären wo die Inspiration hierfür herkommt, denn Foreman DLM (Distributed Lock Manager) wurde stark vom Updatemechanismus von CoreOS inspiriert. Hierbei bilden CoreOS-Systeme einen Cluster und über eine Policy wird eingestellt wie viele gleichzeitig ein Update durchführen dürfen. Sobald nun ein neues Update verfügbar ist, beginnt ein System mit dem Download und schreibt in einen zentralen Speicher ein Lock. Dieses Lock wird dann nach erfolgreichem Update wieder freigegeben. Sollte allerdings ein weitere System ein Lock anfordern um sich upzudaten und die maximalen gleichzeitigen Locks werden bereits von anderen Systemen gehalten, wird kein Update zu dem Zeitpunkt durchgeführt sondern später erneut angefragt. So wird sichergestellt, dass die Container-Plattform immer mit genug Ressourcen läuft. CoreOS hat dazu dann noch weitere Mechnismen wie einen einfachen Rollback auf den Stand vor dem Update und verschiedene Channel zum Testen der Software, welche so einfach nicht auf Linux zur Verfügung stehen. Aber einen Locking-Mechanismus zur Verfügung zu stellen sollte machbar sein, dachte sich dmTech. Dass die Wahl auf die Entwicklung als ein Foreman-Plugin fiel lässt sich leicht erklären, denn dieser dient dort als das zentrale Tool für die Administration.

Wie sieht nun die Lösung aus? Mit der Installation des Plugins bekommt Foreman einen neuen API-Endpunkt über den Locks geprüft, bezogen und auch wieder freigegeben werden können. Zur Authentifizierung werden die Puppet-Zertifikate (oder im Fall von Katello die des Subscription-Managers) genutzt, die verschiedenen HTTP-Methoden stehen für eine Abfrage (GET), Beziehen (PUT) oder Freigaben (DELETE) des Lock und die Antwort besteht aus einem HTTP-Status-Code und einem JSON-Body. Der Status-Code 200 OK für erfolgreiche Aktionen und 412 Precondition Failed wenn Beziehen und Freigeben des Locks nicht möglich ist sowie der Body können dann im eigenen Update-Skript ausgewertet werden. Ein einfaches Beispiel findet sich hierbei direkt im Quelltext-Repository. Ein etwas umfangreicheres Skript bzw. quasi ein Framework wurde von einem Nutzer in Python entwickelt und ebenfalls frei zur Verfügung gestellt.

Im Folgenden nun noch ein paar Beispiele von Kommandozeile und Visualisierung aus meiner eigenen Katello-Instance.

Als Ausgangsbasis ist das Lock verfügbar.
Foreman DLM - Lock verfügbar

Mit dem folgenden Befehl wird das Lock katello bezogen.

# curl -H 'Content-Type: application/json' --key /etc/pki/katello-certs-tools/private/katello.osdc-puppet-client.key --cert /etc/pki/katello-certs-tools/certs/katello.osdc-puppet-client.crt -X PUT https://katello.osdc/api/dlmlocks/katello/lock
{"created_at":"2019-06-13 12:14:53 UTC","updated_at":"2019-07-10 18:33:47 UTC","id":1,"host_id":1,"name":"katello","enabled":true,"type":"ForemanDlm::Dlmlock::Update","host":{"name":"katello.osdc"}}

Und auch in der Oberfläche wird es als reserviert angezeigt.
Foreman DLM - Lock reserviert

Zeit das Lock wieder freizugeben.

# curl -H 'Content-Type: application/json' --key /etc/pki/katello-certs-tools/private/katello.osdc-puppet-client.key --cert /etc/pki/katello-certs-tools/certs/katello.osdc-puppet-client.crt -X DELETE https://katello.osdc/api/dlmlocks/katello/lock
{"created_at":"2019-06-13 12:14:53 UTC","updated_at":"2019-07-10 18:35:39 UTC","id":1,"host_id":null,"name":"katello","enabled":true,"type":"ForemanDlm::Dlmlock::Update","host":null}

Das Lock lässt sich auch in der Oberfläche sperren.
Foreman DLM - Lock gesperrt

Nun lässt es sich auch nicht mehr beziehen.

# curl -H 'Content-Type: application/json' --key /etc/pki/katello-certs-tools/private/katello.osdc-puppet-client.key --cert /etc/pki/katello-certs-tools/certs/katello.osdc-puppet-client.crt -X PUT https://katello.osdc/api/dlmlocks/katello/lock
{
  "error": {"id":1,"message":"Precondition failed. Lock is in invalid state for this operation."}
}

Wie man sieht kein Hexenwerk, aber ein extrem hilfreiches Werkzeug um es in seinen automatisierten Update-Workflow einzubinden oder mit Hilfe der Beispiele einen zu entwickeln.

Dieses Plugins ist zwar noch kein Teil der Foreman-Schulung, dafür aber viele andere, die mir im Consulting geholfen haben Kundenanforderungen zu lösen. Außerdem möchte ich noch auf den von NETWAYS und ATIX organisierten Foreman Birthday am 25.07.2019 und das Opensourcecamp on Foreman am 07.11.2019 in Nürnberg hinweisen. Beide Veranstaltungen bieten neben einem interessanten Programm auch die Möglichkeit sich mit Entwicklern und Nutzern auszutauschen und genau solche Plugins und Workflows kennenzulernen.

Dirk Götz
Dirk Götz
Principal Consultant

Dirk ist Red Hat Spezialist und arbeitet bei NETWAYS im Bereich Consulting für Icinga, Puppet, Ansible, Foreman und andere Systems-Management-Lösungen. Früher war er bei einem Träger der gesetzlichen Rentenversicherung als Senior Administrator beschäftigt und auch für die Ausbildung der Azubis verantwortlich wie nun bei NETWAYS.