Como entrar em um contêiner do Docker já em execução com um novo TTY

545

Eu tenho um contêiner que está executando o serviço Apache em primeiro plano. Eu gostaria de poder acessar o contêiner de outro shell para "bisbilhotar" dentro dele e examinar os arquivos. No momento, se eu conectar ao contêiner, fico olhando para o daemon Apache e não consigo executar nenhum comando.

É possível anexar outro tty a um contêiner em execução? Possivelmente, posso tirar proveito do fato de o Docker estar apenas envolto em contêineres LXC? Eu tentei, sudo lxc-console -n [container-id] -t [1-4]mas parece que apenas um tty é disponibilizado e esse é o que executa o daemon apache. Talvez haja uma maneira de ativar vários consoles lxc durante a compilação?

Prefiro não configurar e criar o contêiner com um serviço openssh, se possível.

Programador
fonte
7
Você tentou docker attach [conainer-id]?
Shabbychef
13
@shabbychef, a menos que o docker attach tenha sido alterado, o comando attach é anexado ao tty em execução, e não ao novo, portanto, o título da pergunta é "... with new TTY". É por isso que a resposta abaixo não usa o comando attach.
Programster
1
Desde a
versão

Respostas:

1061

Com a janela de encaixe 1.3, há um novo comando docker exec. Isso permite que você insira uma janela de encaixe em execução:

docker exec -it [container-id] bash
Michael_Scharf
fonte
30
Alterei esta para ser a resposta correta (por conta própria) porque esse novo método, que não existia no momento da pergunta, é o melhor método atual da IMO.
Programster
3
Observe, no entanto, que execnão atua como um terminal normal. Por exemplo, você não pode alterar o usuário uma vez dentro do contêiner.
Pithikos
3
@Pithikos: Sou capaz de usar exec para executar um shell e depois su someusermudar de usuário. Executando o Docker 1.4.1
lsh
2
Nota para quem lê esta discussão. Tenho certeza de que docker exec -itacabará por fornecer uma tty pseudo totalmente funcional, mas por agora (Docker versão 1.9.1), há algumas limitações: github.com/docker/docker/issues/8755
BLONG
18
se você receber o erro 'exec: "bash": arquivo executável não encontrado em $ PATH', você pode tentar o seguinte: docker exec -it [id do container] / bin / sh
Dai Kaixian 12/16
42

Você deve usar a ferramenta de Jérôme Petazzoni chamada 'nsenter' para inserir um contêiner sem usar o SSH. Consulte: https://github.com/jpetazzo/nsenter

Instale simplesmente executando: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Em seguida, use o comando docker-enter <container-id>para inserir o contêiner.

Hyperfocus
fonte
Este é o caminho certo. Veja o blog .
Jesse Glick
5
Com a janela de encaixe 1.3, há um novo comando docker exec. Isso permite que você digite uma janela de encaixe em execução: docker exec -it <container-id> bash(ver minha resposta abaixo)
Michael_Scharf
5
Será que docker-enterainda existe? Isso me dá command not found.
Snowcrash 10/10
22

Atualizar

A partir do docker 0.9, para que as etapas abaixo funcionem agora, é necessário atualizar o /etc/default/dockerarquivo com a '-e lxc'opção de inicialização do daemon do docker antes de reiniciar o daemon (eu fiz isso reinicializando o host).

atualizar para o arquivo / etc / default / docker

Isso é tudo porque ...

... [docker 0.9] contém uma nova abstração "driver de mecanismo" para possibilitar o uso de outra API que não o LXC para iniciar contêineres. Ele também fornece um novo driver de mecanismo baseado em uma nova biblioteca de API (libcontainer) capaz de lidar com grupos de controle sem usar ferramentas LXC. O principal problema é que, se você conta com o lxc-attach para executar ações em seu contêiner, como iniciar um shell dentro do contêiner, o que é incrivelmente útil para o ambiente de desenvolvimento ...

fonte

Observe que isso impedirá que o novo recurso opcional de rede do docker 0.11 do " host " funcione e você verá apenas a interface de loopback. relatório de erro


Acontece que a solução para uma pergunta diferente também foi a solução para esta:

... você pode usar o docker ps -notruncpara obter o ID do contêiner lxc completo e, em seguida, usar lxc-attach -n <container_id>run bash nesse contêiner como raiz.

Atualização: em breve você precisará usar, e ps --no-truncnão o ps -notruncque está sendo preterido.

insira a descrição da imagem aqui Encontre o ID completo do contêiner

insira a descrição da imagem aqui Digite o comando lxc attach.

insira a descrição da imagem aqui O topo mostra meu processo apache executando a janela de encaixe iniciada.

