Jak wejść do kontenera Docker, który już działa z nowym TTY

545

Mam kontener z uruchomioną usługą Apache na pierwszym planie. Chciałbym mieć dostęp do kontenera z innej powłoki, aby „zajrzeć” do niej i sprawdzić pliki. W tej chwili, jeśli podłączę się do kontenera, pozostanie mi patrząc na demona Apache i nie mogę uruchomić żadnych poleceń.

Czy można dołączyć kolejny tty do działającego kontenera? Być może mogę skorzystać z faktu, że Docker właśnie owija pojemniki LXC? Próbowałem, sudo lxc-console -n [container-id] -t [1-4]ale wydaje się, że dostępny jest tylko jeden tty i to on uruchamia demona apache. Być może istnieje sposób na włączenie wielu konsol LXC podczas kompilacji?

Wolę nie konfigurować i nie budować kontenera za pomocą usługi openssh, jeśli to możliwe.

Programista
źródło
7
Próbowałeś docker attach [conainer-id]?
shabbychef
13
@shabbychef, chyba że zmieniło się okno docker attach, polecenie attach dołącza się do działającego tty, a nie nowego, stąd tytuł pytania brzmi „... with new TTY”. Dlatego w poniższej odpowiedzi nie użyto polecenia attach.
Programster
1
Od wersji 1.3 istnieje łatwiejszy sposób opisany w tej odpowiedzi
Thomasleveil

Odpowiedzi:

1060

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 [container-id] bash
Michael_Scharf
źródło
30
Zmieniłem to, aby była poprawną odpowiedzią (z mojej własnej), ponieważ ta nowa metoda, której nie było w chwili pytania, jest najlepszą obecnie metodą IMO.
Programster
3
Zauważ jednak, że execto nie działa jak normalny terminal. Na przykład nie możesz zmienić użytkownika raz w kontenerze.
Pithikos
3
@Pithikos: Mogę użyć exec do uruchomienia powłoki, a następnie su someuserdo zmiany użytkownika. Uruchamianie
Dockera
2
Uwaga dla każdego, kto czyta tę dyskusję. Jestem pewien, docker exec -itże w końcu dostarczy w pełni funkcjonalny pseudo tty, ale na razie (wersja Docker 1.9.1) istnieją pewne niedociągnięcia: github.com/docker/docker/issues/8755
blong
18
jeśli pojawi się błąd „exec:„ bash ”: nie znaleziono pliku wykonywalnego w $ PATH”, możesz spróbować: docker exec -it [id-kontenera] / bin / sh
Dai Kaixian
42

Powinieneś użyć narzędzia Jérôme Petazzoni o nazwie „nsenter”, aby wejść do kontenera bez użycia SSH. Zobacz: https://github.com/jpetazzo/nsenter

Zainstaluj po prostu uruchamiając: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Następnie użyj polecenia, docker-enter <container-id>aby wejść do kontenera.

Hyperfocus
źródło
To jest właściwa droga. Zobacz blog .
Jesse Glick
5
W dokerze 1.3 pojawiło się nowe polecenie docker exec. Pozwala to wejść do działającego dokera: docker exec -it <container-id> bash(patrz moja odpowiedź poniżej)
Michael_Scharf
5
Czy docker-enternadal istnieje? Daje mi to command not found.
Snowcrash,
22

Aktualizacja

Począwszy od dokera 0.9, aby poniższe kroki mogły teraz działać, należy teraz zaktualizować /etc/default/dockerplik za pomocą '-e lxc'opcji uruchamiania demona dokera przed ponownym uruchomieniem demona (zrobiłem to przez ponowne uruchomienie hosta).

zaktualizuj plik / etc / default / docker

To wszystko dlatego, że ...

... to [docker 0.9] zawiera nową abstrakcję „sterownika silnika”, aby umożliwić użycie innego API niż LXC do uruchamiania kontenerów. Zapewnia również nowy sterownik silnika oparty na nowej bibliotece API (libcontainer), który jest w stanie obsługiwać grupy kontrolne bez użycia narzędzi LXC. Główny problem polega na tym, że jeśli używasz lxc-attach do wykonywania działań na kontenerze, takich jak uruchamianie powłoki w kontenerze, co jest niezwykle przydatne w środowisku programistycznym ...

źródło

Należy pamiętać, że uniemożliwi to „funkcjonowanie” nowej opcjonalnej funkcji dokera 0.11 w sieci tylko dla hosta i będzie widoczny tylko interfejs sprzężenia zwrotnego. Zgłoszenie błędu


Okazuje się, że rozwiązanie innego pytania było również rozwiązaniem tego:

... możesz użyć ps -notruncokna dokowanego, aby uzyskać pełny identyfikator kontenera LXC, a następnie użyć polecenia lxc-attach -n <container_id>bash w tym kontenerze jako root.

Aktualizacja: wkrótce będziesz musiał użyć ps --no-trunczamiast tego ps -notruncjest przestarzałe.

wprowadź opis zdjęcia tutaj Znajdź pełny identyfikator kontenera

wprowadź opis zdjęcia tutaj Wpisz polecenie lxc attach.

wprowadź opis zdjęcia tutaj Na górze pokazuje mój proces Apache z uruchomionym dokerem.

