Czy można rozpocząć sesję powłoki w działającym kontenerze (bez ssh)

341

Naiwnie spodziewałem się, że to polecenie uruchomi powłokę bash w działającym kontenerze:

docker run "id of running container" /bin/bash

wygląda na to, że to niemożliwe, pojawia się błąd:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

Więc jeśli chcę uruchomić powłokę bash w działającym kontenerze (np. Do celów diagnostycznych)

czy muszę na nim uruchomić serwer SSH i zalogować się przez ssh?

Max L.
źródło
1
docker run CONTAINERplanowane jest na 1.0
kolypto
7
Od dokera 1.3 powinieneś naprawdę postępować zgodnie z opisem w tej odpowiedzi
Thomasleveil
1
justdocker attach container_name
maxbellec
1
Wygląda na to, że druga odpowiedź jest obecnie znacznie lepsza niż zaakceptowana - czy możesz rozważyć zmianę przyjętej odpowiedzi?
jsbueno

Odpowiedzi:

285

EDYCJA: Teraz możesz użyć docker exec -it "id of running container" bash( doc )

Wcześniej odpowiedź na to pytanie brzmiała:

Jeśli naprawdę musisz i jesteś w środowisku debugowania, możesz to zrobić: sudo lxc-attach -n <ID> Zauważ, że identyfikator musi być pełny ( docker ps -notrunc).

Jednak zdecydowanie odradzam to.

Uwaga: -notruncjest przestarzałe, wkrótce zostanie zastąpione przez --no-trunc.

skrzyp
źródło
1
dlaczego odradzasz to?
Max L.
7
Odradzam to, ponieważ 1) wymaga najnowszego jądra, 2) Robisz rzeczy poza dokerem, więc nie będziesz w stanie go śledzić (logi, załączanie itp.). Ponadto doker może teraz używać lxc, ale nie ma gwarancji, że będzie to robić na zawsze.
creack
1
Spróbuj zaktualizować do wersji 0.7.6. Docker nadal używa lxc i lxc-attachpowinien działać dobrze. Właśnie dwukrotnie sprawdziłem i to działa dla mnie. (Pamiętaj, że nie będzie działać z jądrem wcześniejszym niż 3.8).
creack
2
od wersji 0.9 doker nie działa już domyślnie z LXC. Będziesz musiał uruchomić docker -d -e lxc
dokera deamon za
2
Max L., twój przypadek użycia można rozwiązać za pomocą woluminów danych . Nie testowano na przykład: 1) przebiegają pojemnik Nginx kłód w ilości danych: docker run -v /var/log/nginx -name somename imagename command; 2) uruchomienia innego pojemnika, aby zobaczyć zawartość objętościowa produktu: docker run -volumes-from somename -i -t busybox /bin/sh.
ciastek
615

W dokerze 1.3 pojawiło się nowe polecenie docker exec. Umożliwia to wejście do działającego okna dokowanego:

docker exec -it "id of running container" bash
Michael_Scharf
źródło
2
To zadziałało dla mnie świetnie. Bardzo pomocny dodatek do uruchomienia dokera.
oraserrata
Co jeśli wprowadzę zmiany podczas wykonywania działającego kontenera i chcę odzwierciedlić zmiany w trybie online? jakie są najlepsze praktyki?
mediaroot
Bardzo przydatne. Dzięki
luongnv89,
użyj, docker psaby uzyskać identyfikator uruchomionych instancji
muon
Uwaga: Kontener może nie mieć bash (»exec:" bash ": nie znaleziono pliku wykonywalnego«). Użyj, docker inspect <image>aby zobaczyć, jaka powłoka jest dostępna. Np. Uruchom docker exec -it <container id> /bin/shzamiast tego.
pixelbrackets 21.04.17
14

Po prostu zrób

docker attach container_name

Jak wspomniano w komentarzach, aby odłączyć się od pojemnika bez zatrzymywania go, wpisz Ctrlpnastępnie Ctrlq.

