Fedora CoreOS ist ein leichtgewichtiges, containerfokussiertes Betriebssystem, das darauf ausgelegt ist, automatisch und häufig mit atomaren Updates aktualisiert zu werden. Das bedeutet, dass das gesamte Betriebssystem als Ganzes aktualisiert wird. Dies ist eine großartige Funktion, um Ihr System auf dem neuesten Stand und sicher zu halten. Es kann jedoch eine Herausforderung sein, Updates über mehrere Maschinen hinweg zu koordinieren. Es gibt einige Anwendungsfälle, bei denen es sinnvoll ist, das Timing der Updates zu steuern. Zum Beispiel, wenn Sie einen 3-Knoten-Datenbank-Cluster betreiben, möchten Sie nicht alle Maschinen gleichzeitig aktualisieren (was einen Neustart erfordert). Dies würde zu einem Ausfall Ihrer Datenbank führen. Stattdessen sollten Sie eine Maschine nach der anderen aktualisieren, damit die Datenbank auf einen anderen Knoten übergehen kann, während die erste Maschine aktualisiert wird. Dies wird als “Rolling Update” bezeichnet. In diesem Blogpost erfahren wir, wie man OS-Updates auf mehreren Fedora CoreOS-Maschinen mithilfe von etcd und Airlock koordiniert.

Voraussetzungen

  • Ein etcd-Cluster, der von Airlock zur Koordinierung der OS-Updates verwendet wird. Wir haben einen Blogbeitrag, der beschreibt, wie Sie einen etcd-Cluster einrichten hier.
  • Zwei oder mehr Fedora CoreOS-Maschinen, die Airlock ausführen. In diesem Fall verwenden wir Maschinen, die das Spilo-Container-Image nutzen. Die Anleitung zur Einrichtung von Spilo auf Fedora CoreOS finden Sie hier.

Airlock-Konfiguration

Airlock ist ein Tool zur Koordinierung von OS-Updates auf mehreren Fedora CoreOS-Maschinen. Es ist ein einfaches Tool, das etcd zur Koordination der Updates verwendet. Es ist als Container-Image verfügbar und kann auf jedem Container-Runtime-System ausgeführt werden.

Airlock benötigt eine .toml-Datei für seine Konfiguration. Wir können die folgende config.toml-Datei für unser Setup verwenden:

# Konfiguration des Statusdienstes
[status]
enabled = true
address = "localhost" # Kann auf private / öffentliche IP der Maschine geändert werden
port = 2222
tls = false

# Hauptdienstkonfiguration
[service]
address = "localhost" # Kann auf private / öffentliche IP der Maschine geändert werden
port = 3333
tls = false

# Etcd-v3 Client Konfiguration
[etcd3]
endpoints = [ "http://10.0.1.33:2379","http://10.0.1.34:2379" ] 

# Ersetzen Sie diese durch Ihre etcd-Endpunkte
client_cert_pub_path = "/etc/ssl/self-certs/proventa-client-cert.pem"
client_cert_key_path = "/etc/ssl/self-certs/proventa-client-cert-key.pem"

# Sperrkonfiguration, Basis-Reboot-Gruppe
[lock]
default_group_name = "default"
default_slots = 2

# Zusätzliche Reboot-Gruppen
[[lock.groups]]
name = "patroni"
slots = 1

Der Abschnitt status konfiguriert den Statusdienst, der verwendet wird, um den Status der Maschine zu überprüfen. Dieser Endpunkt ist nützlich für die Überwachung des Airlock-Status mit Prometheus und Grafana.

Der Abschnitt service konfiguriert den Hauptdienst, der zur Koordinierung der OS-Updates verwendet wird. An diesen Endpunkt sendet Zincati eine FleetLock-Anfrage, um zu prüfen, ob die Maschine für ein Update neu gestartet werden kann. Das FleetLock-Protokoll ist ein Anfrage-Antwort-Protokoll, das auf HTTP basiert. Mit diesem Protokoll kann Zincati eine Sperre zum Neustart der Maschine anfordern. Die Antwort lautet entweder OK oder BUSY. Bei der Antwort OK kann die Maschine neu gestartet werden. Bei BUSY darf die Maschine nicht neu gestartet werden.

Der Abschnitt etcd3 konfiguriert den etcd-Cluster, den Airlock verwendet. Wir können die IP-Adressen unseres etcd-Clusters im Abschnitt endpoint angeben. Da unser etcd TLS verwendet, haben wir die Pfade zum Client-Zertifikat und zum Schlüssel konfiguriert.

Der Abschnitt lock konfiguriert die Sperre, die von Airlock zur Koordinierung der OS-Updates verwendet wird. Standardmäßig gehört Zincati zur Gruppe default. Daher geben wir default als Namen für default_group_name an, der als Standardgruppenname von Airlock verwendet wird. Die default_slots geben die Anzahl der Maschinen an, die gleichzeitig aktualisiert werden können. Der Abschnitt [[lock.groups]] kann verwendet werden, um zusätzliche Gruppen zu konfigurieren. In diesem Fall haben wir eine Gruppe namens patroni mit einem Slot konfiguriert. Das bedeutet, dass nur eine Maschine in der Gruppe patroni die Sperre übernehmen und das OS-Update durchführen kann.

Zincati-Konfiguration

Nachdem wir die Airlock config.toml-Datei konfiguriert haben, müssen wir Zincati so einrichten, dass es Airlock verwendet. Dazu fügen wir die folgenden Zeilen in die Datei /etc/zincati/config.d/55-updates-strategy.toml ein:

