Comment entrer dans un conteneur Docker déjà en cours d'exécution avec un nouveau TTY

545

J'ai un conteneur qui exécute le service Apache au premier plan. Je voudrais pouvoir accéder au conteneur à partir d'un autre shell afin de «fouiller» à l'intérieur et d'examiner les fichiers. Pour le moment, si je m'attache au conteneur, je regarde le démon Apache et je ne peux exécuter aucune commande.

Est-il possible d'attacher un autre tty à un conteneur en cours d'exécution? Peut-être que je peux profiter du fait que Docker ne fait que s'enrouler autour des conteneurs LXC? J'ai essayé sudo lxc-console -n [container-id] -t [1-4]mais il semble qu'un seul tty soit mis à disposition et c'est celui qui exécute le démon apache. Peut-être existe-t-il un moyen d'activer plusieurs consoles lxc pendant la génération?

Je préfère ne pas configurer et construire le conteneur avec un service openssh si possible.

Programster
la source
7
As-tu essayé docker attach [conainer-id]?
shabbychef
13
@shabbychef à moins que docker attach n'ait changé, la commande attach s'attache au tty en cours d'exécution, pas un nouveau, donc le titre de la question est "... avec un nouveau TTY". C'est pourquoi la réponse ci-dessous n'utilise pas la commande attach.
Programster du
1
Depuis la version 1.3, il existe un moyen plus simple comme décrit dans cette réponse
Thomasleveil

Réponses:

1061

Avec docker 1.3, il y a une nouvelle commande docker exec. Cela vous permet d'entrer un docker en cours d'exécution:

docker exec -it [container-id] bash
Michael_Scharf
la source
30
J'ai changé cela pour être la bonne réponse (de la mienne) parce que cette nouvelle méthode, qui n'existait pas au moment de la question, est la meilleure méthode actuelle de l'OMI.
Programster
3
Notez cependant que cela execn'agit pas comme un terminal normal. Par exemple, vous ne pouvez pas changer d'utilisateur une fois à l'intérieur du conteneur.
Pithikos
3
@Pithikos: je peux utiliser exec pour exécuter un shell puis su someuserchanger d'utilisateur. Running Docker 1.4.1
lsh
2
Note à tous ceux qui lisent cette discussion. Je suis sûr docker exec -itqu'il fournira éventuellement un pseudo tty entièrement fonctionnel, mais pour l'instant (Docker version 1.9.1), il y a quelques lacunes: github.com/docker/docker/issues/8755
blong
18
si vous obtenez l'erreur 'exec: "bash": fichier exécutable introuvable dans $ PATH', vous pouvez essayer ceci: docker exec -it [id-conteneur] / bin / sh
Dai Kaixian
42

Vous devez utiliser l'outil de Jérôme Petazzoni appelé «nsenter» pour entrer dans un conteneur sans utiliser SSH. Voir: https://github.com/jpetazzo/nsenter

Installez en exécutant simplement: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Utilisez ensuite la commande docker-enter <container-id>pour entrer dans le conteneur.

Hyperfocus
la source
C'est le bon chemin. Voir le blog .
Jesse Glick du
5
Avec docker 1.3, il y a une nouvelle commande docker exec. Cela vous permet d'entrer un docker en cours d'exécution: docker exec -it <container-id> bash(voir ma réponse ci-dessous)
Michael_Scharf
5
docker-enterExiste-t- il encore? Ça me donne command not found.
Snowcrash
22

Mise à jour

À partir de docker 0.9, pour que les étapes ci-dessous fonctionnent maintenant, il faut maintenant mettre à jour le /etc/default/dockerfichier avec l' '-e lxc'option de démarrage du démon docker avant de redémarrer le démon (je l'ai fait en redémarrant l'hôte).

mise à jour du fichier / etc / default / docker

C'est parce que ...

... il [docker 0.9] contient une nouvelle abstraction de "pilote de moteur" pour rendre possible l'utilisation d'une autre API que LXC pour démarrer les conteneurs. Il fournit également un nouveau pilote de moteur basé sur une nouvelle bibliothèque d'API (libcontainer) qui est capable de gérer les groupes de contrôle sans utiliser les outils LXC. Le problème principal est que si vous comptez sur lxc-attach pour effectuer des actions sur votre conteneur, comme démarrer un shell à l'intérieur du conteneur, ce qui est incroyablement utile pour l'environnement de développement ...

la source

Veuillez noter que cela empêchera la nouvelle fonctionnalité optionnelle de mise en réseau de l'hôte uniquement de docker 0.11 de "fonctionner" et vous ne verrez que l'interface de bouclage. rapport d'erreur


Il s'avère que la solution à une autre question était également la solution à celle-ci:

... vous pouvez utiliser docker ps -notruncpour obtenir l'ID complet du conteneur lxc, puis utiliser lxc-attach -n <container_id>run bash dans ce conteneur en tant que root.

Mise à jour: vous devrez bientôt utiliser ps --no-truncau lieu de celui ps -notruncqui est obsolète.

entrez la description de l'image ici Trouver l'ID complet du conteneur

entrez la description de l'image ici Entrez la commande lxc attach.

entrez la description de l'image ici Le haut montre mon processus apache exécutant ce docker.

