Docker de la Ground Up Construirea de imagini

Containerele Docker sunt în creștere ca o bună practică pentru implementarea și gestionarea sistemelor distribuite în nori cloud. Containerele sunt exemple de imagini Docker. Se pare că există multe de știut și de înțeles despre imagini. 

În acest tutorial în două părți, eu acoperă imaginile Docker în profunzime. În prima parte am discutat principiile de bază, considerațiile de proiectare și inspectarea imaginilor interne. În această parte, vă acoperăm construirea propriilor imagini, depanarea și lucrul cu arhivele de imagini. 

Când ieșiți pe cealaltă parte, veți avea o înțelegere solidă a ceea ce sunt exact imaginile Docker și cum să le utilizați eficient în propriile aplicații și sisteme.

Construirea de imagini

Există două moduri de a crea imagini. Puteți modifica containerul existent și apoi îl puteți angaja ca o imagine nouă sau puteți scrie un fișier Docker și îl puteți construi într-o imagine. Vom trece pe amândouă și vom explica argumentele pro și contra.

Manual Builds

Cu construirea manuală, tratați containerul ca un computer obișnuit. Instalați pachete, scrieți fișiere și atunci când totul este spus și terminat, îl comiteți și ajungeți la o nouă imagine pe care o utilizați ca șablon pentru a crea mult mai multe containere identice sau chiar a baza alte imagini pe.

Să începem cu imaginea alpină, care este o imagine foarte mică și spartană bazată pe Alpine Linux. Putem rula în modul interactiv pentru a intra într-o coajă. Scopul nostru este să adăugăm un fișier numit "da" care conține textul "funcționează!" la directorul rădăcină și apoi să creați o nouă imagine din el numită "yeah-alpine". 

Începem. Bine, suntem deja în rădăcina dir. Să vedem ce e acolo.

> docker run -n / a alpine / bin / sh / # ls bin dev acasă lib linuxrc media mnt proc rădăcină run sbin srv sys tmp usr var

Ce editor este disponibil? Nu vim, nici nano?

/ # vim / bin / sh: vim: nu a fost găsit / # nano / bin / sh: nano: nu a fost găsit

Bine. Vrem doar să creați un fișier:

/ # echo "funcționează!" > Da / # pisica da functioneaza! 

Am ieșit din shell-ul interactiv și pot vedea containerul numit "vibrant_spenc" cu docker ps - tot. --toate steagul este important deoarece containerul nu mai rulează.

> docker ps --all CONTAINER ID IMAGE COMMAND CREAȚI nume de stare c8faeb05de5f alpine "/ bin / sh" acum 6 minute Exited vibrant_spence

Aici, creez o nouă imagine din containerul "vibrate_spence". Am adăugat mesajul de comitet "a mea, a mea, a mea" pentru o măsură bună.

> docker commit -m "a mea, a mea, a mea" vibrant_spence yeah-alpine sha256: e3c98cd21f4d85a1428 ... e220da99995fd8bf6b49aa

Hai să verificăm. Da, există o nouă imagine, iar în istoria ei puteți vedea un nou strat cu comentariul "mină, a mea, a mea".

> imagini docer REPOSITORY TAG IMAGINE ID DIMENSIUNEA yeah-alpine mai recent e3c98cd21f4d 4.8 MB python cele mai recente 775dae9b960e 687 MB d4w / nsenter Ultimele 9e4f13a0901e 83.8 kB ubuntu-with-ssh Ultimele 87391dca396d 221 MB ubuntu cea mai recentă bd3d4369aebc 127 MB hello-world târziu c54a2cc56cbb 1.85 kB alpine 4e38e38c8ce0 4.8 MB nsqio / nsq cele mai recente 2a82c70fe5e3 70.7 MB> istorie docker yeah-alpine IMAGINE CREATED SIZE COMMENT e3c98cd21f4d 40 secunde în urmă 66 B mine, a mea, a mea 4e38e38c8ce0 7 luni în urmă 4.8 MB

Acum pentru testul real. Să ștergem containerul și să creăm un nou container din imagine. Rezultatul așteptat este că fișierul "yeah" va fi prezent în noul container.

