Verwenden einer Falle zum Durchführen einer Umgebungsbereinigung vor dem ordnungsgemäßen Herunterfahren des Docker-Containers

Verwenden einer Falle zum Durchführen einer Umgebungsbereinigung vor dem ordnungsgemäßen Herunterfahren des Docker-Containers

Wie können wir beim Beenden eines laufenden Containers einige vordefinierte Aktionen ausführen, z. B. die Umgebung bereinigen, bevor der Container vollständig beendet wird? Dies ist ein Hook-Erlebnis ähnlich dem Pre-Stop. Docker selbst kann diese Funktion jedoch nicht bereitstellen. Dieser Artikel kombiniert den in Linux integrierten Befehl Trap, um benutzerdefinierte Vorgänge zu implementieren, bevor der Container ordnungsgemäß geschlossen wird.

Wie können wir beim Beenden eines laufenden Containers einige vordefinierte Aktionen ausführen, z. B. die Umgebung bereinigen, bevor der Container vollständig beendet wird? Dies ist ein Hook-Erlebnis ähnlich dem Pre-Stop. Docker selbst kann diese Funktion jedoch nicht bereitstellen. Dieser Artikel kombiniert den in Linux integrierten Befehl Trap, um benutzerdefinierte Vorgänge zu implementieren, bevor der Container ordnungsgemäß geschlossen wird.

So verschließen Sie einen Container

Ich verstehe, dass es drei Möglichkeiten gibt, einen laufenden Container herunterzufahren, die alle über die Docker-Befehlszeile initiiert werden.

  • Die erste ist eine elegantere Möglichkeit docker stop ContainerID
  • Die zweite scheint eher willkürlich: docker rm -f ContainerID
  • Der dritte Typ wird von weniger Leuten verwendet docker kill --signal=KILL ContainerID

Die Entwickler von Docker würden nicht ohne Grund drei Befehlskombinationen zum Herunterfahren von Containern entwerfen. In welchen Szenarien sollten die drei Methoden verwendet werden?

Diese drei Möglichkeiten zum Beenden von Containern unterscheiden sich geringfügig. Bevor diese Unterschiede erläutert werden, müssen einige Wissenspunkte erwähnt werden, die scheinbar nichts mit Containern zu tun haben – SIGNAL.

Prozesse und Signale

Benutzer können durch das Senden von Signalen mit Prozessen kommunizieren.

Fast jeder Betriebs- und Wartungsingenieur hat schon einmal den folgenden Befehl ausgeführt, um einen Prozess zu beenden:

töten -9 PID

Dieser Befehl scheint korrekt zu sein, ich habe einen Prozess „beendet“, aber warum „-9“?

9 ist der Code für das Signal SIGKILL. Der obige Befehl sendet tatsächlich ein Signal an den entsprechenden Prozess, ein Signal, das den Prozess beenden kann.

Die eigentliche Bedeutung des kill -Befehls besteht darin, ein bestimmtes Signal an den Prozess zu senden. Neben SIGKILL(9) kann er auch eine Reihe anderer Signale senden:

root@ubuntuserver:~# kill --help

kill: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... oder kill -l [sigspec]

Senden Sie ein Signal an einen Job.

root@ubuntuserver:~# kill -l

1) Anmelden 2) ZEICHEN 3) SIGQUIT 4) SIEGEL 5) SIGTRAP

6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1

11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM

16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

26) Zeichen 27) SIGPROF 28) SICHERUNGSWINDE 29) SIEG 30) SIGPWR

31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3

38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7

58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

63) SIGRTMAX-1 64) SIGRTMAX

Ich habe nicht vor, die Bedeutung der einzelnen Signale im Detail zu erklären. Dazu reichen meine Fähigkeiten noch lange nicht aus. Ich werde hier nur das zu unserem Thema passende Wissen zur Erklärung herausgreifen.

Es gibt zwei Signale, die mit unserem Thema in Zusammenhang stehen: SIGTERM und SIGKILL .

Signalname Code Kann es erfasst oder ignoriert werden?
SIGTERM 15 Kann
SIGKILL 9 Kippen

SIGTERM ist das Standardsignal, das vom kill -Befehl gesendet wird. Wenn der Benutzer die Beendigung des Prozesses anfordert, wird ein SIGTERM-Signal generiert. Das SIGTERM-Signal kann abgefangen oder ignoriert werden. Dadurch kann der Prozess gehaltene Ressourcen freigeben und seinen Status speichern, bevor er beendet wird.

