Je ne peux plus me connecter à une VM avec un conteneur Docker pouvant se connecter via SSH

(2020/09/25) Cet article est une correction supplémentaire de la partie de dépannage extraite de l'article suivant. Créez un conteneur Docker qui peut être connecté SSH à CentOS 8 avec la configuration minimale

Aperçu

Après avoir joué avec un conteneur Docker pouvant se connecter à SSH pendant un certain temps, j'ai rencontré un problème selon lequel la machine virtuelle contenant le conteneur ne pouvait pas se connecter à SSH, je vais donc résumer l'enquête et la solution.

environnement

--Windows10 Home (1909) (hôte)

Problèmes et solutions

Dans cet article, des informations sur le périphérique sont ajoutées au début de la ligne de commande afin de clarifier où la commande est exécutée. Ceux qui commencent par [centos @ dockertest ~] $ indiquent la VM invitée, et ceux qui commencent par test ~: $ indiquent l'exécution de la commande sur le conteneur.

un problème est survenu

Après avoir joué pendant un certain temps, comme l'écriture d'un script pour l'accès SSH au conteneur configuré, je ne pouvais soudainement pas établir de connexion SSH entre l'hôte et la VM invitée. Plus précisément, lorsque j'essaye d'y accéder avec TeraTerm, l'écran reste noir et il n'y a pas de réponse. De plus, lorsque j'essaye d'accéder à la VM invitée avec le conteneur d'une autre VM invitée avec ssh, le message suivant apparaît et la connexion est inversée.

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

Sondage

Lorsque j'ai recherché sur Google en fonction du message ci-dessus (la requête du shell a échoué sur le canal 0), l'article suivant était un succès.

Référence: Comment traiter "la requête shell a échoué sur le canal 0" qui ne peut pas se connecter à ssh

Bien qu'il existe des différences telles que l'environnement, je vais essayer de savoir quel processus est en cours d'exécution, en supposant que l'environnement du processus est suspect.

[centos@dockertest ~]$ ps aux | grep ssh
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
(~ Omis ~)
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>
(~ Omis ~)

Oh, oh ...

D'après les notations «Z» et «défunt», il semble qu'un grand nombre de processus «ssh» sont devenus des zombies et consomment les ID de processus disponibles. Si vous redémarrez la VM ou le conteneur invité, vous pourrez vous reconnecter une fois, mais comme le nombre de processus zombies augmentera à chaque fois que vous établissez une connexion SSH, ce ne sera pas une contre-mesure permanente et vous aurez une bombe chronométrée.

[centos@dockertest ~]$ ps aux | grep Z | wc -l
2
(Pendant ce temps, connexion SSH de l'hôte au conteneur avec TeraTerm ⇒ Exécuter la déconnexion)
[centos@dockertest ~]$ ps aux | grep Z | wc -l
3

Cause

Après examen, il semble que sous Linux, un processus appelé init soit généralement l'ancêtre de tous les processus, ce qui gère bien le processus et empêche généralement les processus zombies de se reproduire. .. Cependant, le conteneur Docker créé cette fois n'a pas de processus init, il ne peut donc pas bénéficier de la gestion des processus. En conséquence, il semble que le processus ssh une fois connecté perd sa place et devient un zombie après avoir terminé son rôle, et il est empilé et finalement un nouveau processus ssh ne peut pas être démarré.

À propos, init semble avoir le numéro 1 (PID 1) comme ID de processus, mais le conteneur PID 1 se voit attribuer la queue '' décrite dans l'instruction CMD du Dockerfile.

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

Pour le principe détaillé du processus zombie, l'article suivant a été utile.

Référence: Processus Unix et Docker trap

Solution

Il semble y avoir différentes méthodes, mais depuis que j'ai appris sur «init» au cours du processus de recherche, j'aimerais le résoudre dans le sens de l'utiliser. Si Docker Compose est la version 3.7 ou supérieure, l'ajout de init: true à docker-compose.yml fera fonctionner init dans le conteneur.

Référence: À propos du drapeau --init de Docker

docker-compose.yml(modifié)


version: '3.8'

services:
  test:
    build: .
    container_name: test
    hostname: test
    ports:
      - "2222:22"
    tty: true
    init: true #Ajouter cette ligne

Réécrivez le fichier comme décrit ci-dessus et redémarrez le conteneur.

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

Lorsque le conteneur démarre, SSH de l'hôte au conteneur à nouveau avec TeraTerm et vérifiez le processus.

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, la partie COMMAND a bien changé. Pour être prudent, assurez-vous que la connexion SSH n'augmente pas le nombre de processus zombie.

[centos@dockertest ~]$ ps aux | grep Z | wc -l
2
(Pendant ce temps, connexion SSH de l'hôte au conteneur avec TeraTerm ⇒ Exécuter la déconnexion)
[centos@dockertest ~]$ ps aux | grep Z | wc -l
2

Est-ce bien?

Sommaire

Je n'avais pas été particulièrement préoccupé par la gestion des processus, alors j'ai beaucoup appris. En premier lieu, il y a un problème de savoir si un conteneur qui peut être connecté à SSH est l'idée de Docker, mais j'aimerais étudier cette zone un par un.

Recommended Posts

Je ne peux plus me connecter à une VM avec un conteneur Docker pouvant se connecter via SSH
Créons un conteneur Docker qui peut SSH à la configuration minimale de CentOS 8
J'ai créé un conteneur Docker pour exécuter Maven
J'ai essayé de mettre facilement CentOS-7 dans un PC dont je n'ai plus besoin
[Android] Je souhaite créer un ViewPager pouvant être utilisé pour les didacticiels
Créer un contrôle de page qui peut être utilisé avec RecyclerView
Rechercher une instruction Switch qui peut être convertie en une expression Switch
J'ai essayé de créer un environnement de développement padrino avec Docker
Après la mise à jour vers OSX Catalina, je ne peux plus sass
Quand j'ai essayé de composer une mise à jour dans le conteneur Docker, je me suis fâché avec proc_open (): fork a échoué
Une histoire que j'ai eu du mal à défier le pro de la concurrence avec Java
J'ai posé une question qui peut être utilisée pour des entretiens techniques
J'ai essayé d'apprendre Java avec une série que les débutants peuvent comprendre clairement
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
J'ai utilisé Docker pour solidifier le modèle à développer avec Spring Boot.
Comment démarrer un conteneur Docker avec un volume monté dans un fichier de commandes
J'ai essayé de créer un portefeuille avec AWS, Docker, CircleCI, Laravel [avec lien de référence]
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part3 ~ Practice ~
Je souhaite pouvoir lire des fichiers en utilisant refile avec administrate [rails6]
J'ai créé un client API THETA qui peut être utilisé pour le développement de plugins
[Java] J'ai essayé de me connecter en utilisant le pool de connexion avec Servlet (tomcat) & MySQL & Java
J'étais accro à ne pas pouvoir me connecter à AWS-S3 à partir du conteneur Docker
[Partie 1] Création d'un conteneur Docker qui fournit Markdown en HTML avec Apache / Pandoc
Solution lorsque la connexion à la base de données n'est pas possible avec un nouveau conteneur car le port est affecté au conteneur docker existant
J'ai utilisé Docker pour mon portfolio en tant que débutant, donc j'espère que même 1 mm sera utile à quelqu'un.