Programador
fonte
Portanto, não há como fazer isso apenas com o Docker, certo? Pessoalmente, prefiro não me misturar ao LXC.
Qkrijger
Existe alguma maneira de executar um comando com o lxc-attach para iniciar o bash? valeu!!
joselo
@qkrijger, tanto quanto sei que está correto. Por que se preocupar em "misturar" LXC? Você percebe que o docker é construído sobre o LXC, certo?
Programster
@joselo Não entendi sua pergunta, mas sugiro que você crie uma nova postagem com mais detalhes? Há muitas maneiras de iniciar um processo de janela de encaixe, como com o bash ou como um daemon com -d etc.
Programster
@programster sim, eu sei disso :) Ainda assim, usar o LXC diretamente em combinação com o Docker parece um hack. Divertido, mas não realmente sustentável. Em geral, deve-se código na camada de abstração que se escolheu para trabalhar em se você realmente precisa LXC-se, talvez seja tempo para uma solicitação de recebimento em Docker :).
qkrijger
7

Primeira etapa: obter o ID do contêiner:

docker ps

Isso mostrará algo como

ID DO RECIPIENTE COMANDO DE IMAGEM NOMES DE PORTAS DE STATUS CRIADAS

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" há 26 segundos Up 25 segundos 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 é o ID do contêiner neste caso.

Segundo , entre na janela de encaixe:

docker exec -it [container_id] bash

então no caso acima: docker exec -it 1170fe9e9460 bash

patapouf_ai
fonte
5

Que tal executar o tmux / GNU Screen dentro do contêiner? Parece a maneira mais fácil de acessar quantos vty você deseja com um simples:

$ docker attach {container id}
cig0
fonte
Essa é uma solução aceitável se você souber que deseja obter acesso a um contêiner (por exemplo, depurá-lo), mas isso não ajudaria o OP que afirma que deseja procurar um contêiner existente.
Luca Spiller #
1
Meu problema com essa resposta é que as pessoas já têm perguntado sobre usando docker attache eu apontou que:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster
Bem, se o contêiner já estiver em execução, esta solução não ajudará, mas se você anteriormente deixar um multiplexador em execução, não precisará de ttys adicionais ... De fato, desde que comecei a usar o tmux, uso um tty e apenas um para fazer tudo o que preciso desde que, uma vez no tmux, posso gerar quantos vtys quiser.
fácil
4

nsenterfaz isso. No entanto, eu também precisava inserir um contêiner de uma maneira simples e o nsenter não era suficiente para minhas necessidades. Era um bug em algumas ocasiões (a tela preta mais a bandeira -wd não estava funcionando). Além disso, eu queria entrar como um usuário específico e em um diretório específico.

Acabei fazendo minha própria ferramenta para entrar em contêineres. Você pode encontrá-lo em: https://github.com/Pithikos/docker-enter

Seu uso é tão fácil quanto

./docker-enter [-u <user>] [-d <directory>] <container ID>
Pithikos
fonte
Apenas tentei, muito legal! No ubuntu, tive que executar o sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> É bom que eu não precise obter o ID completo como com A base de código lxc-attach -n é curta o suficiente para que você possa verificar a totalidade rapidamente para procurar qualquer coisa maliciosa.
Programster
Eu disponibilizei um ebuild no gentoo em github.com/steveeJ/personal-portage-overlay como app-emulation / docker-enter.
stefanjunker
Eu adicionei um tutorial / script para isso automaticamente para usuários do ubuntu em programster.blogspot.co.uk/2014/01/…
Programster
2

A maneira "nsinit" é:

instalar nsinit

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

de dentro do contêiner:

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

de fora:

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

use-o

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

Levará você ao console de contêineres.

Danstan
fonte
Cheguei a essa pergunta porque tinha o mesmo problema. A resposta que parece semelhante não funcionou para mim até que eu modifiquei. Eu posso excluir isso embora.
Danstan 26/06
2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh
Flavio
fonte
1

Comecei o powershell em um microsoft / iis executando como daemon usando

docker exec -it <nameOfContainer> powershell
Ahmed Samir
fonte
Parece que a pergunta era sobre um contêiner baseado em linux. Essa resposta provavelmente funcionará apenas se você tiver um contêiner baseado no Windows - ou - se você tiver a versão do .NET Core do PowerShell instalada, por exemplo, o PowerShell 6 ou posterior.
Manfred #
0

No Windows 10 , tenho a janela de encaixe instalada. Estou executando o Jnekins em um contêiner e encontrei a mesma mensagem de erro. Aqui está um guia passo a passo para resolver esse problema:

Passo 1: Abra o gitbash e execute a janela de encaixe run -p 8080: 8080 -p 50000: 50000 jenkins.

Passo 2: Abra um novo terminal.

Etapa 3: execute "docker ps" para obter a lista do contêiner em execução. Copie a identificação do contêiner.

Passo 4: Agora, se você executar "docker exec -it {container id} sh" ou "docker exec -it {container id} bash", receberá uma mensagem de erro semelhante a "o dispositivo de entrada não é um TTY. Se você estiver usando mintty, tente prefixar o comando com 'winpty' "

Etapa 5: execute o comando " $ winpty docker exec -it {container id} sh "

vola !! Agora você está dentro do terminal.

Dev 00721
fonte