maxbellec
źródło
5
Dzięki!! Pomogło. W kontekście rzeczywistego pytania chciałbym coś dodać. Po debugowaniu naszego kontenera za pomocą, docker attach container_nameużyj ctrl pi ctrl qzamiast exit. exitpolecenie zatrzymuje kontener, gdzie jak ctrlpi ctrl qpo prostu odłącza ten kontener i utrzymuje go w działaniu
feniks
10

Ponieważ wszystko się zmienia, w tej chwili używa się zalecanego sposobu dostępu do działającego kontenera nsenter.

Możesz znaleźć więcej informacji na temat tego repozytorium github . Ale ogólnie możesz użyć nsenter w ten sposób:

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

lub możesz użyć opakowania docker-enter:

docker-enter <container_name_or_ID>

Dobre wyjaśnienie na ten temat można znaleźć na blogu Jérôme Petazzoni: Dlaczego nie musisz uruchamiać sshd w kontenerach dokerów

Teudimundo
źródło
niestety zmienne env są pomieszane przy użyciu tego podejścia (jeśli chcesz sprawdzić zmienne utworzone przez link). Proponuję robić source /proc/*/environ.
Tomas Tomecek
8

Pierwsza rzecz, której nie możesz uruchomić

docker run "existing container" command

Ponieważ to polecenie oczekuje obrazu, a nie kontenera, i tak spowoduje powstanie nowego kontenera (więc nie tego, na który chciałeś spojrzeć)

Zgadzam się z faktem, że dzięki dokerowi powinniśmy zmuszać się do myślenia w inny sposób (więc powinieneś znaleźć sposoby, aby nie trzeba było logować się do kontenera), ale nadal uważam to za przydatne i tak działam dookoła tego.

Uruchamiam polecenia za pośrednictwem opiekuna w trybie DEAMON.

Następnie wykonuję to, co nazywam docker_loop.sh . Treść jest prawie taka:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

Umożliwia to „dołączenie” do kontenera i przedstawienie supervisorctlinterfejsu umożliwiającego zatrzymanie / uruchomienie / ponowne uruchomienie i sprawdzenie dzienników. Jeśli to nie wystarczy, możesz Ctrl+Di wpadniesz do powłoki, która pozwoli ci rzucić okiem, jakby to był normalny system.

PROSZĘ RÓWNIEŻ UWAŻAĆ, że ten system nie jest tak bezpieczny, jak posiadanie pojemnika bez skorupy, więc podejmij wszelkie niezbędne kroki, aby zabezpieczyć swój kontener.

Alessandro
źródło
5

Obserwuj tę prośbę: https://github.com/docker/docker/pull/7409

Który implementuje nadchodzące docker exec <container_id> <command>narzędzie. Gdy jest to możliwe, powinno być możliwe np. Uruchomienie i zatrzymanie usługi ssh w działającym kontenerze.

Należy również nsinitto zrobić: „nsinit zapewnia wygodny sposób na uzyskanie dostępu do powłoki wewnątrz działającego obszaru nazw kontenera” , ale uruchomienie jest trudne. https://gist.github.com/ubergarm/ed42ebbea293350c30a6

Foz
źródło
docker execwylądował w Döcker 1.3, więc jest obecnie możliwe, aby utworzyć i dołączyć nową sesję powłoki w pojemniku z systemem
Foz
3

Możesz użyć

docker exec -it <container_name> bash
antikytheraton
źródło
1

W rzeczywistości istnieje sposób na umieszczenie powłoki w pojemniku.

Załóżmy, że /root/run.shuruchamia proces, kierownika procesu (przełożonego) lub cokolwiek innego.

Twórz za /root/runme.shpomocą kilku sztuczek na ekranie GNU:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Teraz masz demony na karcie 0 i interaktywną powłokę na karcie 1. docker attachw dowolnym momencie, aby zobaczyć, co dzieje się w pojemniku.

Inną radą jest utworzenie obrazu „pakietu rozwojowego” na górze obrazu produkcyjnego przy użyciu wszystkich niezbędnych narzędzi, w tym tej sztuczki ekranowej.

kolypto
źródło
1

oto moje rozwiązanie

część DOckerfile:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

część „initd.sh”

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

po zbudowaniu obrazu masz dwie opcje za pomocą exec i attach:

  1. z exec (którego używam) uruchom:

uruchomienie dokera - nazwa $ CONTAINER_NAME -dt $ IMAGE_NAME

następnie

docker exec -it $ CONTAINER_NAME / bin / bash

I użyć

CTRL + D, aby odłączyć

  1. z załącznikiem uruchom:

Uruchom okno dokowane - nazwa $ CONTAINER_NAME -dit $ IMAGE_NAME

następnie

doker dołącza $ CONTAINER_NAME

I użyć

CTRL + P i CTRL + Q, aby odłączyć

różnica między opcjami jest w parametrze -i

tim
źródło
1

Istnieją dwa sposoby.

Z załącznikiem

$ sudo docker attach 665b4a1e17b6 #by ID

Z exec

$ sudo docker exec - -t 665b4a1e17b6 #by ID
gurubelli
źródło
0

Przydatne jest przypisanie nazwy podczas uruchamiania kontenera. Nie musisz odwoływać się do id_kontenera.

docker run --name container_name yourimage docker exec -it container_name bash

Matsumoto Kazuya
źródło
0

najpierw uzyskaj identyfikator kontenera żądanego kontenera przez

docker ps

dostaniesz coś takiego:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

teraz skopiuj ten identyfikator kontenera i uruchom następującą komendę:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh

Umesh
źródło
-2

Być może przy wprowadzaniu kontenerów wprowadzono Cię w błąd, podobnie jak ja, do myślenia o maszynach wirtualnych. Moja rada: staraj się tego nie robić.

Pojemniki są jak każdy inny proces. Rzeczywiście możesz chcieć „dołączyć” do nich w celu debugowania (pomyśl o / proc // env lub strace -p), ale to bardzo szczególny przypadek.

Zwykle po prostu „uruchamiasz” ten proces, więc jeśli chcesz zmodyfikować konfigurację lub odczytać dzienniki, po prostu utwórz nowy kontener i upewnij się, że zapisujesz dzienniki poza nim, udostępniając katalogi, pisząc na standardowe wyjście (aby dzienniki dokera działały) czy jakoś tak.

Do celów debugowania możesz chcieć uruchomić powłokę, potem swój kod, a następnie naciśnij CTRL-p + CTRL-q, aby pozostawić powłokę nietkniętą. W ten sposób możesz ponownie podłączyć, używając:

docker attach <container_id>

Jeśli chcesz debugować kontener, ponieważ robi coś, czego się nie spodziewałeś, spróbuj go debugować: /server/596994/how-can-i-debug-a-docker-container -inicjalizacja

estani
źródło
To jest całkowicie błędne. Możliwość introspekcji przestrzeni nazw LXC, w której działa twoja aplikacja, nie jest „bardzo szczególnym przypadkiem”, jest to codzienna aktywność każdego programisty.
sleepycal
@sleepycal „dowolny programista” brzmi trochę stronniczo. W każdym razie używam introspekcji procesów, więc to samo dotyczy pojemników. Taki jest pomysł debugowania. Do procesu dołączasz debuger (który może mieć plik cli). Myśl, że „jesteś” zalogowany do kontenera, nadal wydaje mi się myląca.
estani
-4

Nie. Nie jest to możliwe. Użyj czegoś takiego, supervisordaby uzyskać serwer ssh, jeśli jest to potrzebne. Chociaż zdecydowanie kwestionuję tę potrzebę.

Nick Stinemon
źródło