Best Practice für automatisierte Linux-Updates

11

Wir arbeiten an einer Möglichkeit, automatische Updates für unsere RHEL / RHEL-basierten Server durchzuführen.

Erste Idee: Mit Puppet deaktivieren wir die Standard-Repositorys und verweisen auf unsere eigenen. Dann verwenden wir ensure => latestfür die Pakete, die wir automatisch aktualisieren möchten.

Problem: Wir sehen, dass einige Dienste nach einem Update (duh) neu gestartet werden.

Frage: Hat jemand Ratschläge, wie Linux-Updates und Strategien zur Abschwächung des automatischen Neustarts von Diensten besser automatisiert werden können? Wir würden eine Lösung bevorzugen, die Puppet enthält, aber wenn wir einen anderen Dienst nutzen müssen, ist dies kein Deal-Breaker.

Bearbeiten

Mögliche Lösung: Ich habe eine Lösung eingereicht, die viele der Vorschläge von @ voretaq7 und @ewwhite implementiert. Scheint so, als ob dies der Weg ist, den ich vorerst gehe. Wenn Sie weitere Vorschläge haben, kommentieren Sie diese bitte oder senden Sie eine Antwort.

Belmin Fernandez
quelle

Antworten:

14

Ihre allgemeine Update-Strategie ist solide: Sie haben ein lokales Repo (von dem ich annehme, dass Sie es in einer Entwicklungsumgebung testen), und Sie aktualisieren alles basierend auf diesem Repo (ich nehme an, dass es als gut bekannt ist).

Der Neustart des Dienstes ist unvermeidlich: Wenn sich der zugrunde liegende Code geändert hat, müssen Sie den Dienst neu starten, damit diese Änderung wirksam wird. Andernfalls kann dies zu schlimmeren Konsequenzen führen (nicht synchroner Code mit einer gemeinsam genutzten Bibliothek führt zum Absturz der Anwendung).
In meiner Umgebung betrachte ich die vierteljährlichen Patch-Fenster als vierteljährlich "REBOOT ALL THE THINGS!" Fenster auch. Der Vorteil einer solchen Richtlinie besteht darin, dass Sie wissen, dass Ihre Server nach einem Neustart wieder hochgefahren werden und dass sie ordnungsgemäß funktionieren (weil Sie sie regelmäßig testen).


Mein bester Rat an Sie ist, die Softwareversionen zu planen (möglicherweise bedeutet dies, dass Sie sie "manuell" mit Puppet auslösen müssen) und Ihre Benutzer über die geplanten Wartungs- / Ausfallzeiten zu informieren.
Alternativ (oder als Teil davon) können Sie die Redundanz in Ihrer Umgebung so konfigurieren, dass einige Computer oder Dienste neu gestartet werden und den Endbenutzern weiterhin Dienste zur Verfügung gestellt werden. Dadurch werden Störungen möglicherweise nicht vollständig beseitigt, sie können jedoch minimiert werden.

Die zusätzliche Redundanz schützt Sie auch bei Hardwarefehlern, die über einen ausreichend langen Zeitraum unvermeidlich sind.

voretaq7
quelle
4
+1 für Neustart aller Dinge.
Tom O'Connor
2
@ TomO'Connor Ich habe es auf die harte Tour gelernt. Ich fühle mich bis zu 3 Monate zwischen den Neustarts sehr wohl. Danach frage ich mich, was ich getan habe, das wird verschwinden. Beim letzten Neustart haben wir tatsächlich einen VPN-Tunnel verloren (Der Tunnel war fest codiert und wurde
aufgerufen
Gepostet eine mögliche Lösung von Ihnen inspiriert @ voretaq7
Belmin Fernandez
@ BeamingMel-Bin Das solltest du als Antwort posten - es klingt nach einem vernünftigen Ansatz.
voretaq7
Vielen Dank. Veröffentlichte es zusammen mit einigen Änderungen am Workflow, je nachdem, was ich auf der Heimfahrt gedacht hatte.
Belmin Fernandez
5

Gibt es notwendigerweise ein Problem beim Neustart eines Dienstes nach einer Paketaktualisierung? Testen Sie vor der Bereitstellung in kleinem Maßstab, um festzustellen, ob Probleme vorliegen. Ich hatte kürzlich ein hässliches Problem mit dem rpmforge-Paket von DenyHosts . Es hat tatsächlich den Speicherort seiner Konfigurations- und Arbeitsverzeichnisse zwischen den Revisionen eines yum-Updates geändert. Das ist völlig unerwünschtes Verhalten. Normalerweise gibt es innerhalb derselben Version von RHEL nicht allzu viele Probleme, aber Sie können nie sicher sein, ohne die Auswirkungen genau zu testen und zu beobachten.