SIGKILL Das Senden eines SIGKILL-Signals an einen Prozess führt zu seiner sofortigen Beendigung (KILL). Im Gegensatz zu SIGTERM kann dieses Signal nicht abgefangen oder ignoriert werden, und der empfangende Prozess darf beim Empfang dieses Signals keine Bereinigung durchführen. Aber manchmal führt kill -9 nicht unbedingt dazu, dass der Prozess beendet und Ressourcen freigegeben werden. Es gibt einige Sonderfälle:

  • Zombieprozesse können nicht beendet werden, da sie bereits tot sind und darauf warten, von ihrem übergeordneten Prozess geholt zu werden.
  • Blockierte Prozesse werden erst beendet, wenn sie wieder aktiviert werden. Der Init-Prozess ist etwas Besonderes:
  • init empfängt keine Signale, die es nicht verarbeiten soll, und ignoriert daher SIGKILL. Es gibt eine Ausnahme von dieser Regel. Wenn init unter Linux ptrace ist, kann es SIGKILL empfangen und beendet werden.
  • Ein Prozess im ununterbrechungsfreien Ruhezustand wird möglicherweise nicht beendet (und gibt seine Ressourcen nicht frei), selbst wenn ihm ein SIGKILL-Befehl gesendet wird. Dies ist eine der wenigen Situationen, in denen ein Unix-System neu gestartet werden muss, um ein vorübergehendes Softwareproblem zu beheben.

Container und Signale

Die Essenz eines Containers ist eine Gruppe gekapselter Prozesse. Daher handelt es sich beim Schließen eines laufenden Containers über die drei eingangs genannten Befehlszeilenmethoden im Wesentlichen um eine Interaktion mit dem Prozess im Container durch das Senden von Signalen zum „Beenden“ dieses Prozesses.

  • Docker-Stopp

Wenn Sie docker stop ContainerID ausführen, wird ein SIGTERM Signal an den Hauptprozess im Container gesendet. Nach einer Nachfrist wird SIGKILL -Signal gesendet, um den Container vollständig zu beenden.

Der Originaltext des Docker-Handbuchs lautet wie folgt:

Der Hauptprozess im Container erhält SIGTERM und nach einer Nachfrist SIGKILL

  • docker rm -f

Durch Ausführen docker rm -f ContainerID wird ein SIGKILL -Signal direkt an den Hauptprozess im Container gesendet. Nachdem der Container beendet wurde, wird auch der Container gelöscht. Gemessen am Löschvorgang des Containers wird dieser Befehl zum Löschen eines angehaltenen Containers verwendet, nicht zum Anhalten eines laufenden Containers.

  • Docker töten

Die Ausführung von docker kill --signal=KILL ContainerID ist eine Möglichkeit, verschiedene benutzerdefinierte Signale an den Hauptprozess des Containers zu senden. Mit anderen Worten, es ist der kill -Befehl für Container. Der aktuelle Befehl sendet ein SIGKILL -Signal an den Hauptprozess des Containers.

Im Vergleich dazu sollte docker rm -f ContainerID nicht verwendet werden, um einen laufenden Container zu stoppen. Unter den beiden verbleibenden Methoden ist docker stop ContainerID offensichtlich die elegantere. Sie kann nicht nur sicherstellen, dass der Container schließlich beendet wird, sondern stellt auch SIGTERM bereit, damit Benutzer es erfassen und später verarbeiten können.

Kommen wir nun endlich zur Sache.

Erfassen und Verarbeiten des Signals

Das Signal SIGTERM ist ein abfangbares Signal. Wenn der Hauptprozess des Containers dieses Signal erfasst, kann er die vorgefertigte Logik auslösen, um die geplanten Aufgaben abzuschließen, bevor er vollständig beendet wird. Beispielsweise kann es die Ausführungsumgebung bereinigen, Daten speichern, andere Prozesse schließen, die nicht vom Hauptprozess gesteuert werden, und so weiter. In einigen Szenarien ist diese Anforderung sehr ausgeprägt.

Linux bietet einen integrierten trap -Befehl, der für das Erfassen von Signalen verantwortlich ist und sicherstellt, dass bestimmte Aufgaben ausgeführt werden, bevor der Prozess vollständig beendet wird.

root@ubuntuserver:~# trap --help

