É possível executar o docker de dentro do docker?

185

Estou executando o Jenkins dentro de um contêiner do Docker. Será que o contêiner Jenkins também é um host do Docker? O que estou pensando é iniciar um novo contêiner do docker para cada compilação de teste de integração do Jenkins (para iniciar bancos de dados, intermediários de mensagens etc.). Os contêineres devem, portanto, ser desligados após a conclusão dos testes de integração. Existe uma razão para evitar a execução de contêineres de docker de dentro de outro contêiner de dockers dessa maneira?

Johan
fonte
11
Outra possibilidade é montar o soquete do docker do host como um volume no contêiner. Isso permite criar contêineres "irmãos" e tem a vantagem de poder reutilizar o cache.
Adrian Mouat
4
Descobri que, ao usar o soquete do docker do host, nos casos em que desejo montar volumes externos, é necessário definir o caminho do volume em relação ao host, pois é onde o daemon do docker é executado. A configuração em relação ao contêiner que inicia os contêineres não funcionará necessariamente, a menos que os caminhos coincidam.
Jakob Runge

Respostas:

224

A execução do Docker no Docker (também conhecido como dind ), embora possível, deve ser evitada, se possível. (Fonte fornecida abaixo.) Em vez disso, você deseja configurar uma maneira de o seu contêiner principal produzir e se comunicar com os contêineres irmãos .

Jérôme Petazzoni - o autor do recurso que possibilitou a execução do Docker dentro de um contêiner do Docker - na verdade escreveu uma postagem no blog dizendo para não fazê-lo . O caso de uso que ele descreve corresponde ao caso de uso exato do OP de um contêiner do CI Docker que precisa executar tarefas em outros contêineres do Docker.

Petazzoni lista duas razões pelas quais o dind é problemático:

  1. Não coopera bem com o Linux Security Modules (LSM).
  2. Ele cria uma incompatibilidade nos sistemas de arquivos que cria problemas para os contêineres criados dentro dos contêineres pai.

A partir dessa postagem do blog, ele descreve a seguinte alternativa,

[A] maneira mais simples é apenas expor o soquete do Docker ao seu contêiner de CI, montando-o com o -vsinalizador.

Simplificando, quando você inicia seu contêiner de IC (Jenkins ou outro), em vez de hackear algo junto com o Docker-in-Docker, inicie-o com:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Agora, esse contêiner terá acesso ao soquete do Docker e, portanto, poderá iniciar os contêineres. Exceto que, em vez de iniciar contêineres "filho", ele iniciará contêineres "irmãos".

predmijat
fonte
1
Como executar comandos do docker sem sudofazer isso? Graças
c4k
3
Você precisa adicionar o usuário dockergrupo: sudo usermod -aG docker $USER. Você precisará registrar novamente depois disso.
predmijat
2
Como relogar de dentro de um porta-moedas?
Thiagowfx
1
@AlexanderMills É o mesmo porque o soquete do docker também está localizado /var/run/docker.sockquando você executa o docker for mac na sua máquina macos.
Bruce Sun
1
e as janelas? Eu não tenho #/var/run/docker.sock
23417 Abdelhafid
54

Eu respondi uma pergunta semelhante antes sobre como executar um contêiner do Docker dentro do Docker .

É definitivamente possível executar o docker dentro do docker. O principal é que você runcontenha o contêiner externo com privilégios extras (começando com --privileged=true) e instale a janela de encaixe nesse contêiner.

Confira esta postagem no blog para obter mais informações: Docker-in-Docker .

Um possível caso de uso para isso é descrito nesta entrada . O blog descreve como criar contêineres em um contêiner Jenkins.

No entanto, o Docker no Docker não é a abordagem recomendada para resolver esse tipo de problema. Em vez disso, a abordagem recomendada é criar contêineres "irmãos", conforme descrito nesta postagem

Portanto, a execução do Docker no Docker foi considerada por muitos como um bom tipo de solução para esse tipo de problema. Agora, a tendência é usar contêineres "irmãos". Veja a resposta de @predmijat nesta página para mais informações.

wassgren
fonte
Veja o comentário abaixo sobre como evitar a janela de encaixe na janela de encaixe.
Dan Poltawski
6

Não há problema em executar o Docker-in-Docker (DinD) e, de fato, o Docker (a empresa) tem uma imagem oficial do DinD para isso.

A ressalva, no entanto, é que ele requer um contêiner privilegiado, que, dependendo das suas necessidades de segurança, pode não ser uma alternativa viável.

A solução alternativa de executar o Docker usando contêineres irmãos (também conhecido como Docker-out-Docker ou DooD) não requer um contêiner privilegiado, mas possui algumas desvantagens decorrentes do fato de você estar iniciando o contêiner dentro de um contexto diferente daquele em que está sendo executado (ou seja, você inicia o contêiner de dentro de um contêiner, mas está sendo executado no nível do host, não dentro do contêiner).

Eu escrevi um blog descrevendo os prós / contras de DinD vs DooD aqui .

Dito isso, a Nestybox (uma startup que acabei de fundar) está trabalhando em uma solução que executa o Docker-in-Docker verdadeiro de forma segura (sem usar contêineres privilegiados). Você pode conferir em www.nestybox.com .

ctalledo
fonte
0

Sim, podemos executar a janela de encaixe na janela de encaixe, precisamos anexar o sockeet unix "/var/run/docker.sock" no qual o daemon do docker escuta por padrão como volume a janela de encaixe pai usando "-v / var / run /docker.sock:/var/run/docker.sock ". Às vezes, podem surgir problemas de permissão para o soquete do daemon do docker, no qual você pode escrever "sudo chmod 757 /var/run/docker.sock".

E também seria necessário executar a janela de encaixe no modo privilegiado, para que os comandos fossem:

sudo chmod 757 /var/run/docker.sock

docker run --privileged = true -v /var/run/docker.sock:/var/run/docker.sock -it ...

Renu Saini
fonte