Ich kann keine Verbindung mehr zu einer VM mit einem Docker-Container herstellen, der eine Verbindung über SSH herstellen kann

(2020/09/25) Dieser Artikel ist eine zusätzliche Korrektur des Teils zur Fehlerbehebung, der aus dem folgenden Artikel extrahiert wurde. Erstellen Sie einen Docker-Container, der mit der Mindestkonfiguration über SSH mit CentOS 8 verbunden werden kann

Überblick

Nachdem ich eine Weile mit einem Docker-Container gespielt habe, der eine Verbindung zu SSH herstellen kann, ist ein Problem aufgetreten, bei dem die VM, die den Container enthält, keine Verbindung zu SSH herstellen konnte. Daher werde ich die Untersuchung und Lösung zusammenfassen.

Umgebung

Probleme und Lösungen

In diesem Artikel werden Geräteinformationen am Anfang der Befehlszeile hinzugefügt, um zu verdeutlichen, wo der Befehl ausgeführt wird. Diejenigen, die mit "[centos @ dockertest ~] $" beginnen, geben die Gast-VM an, und diejenigen, die mit "test ~: $" beginnen, geben die Befehlsausführung auf dem Container an.

Es ist ein Problem aufgetreten

Nachdem ich eine Weile gespielt hatte, z. B. ein Skript für den SSH-Zugriff auf den von mir eingerichteten Container geschrieben hatte, konnte ich plötzlich keine SSH-Verbindung vom Host zur Gast-VM herstellen. Insbesondere wenn ich versuche, mit TeraTerm darauf zuzugreifen, bleibt der Bildschirm schwarz und es erfolgt keine Antwort. Wenn ich versuche, mit dem Container von einer anderen Gast-VM mit "ssh" auf die Gast-VM zuzugreifen, wird die folgende Meldung angezeigt und die Verbindung wird gekippt.

[centos@othervm ~]$ ssh -p 2222 [email protected]
shell request failed on channel 0

Umfrage

Als ich basierend auf der obigen Nachricht gegoogelt habe (Shell-Anfrage auf Kanal 0 fehlgeschlagen), war der folgende Artikel ein Hit.

Referenz: Umgang mit "Shell-Anforderung auf Kanal 0 fehlgeschlagen", die sich nicht bei ssh anmelden kann

Obwohl es Unterschiede wie die Umgebung gibt, werde ich versuchen herauszufinden, welcher Prozess ausgeführt wird, vorausgesetzt, die Umgebung des Prozesses ist verdächtig.

[centos@dockertest ~]$ ps aux | grep ssh
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
(~ Ausgelassen ~)
22        7762  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7764  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7766  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7768  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7770  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7772  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7774  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7776  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7778  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7780  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7782  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7784  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7786  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
22        7788  0.0  0.0      0     0 ?        Z    02:27   0:00 [sshd] <defunct>
(~ Ausgelassen ~)

Oh, oh ...

Aus der Notation " Z "und" defunct" geht hervor, dass eine große Anzahl von ssh -Prozessen zu Zombies geworden sind und die verfügbaren Prozess-IDs auffressen. Wenn Sie die Gast-VM oder den Gastcontainer neu starten, können Sie die Verbindung einmal wieder herstellen. Da sich die Anzahl der Zombie-Prozesse jedoch jedes Mal erhöht, wenn Sie eine SSH-Verbindung herstellen, ist dies keine dauerhafte Gegenmaßnahme und Sie haben eine zeitgesteuerte Bombe.

[centos@dockertest ~]$ ps aux | grep Z | wc -l
2
(Während dieser Zeit SSH-Verbindung vom Host zum Container mit TeraTerm ⇒ Trennung ausführen)
[centos@dockertest ~]$ ps aux | grep Z | wc -l
3

Ursache

Bei der Prüfung scheint es, dass unter Linux der Prozess "init" im Allgemeinen der Vorfahr aller Prozesse ist. Dies verwaltet den Prozess gut und verhindert normalerweise, dass Zombie-Prozesse entstehen. .. Der diesmal erstellte Docker-Container verfügt jedoch nicht über einen Init-Prozess, sodass er nicht von der Prozessverwaltung profitieren kann. Infolgedessen scheint es, dass der "ssh" -Prozess, sobald er verbunden ist, seinen Platz verliert und nach Beendigung seiner Rolle zu einem Zombie wird. Er ist gestapelt und schließlich kann kein neuer "ssh" -Prozess gestartet werden.

Übrigens scheint "init" die Nummer 1 (PID 1) als Prozess-ID zugewiesen zu haben, aber der Container-PID 1 wird der "Schwanz" zugewiesen, der in der "CMD" -Anweisung in der "Docker-Datei" beschrieben ist.

test:~$ ps
PID   USER     TIME  COMMAND
    1 root      0:00 tail -f /dev/null
  ...

Für das detaillierte Prinzip des Zombie-Prozesses war der folgende Artikel hilfreich.

