Eu imagino que minha história é muito parecida com a de tantas outras pessoas trabalhando com integração contínua (CI).

Você começa a montar a esteira CI usando Jenkins, e em um determinado momento vem o pensamento:

“Por quê não executar o Jenkins em um container docker?”

E, como um raio, um segundo pensamento cai sobre você:

“Qual docker (executável) o Jenkins vai utilizar para os builds?”

A partir daí, é um caminho sem volta de tentativas e de buscar alguma solução entre documentações, blogs e fóruns online.

Independente do percurso, todos temos um mesmo checkpoint: o artigo de Jérôme Petazzoni sobre Docker-in-Docker (dind, para os intimos).

De forma prática, ao falar de dind, estamos nos referindo a um container docker com uma instalação docker que permite executar outros containers…

(…) que podem ser outros containers docker-in-docker que podem executar outros containers docker-in-docker…

No artigo, temos um dos contribuidores da flag --privileged, essencial para a execução do dind, criticando o uso do dind para determinados cenários - inclusive para o Jenkins.

Nesse mesmo artigo, uma solução é apresentada: montar o docker.sock da máquina host como forma do container contendo o Jenkins, executar e guardar seu cache no Docker instalado no host.

Longe de dizer qual das duas alternativas é a “correta” neste post, quero discutir alguns dos pontos envolvendo essas abordagens.

TL;DR

A abordagem de montar o docker.sock no container, de fato, soluciona as potenciais questões de data corruption (pelo compartilhamento do /var/lib/docker) e de incompatibilidade entre filesystems relacionadas ao docker-in-docker.

Por outro lado, ao expor o docker.sock para o container, este se torna um ponto de vulnerabilidade, em termos de segurança, por dar acesso completo ao usuário (root) do docker da máquina host - tornando possível executar containers com código malicioso. No caso de um usuário não-root, a situação ainda piorará pela necessidade de alteração das permissões do docker.sock.

Finalmente, o que vai decidir a melhor abordagem são os requisitos de seu projeto e a análise dos potenciais riscos em seu ambiente produtivo.

Para facilitar o teste/implementação das abordagens citadas, disponibilizei os seguintes arquivos docker-compose com as instruções necessárias para executar sua aplicação Jenkins com dind ou com a montagem do socket.

Jenkins associado a um container docker-in-docker


Container Jenkins com o docker.sock montado


Referências

[1] Artigo original de Jérôme Petazzoni

[2] Artigo sobre a vulnerabilidade de montar o docker.sock

[3] Discussão sobre a vulnerabilidade de montar o docker.sock

[4] Documentação oficial da imagem docker:dind

[5] Instruções para execução do docker-in-docker associado ao Jenkins


* * *

Agradecimentos ao @renancmonteiro_ pelas discussões sobre o tema!

* * *

Esta é uma modalidade de post “rápido”, onde apresento as principais conclusões sobre algum tema e compartilho códigos que possam ajudar nos problemas envolvidos. Uma discussão detalhada será publicada e linkada posteriormente.