Programster
la source
Donc, il n'y a aucun moyen de le faire avec juste Docker, non? Personnellement, je préfère ne pas mélanger moi-même LXC.
qkrijger
Existe-t-il un moyen d'exécuter une commande avec lxc-attach à la place pour lancer le bash? THX!!
joselo
@qkrijger pour autant que je sache, c'est correct. Pourquoi s'inquiéter de "mélanger" LXC? Vous vous rendez compte que le docker est construit au-dessus de LXC, non?
Programster
@joselo Je ne comprends pas votre question, mais je vous suggère de créer un nouveau message avec plus de détails? Il existe de nombreuses façons de démarrer un processus de docker, comme avec bash ou en tant que démon avec -d etc.
Programster
@programster oui, je m'en rends compte :) Pourtant, utiliser LXC directement en combinaison avec Docker ressemble à du piratage. Amusant, mais pas vraiment maintenable. En général, on devrait coder dans la couche d'abstraction dans laquelle on a choisi de travailler. Si vous avez vraiment besoin de LXC lui-même, il est peut-être temps de faire une demande d'extraction sur Docker :)
qkrijger
7

Première étape, obtenez l'ID du conteneur:

docker ps

Cela vous montrera quelque chose comme

NOMS DE PORTS D'ÉTAT CRÉÉS PAR COMMANDE D'IMAGE ID DE CONTENANT

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" il y a 26 secondes Jusqu'à 25 secondes 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 est l'ID du conteneur dans ce cas.

Deuxièmement , entrez le menu fixe:

docker exec -it [container_id] bash

donc dans le cas ci-dessus: docker exec -it 1170fe9e9460 bash

patapouf_ai
la source
5

Qu'en est-il de l'exécution de tmux / GNU Screen dans le conteneur? Semble la manière la plus simple d'accéder à autant de vty que vous le souhaitez avec un simple:

$ docker attach {container id}
cig0
la source
C'est une bonne solution si vous savez que vous voudrez accéder à un conteneur (par exemple pour le déboguer), mais cela n'aidera pas OP qui déclare vouloir regarder autour d'un conteneur existant.
Luca Spiller
1
Mon problème avec cette réponse est que les gens ont déjà posé des questions sur l'utilisation docker attachet j'ai souligné que:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster
Eh bien, si le conteneur est déjà en cours d'exécution, cette solution ne vous aidera pas, mais si vous avez précédemment pris soin de laisser un multiplexeur en cours d'exécution, vous n'aurez pas besoin de ttys supplémentaires ... En fait, depuis que j'ai commencé à utiliser tmux, j'utilise un tty et un seul pour faire tout ce dont j'ai besoin car une fois dans tmux, je peux générer autant de vtys que je veux.
cig0
4

nsenterest-ce que. Cependant, je devais également entrer un conteneur de manière simple et nsenter ne suffisait pas à mes besoins. Il était buggé à certaines occasions (écran noir plus le drapeau -wd ne fonctionnait pas). De plus, je voulais me connecter en tant qu'utilisateur spécifique et dans un répertoire spécifique.

J'ai fini par fabriquer mon propre outil pour entrer dans des conteneurs. Vous pouvez le trouver sur: https://github.com/Pithikos/docker-enter

Son utilisation est aussi simple que

./docker-enter [-u <user>] [-d <directory>] <container ID>
Pithikos
la source
Je viens d'essayer, très cool! Sur Ubuntu, il fallait exécuter sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> C'est bien que je n'ai pas à obtenir l'ID complet comme avec lxc-attach -n Codebase est suffisamment court pour que l'on puisse analyser l'intégralité rapidement pour rechercher tout élément malveillant.
Programster
J'ai rendu un ebuild disponible sur gentoo à github.com/steveeJ/personal-portage-overlay en tant qu'émulation d'application / docker-enter.
stefanjunker
J'ai ajouté un tutoriel / script pour cela automatique pour les utilisateurs d'ubuntu sur programster.blogspot.co.uk/2014/01/…
Programster
2

La manière "nsinit" est:

installer nsinit

git clone [email protected]:dotcloud/docker.git
cd docker
make shell

de l'intérieur du conteneur:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

de dehors:

docker cp id_docker_container:/go/bin/nsinit /root/

utilise le

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash
Ivailo Bardarov
la source
2
docker exec -t -i container_name /bin/bash

Vous amènera à la console des conteneurs.

Danstan
la source
J'ai atterri sur cette question parce que j'avais le même problème. La réponse qui semble similaire n'a pas fonctionné pour moi jusqu'à ce que je modifie. Je peux cependant supprimer cela.
Danstan
2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh
Flavio
la source
1

J'ai démarré PowerShell sur un microsoft / iis en cours d'exécution en tant que démon en utilisant

docker exec -it <nameOfContainer> powershell
Ahmed Samir
la source
Il semble que la question concerne un conteneur basé sur Linux. Cette réponse ne fonctionnera probablement que si vous avez un conteneur basé sur Windows -ou- si la version .NET Core de PowerShell est installée, par exemple PowerShell 6 ou version ultérieure.
Manfred
0

Sur Windows 10 , j'ai installé docker. J'exécute Jnekins sur un conteneur et j'ai rencontré le même message d'erreur. Voici un guide étape par étape pour résoudre ce problème:

Étape 1: Ouvrez gitbash et exécutez docker run -p 8080: 8080 -p 50000: 50000 jenkins.

Étape 2: ouvrez un nouveau terminal.

Étape 3: Faites "docker ps" pour obtenir la liste du conteneur en cours d'exécution. Copiez l'ID du conteneur.

Étape 4: Maintenant, si vous faites "docker exec -it {conteneur id} sh" ou "docker exec -it {conteneur id} bash", vous obtiendrez un message d'erreur similaire à "le périphérique d'entrée n'est pas un ATS. Si vous êtes en utilisant mintty, essayez de préfixer la commande avec 'winpty' "

Étape 5: Exécutez la commande " $ winpty docker exec -it {container id} sh "

vola !! Vous êtes maintenant à l'intérieur du terminal.

Dev 00721
la source