Come posso accedere alla shell di un container Docker?


1163

Sto iniziando a lavorare con Docker. Sto usando l'immagine di base di WordPress e la finestra mobile-componi.

Sto cercando di ssh in uno dei container per ispezionare i file / le directory che sono stati creati durante la build iniziale. Ho provato a correre docker-compose run containername ls -la, ma questo non ha fatto nulla. Anche se lo facesse, preferirei avere una console in cui posso attraversare la struttura della directory, piuttosto che eseguire un singolo comando. Qual è il modo giusto per farlo con Docker?


Quindi sembra che la risposta sia allegare alla finestra mobile. Ma come posso farlo da docker-compose?
Andrew,

3
Usa docker exec askubuntu.com/a/543057/35816 . Ottieni l'ID contenitore utilizzandodocker ps
Mauricio Scheffer,

26
sudo docker run -it --entrypoint /bin/bash <container_name>ti porta nel contenitore in modo interattivo. Quindi si può ispezionare il file system nel contenitore usandocd <path>
Sergei

Risposte:


1736

docker attachti permetterà di connetterti al tuo contenitore Docker, ma non è esattamente la stessa cosa di ssh. Se il tuo contenitore sta eseguendo un server web, ad esempio, docker attachprobabilmente ti collegherà allo stdout del processo del server web. Non ti darà necessariamente un guscio.

Il docker execcomando è probabilmente quello che stai cercando; questo ti consentirà di eseguire comandi arbitrari all'interno di un contenitore esistente. Per esempio:

docker exec -it <mycontainer> bash

Ovviamente, qualunque comando tu stia eseguendo deve esistere nel filesystem container.

Nel comando sopra <mycontainer>è il nome o l'ID del contenitore di destinazione. Non importa se stai usando o meno docker compose; basta eseguire docker pse utilizzare l'ID (una stringa esadecimale visualizzata nella prima colonna) o il nome (visualizzato nella colonna finale). Ad esempio, dato:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Posso correre:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Potrei realizzare la stessa cosa eseguendo:

$ docker exec -it d2d4a89aaee9 ip addr

Allo stesso modo, potrei avviare una shell nel contenitore;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$

76
Inoltre, docker execfunziona solo su container in esecuzione (altrimenti utilizza docker run -it --entrypoint /bin/basho simili).
L0j1k,

59
per tua comodità, -itè una combinazione di -ie -tche è --interactive("Mantieni STDIN aperto anche se non attaccato") rispettivamente --tty("Allocate a pseudo-TTY").
Adrian Föder,

23
Sui contenitori basati su Alpine Linux potresti non avere bash, quindi in questo caso usa sh invece.
Robin Green

9
@ L0j1k lo è docker run -it --entrypoint /bin/bash <imageid> --any --more --args, solo per chiarire le persone
Alexander Mills,

2
@AlexanderMills Sì, e per chiarire ulteriormente, quelli --any --more --argsche hai verranno inseriti in qualunque immagine definita come sua CMDe non Docker (o se la tua immagine definisce solo un ENTRYPOINTe no CMD, allora queste opzioni verranno inserite /bin/bashcome hai specificato qui ). Ad esempio, qualsiasi altra docker runopzione (ad es. --net "host") Deve essere preceduta da <imageid>.
L0j1k,

302

Per colpire in un contenitore in esecuzione, digitare questo:

docker exec -t -i container_name /bin/bash

o

docker exec -ti container_name /bin/bash

o

docker exec -ti container_name sh

Presumendo che sia un contenitore Linux?
Peter Mortensen,

5
/ bin / bash non era richiesto, ma bash l'ha fatto per me
Anand Varkey Philips,

6
Preferirei docker exec -itinvecedocker exec -t -i
VaTo

qual è la differenza @VaTo
AATHITH RAJENDRAN il

@AATHITHRAJENDRANI preferisce solo una forma più breve del comando invece di avere due flag, puoi includere queste due opzioni nello stesso argomento -it.
Va

85

Diciamo, per motivi che sono tuoi, vuoi davvero usare SSH. Bastano pochi passaggi, ma può essere fatto. Ecco i comandi che eseguiresti all'interno del contenitore per configurarlo ...

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Ora puoi persino eseguire applicazioni grafiche (se installate nel contenitore) usando l'inoltro X11 al client SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Ecco alcune risorse correlate:


34

Se stai cercando una risposta specifica di Docker Compose come me, fornisce un modo semplice per accedere senza dover cercare l'ID contenitore generato.

docker-compose execprende il nome del servizio come da docker-compose.ymlfile.

Quindi, per ottenere una shell Bash per il tuo servizio "web", puoi fare:

$ docker-compose exec web bash

docker-compose runfunziona anche se il tuo contenitore non esiste ancora.
Paul

23

Avviso : questa risposta promuove uno strumento che ho scritto.

