Wenn Sie versuchen, den Container mit "Docker Stop" zu stoppen, während Sie Rails (Puma) auf Docker ausführen, erhalten Sie Exit 1 (SIGHUP). Wenn Sie ECS oder Kubernetes verwenden, wird der Container möglicherweise nicht ordnungsgemäß beendet und kann unerwartete Probleme verursachen.
% docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxx rails "bundle exec rails s…" 44 seconds ago Exited (1) 3 seconds ago api
xxx
Ursache ist das sogenannte "PID 1-Problem [^ 1]". PID 1 wird als Init-Prozess bezeichnet, ein spezieller Prozess, der vom Kernel beim Systemstart aufgerufen wird. Der Init-Prozess verarbeitet Signale, erzeugt untergeordnete Prozesse, löscht Zombie-Prozesse und so weiter. Dieses Mal, als ich Rails ([^ 2]) startete, wurde PID 1 verwendet, und es gab ein Problem, dass das Signal nicht richtig verarbeitet werden konnte.
#Ergebnis der Ausführung des Befehls top für den Container
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 2.2m 1.5m 0.0 0.1 0:00.02 S /bin/bash /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.
Wenn Sie sich den Prozess ansehen, können Sie sehen, dass Rails mit PID 1 ausgeführt wird.
Als untergeordneter Prozess von PID 1 mithilfe von Programmen wie tini und dumm-init Es ist möglich, die Anwendung zu starten.
Wenn Docker-Compose 3.7 oder höher verfügbar ist, können Sie das Problem umgehen, indem Sie den Parameter init
zu docker-compose.yml
([^ 3]) hinzufügen.
#Rails startet als untergeordneter Prozess des Init-Prozesses
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 1.0m 0.0m 0.0 0.0 0:00.03 S /sbin/docker-init -- /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.0
6 root 20 0 2.2m 1.5m 0.0 0.1 0:00.00 S `- /bin/bash /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.0
Wenn Sie den Prozess nach dem Ausführen von "Docker-Compose Down" betrachten, wird der Container bei 143 (SIGTERM) gestoppt.
% docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------
api /bin/docker-entrypoint.sh ... Exit 143
Fügen Sie der Aufgabendefinition initProcessEnabled: true
([^ 4]) hinzu. initProcessEnabled
entspricht --init
in docker run
.
Sie können auch ein leichtes Init wie tini verwenden. Ab Kubernetes 1.17 können Sie das Problem jedoch mithilfe des Share Process Namespace ([^ 5]) umgehen.
Recommended Posts