Comment obtenir bash ou ssh dans un conteneur en cours d'exécution en arrière-plan?

934

Je veux SSH ou bash dans un conteneur de docker en cours d'exécution. S'il vous plaît, voir exemple:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

maintenant je veux obtenir quelque chose comme ça (allez dans le conteneur en cours d'exécution):

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/# 
However when I run the line above I get new CONTAINER ID
$ root@42f1e37bd0e5:/#

J'ai utilisé Vagrant et j'aimerais avoir un comportement similaire à celui de vagrant ssh.

Timur Fayzrakhmanov
la source
alternativement sudo docker exec -i -t 665b4a1e17b6 /bin/shpour être en mesure d'installer des programmes apt et forfaits
fonjeekay
1
Notez que l'utilisation de SSH pour démarrer dans un conteneur en cours d'exécution est une mauvaise pratique - voir la justification ici . sudo docker exec -i -t container-name /bin/bashest un chemin à parcourir.
patryk.beza

Réponses:

1306

La réponse est la attachcommande de Docker . Donc, pour mon exemple ci-dessus, la solution sera:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#

Pour Docker version 1.3 ou ultérieure: Merci à l'utilisateur WiR3D qui a suggéré un autre moyen d'obtenir le shell d'un conteneur. Si nous utilisons, attachnous ne pouvons utiliser qu'une seule instance du shell. Donc, si nous voulons ouvrir un nouveau terminal avec une nouvelle instance du shell d'un conteneur, il nous suffit d'exécuter les opérations suivantes:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

ou

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fayzrakhmanov
la source
5
Sinon, exécutezsudo docker attach loving_heisenberg
Thiago Perrotta
51
la commande attacher ne fonctionne pas pour moi, elle provoque le blocage du docker .. des idées pour lesquelles cela se produit?
Mo J. Mughrabi
10
Rappel pour les utilisateurs de boot2docker: supprimez sudo :)
Henno
17
-i -test égal à-it
pasha.zhukov
47
C'est une réponse dangereuse à sélectionner et donc à voter. docker attachPar exemple, si vous vous connectez à une instance MongoDB, l’instance sera détruite. Comme expliqué plus en détail dans cette question attach et execsont des animaux différents.
Fwc
676

À partir de Docker 1.3:

docker exec -it <containerIdOrName> bash

Fondamentalement, si le conteneur Docker a été démarré à l'aide de la /bin/bashcommande, vous pouvez y accéder à l'aide de attach. Sinon, vous devez exécuter la commande pour créer une instance Bash dans le conteneur à l'aide de exec.

Également pour quitter Bash sans laisser Bash s'exécuter dans un processus non autorisé:

exit

Oui, c'est aussi simple que cela.

WiR3D
la source
Je n'ai toujours pas compris comment faire fonctionner le nano. Pense que cela peut impliquer docker-ssh de phusion
WiR3D
Est-il possible de définir bash par défaut dans les dockers?
ipeacocks
@ipeacocks oui, si la RUNcommande dans le fichier docker est /bin/bash. Mais cela dépend de ce que vous voulez dire. Si vous voulez exécuter le conteneur et que bash soit disponible immédiatement dans ce même terminal, alors exécutez-le avec -itdevrait le faire
WiR3D
10
Utiliser un groupe de dockers est une mauvaise pratique. Tout utilisateur appartenant au groupe de docker est essentiellement utilisé avec des autorisations root sans qu'il soit nécessaire d'utiliser sudo. projectatomic.io/blog/2015/08/…
Maiku Mori Le
1
Je pense que cela ne fait pas beaucoup de différence, du point de vue de la sécurité de l'hôte, que vous utilisiez sudovs dockergroup. Quoi qu'il en soit, docker sudocomporte une faille de sécurité pouvant fournir tous les privilèges du système de fichiers hôte à partir de l'invité, que vous utilisiez le groupe de docker ou que vous lanciez le conteneur.
novembre
123

Bien que l’auteur de la question ait spécifiquement indiqué qu’il était intéressé par un conteneur en cours d’exécution, il convient également de noter que si le conteneur n’est pas en cours d’exécution, vous souhaitez le lancer pour fouiller dans tous les sens:

docker run -i -t --entrypoint /bin/bash <imageID>

Adam Kalnas
la source
10
Cela donne un conteneur différent, tout comme la réponse de @ kraxor.
Blaisorblade
19

Sur la base de la réponse de @ Timur, j'ai créé le script suivant:

Installer

Mettez le docker-sshfichier dans votre $PATHavec le contenu suivant

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l