Referenz: Unix-Prozess und Docker-Trap

Lösung

Es scheint verschiedene Methoden zu geben, aber da ich während des Forschungsprozesses etwas über "init" gelernt habe, möchte ich es lösen, um dies zu nutzen. Wenn Docker Compose Version 3.7 oder höher ist, wird durch Hinzufügen von "init: true" zu "docker-compose.yml" "init" im Container ausgeführt.

Referenz: Über das Flag --init von Docker

docker-compose.yml(Überarbeitet)


version: '3.8'

services:
  test:
    build: .
    container_name: test
    hostname: test
    ports:
      - "2222:22"
    tty: true
    init: true #Fügen Sie diese Zeile hinzu

Schreiben Sie die Datei tatsächlich wie oben beschrieben neu und starten Sie den Container erneut.

[centos@dockertest ~]$ docker-compose down
[centos@dockertest ~]$ docker-compose build
[centos@dockertest ~]$ docker-compose up -d

Wenn der Container gestartet wird, SSH vom Host zum Container erneut mit TeraTerm und überprüfen Sie den Prozess.

test:~$ ps
PID   USER     TIME  COMMAND
    1 root      0:00 /sbin/docker-init -- /bin/sh -c /etc/init.d/sshd start && tail -f /dev/null
  ...

Oh, der COMMAND Teil hat sich richtig geändert. Stellen Sie zur Sicherheit sicher, dass die SSH-Verbindung die Anzahl der Zombie-Prozesse nicht erhöht.

[centos@dockertest ~]$ ps aux | grep Z | wc -l
2
(Während dieser Zeit SSH-Verbindung vom Host zum Container mit TeraTerm ⇒ Trennung ausführen)
[centos@dockertest ~]$ ps aux | grep Z | wc -l
2

Ist es gut?

Zusammenfassung

--Lassen Sie init ausführen, wenn Sie einen Docker-Container erstellen, der SSH kann

Die Geschichte im Zusammenhang mit dem Prozessmanagement hat mich nicht wirklich interessiert, deshalb habe ich viel gelernt. Erstens gibt es ein Problem, ob ein Container, der mit SSH verbunden werden kann, die Idee von Docker ist, aber ich möchte diesen Bereich einzeln untersuchen.

Recommended Posts

Ich kann keine Verbindung mehr zu einer VM mit einem Docker-Container herstellen, der eine Verbindung über SSH herstellen kann
Erstellen wir einen Docker-Container, der SSH auf die Mindestkonfiguration von CentOS 8 ausführen kann
Ich habe einen Docker-Container erstellt, um Maven auszuführen
Ich habe versucht, CentOS-7 einfach in einen PC zu integrieren, den ich nicht mehr benötige
[Android] Ich möchte einen ViewPager erstellen, der für Tutorials verwendet werden kann
Erstellen Sie ein Seitensteuerelement, das mit RecyclerView verwendet werden kann
Suchen Sie eine Switch-Anweisung, die in einen Switch-Ausdruck konvertiert werden kann
Ich habe versucht, mit Docker eine Padrino-Entwicklungsumgebung zu erstellen
Nach dem Update auf OSX Catalina kann ich nicht mehr sass
Als ich versuchte, ein Composer-Update im Docker-Container durchzuführen, wurde ich wütend auf proc_open (): fork failed
Eine Geschichte, die ich mit Java nur schwer herausfordern konnte
Ich habe versucht, Java mit einer Reihe zu lernen, die Anfänger klar verstehen können
Ich habe versucht, eine Web-API zu erstellen, die mit Quarkus eine Verbindung zur Datenbank herstellt
Ich habe Docker verwendet, um die Vorlage zu verfestigen, die mit Spring Boot entwickelt werden soll.
So starten Sie einen Docker-Container mit einem in einer Batchdatei bereitgestellten Volume
Ich habe versucht, ein Portfolio mit AWS, Docker, CircleCI, Laravel [mit Referenzlink] zu erstellen.
Ich habe eine App für maschinelles Lernen mit Dash (+ Docker) Teil 3 ~ Übung ~ erstellt
Ich möchte in der Lage sein, Dateien mit refile mit administrate [rails6] zu lesen.
Ich habe einen THETA API-Client erstellt, der für die Plug-Entwicklung verwendet werden kann
[Java] Ich habe versucht, über den Verbindungspool eine Verbindung mit Servlet (Tomcat) & MySQL & Java herzustellen
Ich war süchtig danach, vom Docker-Container aus keine Verbindung zu AWS-S3 herstellen zu können
[Teil 1] Erstellen eines Docker-Containers, der mit Apache / Pandoc Markdown in HTML liefert
So lösen Sie, wenn Sie mit einem neuen Container keine Verbindung zur Datenbank herstellen können, weil der Port dem vorhandenen Docker-Container zugewiesen ist
Ich habe Docker als Anfänger für mein Portfolio verwendet, daher hoffe ich, dass sogar 1 mm für jemanden hilfreich ist.