Programista
źródło
Więc nie ma sposobu, aby to zrobić za pomocą Dockera, prawda? Ja osobiście wolę nie mieszać w LXC.
qkrijger
Czy jest jakiś sposób, aby uruchomić polecenie za pomocą lxc-attach zamiast uruchomić bash? dzięki!!
Joselo
@qkrijger, o ile wiem, że jest poprawny. Dlaczego martwisz się o „miksowanie” LXC? Zdajesz sobie sprawę, że doker jest zbudowany na LXC, prawda?
Programster
@joselo Nie rozumiem twojego pytania, ale sugeruję, aby utworzyć nowy post z bardziej szczegółowymi informacjami? Istnieje wiele sposobów na rozpoczęcie procesu dokowania, takich jak bash lub jako demon z -d itp.
Programster
@programster tak, zdaję sobie z tego sprawę :) Jednak używanie LXC bezpośrednio w połączeniu z Dockerem wydaje się być hackowaniem. Zabawne, ale nie do utrzymania. Ogólnie rzecz biorąc, należy napisać kod w warstwie abstrakcji, w której postanowiono pracować. Jeśli naprawdę potrzebujesz samego LXC, może to być czas na żądanie ściągnięcia na
Dockerze
7

Pierwszym krokiem jest uzyskanie identyfikatora kontenera:

docker ps

To pokaże ci coś takiego

ID KONTENERA OBRAZ KOMUNIKAT STWORZYŁ STATUS NAZWY

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" 26 sekund temu Do 25 sekund 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 jest identyfikatorem kontenera w tym przypadku.

Po drugie , wejdź do okna dokowanego:

docker exec -it [container_id] bash

więc w powyższym przypadku: docker exec -it 1170fe9e9460 bash

patapouf_ai
źródło
5

Co z uruchomieniem ekranu tmux / GNU w kontenerze? Wydaje się, że sposób na łatwiejszy dostęp do dowolnej liczby vty jest prosty:

$ docker attach {container id}
cig0
źródło
Jest to dobre rozwiązanie, jeśli wiesz, że będziesz chciał uzyskać dostęp do kontenera (na przykład w celu jego debugowania), ale nie pomogłoby to OP, który twierdzi, że chce rozejrzeć się po istniejącym kontenerze.
Luca Spiller
1
Mój problem z tą odpowiedzią polega na tym, że ludzie już pytali o używanie docker attachi zauważyłem, że:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster
Cóż, jeśli kontener już działa, to rozwiązanie ci nie pomoże, ale jeśli wcześniej zadbałeś o pozostawienie uruchomionego multipleksera, nie będziesz potrzebować dodatkowych tty ... W rzeczywistości odkąd zacząłem używać tmux, używam jednego tty i tylko jeden, aby zrobić wszystko, czego potrzebuję, ponieważ raz w tmuxie mogę spawnować tyle vtys, ile chcę.
cig0
4

nsenterrobi to. Jednak musiałem również wejść do kontenera w prosty sposób i nsenter nie wystarczył na moje potrzeby. W niektórych przypadkach było to błędne (czarny ekran plus flaga -wd nie działa). Ponadto chciałem zalogować się jako konkretny użytkownik w określonym katalogu.

W końcu stworzyłem własne narzędzie do wprowadzania pojemników. Można go znaleźć na stronie : https://github.com/Pithikos/docker-enter

Jego użycie jest tak proste, jak

./docker-enter [-u <user>] [-d <directory>] <container ID>
Pithikos
źródło
Właśnie spróbowałem, bardzo fajnie! Na Ubuntu musiałem uruchomić sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> Fajnie, że nie muszę uzyskać pełnego identyfikatora jak lxc-attach -n Codebase jest na tyle krótki, że można szybko zeskanować całość w poszukiwaniu szkodliwego oprogramowania.
Programster
Udostępniłem ebuild na Gentoo pod adresem github.com/steveeJ/personal-portage-overlay jako emulacja aplikacji / docker-enter.
stefanjunker
Dodałem tutorial / skrypt do automatycznego tego dla użytkowników ubuntu na programster.blogspot.co.uk/2014/01/…
Programster
2

Sposób „nsinit” to:

zainstaluj nsinit

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

z wnętrza pojemnika:

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

z zewnątrz:

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

Użyj tego

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash
Ivailo Bardarov
źródło
2
docker exec -t -i container_name /bin/bash

Zabierze Cię do konsoli kontenerów.

Danstan
źródło
Wylądowałem na tym pytaniu, ponieważ miałem ten sam problem. Odpowiedź, która wydaje się podobna, nie działała dla mnie, dopóki nie zmodyfikowałem. Mogę to jednak usunąć.
Danstan
2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh
Flavio
źródło
1

Uruchomiłem PowerShell na działającym systemie Microsoft / iOS uruchomionym jako demon

docker exec -it <nameOfContainer> powershell
Ahmed Samir
źródło
Wygląda na to, że pytanie dotyczyło kontenera opartego na systemie Linux. Ta odpowiedź prawdopodobnie zadziała tylko wtedy, gdy masz kontener oparty na systemie Windows - lub - jeśli masz zainstalowaną wersję PowerNET Shell .NET Core, np. PowerShell 6 lub nowszy.
Manfred,
0

W systemie Windows 10 mam zainstalowane okno dokowane. Korzystam z Jnekins na kontenerze i napotkałem ten sam komunikat o błędzie. Oto przewodnik krok po kroku, aby rozwiązać ten problem:

Krok 1: Otwórz gitbash i uruchom polecenie docker -p 8080: 8080 -p 50000: 50000 jenkins.

Krok 2: Otwórz nowy terminal.

Krok 3: Wykonaj polecenie „docker ps”, aby uzyskać listę działającego kontenera. Skopiuj identyfikator kontenera.

Krok 4: Teraz jeśli wykonasz polecenie „docker exec -it {identyfikator kontenera} sh” lub „docker exec -it {identyfikator kontenera} bash”, pojawi się komunikat o błędzie podobny do „urządzenie wejściowe nie jest urządzeniem TTY. używając mintty, spróbuj poprzedzić komendę „winpty” ”

Krok 5: Uruchom polecenie „ $ winpty docker exec -it {id kontenera} sh

vola !! Jesteś teraz w terminalu.

Dev 00721
źródło