Wissen Sie, wie man Signale in Docker-Containern abfängt?
Ich glaube, Sie müssen den Docker-Stop-Befehl verwendet haben, um einen laufenden Container zu stoppen. Manchmal verwenden wir auch den Docker-Kill-Befehl, um den Container zwangsweise zu schließen oder ein Signal an den Prozess im Container zu übergeben.
Tatsächlich handelt es sich bei den von uns ausgeführten Vorgängen im Wesentlichen um die Interaktion zwischen dem Host und dem Programm im Container, indem Signale vom Host an den Container gesendet werden. Wenn wir beispielsweise ein Neuladesignal an die Anwendung im Container senden, führt die Anwendung im Container nach dem Empfang des Signals den entsprechenden Handler aus, um die Aufgabe des Neuladens der Konfigurationsdatei abzuschließen.
Signale (Linux)
Signale sind eine Form der Kommunikation zwischen Prozessen. Ein Signal ist eine Nachricht, die der Kernel an einen Prozess sendet, um ihm mitzuteilen, dass ein bestimmtes Ereignis eingetreten ist. Wenn ein Signal an einen Prozess gesendet wird, unterbricht der Prozess sofort den aktuellen Ausführungsfluss und beginnt mit der Ausführung des Signalhandlers (es ist nicht korrekt zu sagen, dass das Signal zu einem bestimmten Zeitpunkt verarbeitet wird). Wenn für dieses Signal kein Handler angegeben ist, wird der Standardhandler ausgeführt.
Der Prozess muss Handler für die Signale registrieren, an denen er interessiert ist. Damit das Programm beispielsweise ordnungsgemäß beendet werden kann (um Ressourcen nach Erhalt der Exit-Anfrage zu bereinigen), verarbeitet das Programm im Allgemeinen das SIGTERM-Signal. Im Gegensatz zum SIGTERM-Signal beendet das SIGKILL-Signal einen Prozess gewaltsam. Daher sollte unsere Anwendung ein solches Verzeichnis implementieren: Erfassen und verarbeiten Sie das SIGTERM-Signal, um das Programm ordnungsgemäß zu beenden. Wenn wir scheitern, muss der Benutzer als letzten Ausweg auf das SIGKILL-Signal zurückgreifen. Neben SIGTERM und SIGKILL gibt es Signale wie SIGUSR1, die gezielt benutzerdefiniertes Verhalten unterstützen. Der folgende Code erklärt einfach, wie man einen Handler für ein Signal in nodejs registriert:
process.on('SIGTERM', function() { console.log('shutting down...'); });
Weitere Informationen zu Signalen hat der Autor im Artikel „Linux-Kill-Befehl“ erwähnt und wird hier nicht wiederholt.
Signale im Container
Dockers Stop- und Kill-Befehle werden verwendet, um Signale an den Container zu senden. Beachten Sie, dass nur Prozess Nr. 1 im Container das Signal empfangen kann. Dies ist sehr kritisch! Der Befehl
stop sendet zunächst das SIGTERM-Signal und wartet darauf, dass die Anwendung ordnungsgemäß beendet wird. Wenn festgestellt wird, dass die Anwendung nicht beendet wurde (der Benutzer kann die Wartezeit angeben), senden Sie ein weiteres SIGKILL-Signal, um das Programm zwangsweise zu beenden.
Der Kill-Befehl sendet standardmäßig das SIGKILL-Signal. Natürlich können Sie über die Option -s jedes beliebige Signal angeben.
Im Folgenden verwenden wir eine NodeJS-Anwendung, um den Arbeitsprozess von Signalen im Container zu demonstrieren. Erstellen Sie eine app.js-Datei mit folgendem Inhalt:
'use strict'; var http = require('http'); var server = http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(3000, '0.0.0.0'); console.log('server started'); var signals = { 'SIGINT': 2, 'SIGTERM': 15 }; function shutdown(signal, value) { server.close(function () { console.log('server stopped by ' + signal); process.exit(128 + value); }); } Object.keys(signals).forEach(function (signal) { process.on(signal, function () { shutdown(signal, signals[signal]); }); });
Diese App ist ein HTTP-Server, der Port 3000 überwacht, wobei Handler für die Signale SIGINT und SIGTERM registriert sind. Als Nächstes stellen wir vor, wie Signale beim Ausführen von Programmen in Containern auf unterschiedliche Weise gehandhabt werden.
Die Anwendung dient als Prozess Nr. 1 im Container
Erstellen Sie eine Dockerfile-Datei und packen Sie die obige Anwendung in das Image:
FROM iojs:onbuild COPY ./app.js ./app.js COPY ./package.json ./package.json EXPOSE 3000ENTRYPOINT ["node", "app"]
Bitte achten Sie auf die Schreibweise der ENTRYPOINT-Anweisung Prozess Nr. 1 im Container ausführen.
Als nächstes das Image erstellen:
$ docker build --no-cache -t signal-app -f Dockerfile .
Dann den Container starten und die Anwendung ausführen:
请注意 ENTRYPOINT 指令的写法,这种写法会让 node 在容器中以 1 号进程的身份运行。 接下来创建镜像: $ docker build --no-cache -t signal-app -f Dockerfile . 然后启动容器运行应用程序: $ docker run -it --rm -p 3000:3000 --name="my-app" signal-app 此时 node 应用在容器中的进程号为 1:
Zu diesem Zeitpunkt ist die Prozessnummer der Knotenanwendung im Container 1:
Jetzt lassen wir das Programm beenden und führen Sie den Befehl aus:
$ docker container kill --signal="SIGTERM" my-app
An diesem Punkt wird die Anwendung wie erwartet beendet:
Die Anwendung ist nicht der Prozess Nr. 1 im Container
Erstellen Sie eine Skriptdatei app1.sh, die den startet Anwendung mit folgendem Inhalt:
#!/usr/bin/env bash node app
Dann erstellen Sie die Dockerfile1-Datei. Der Inhalt lautet wie folgt:
FROM iojs:onbuild COPY ./app.js ./app.js COPY ./app1.sh ./app1.sh COPY ./package.json ./package.json RUN chmod +x ./app1.sh EXPOSE 3000 ENTRYPOINT ["./app1.sh"]
Als nächstes erstellen Sie das Image:
$ docker build --no-cache -t signal-app1 -f Dockerfile1 .
Starten Sie dann den Container, um die Anwendung auszuführen:
$ docker run -it --rm -p 3000:3000 --name="my-app1" signal-app1
Zu diesem Zeitpunkt wird die Prozessnummer der Knotenanwendung im Container ist nicht mehr 1:
现在给 my-app1 发送 SIGTERM 信号试试,已经无法退出程序了!在这个场景中,应用程序由 bash 脚本启动,bash 作为容器中的 1 号进程收到了 SIGTERM 信号,但是它没有做出任何的响应动作。
我们可以通过:
$ docker container stop my-app1 # or $ docker container kill --signal="SIGKILL" my-app1
退出应用,它们最终都是向容器中的 1 号进程发送了 SIGKILL 信号。很显然这不是我们期望的,我们希望程序能够收到 SIGTERM 信号优雅的退出。
在脚本中捕获信号
创建另外一个启动应用程序的脚本文件 app2.sh,内容如下:
#!/usr/bin/env bash set -x pid=0 # SIGUSR1-handler my_handler() { echo "my_handler" } # SIGTERM-handler term_handler() { if [ $pid -ne 0 ]; then kill -SIGTERM "$pid" wait "$pid" fi exit 143; # 128 + 15 -- SIGTERM } # setup handlers # on callback, kill the last background process, which is `tail -f /dev/null` and execute the specified handler trap 'kill ${!}; my_handler' SIGUSR1 trap 'kill ${!}; term_handler' SIGTERM # run application node app & pid="$!" # wait forever while true do tail -f /dev/null & wait ${!} done
这个脚本文件在启动应用程序的同时可以捕获发送给它的 SIGTERM 和 SIGUSR1 信号,并为它们添加了处理程序。其中 SIGTERM 信号的处理程序就是向我们的 node 应用程序发送 SIGTERM 信号。
然后创建 Dockerfile2 文件,内容如下:
FROM iojs:onbuild COPY ./app.js ./app.js COPY ./app2.sh ./app2.sh COPY ./package.json ./package.json RUN chmod +x ./app2.sh EXPOSE 3000 ENTRYPOINT ["./app2.sh"]
接下来创建镜像:
$ docker build --no-cache -t signal-app2 -f Dockerfile2 .
然后启动容器运行应用程序:
$ docker run -it --rm -p 3000:3000 --name="my-app2" signal-app2
此时 node 应用在容器中的进程号也不是 1,但是它却可以接收到 SIGTERM 信号并优雅的退出了:
结论
容器中的 1 号进程是非常重要的,如果它不能正确的处理相关的信号,那么应用程序退出的方式几乎总是被强制杀死而不是优雅的退出。究竟谁是 1 号进程则主要由 EntryPoint, CMD, RUN 等指令的写法决定,所以这些指令的使用是很有讲究的。
相关推荐:docker入门教程
Das obige ist der detaillierte Inhalt vonWissen Sie, wie man Signale in Docker-Containern abfängt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Um die Docker -Version zu erhalten, können Sie die folgenden Schritte ausführen: Führen Sie den Befehl Docker "Docker --version" aus, um die Client- und Serverversionen anzuzeigen. Für Mac oder Windows können Sie auch Versionsinformationen über die Registerkarte Version der Docker -Desktop -GUI oder das Menü Docker Desktop anzeigen.