Falle: Falle [-lp] [[arg] Signalspezifikation ...]

Trap-Signale und andere Ereignisse.

Die grundlegende Verwendung ist wie folgt:

Falle mache_einige_Dinge SIGSPEC

Die Idee ist klar. Wir müssen dem Container-Startskript die trap -Anweisung hinzufügen , um alle Dinge abzuschließen, die der Container vor dem Beenden tun muss.

Das Folgende ist ein Beispiel für ein Skript, das als EINSTIEGSPUNKT eines Containers ausgeführt wird.

#!/bin/bash

Funktion Bereinigungsterm {
  rm -rf /Daten/tmp
  echo "clean_up_term in Ausführung"
}

Trap-Bereinigungsterm SIGTERM

für ((i=1;i<=1000;i++))
  Tun
    echo "Warte auf $i"
    Schlaf 1
  Erledigt 

Nachdem der Container gestartet wurde, wird der Befehl docker stop ContainerID von einem anderen Terminal ausgeführt und die folgenden Ergebnisse können beobachtet werden.

guox@MacBook-Pro-For-Guox: /Benutzer/guox/GitHub/test-plugin git:(master) ✗

➜ docker run -ti --name=clean -v $(pwd)/data:/data clean

Warten Sie auf 1

Warten Sie auf 2

Warten Sie 3

Warten Sie auf 4

Warten Sie 5

Warten Sie auf 6

Warten Sie auf 7

Warten Sie auf 8

Warten Sie auf 9

Warten Sie 10

Warten Sie auf 11

Warten Sie auf 12

Warten Sie auf 13

clean_up_term in Ausführung

Warten Sie auf 14

Warten Sie 15

Warten Sie auf 16

Warten Sie auf 17

Warten Sie auf 18

Warten Sie auf 19

Warten Sie 20

Warten Sie auf 21

Warten Sie auf 22

Warten Sie auf 23

guox@MacBook-Pro-For-Guox: /Benutzer/guox/GitHub/test-plugin git:(master) ✗

Das SIGTERM Signal wird tatsächlich vom Container abgefangen und die entsprechenden Bereinigungsvorgänge werden durchgeführt. docker stop ContainerID bietet eine Nachfrist, sodass der Hauptprozess des Containers nach der Durchführung des Bereinigungsvorgangs noch eine Weile weiter ausgeführt wird, bevor er beendet wird.

Dies ist das Ende dieses Artikels über die Verwendung von Trap zur Durchführung einer Umgebungsbereinigung, bevor der Docker-Container ordnungsgemäß geschlossen wird. Weitere Informationen zur Bereinigung der Ausführungsumgebung von Docker-Containern finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Docker-Batch starten und alle Container schließen
  • Detaillierte Erklärung, wie man einen Docker-Container verlässt, ohne ihn zu schließen
  • Docker-Bereinigungsumgebungsvorgang

<<:  Vergleichstabelle chinesischer und englischer Schriftnamen (einschließlich Founder und Arphic)

>>:  Implementierung des CSS-Animationseffekts für dynamische Höhenübergänge

Artikel empfehlen

Einführung in den glibc-Upgradeprozess für Centos6.5

Inhaltsverzeichnis Szenarioanforderungen glibc-Ve...

Führen Sie die folgenden Schritte aus, damit Docker Images abrufen kann

1. Docker Pull zieht das Image Wenn Sie zum Abruf...

Tipps zur Verwendung von Bildlaufleisten in HTML

Als wir heute das Pressemitteilungssystem von Niu ...

JavaScript zum Erreichen eines dynamischen Farbwechsels der Tabelle

In diesem Artikel wird der spezifische Code für J...

Detaillierte Erklärung der jQuery-Kettenaufrufe

Inhaltsverzeichnis Kettenanrufe Ein kleiner Koffe...

Spezifische Verwendung der MySQL-Vorbereitungsvorverarbeitung

Inhaltsverzeichnis 1. Vorverarbeitung 2. Vorbehan...

MySQL-Variablenprinzipien und Anwendungsbeispiele

In der MySQL-Dokumentation können MySQL-Variablen...

MYSQL METADATA LOCK (MDL LOCK) Theorie und Sperrtyptest

Inhaltsverzeichnis MYSQL METADATA LOCK (MDL LOCK)...

Implementierung der Wiederaufnahme des K8S-Knotens in den Master-Cluster

1. Knoten löschen Führen Sie kubectl delete node ...