(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
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.
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.
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
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
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
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?
--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.