Schritte zum Erstellen eines Docker -Images: Schreiben Sie eine Dockerfile, die die Build -Anweisungen enthält. Erstellen Sie das Bild im Terminal mit dem Befehl Docker Build. Markieren Sie das Bild und weisen Sie Namen und Tags mit dem Befehl Docker Tag zu.

Wie benutze ich Docker Desktop? Docker Desktop ist ein Werkzeug zum Ausführen von Docker -Containern auf lokalen Maschinen. Zu den zu verwendenden Schritten gehören: 1.. Docker Desktop installieren; 2. Start Docker Desktop; 3.. Erstellen Sie das Docker -Bild (mit Dockerfile); 4. Build Docker Image (mit Docker Build); 5. Docker -Container ausführen (mit Docker Run).

Sie können zur Quelle der Inlandsspiegel wechseln. Die Schritte sind wie folgt: 1. Bearbeiten Sie die Konfigurationsdatei /etc/docker/daemon.json und fügen Sie die Spiegelquellenadresse hinzu; 2. Starten Sie den Docker Service Sudo SystemCtl Docker neu, um die Download -Geschwindigkeit und -stabilität des Bilddownloads zu verbessern.

Sie können den Namen des Docker -Containers abfragen, indem Sie den Schritten folgen: Alle Container auflisten (Docker PS). Filtern Sie die Containerliste (unter Verwendung des GREP -Befehls). Ruft den Containernamen ab (befindet sich in der Spalte "Namen").

Zu den Methoden zum Anzeigen von Docker -Protokollen gehören: Verwenden des Befehls docker Protokolle, z. cat /var/log/container_name.log Verwenden Sie den Befehl docker-compose-Protokolle von Docker Compose, zum Beispiel: Docker-compose -f Docker-com

Die Schritte zur Aktualisierung eines Docker -Images sind wie folgt: Ziehen Sie das neueste Bild -Tag. Neues Bild Löschen Sie das alte Bild für ein bestimmtes Tag (optional) den Container neu (falls erforderlich) neu starten Sie neu (falls erforderlich).

Startschritte des Docker -Containers: Ziehen Sie das Containerbild: Führen Sie "Docker Pull [Mirror Name]" aus. Erstellen eines Containers: Verwenden Sie "Docker erstellen [Optionen] [Spiegelname] [Befehle und Parameter]". Starten Sie den Container: Führen Sie "Docker Start [Container Name oder ID]" aus. Containerstatus überprüfen: Stellen Sie sicher, dass der Container mit "Docker PS" ausgeführt wird.