Ho creato un server SSH containerizzato che puoi "attaccare" a qualsiasi container in esecuzione. In questo modo puoi creare composizioni con ogni contenitore. L'unico requisito è che il contenitore abbia Bash.

L'esempio seguente avvierebbe un server SSH collegato a un contenitore con il nome "my-container".

docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

ssh localhost -p 2222

Quando ti connetti a questo servizio SSH (con il tuo client SSH preferito) verrà avviata una sessione Bash nel contenitore con il nome "my-container".

Per ulteriori suggerimenti e documentazione, consultare: https://github.com/jeroenpeeters/docker-ssh


1
È piuttosto dolce. Il grande vantaggio di farlo in questo modo è ottenere un terminale completamente funzionale. Quando ho usato l'approccio "docker exec" non riuscivo a cancellare il contenuto del terminale, lessogni volta che lo eseguivo mostravo un avviso, ecc. L'uso del contenitore di Jeroen mi ha dato un'esperienza molto migliore finora. Assicurati di controllare la documentazione . Il comando di esempio nella risposta non sembra più valido.
Rafał G.,

1
E 'un ottimo strumento. Sai come posso usarlo come agente docker della pipeline jenkins? Voglio che jenkins trasferisca alcuni file tramite SCP su un host remoto ed esegua con SSH
Gilson

21

Se stai usando Docker su Windows e vuoi ottenere l'accesso shell a un contenitore, usa questo:

winpty docker exec -it <container_id> sh

Molto probabilmente, hai già installato Git Bash . In caso contrario, assicurati di installarlo.


1
Presume un contenitore Docker Linux?
Peter Mortensen,

1
docker exec -ti <container_id> cmd funziona bene
PBo

17

Se il contenitore è già uscito (forse a causa di un errore), puoi farlo

$ docker run --rm -it --entrypoint /bin/ash image_name

o

$ docker run --rm -it --entrypoint /bin/sh image_name

o

$ docker run --rm -it --entrypoint /bin/bash image_name

per creare un nuovo contenitore e inserirvi una shell. Dato che hai specificato --rm, il contenitore verrebbe eliminato quando esci dalla shell.


16

In alcuni casi la tua immagine può essere di tipo alpino. In questo caso genererà:

Runtime OCI exec non riuscito: exec non riuscito: container_linux.go: 348: l'avvio del processo del contenitore ha causato "exec: \" bash \ ": file eseguibile non trovato in $ PATH": sconosciuto

Perché /bin/bashnon esiste. Invece di questo dovresti usare:

docker exec -it 9f7d99aa6625 ash

o

docker exec -it 9f7d99aa6625 sh

15

SSH in un contenitore Docker usando questo comando:

sudo docker exec -i -t (container ID) bash

12

Per connettersi a cmd in un contenitore di Windows, utilizzare

docker exec -it d8c25fde2769 cmd

Dove d8c25fde2769 è l'ID contenitore.


11

È semplice !

Elenca tutte le tue immagini Docker:

sudo docker images

Sul mio sistema ha mostrato il seguente output:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

Ho due immagini Docker sul mio PC. Diciamo che voglio eseguire il primo.

sudo docker run -i -t ubuntu:latest /bin/bash

Questo ti darà il controllo terminale del contenitore. Ora puoi eseguire tutti i tipi di operazioni shell all'interno del contenitore. Come fare, lsverranno visualizzate tutte le cartelle nella radice del file system.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

11

Per ispezionare i file, eseguire docker run -it <image> /bin/shper ottenere un terminale interattivo. L'elenco delle immagini può essere ottenuto da docker images. Al contrario di docker execquesta soluzione funziona anche nel caso in cui un'immagine non si avvia (o si chiude immediatamente dopo l'esecuzione).


Presumendo un'immagine Docker di Linux?
Peter Mortensen,

10

SOLUZIONE GOINSIDE

installa lo goinsidestrumento da riga di comando con:

sudo npm install -g goinside

e vai all'interno di un contenitore docker con una dimensione terminale corretta con:

goinside docker_container_name

vecchia risposta

Abbiamo inserito questo frammento ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

Questo non solo rende tutti in grado di entrare in un container in esecuzione con:

goinside containername

Risolve inoltre un problema di lunga durata relativo alle dimensioni fisse dei terminali del contenitore Docker . Il che è molto fastidioso se lo affronti.

Inoltre, se segui il link avrai il completamento del comando anche per i nomi dei container della finestra mobile.


1
Grazie. Funziona come un incantesimo, almeno per quelle immagini che hanno già incluso bash. Potrebbe non funzionare per le immagini di base alpina, tuttavia, può essere risolto con una diversa funzione scritta appositamente per sh / ash ecc.
Gaurav Bhaskar,

8
$ docker exec -it <Container-Id> /bin/bash

O a seconda della shell, può essere

$ docker exec -it <Container-Id> /bin/sh

È possibile ottenere l' ID contenitore tramite docker pscomando

-i = interattivo

-t = allocare un psuedo-TTY


8

Ho creato una funzione terminale per un più facile accesso al terminale del contenitore. Forse è utile anche a voi ragazzi:

Quindi il risultato è, invece di digitare:

docker exec -it [container_id] /bin/bash

scriverai:

dbash [container_id]

Inserisci quanto segue nel tuo ~ / .bash_profile (o qualsiasi altra cosa che funzioni per te), quindi apri una nuova finestra del terminale e goditi il ​​collegamento:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}

