Como (e por que) executar o Docker dentro do Docker


0

Executar o Docker dentro do Docker permite construir imagens e iniciar contêineres dentro de um ambiente já contêinerizado. Existem duas abordagens possíveis para fazer isso, dependendo se você deseja iniciar contêineres filho ou irmão.

O acesso ao Docker de dentro de um contêiner do Docker é mais frequentemente desejável no contexto de sistemas CI e CD. É comum hospedar os agentes que executam o pipeline dentro de um contêiner do Docker. Você acabará usando uma estratégia Docker-in-Docker se um dos estágios do pipeline criar uma imagem ou interagir com contêineres.

A imagem Docker-in-Docker

O Docker é fornecido como uma imagem independente por meio do docker:dind tag no Docker Hub. Iniciar esta imagem fornecerá uma instalação funcional do daemon do Docker dentro de seu novo contêiner. Ele vai operar independentemente do daemon do seu host que está executando o dind recipiente, então docker ps dentro do contêiner dará resultados diferentes para docker ps em seu host.

docker run -d --privileged --name docker 
    -e DOCKER_TLS_CERTDIR=/certs 
    -v docker-certs-ca:/certs/ca 
    -v docker-certs-client:/certs/client 
    docker:dind

Usar o Docker-in-Docker dessa maneira traz uma grande advertência: você precisa usar o modo privilegiado. Essa restrição se aplica mesmo se você estiver usando contêineres sem raiz. O modo privilegiado é ativado pelo --privileged sinalizar no comando mostrado acima.

Usar o modo privilegiado fornece ao contêiner acesso completo ao sistema host. Isso é necessário em um cenário Docker-in-Docker para que seu Docker interno seja capaz de criar novos contêineres. No entanto, pode ser um risco de segurança inaceitável em alguns ambientes.

Propaganda

Existem outros problemas com dind também. Certos sistemas podem ter conflitos com os Módulos de Segurança do Linux (LSM), como AppArmor e SELinux. Isso ocorre quando o Docker interno aplica políticas LSM que o daemon externo não pode antecipar.

Outro desafio diz respeito aos sistemas de arquivos de contêiner. O daemon externo será executado no sistema de arquivos regular do seu host, como ext4. Todos os seus contêineres, incluindo o daemon interno do Docker, permanecerão em um sistema de arquivos copy-on-write (CoW). Isso pode criar incompatibilidades se o daemon interno estiver configurado para usar um driver de armazenamento que não pode ser usado em cima de um sistema de arquivos CoW existente.

Em vez disso, montar o soquete Docker do seu host

Os desafios associados com dind são melhor tratados evitando seu uso. Em muitos cenários, você pode obter o efeito pretendido montando o soquete Docker do seu host em um docker recipiente:

docker run -d --name docker
    -v /var/run/docker.sock:/var/run/docker.sock 
    docker:latest

O Docker CLI dentro do docker imagem interage com o socket daemon Docker que encontra em /var/run/docker.sock. Montar o soquete do seu host neste caminho significa docker os comandos executados dentro do contêiner serão executados no daemon existente do Docker.

Isso significa que os contêineres criados pelo Docker interno residirão em seu sistema host, ao lado do próprio contêiner do Docker. Todos os contêineres existirão como irmãos, mesmo que pareça que o Docker aninhado é filho do pai. Correndo docker ps produzirá os mesmos resultados, seja executado no host ou dentro do seu contêiner.

Esta técnica atenua os desafios de implementação de dind. Ele também elimina a necessidade de usar o modo privilegiado, embora a montagem do soquete Docker seja uma preocupação potencial de segurança. Qualquer coisa com acesso ao soquete pode enviar instruções ao daemon do Docker, fornecendo a capacidade de iniciar contêineres em seu host, extrair imagens ou excluir dados.

Quando usar cada abordagem

Docker-in-Docker via dind historicamente tem sido amplamente utilizado em ambientes de CI. Isso significa que os contêineres “internos” têm uma camada de isolamento do host. Um único contêiner de execução de CI oferece suporte a todos os contêineres de pipeline sem poluir o daemon do Docker do host.

Propaganda

Embora muitas vezes funcione, isso está repleto de efeitos colaterais e não é o caso de uso pretendido para dind. Ele foi adicionado para facilitar o desenvolvimento do próprio Docker, não para fornecer suporte ao usuário final para instalações do Docker aninhadas.

De acordo com Jérôme Petazzoni, o criador do dind implementação, a adoção da abordagem baseada em soquete deve ser sua solução preferida. A montagem do Bind no soquete daemon do seu host é mais segura, mais flexível e tão completa quanto iniciar um dind recipiente.

Se o seu caso de uso significa que você absolutamente requer dind, há uma maneira mais segura de implantá-lo. O projeto Sysbox moderno é um tempo de execução de contêiner dedicado que pode aninhar outros tempos de execução sem usar o modo privilegiado. Os contêineres Sysbox tornam-se semelhantes a VM, de modo que são capazes de oferecer suporte a software que geralmente é executado bare-metal em uma máquina física ou virtual. Isso inclui Docker e Kubernetes sem nenhuma configuração especial.

Conclusão

Executar o Docker dentro do Docker é um requisito relativamente comum. É mais provável que você veja isso ao configurar servidores de CI que precisam oferecer suporte a construções de imagens de contêiner de dentro de pipelines criados pelo usuário.

Usando docker:dind oferece um daemon Docker independente em execução em seu próprio contêiner. Ele cria contêineres filhos que não são diretamente visíveis do host. Embora pareça oferecer um forte isolamento, dind na verdade, abriga muitos problemas de casos extremos e preocupações de segurança. Isso ocorre devido às interações do sistema operacional do Docker.

Propaganda

Montagem do soquete Docker do seu host em um contêiner que inclui o docker binário é uma alternativa mais simples e previsível. Isso permite que o processo do Docker aninhado inicie contêineres que se tornam seus próprios irmãos. Nenhuma configuração adicional é necessária quando você usa a abordagem baseada em soquete.


Like it? Share with your friends!

0

0 Comments

Your email address will not be published. Required fields are marked *