[updates]
strategy = "fleet_lock"
[updates.fleet_lock]
base_url = "http://127.0.0.1:3333" # Change to the address of the Airlock service

Um die von Zincati verwendete Gruppe anzugeben, fügen wir die folgenden Zeilen in die Datei /etc/zincati/config.d/90-custom-identity.toml ein:

[identity]
group = "patroni"

Airlock ausführen

Airlock und Zincati sind nun konfiguriert. Jetzt können wir Airlock auf unseren Fedora CoreOS-Maschinen ausführen. Wir können die folgende Systemd-Unit-Datei-Konfiguration zur bestehenden Butane-Datei für unser Postgres-Cluster aus dem vorherigen Blogpost hinzufügen:

- name: airlock.service
  enabled: true
  contents: |
    [Unit]
    Description=airlock with Podman

    [Service]
    User=patroni-user
    Restart=always
    RestartSec=5s
    TimeoutStartSec=0
    LimitNOFILE=40000

    ExecStartPre=/usr/bin/loginctl enable-linger patroni-user
    ExecStartPre=/usr/bin/podman rm -f airlock-container
    ExecStart=/usr/bin/podman \
    run \
    --rm \
    --net=host \
    --name airlock-container \
    --volume=/etc/ssl/certs:/etc/ssl/certs \
    --volume=/etc/ssl/self-certs:/etc/ssl/self-certs \
    --volume=${HOME}/airlock-config.toml:/etc/airlock/config.toml \
    quay.io/coreos/airlock:main \
    airlock serve -vv
    ExecStop=/usr/bin/podman rm -f airlock-container

    [Install]
    WantedBy=multi-user.target

In dieser Unit-Datei gibt es keine speziellen Konfigurationen. Wir mounten lediglich die erstellte config.toml-Datei und führen den Airlock-Container mit dem Befehl airlock serve -vv aus.

Anschließend können wir das ansible-playbook aus dem vorherigen Blogpost ausführen, um die Maschinen bereitzustellen.

Airlock testen

Nachdem die Maschinen bereitgestellt wurden und Airlock läuft, können wir den Airlock-Dienst testen.

Zuerst benötigen wir die ID der Maschine. Diese erhalten Sie, indem Sie den folgenden Befehl ausführen:

cat /etc/machine-id

Ein Beispiel für die Ausgabe:

2204af7f41984cb19b8cde4edc06c142

Danach erstellen wir eine JSON-Datei für die FleetLock-Anfrage. Wir können eine Datei namens body.json mit folgendem Inhalt erstellen:

{
  "id": "2204af7f41984cb19b8cde4edc06c142",
  "group": "patroni"
}

Zum Schluss senden wir die FleetLock-Anfrage an den Airlock-Dienst mit dem folgenden Befehl:

curl -H "fleet-lock-protocol: true" -d @body.json http://127.0.0.1:3333/v1/pre-reboot

Anschließend können wir das Log des Airlock-Containers überprüfen, um die Antwort zu sehen, indem wir den folgenden Befehl zur Anzeige der Logs ausführen:

podman logs airlock-container

Ein Beispiel für die Ausgabe:

time="2023-09-26T12:58:45Z" level=debug msg="got pre-reboot request"
time="2023-09-26T12:58:45Z" level=debug msg="processing client pre-reboot request" 
group=patroni id=2204af7f41984cb19b8cde4edc06c142
time="2023-09-26T12:58:45Z" level=debug msg="givin green-flag to pre-reboot request" 
group=patroni id=2204af7f41984cb19b8cde4edc06c142

In diesem Fall ist die Antwort green-flag, was bedeutet, dass die Maschine neu gestartet werden kann.

Wenn die Ausgabe jedoch wie folgt aussieht:

time="2023-09-26T15:03:16Z" level=error msg="failed to lock semaphore: all 1 
semaphore slots currently locked"

Dann ist die Antwort red-flag, was bedeutet, dass die Maschine nicht neu gestartet werden kann und die Sperre derzeit von einer anderen Maschine verwendet wird. Sie können diese Antwort erzeugen, indem Sie die ID der Maschine in der body.json-Datei ändern und die Anfrage erneut senden.

Beachten Sie, dass die FleetLock-Anfragen automatisch von Zincati gesendet werden. Es ist daher nicht erforderlich, die Anfragen manuell zu senden. Wir haben die Anfrage nur manuell gesendet, um den Airlock-Dienst zu testen.

Fazit

In diesem Blogpost haben wir gelernt, wie man OS-Updates auf mehreren Fedora CoreOS-Maschinen mit Hilfe von etcd und Airlock koordiniert. Außerdem haben wir gelernt, wie man Airlock und Zincati so konfiguriert, dass Airlock verwendet wird. Schließlich haben wir gelernt, wie man den Airlock-Dienst testet. An diesem Punkt sollten Sie in der Lage sein, OS-Updates auf mehreren Fedora CoreOS-Maschinen mit Hilfe von Airlock zu koordinieren, sodass immer nur eine Maschine gleichzeitig aktualisiert wird. Wir hoffen, dass Sie diesen Blogpost nützlich fanden!

Dirk Aumüller

Dirk Aumueller arbeitet als Associate Partner für die Proventa AG. Sein technologischer Schwerpunkt liegt bei Datenbankarchitekturen mit PostgreSQL sowie Data Management Lösungen mit Pentaho. Zusätzlich zu seinen Datenbanktransformations-Projekteinsätzen ist er regelmäßig als PostgreSQL Trainer unterwegs und betreut Studenten bei ihren Abschlussarbeiten. Seine fachlichen Erfahrungen erstrecken sich über die Branchen Telco und Financial Services.