> docker rm vibrant_spence vibrant_spence> docker rulați -ai da-alpin / bin / sh / # pisica da funcționează! / #

Ce pot sa spun? Da, funcționează!

Folosind un fișier Docker

Crearea imaginilor din recipiente modificate este rece, dar nu există responsabilitate. Este greu să urmăriți modificările și să știți care au fost modificările specifice. Modul disciplinat de a crea imagini este să le construiți folosind un fișier Docker.

Dockerfile este un fișier text care este similar cu un script shell, dar acceptă mai multe comenzi. Fiecare comandă care modifică sistemul de fișiere creează un nou strat. În prima parte am discutat importanța împărțirii imaginii în straturi în mod corespunzător. Dockerfile este un subiect important în sine. 

Aici, voi demonstra doar câteva comenzi pentru a crea o altă imagine, "oh-yeah-alpine", bazată pe un Dockerfile. În plus față de crearea fișierului "yeah" infamous, să instalați și vim. Distribuția alpină Linux folosește un sistem de gestionare a pachetelor numit "apk". Aici este Dockerfile:

Din alpine # Copiați fișierul "yeah" de la gazda COPY da / da # Actualizați și instalați vim utilizând apk RUN apk update && apk adăugați vim CMD pisică / da

Imaginea de bază este alpină. Se copiază fișierul "yeah" din același director gazdă unde este Dockerfile (calea de construire a contextului). Apoi rulează Actualizare apk și instalează vim. În cele din urmă, acesta stabilește comanda care este executată atunci când containerul rulează. În acest caz, se va imprima pe ecran conținutul fișierului "yeah".

O.K. Acum, că știm la ce intrăm, să construim chestia asta. Opțiunea "-t" stabilește depozitul. Nu am specificat o etichetă, așa că va fi implicit "ultima".

> docker build -t oh-yeah-alpine. Trimiterea contextului de construire la daemonul Docker 3.072 kB Pasul 1/4: Din alpine ---> 4e38e38c8ce0 Pasul 2/4: COPY da / da ---> 1b2a228cc2a5 Scoaterea containerului intermediar a6221f725845 Pasul 3/4: RUN apk update && apk adauga vim ---> Rularea în e2c0524bd792 preluare http://dl-cdn.alpinelinux.org/.../APKINDEX.tar.gz preluare http: //dl-cdn.alpinelinux.org.../x86_64/APKINDEX.tar.gz v3. 4.6-60-gc61f5bf [http://dl-cdn.alpinelinux.org/alpine/v3.4/main] v3.4.6-33-g38ef2d2 [http://dl-cdn.alpinelinux.org/.../v3. 4 / comunitate] OK: 5977 pachete distincte disponibile (1/5) Instalarea lua5.2-libs (5.2.4-r2) (2/5) Instalarea ncurses-terminfo-base Instalarea ncurses-libs (6.0-r7) (5/5) Instalarea vim (7.4.1831-r2) Executarea busybox-1.24.2-r9.trigger OK: 37 MiB în 16 pachete ---> 7fa4cba6d14f Eliminarea containerului intermediar e2c0524bd792 Pasul 4/4: CMD pisica / da ---> Rularea în 351b4f1c1eb1 ---> e124405f28f4 Eliminarea containerului intermediar 351b4f1c1eb1 Successf construit recent e124405f28f4

Arata bine. Să verificăm că imaginea a fost creată:

> imagini de docare grep oh-yeah oh-yeah-alpine mai târziu e124405f28f4 Despre un minut în urmă 30.5 MB

Rețineți cum instalarea vim și dependențele sale au umflat dimensiunea containerului de la cele 4.8 MB ale imaginii alpine de bază la o masă de 30.5 MB!

Totul este foarte frumos. Dar funcționează?

> docker rulează oh-yeah-alpine funcționează!

Da, funcționează!

În cazul în care sunteți încă suspicios, hai să mergem în container și să examinăm fișierul "yeah" cu vim proaspăt instalat.

> docker rula -i oh-da-alpin / bin / sh / # vim da funcționează! ~ ~ ... ~ "da" 1L, 10C

Contextul de construire și fișierul .dockerignore

