Un contenitore Docker in un contenitore Docker utilizza il daemon Docker dell'HOST padre e, di conseguenza, tutti i volumi montati nel caso "docker-in-docker" sono ancora referenziati dall'HOST e non dal contenitore.
Pertanto, il percorso effettivo montato dal contenitore Jenkins "non esiste" nell'HOST. Per questo motivo, viene creata una nuova directory nel contenitore "docker-in-docker" che è vuoto. La stessa cosa vale quando una directory viene montata su un nuovo contenitore Docker all'interno di un contenitore.
Cosa molto semplice e ovvia che mi mancava, ma ho realizzato non appena ho digitato la domanda.
Un altro modo per farlo è utilizzare volumi denominati o contenitori di volumi di dati. In questo modo, il contenitore all'interno non deve sapere nulla dell'host e sia il contenitore Jenkins che il contenitore di build fanno riferimento al volume di dati allo stesso modo.
Ho provato a fare qualcosa di simile a quello che stai facendo, tranne che con un agente piuttosto che usare il master Jenkins. Il problema era lo stesso in quanto non riuscivo a montare l'area di lavoro di Jenkins nel contenitore interno. Ciò che ha funzionato per me è stato utilizzare l'approccio del contenitore del volume di dati ei file dell'area di lavoro erano visibili sia al contenitore dell'agente che al contenitore interno. Quello che mi è piaciuto dell'approccio è che entrambi i contenitori fanno riferimento al volume di dati allo stesso modo. Il montaggio delle directory con un contenitore interno sarebbe complicato poiché il contenitore interno ora ha bisogno di sapere qualcosa sull'host su cui è in esecuzione il suo contenitore padre.
Ho un post di blog dettagliato sul mio approccio qui:
http://damnhandy.com/2016/03/06/creating-containerized-build-environments-with-the-jenkins-pipeline-plugin-and-docker-well-almost/
Oltre al codice qui:
https://github.com/damnhandy/jenkins-pipeline-docker
Nel mio caso specifico, non tutto funziona come vorrei in termini di plug-in Jenkins Pipeline. Ma risolve il problema del contenitore interno in grado di accedere alla directory dell'area di lavoro di Jenkins.
Molte buone informazioni in questi post, ma trovo che nessuno di loro sia molto chiaro su quale contenitore si riferisca. Quindi etichettiamo i 3 ambienti:
- host:H
- contenitore docker in esecuzione su H:D
- contenitore docker in esecuzione in D:D2
Sappiamo tutti come montare una cartella da H a D:inizia D con
docker run ... -v <path-on-H>:<path-on-D> -v /var/run/docker.sock:/var/run/docker.sock ...
La sfida è:vuoi path-on-H
essere disponibile in D2 come path-on-D2
.
Ma siamo stati tutti morsi quando abbiamo provato a montare lo stesso path-on-H
in D2, perché abbiamo iniziato D2 con
docker run ... -v <path-on-D>:<path-on-D2> ...
Quando condividi il socket docker su H con D, l'esecuzione dei comandi docker in D li esegue essenzialmente su H. In effetti, se avvii D2 in questo modo, tutto funziona (in modo abbastanza inaspettato all'inizio, ma ha senso se ci pensi):
docker run ... -v <path-on-H>:<path-on-D2> ...
La prossima parte complicata è che per molti di noi, path-on-H
cambierà a seconda di chi lo gestisce. Ci sono molti modi per passare i dati in D in modo che sappia cosa usare per path-on-H
, ma probabilmente la più semplice è una variabile di ambiente. Per rendere più chiaro lo scopo di tale var, inizio il suo nome con DIND_
. Poi da H inizia D in questo modo:
docker run ... -v <path-on-H>:<path-on-D> --env DIND_USER_HOME=$HOME \
--env DIND_SOMETHING=blabla -v /var/run/docker.sock:/var/run/docker.sock ...
e da D inizia D2 in questo modo:
docker run ... -v $DIND_USER_HOME:<path-on-D2> ...