Jenkins per la creazione di imageDocker

L’affermazione di Docker come strumento devops ha portato vantaggi in tutta l’infrastruttura IT: sia lo sviluppatore che il sysadmin ne traggono enormi benefici visto che possono cooperare in maniera più semplice e veloce abbattendo le complessità che prima sembravano insormontabili. A fianco di questi miglioramenti sono nate nuove necessità derivanti dall’utilizzo del nuovo strumento: automatizzare la creazione di images Docker e il successivo push su repository è un bisogno che in molti sentono. La soluzione che propongo oggi è l’utilizzo combinato di git, Jenkins e Docker per rendere questo processo semplice e veloce: con un click potremmo fare il build e push di un’image Docker a partire da un Dockerfile presente in un nostro repository git. System Requirements Questo tutorial è stato sviluppato e testato su Ubuntu Linux per cui se usate Osx o Windows ci saranno alcuni passaggi da adattare, inoltre per facilitare il tutorial dovremmo andare a modificare qualche file di configurazione a mano. Setup Abbiamo bisogno che il daemon Docker sia raggiungibile dall’esterno. Tale modifica va fatta solo a fini di esercizio perchè espone Docker alla rete alla quale siamo connessi per cui va ripristinato il file originale quando abbiamo finito il tutorial. Modifichiamo il file “/lib/systemd/system/docker.service” e creiamo un’ulteriore interfaccia di ascolto al daemon aggiungendo “-H tcp://0.0.0.0:2375” al parametro “ExecStart” ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 Facciamo il reload di systemd e del daemon Docker: → systemctl daemon-reload → systemctl restart docker A questo punto cloniamo il compose file che contiene i container e le configurazioni che ci servono: Jenkins ed il registry. Successivamente andiamo a copiare i certificati senza i quali non potremmo collegarci al registry ed avviamo il compose file. → git clone https://github.com/and9000/ci-jenkins-repo.gi → cd ci-jenkins-repo → sudo cp registry/certs/domain.crt /usr/local/share/ca-certificates/registry.crt → sudo update-ca-certificates → systemctl restart docker → docker-compose up Prima di passare a Jenkins, dobbiamo solamente identificare e segnarci che ip ha assegnato alla nostra macchina il daemon Docker e quale ha assegnato al registry. Spostiamoci in un altro terminale ed eseguiamo: → ifconfig docker0 \| grep 'inet:' \| cut -d: -f2 \| awk '{ print $1}' 172.17.0.1 → docker inspect -f '{{ .NetworkSettings.IPAddress }}' registry 172.19.0.2 Il daemon Docker risponde all’ip 172.17.0.1 mentre il registry ha ip 172.19.0.2. Per comodità aggiungiamo l’ip del registry al file host della macchina: sudo echo “172.19.0.2 registry“ >> /etc/hosts Approfondimento docker-compose.yml Il repository git che abbiamo scaricato contiene un compose file che avvia il container con Jenkins ed il container del registry. Il registry è configurato con certificati self-signed, tali certificati li abbiamo aggiunti alla macchina in un passaggio precedente. Nella configurazione del container Jenkins andiamo inoltre a montare l’eseguibile Docker dell’host così da non doverlo installare nel container stesso. volumes: - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker Nel Dockerfile di Jenkins andiamo anche ad installare il plugin che ci serve (e le sue dipendenze): RUN /usr/local/bin/install-plugins.sh docker-build-publish Configurazione Jenkins Siamo pronti ora a configurare Jenkins. Torniamo nel terminale dove abbiamo lanciato il “docker-compose up” e osserviamo l’output fino a trovare un log simile a questo: jenkins-ci \| ************************************************************* jenkins-ci jenkins-ci \| Jenkins initial setup is required. An admin user has been created and a password generated. jenkins-ci \| Please use the following password to proceed to installation: jenkins-ci jenkins-ci \| aeb09f144a584f79a5bac6880fabf4c6 jenkins-ci jenkins-ci \| This may also be found at: /var/jenkins_home/secrets/initialAdminPassword jenkins-ci jenkins-ci \| ************************************************************* Copiamo la password (sarà diversa ad ogni primo avvio del container Jenkins) e colleghiamoci al container Jenkins aprendo il browser all’indirizzo “http://localhost:8080”. Sarà necessario immettere la password appena copiata: Clicchiamo su “Continue” e procediamo con la configurazione:
Selezioniamo “Install suggested plugins” ed attendiamo finché Jenkins ha terminato l’installazione dei plugin di default.
A questo punto ci comparirà il form che compileremo con i nostri dati:
Clicchiamo su “Continue as admin” e Jenkins ci comunicherà di essere pronto:
Dandoci inoltre il benvenuto:
Finora abbiamo configurato l’infrastruttura di base che andremo ad usare ora per fare il build ed il push su registry di un’image Docker. Creazione Job Jenkins Clicchiamo su “create new job”, immettiamo un nome significativo (nel mio caso “ci-example-image”), selezioniamo “Freestyle project” e proseguiamo:
Ci comparirà l’interfaccia di default di un job Jenkins:
Selezioniamo subito “git” sotto “Source Code Management” ed immettiamo il repo che contiene il Dockerfile del quale vogliamo creare l’image. Nel nostro esempio useremo “https://github.com/and9000/ci-example-image.git” che contiene un semplice Dockerfile.
Clicchiamo ora su “Build” -> “Add build step” -> “Docker Build and Publish”.
Configuriamo lo step: Repository name: il nome della nostra image Tag: il tag della image (di default sarà aggiunto anche il tag “latest”) Docker Host URI: l’URI del nostro daemon Docker che ci siamo salvati in precedenza Docker registry URL: l’url del container registry di esempio già configurato
Clicchiamo su “Save”, successivamente su “Build Now” e poi su “Console Output” dal sottomenu che compare selezionando la freccia a destra del job nel widget “Build History”
Possiamo osservare l’output della build: dopo aver clonato il nostro repository con il Dockerfile sta eseguendo la build e precisamente sta scaricando l’image base.
“Finished: SUCCESS”: come possiamo vedere dai log il job è andato a buon fine. È stato eseguito correttamente il build dell’image ed è stato fatto con successo il push nel nostro repository:
Risultati Ora dobbiamo verificare se la nostra image appena creata funziona. Analizzando il Dockerfile possiamo vedere che tale image è basata su ubuntu:14.04 e una volta eseguita stampa nel terminale la versione di linux usata. Confermiamo che tutto è andato a buon fine: → docker run --rm registry:5000/ibandrea/ci-example-image:0.0.1 Distributor ID: Ubuntu Description: Ubuntu 14.0.5 LTS Release: 14.04 Codename: trusty No LSB modules are available. Conclusioni Docker è uno strumento potentissimo che oltre ad aprire nuove possibilità e metodi di lavoro ha creato nuove necessità. In questo tutorial abbiamo proposto una soluzione ad una di queste: l’utilizzo combinato di git, Jenkins e Docker per automatizzare il processo di build e push verso registry di images. Voi che metodi usate? Fatecelo sapere nei commenti!
Realizziamo qualcosa di straordinario insieme!
Siamo consulenti prima che partner, scrivici per sapere quale soluzione si adatta meglio alle tue esigenze. Potremo trovare insieme la soluzione migliore per dare vita ai tuoi progetti.