Nu v-am spus, dar inițial când am încercat să construiesc imaginea oh-yeah-alpină, ea a atârnat doar câteva minute. Problema a fost că am pus Dockerfile-ul în directorul meu de acasă. Atunci când Docker construiește o imagine, mai întâi împachetează întreaga adresă unde este Dockerfile (inclusiv subdirectoarele) și o face disponibilă pentru comenzile COPY din Dockerfile. 

Docker nu încearcă să fie inteligent și analizează comenzile COPY. Pur și simplu împachetează totul. Rețineți că conținutul de construire nu se va termina în imaginea dvs., dar va încetini comanda dvs. de construire dacă contextul dvs. de construire este inutil de mare.

În acest caz, am copiat doar fișierul Docker și "da" într-un sub-director și am rulat comanda de construire a doc-ului în acel sub-director. Dar uneori aveți un arbore de directoare complicat din care doriți să copiați subdirectoare și fișiere specifice și să ignorați altele. Introduceți fișierul .dockerignore. 

Acest fișier vă permite să controlați exact ce se întâmplă în contextul de construire. Trucul meu preferat este să excludem mai întâi totul și apoi să încep să includ și bucățile și piesele de care am nevoie. De exemplu, în acest caz aș putea să creez următorul fișier .dockerignore și să păstrez fișierul Docker și "yeah" în directorul meu de acasă:

# Excludeți TOATE primul * * Acum includeți selectiv chestii! Da

Nu este nevoie să includeți fișierul "Dockerfile" sau fișierul ".dockerignore" în contextul de construire.

Copierea vs. montare

Copierea fișierelor în imagine este uneori ceea ce aveți nevoie, dar în alte cazuri este posibil să doriți ca containerele să fie mai dinamice și să lucreze cu fișierele de pe gazdă. Acesta este locul unde volumele și montajele intră în joc. 

Mounting directoare gazdă este un joc diferit de minge. Datele sunt deținute de gazdă și nu de container. Datele pot fi modificate când containerul este oprit. Același container poate fi pornit cu mai multe directoare gazdă montate.

Etichetarea imaginilor

Etichetarea imaginilor este foarte importantă dacă dezvoltați un sistem bazat pe microservicii și generați o mulțime de imagini care trebuie uneori asociate unele cu altele. Puteți adăuga câte etichete pe care le doriți unei imagini. 

Ați văzut deja eticheta implicită "cea mai recentă". Uneori, este logic să adăugați alte etichete, cum ar fi "testate", "release-1.4" sau comitetul git care corespunde imaginii.

Puteți să etichetați o imagine în timpul unei construcții sau mai târziu. Iată cum puteți adăuga o etichetă unei imagini existente. Rețineți că, în timp ce se numește o etichetă, puteți atribui și un depozit nou.

> eticheta docker oh-yeah-alpine oh-yeah-alpine: rece-eticheta> eticheta de docare oh-yeah-alpine oh-yeah-alpine-2> imagini docker | grep oh-yeah oh-yeah-alpine-2 mai târziu e124405f28f4 30.5 MB oh-yeah-alpine cool-tag e124405f28f4 30.5 MB oh-yeah-alpine târziu e124405f28f4 30.5 MB

De asemenea, puteți bloca imaginea prin eliminarea unei imagini după numele etichetei acesteia. Acest lucru este puțin înspăimântător, deoarece dacă eliminați ultima etichetă accidental, veți pierde imaginea. Dar dacă construiți imagini dintr-un fișier Docker, puteți doar să reconstruiți imaginea.

> docker rmi oh-yeah-alpine-2 Necunoscuta: oh-yeah-alpine-2: cea mai recentă> docker rmi oh-yeah-alpine: cool-tag Nu etichetat: oh-yeah-alpine: cool-tag

Dacă încerc să îndepărtez ultima imagine rămasă etichetă rămasă, am o eroare deoarece este utilizată de un container.

> docker rmi oh-yeah-alpine Răspunsul la eroare de la daemon: conflict: imposibilitatea de a elimina referința repository "oh-yeah-alpine" (trebuie să forțeze) - containerul a1443a7ca9d2 folosește imaginea de referință e124405f28f4

Dar dacă voi scoate containerul ...