Remarque : Certains conteneurs ne contiennent pas bash, mais ash, shetc. Dans ces cas, ils bashdoivent être remplacés dans le script ci-dessus.

Usage

Si vous n'avez qu'une seule instance en cours d'exécution, lancez simplement

$> docker-ssh 

Sinon, fournissez-lui un paramètre d’identificateur de menu fixe que vous obtenez de docker ps(première col)

$> docker-ssh 50m3r4nd0m1d
Matyas
la source
Puis-je savoir pourquoi nous avons besoin de -l à la fin?
Nam G VU
pour démarrer bash en tant que shell de connexion, en lisant les paramètres d'environnement (décrits dans la ligne au-dessus de la commande)
Matyas
13

Si votre conteneur n'est pas installé sur bash, vous pouvez essayer sh:

docker exec -it CONTAINER /bin/sh

Ou cherchez d'abord les coquillages dans / bin:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
la source
Qu'est-ce que "consul" ? Avez-vous une référence pour cela? Voulez-vous dire "console" ?
Peter Mortensen
9

J'ai créé un serveur SSH conteneurisé qui fournit des fonctionnalités SSH à tout conteneur en cours d'exécution. Vous n'avez pas besoin de changer votre conteneur. La seule exigence est que le conteneur ait bash.

Si vous avez un conteneur avec le nom 'web-server1'. La commande suivante de docker run démarrera un deuxième conteneur qui fournirait SSH pour le premier conteneur.

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh

Pour plus de pointeurs, consultez https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
la source
Cela devrait être la réponse acceptée ^
Nam G VU
À propos, comment pouvons-nous charger automatiquement .bashrc lors du démarrage d’une session SSH avec votre solution? Également publié un numéro sur github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

@jpetazzo a un post génial à ce sujet . La réponse courte serait d'utiliser nsenter:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

PS: N'oubliez pas de vérifier la discussion dans les commentaires du message ...

À votre santé

Richard
la source
1
C'est un article plutôt ancien qui n'est plus vraiment nécessaire . La docker execsolution de @ WiR3D est plutôt plus pratique.
Drevicko
4

Vous pouvez également attribuer au conteneur Docker une adresse IP routable avec Pipework, puis SSH dans la machine avec cette nouvelle adresse IP.

Ce sera plus "traditionnel" (ssh), au lieu d'utiliser une commande spécifique à l'application telle que docker attach, et le rendra éventuellement plus "portable" entre systèmes et versions.

radriaanse
la source
S'il vous plaît, ajoutez le moyen simple comment le faire. Si pour être honnête, j'en ai vraiment besoin, mais je n'ai pas le temps de chercher la solution la plus simple. Pourriez-vous poster votre réponse ici? Ce serait génial ..
Timur Fayzrakhmanov
2
Il y a 2 façons d'accomplir cela, mais ce n'est pas simple et deviendrait un poste important. Vous pouvez vérifier ce lien par vous-même, pour l’utilisation de pipework ou ce lien , qui remplit essentiellement le même rôle que Pipework et est un peu plus simple, mais vous devez le faire manuellement. Cela dépend donc du nombre de serveurs sur lesquels on parle. Si vous ne pouvez pas trouver quelque chose de plus spécifique, faites le moi savoir. Mais je n'ai pas non plus le temps d'écrire un tutoriel complet.
Radriaanse
Vous avez raison - il n'y a pas de moyen simple et évident de le faire (Merci pour les liens, je pense que je le
reverrai
2
docker run -it openjdk:8

Cela marche :-)

Kishan B
la source
1

ALLER À L'INTÉRIEUR

Installez l' goinsideoutil de ligne de commande avec:

sudo npm install -g goinside

et entrez dans un conteneur de menu fixe avec une taille de terminal appropriée avec:

goinside docker_container_name

pour plus de détails, consultez ceci .

Soorena
la source
0

Pour bash dans un conteneur en cours d'exécution, tapez ceci:

docker exec -t -i container_name /bin/bash
Agustí Sánchez
la source
1
C'est pourtant la même réponse que @AdamKalnas
Bruni
0

Juste pour informations. Si vous devez vous connecter à un conteneur simple qui n'est pas un démon, vous devez utiliser les commandes suivantes:

docker start {id}
docker attach {id}
Nek
la source
-1

Si le conteneur est arrêté, comme par exemple un conteneur de données uniquement, une bonne solution consiste à exécuter un conteneur jetable à chaque fois que vous souhaitez attacher le conteneur de données. Dans ce cas, le conteneur de données lui-même pourrait être entièrement vide, car le conteneur temporaire disposerait des outils du système d'exploitation.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
David Dehghan
la source