7

è possibile interagire con il terminale nel contenitore finestra mobile passando l'opzione -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t sta per terminale -i sta per interattivo


6

docker execsarà sicuramente una soluzione. Un modo semplice per lavorare con la domanda che hai posto è montando la directory all'interno di Docker nella directory del sistema locale .

In questo modo è possibile visualizzare istantaneamente le modifiche nel percorso locale.

docker run -v /Users/<path>:/<container path> 

1
il tuo comando sta effettivamente montando la directory dell'host nel contenitore.
Demonbane,

Si! Eseguire un backup in un'altra directory, quindi montare il volume, quindi spostare il backup nella cartella montata.
Pratik,

6

Uso:

docker attach <container name/id here>

L'altro modo, sebbene ci sia un pericolo, è usare attach, ma se tu Ctrl+ Cper uscire dalla sessione, fermerai anche il contenitore. Se vuoi solo vedere cosa sta succedendo, usa docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)


4

Se hai installato Docker Kitematic, puoi utilizzare la GUI. Apri Kitematicdall'icona Docker e nella Kitematicfinestra seleziona il tuo contenitore, quindi fai clic execsull'icona.

In questa GUI è possibile visualizzare anche il registro contenitore e molte informazioni sul contenitore (nella scheda Impostazioni).

Seleziona Kitematic dal menu

Fai clic su exec


2

Nel mio caso, per qualche motivo, devo controllare tutte le informazioni sulla rete coinvolte in ciascun contenitore. Quindi i seguenti comandi devono essere validi in un contenitore ...

ip
route
netstat
ps
...

Ho controllato tutte queste risposte, nessuna mi è stata di aiuto. Ho cercato informazioni in altri siti Web. Non aggiungerò un super link qui, poiché non è scritto in inglese. Quindi ho appena pubblicato questo post con una soluzione di riepilogo per le persone che hanno gli stessi requisiti di me.

Supponi di avere un container in esecuzione chiamato light test. Seguire i passaggi seguenti.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Questo comando riceverà una risposta simile /var/run/docker/netns/xxxx.
  • Poi ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. La directory potrebbe non esistere, eseguire mkdir /var/run/netnsprima.
  • Ora puoi eseguire ip netns exec xxxx ip addr showper esplorare il mondo della rete in container.

PS. xxxxè sempre lo stesso valore ricevuto dal primo comando. E, naturalmente, qualsiasi altro comando è valido, ad es ip netns exec xxxx netstat -antp|grep 8080.


1

Un'altra opzione è usare nsenter .

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

2
Ci sono una serie di problemi con nsenter. Il primo è che richiede l'accesso fisico all'host docker, che non è un dato di fatto (potresti lavorare con un'API docker remota). Inoltre, l'esecuzione in nsenteresenzione ti esonera da molte delle restrizioni di sicurezza e risorse messe in atto da Docker (che può essere un pro o un contro, a seconda del tuo ambiente).
Larks

1
Anche l'autore di nsenter dice di usare in docker execquesti giorni.
L0j1k,

1
@larsks Sì, entrambi hanno i loro vantaggi. Ad esempio, questo è un vantaggio di nsenter over docker exec. docker execmi sembra più elegante.
xuhdev,

2
@ L0j1k Solo per essere meno confusi: il post che hai citato non è dell'autore di nsenter, ma dell'autore di un'immagine Docker che esegue nsenter.
xuhdev,

1

Se stai usando Docker Compose, questo ti porterà all'interno di un contenitore Docker.

docker-compose run container_name /bin/bash

All'interno del contenitore vi porterà a WORKDIR definito nel Dockerfile. È possibile modificare la directory di lavoro di

WORKDIR directory_path # E.g  /usr/src -> container's path

0

Per eseguire in un contenitore in esecuzione denominato test, di seguito sono i seguenti comandi

Se il contenitore ha bashshell

docker exec -it test /bin/bash

Se il contenitore ha bourneshell e la maggior parte dei casi è presente

docker run -it test /bin/sh

-3

Per docker-compose up (Docker4Drupal)

docker-compose exec php bash

Uso Docker per Drupal su un laptop Linux. Dopo aver eseguito il contenitore, utilizzo " docker-compose exec php bash" per connettermi al contenitore in modo da poter eseguire i comandi drush. Funziona bene per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.