> Docher RMI oh-da-alpin Neetichetate: oh-da-alpin: cel mai recent șterse: SHA256: e124405f28f48e ... 441d774d9413139e22386c4820df Șters: SHA256: 7fa4cba6d14fdf ... d8940e6c50d30a157483de06fc59 Șters: SHA256: 283d461dadfa6c ... dbff864c6557af23bc5aff9d66de Șters: SHA256: 1b2a228cc2a5b4 ... 23c80a41a41da4ff92fcac95101e Șters: SHA256: fe5fe2290c63a0 ... 8af394bb4bf15841661f71c71e9a> imagini de docare grep oh-yeah

Da. S-a dus. Dar nu-ți face griji. Putem reconstrui:

> docker build -t oh-yeah-alpine. > imagini de docare grep oh-yeah oh-yeah-alpine mai recent 1e831ce8afe1 1 minut în urmă 30.5 MB 

Da, e înapoi. Dockerfile pentru câștig!

Lucrul cu registrele de imagini

Imaginile sunt foarte asemănătoare, în unele privințe, cu depozitele GIT. Ele sunt, de asemenea, construite dintr-un set ordonat de comitete. Vă puteți gândi la două imagini care utilizează aceleași imagini de bază ca ramurile (deși nu există nici o fuziune sau rebasing în Docker). Un registru de imagini este echivalentul unui serviciu central de găzduire de tip git, cum ar fi GitHub. Ghici care este numele registrului oficial al imaginilor Docker? Așa e, Docker Hub. 

Tragerea imaginilor

Când rulați o imagine, dacă nu există, Docker va încerca să o tragă din unul din registrele de imagini configurate. Implicit merge la Docker Hub, dar îl puteți controla în fișierul "~ / .docker / config.json". Dacă utilizați un registru diferit, puteți să urmați instrucțiunile, care de obicei implică conectarea utilizând datele de conectare.

Să ștergem imaginea "salut-lume" și să o tragem din nou folosind docker trageți comanda.

> imagini dockere grep hello-world salut-lume c54a2cc56cbb 7 luni în urmă 1.85 kB> docker rmi hello-world hello-world

S-a dus. Hai să tragem acum.

> docker pull hello-world Utilizarea etichetei implicite: ultimul cel mai nou: Tragere din bibliotecă / hello-world 78445dd45222: Trageți complet Digest: sha256: c5515758d4c5e1e ... 07e6f927b07d05f6d12a1ac8d7 Stare: Imagine nouă pentru hello-world descărcată | grep hello-world salut-world ultimele 48b5124b2768 2 săptămâni în urmă 1.84 kB

Cel mai recent salut-lume a fost înlocuit cu o versiune mai nouă.

Împingerea imaginilor

Împingerea imaginilor este puțin mai implicată. Mai întâi trebuie să creați un cont pe Docker Hub (sau alt registru). În continuare, vă conectați. Apoi, trebuie să etichetați imaginea pe care doriți să o împingeți în funcție de numele contului ("g1g1" în cazul meu).

> conectare doc-u-g1g1 -p  Conectare Realizat> tag-ul docului hello-world g1g1 / hello-world> imaginile docerelor grep hello g1g1 / hello-world cele mai recente 48b5124b2768 2 săptămâni în urmă 1.84 kB hello-world cele mai recente 48b5124b2768 2 săptămâni în urmă 1.84 kB 

Acum, pot împinge imaginea marcată g1g1 / hello-world tagged.

> docker push g1g1 / hello-world Push se referă la un depozit [docker.io/g1g1/hello-world] 98c944e98de8: montat din bibliotecă / hello-world târziu: digest: sha256: c5515758d4c5e ... f6d12a1ac8d7 dimensiune: 524

Concluzie

Imaginile Docker sunt șabloanele pentru containerele dvs. Acestea sunt concepute pentru a fi eficiente și pentru a oferi o refolosire maximă prin utilizarea unui driver de stocare a sistemului de fișiere de straturi. 

Docker oferă o mulțime de instrumente pentru listarea, inspectarea, construirea și etichetarea imaginilor. Puteți să trageți și să împingeți imaginile în registrele de imagini cum ar fi Docker Hub pentru a vă administra și distribui cu ușurință imaginile.

Cod