Eine weitere Option ist das selektive Aktualisieren von Diensten. Benötigen Sie zum Beispiel immer die neuesten Pakete? Dies geht zurück auf das Verständnis Ihrer Gründe für das Ausführen von Updates. Was ist das eigentliche Ziel?

Der Vorteil des eigenen Repos besteht darin, dass Sie Releases oder Rollouts bereitstellen und den Zeitplan verwalten können. Was ist, wenn Sie einen Hardware-Peripherie- oder Softwareanbieter haben, der RHEL 5.6 benötigt und unter 5.7 kaputt gehen würde? Dies ist einer der Vorteile bei der Verwaltung Ihrer eigenen Pakete.

ewwhite
quelle
Ich würde sagen, wenn das Update-Set einen Neustart des Dienstes auslöst, möchten Sie diesen Neustart auf jeden Fall durchführen. Wenn Sie dieses Update nicht durchführen MÜSSEN (es kauft Ihnen keine Funktion, Sicherheitsverbesserung oder etwas anderes, das Sie benötigen), würde ich es natürlich nicht tun, oder ich würde warten, bis ich den Ausfall planen könnte Seien Sie bequem für mich und meine Benutzer.
voretaq7
2

@Beaming Mel-Bin

Die Vereinfachung macht die Verwendung von ssh für Schleifenwerkzeuge zum Starten / Stoppen der Puppe überflüssig.

Zunächst müssen Sie Ihre Manifeste so ändern, dass sie eine Variable namens "noop" enthalten, deren Wert von der ENC stammt.

So etwas hätten Sie in einer Klasse:

noop => $noop_status

Wo noop_statusist in Ihrer ENC eingestellt. Wenn Sie den Wert noop_statusauf truefestlegen, wird das Manifest nur im Noop-Modus ausgeführt.

Wenn Sie über 100 oder 1000 Hosts verfügen, können Sie eine ENC wie Dashboard oder Foreman verwenden, mit der Sie Parameter für viele Hosts massenweise ändern können, indem Sie sie auf der Ebene "Hostgruppe" oder "Domäne" erben. Sie können dann den Wert für eine kleine Anzahl von Testhosts auf "false" setzen und den Hostgruppenwert überschreiben.

Damit werden alle Änderungen nur auf ausgewählte Hosts angewendet.

Das Ändern eines Parameters an einer zentralen Stelle kann sich auf eine beliebige Anzahl von Hosts auswirken, ohne dass die Puppe mit ssh für Schleifenwerkzeuge ein- oder ausgeschaltet werden muss. Sie können Ihre Hosts aus Sicherheits- / Verwaltungsgründen in mehrere Gruppen aufteilen.

Beachten Sie auch, dass Sie die Versionsnummern der Pakete in Manifesten nicht fest codieren, sondern in die ENC einfügen können. Und genau wie oben können Sie Änderungen selektiv anwenden und Rollouts verwalten.

Wenn Sie mehr Granularität (und Komplexität) wünschen, können Sie sogar Parameter pro Klasse haben, wie z noop_status_apacheClass.

Dies ist möglicherweise schwieriger zu verwalten, wenn Sie includeKlassen in anderen Klassen haben.

Nicht jetzt
quelle
1

Mögliche lösungsbasierte Antwort von @ voretaq7:

  1. Hardcode-Versionsnummern von Paketen in den puppetManifesten und verwalten Sie die Pakete in unserem eigenen Repository.

  2. Wenn wir eine neue Version eines Pakets benötigen, um etwas zu tun, das es bietet (z. B. Sicherheitsverbesserungen, von unseren Kunden geforderte Funktionen usw.), laden wir das Paket in das Repository herunter.

  3. Testen Sie das aktualisierte Paket auf einem Testserver.

  4. Verwenden Sie nach dem Testen des Updates etwas wie funcoder pssh, um den puppetAgenten auf den betroffenen Knoten auszuschalten .

  5. Aktualisieren Sie die puppetManifeste, um sicherzustellen, dass die neue Version des Pakets auf den betroffenen Knoten installiert ist.

  6. Führen Sie schließlich puppet agent --onetime && rebootmit funcoder auf dem Server auspssh

Bitte kommentieren Sie und lassen Sie mich wissen, wenn Sie Mängel in dieser Lösung oder etwas feststellen, das vereinfacht werden könnte.

Belmin Fernandez
quelle
1
Es ist möglich, dies mit einer ENC und Parametern zu vereinfachen. Dies erfordert eine Neuanordnung der Manifeste, die möglicherweise nicht für alle möglich ist.
Nicht jetzt
Bitte erläutern Sie @NotNow und geben Sie eine Antwort. Interessiert zu wissen.
Belmin Fernandez