Heim Betrieb und Instandhaltung Docker Wissen Sie, wie man Signale in Docker-Containern abfängt?

Wissen Sie, wie man Signale in Docker-Containern abfängt?

Feb 22, 2021 am 10:29 AM
docker 信号 容器

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...');
});
Nach dem Login kopieren

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]);
  });
});
Nach dem Login kopieren

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"]
Nach dem Login kopieren

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 .
Nach dem Login kopieren

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:
Nach dem Login kopieren

Zu diesem Zeitpunkt ist die Prozessnummer der Knotenanwendung im Container 1:

Wissen Sie, wie man Signale in Docker-Containern abfängt?

Jetzt lassen wir das Programm beenden und führen Sie den Befehl aus:

$ docker container kill --signal="SIGTERM" my-app
Nach dem Login kopieren

An diesem Punkt wird die Anwendung wie erwartet beendet:

Wissen Sie, wie man Signale in Docker-Containern abfängt?

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
Nach dem Login kopieren

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"]
Nach dem Login kopieren

Als nächstes erstellen Sie das Image:

$ docker build --no-cache -t signal-app1 -f Dockerfile1 .
Nach dem Login kopieren

Starten Sie dann den Container, um die Anwendung auszuführen:

$ docker run -it --rm -p 3000:3000 --name="my-app1" signal-app1
Nach dem Login kopieren

Zu diesem Zeitpunkt wird die Prozessnummer der Knotenanwendung im Container ist nicht mehr 1:

Wissen Sie, wie man Signale in Docker-Containern abfängt?

现在给 my-app1 发送 SIGTERM 信号试试,已经无法退出程序了!在这个场景中,应用程序由 bash 脚本启动,bash 作为容器中的 1 号进程收到了 SIGTERM 信号,但是它没有做出任何的响应动作。
我们可以通过:

$ docker container stop my-app1
# or
$ docker container kill --signal="SIGKILL" my-app1
Nach dem Login kopieren

退出应用,它们最终都是向容器中的 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
Nach dem Login kopieren

这个脚本文件在启动应用程序的同时可以捕获发送给它的 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"]
Nach dem Login kopieren

接下来创建镜像:

$ docker build --no-cache -t signal-app2 -f Dockerfile2 .
Nach dem Login kopieren

然后启动容器运行应用程序:

$ docker run -it --rm -p 3000:3000 --name="my-app2" signal-app2
Nach dem Login kopieren

此时 node 应用在容器中的进程号也不是 1,但是它却可以接收到 SIGTERM 信号并优雅的退出了:

Wissen Sie, wie man Signale in Docker-Containern abfängt?

结论

容器中的 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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So lesen Sie die Docker -Version So lesen Sie die Docker -Version Apr 15, 2025 am 11:51 AM

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.

So erstellen Sie einen Spiegel in Docker So erstellen Sie einen Spiegel in Docker Apr 15, 2025 am 11:27 AM

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.

So verwenden Sie Docker Desktop So verwenden Sie Docker Desktop Apr 15, 2025 am 11:45 AM

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).

So ändern Sie die Docker -Bildquelle in China So ändern Sie die Docker -Bildquelle in China Apr 15, 2025 am 11:30 AM

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.

So überprüfen Sie den Namen des Docker -Containers So überprüfen Sie den Namen des Docker -Containers Apr 15, 2025 pm 12:21 PM

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").

So sehen Sie Protokolle von Docker So sehen Sie Protokolle von Docker Apr 15, 2025 pm 12:24 PM

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

So aktualisieren Sie das Bild von Docker So aktualisieren Sie das Bild von Docker Apr 15, 2025 pm 12:03 PM

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).

So starten Sie einen Container von Docker So starten Sie einen Container von Docker Apr 15, 2025 pm 12:27 PM

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.

See all articles