Postat pe 14 octombrie 2019. Actualizat pe 10 iunie 2020

Punerea unui borcan de grăsime într-un container Docker este o pierdere de depozitare, lățime de bandă și timp. Din fericire, putem valorifica straturile de imagine ale Docker și stocarea în cache a registrului pentru a crea versiuni incrementale și artefacte foarte mici. De exemplu, am putea reduce dimensiunea efectivă a noilor artefacte de la 75 MB la un singur MB! Și cel mai bun este că există un plugin pentru Maven și Gradle care gestionează totul pentru noi.

grase

  • Un borcan de grăsime conține toate dependențele care de obicei nu se schimbă între eliberări. Dar aceste dependențe sunt copiate iar și iar în fiecare borcan de grăsime ducând la o pierdere de spațiu, lățime de bandă și timp.
  • De exemplu, vasul de grăsime al aplicației noastre Spring Boot avea 72 MB mare, dar conținea doar 2 MB cod. De obicei, codul este singura parte care a fost modificată.
  • Din fericire, putem profita de straturile de imagine ale Docker: punând dependențele și resursele în diferite straturi, le putem reutiliza și actualiza doar codul pentru fiecare artefact/versiune.
  • Jib oferă un plugin ușor de utilizat pentru Maven și Gradle pentru a implementa această abordare. Nu este nevoie să scrieți manual un fișier Docker.

Mecanismul stratului Docker este puternic. Dacă toate aplicațiile dvs. utilizează aceeași imagine de bază (cum ar fi openjdk: 11.0.4-jre-slim) Docker reutilizează straturile sistemului de operare și ale JRE. Așadar, economisim spațiu de stocare în registrul Docker și accelerăm încărcarea și descărcarea din registru, deoarece trebuie transferați mai puțini MB (Docker transferă doar straturile noi în registru).

Din păcate, multe aplicații nu folosesc pe deplin acest mecanism puternic, deoarece utilizează borcane de grăsime într-un container Docker.

Fiecare versiune nouă creează un nou strat Docker cu 72 MB

Să presupunem că aplicația noastră Spring Boot este ambalată într-un borcan de grăsime. Acest borcan de grăsime are o dimensiune de 72 MB și este adăugat în ultima linie a fișierului Docker. Aceasta înseamnă că fiecare nouă versiune va necesita 72 MB spațiu de stocare și 72 MB trebuie încărcați și descărcați din registru.

Acum, este important să aruncăm o privire mai atentă asupra acestor 72 MB:

Conținutul unui borcan gras. Majoritatea conținutului său se schimbă rar, dar este copiat iar și iar în fiecare artefact.

Un borcan de grăsime conține trei părți:

  • Dependențe: bibliotecile utilizate iau cea mai mare parte a dimensiunii, dar se schimbă rar. De cele mai multe ori, atunci când creăm o versiune, ne-am atins doar de cod și nu de dependențe. Totuși, dependențele sunt copiate în fiecare versiune.
  • Resursele: Practic, este aceeași problemă aici. Deși resursele (HTML, CSS, imagini, fișiere de configurare etc.) se schimbă mai des decât dependențele, ele nu se schimbă tot atât de des pe cât se modifică codul. Dar sunt și duplicate în fiecare versiune.
  • Codul: codul are doar o mică parte din dimensiunea totală a borcanului de grăsime (300 KB - 2 MB), dar este cea mai frecvent schimbată parte a acestuia.

Deci, codul care este modificat de obicei pentru o nouă versiune este de doar câțiva MB. Totuși, copiem din nou și din nou toate dependențele și resursele din fiecare artefact. Este o pierdere de spațiu, lățime de bandă și timp.

Mai mult, pierderea spațiului se înrăutățește și mai mult atunci când creați un artefact unic, implementabil pentru fiecare commit (folosind hash-ul git commit ca număr de versiune al artefactului). Acest lucru are sens pentru livrarea continuă, dar duce la un consum ridicat de stocare, deoarece fiecare angajare ocupă încă 72 MB.

Care sunt instrumentele utile pentru analiza imaginilor de andocare și vizualizarea impactului borcanelor de grăsime din imaginile de andocare? Este istoria scufundărilor și a andocării .

Scufundarea interactivă din linia de comandă arată stratul de grăsime.

istoria dockerului dezvăluie și stratul de borcan gras:

Din fericire, putem profita de mecanismul de stratificare al lui Docker; la fel cum facem deja pentru sistemul de operare și stratul JRE. Extindem această abordare introducând diferite straturi pentru dependențe, resurse și cod. Și ordonăm straturile după frecvența schimbării.

Împărțirea aplicației cu trei straturi Docker diferite pentru dependențe, resurse și cod. O versiune de obicei va dura acum doar 2 MB în loc de 72 MB.

Acum, dacă creăm o versiune care constă doar din modificări de cod, avem nevoie doar de 2 MB de stocare, deoarece straturile pentru resurse și dependențe pot fi reutilizate. Acestea există deja în registru și nu trebuie să fie transferate din nou la acesta.

Vești bune: nu trebuie să scriem manual fișiere Docker pentru aplicațiile noastre Java. Putem folosi Jib-ul Google. Jib este disponibil ca plugin pentru Maven și Gradle și simplifică containerizarea aplicațiilor Java. Un pitch frumos pentru Jib poate fi găsit în Google Blog, dar o caracteristică este cea mai importantă pentru noi: Jib scanează proiectul nostru Java și creează diferite straturi pentru dependențe, resurse și cod. Este minunat cum funcționează Jib din cutie.

Care sunt pașii?

  1. Adăugați configurația pluginului la pom.xml:

  1. Profit. Istoria scufundărilor și a andocărilor arată noua structură strălucitoare a stratului.

Cele trei straturi diferite pentru dependențe, resurse și cod din imaginea noastră de andocare încorporată cu Jib

Curățare opțională

Curățare 1) Dezactivați maven-deploy-plugin, maven-install-plugin și maven-jar-plugin. Acești pași nu mai sunt necesari și nu ar trebui să fie executați chiar dacă tipurile de dezvoltator mvn se desfășoară din obișnuință.

Curățare 2) Eliminați pluginul spring-boot-maven-dacă folosiți Spring Boot. Nu mai este nevoie să creați un borcan de grăsime.

Jib permite configurarea steagurilor JVM și a argumentelor programului în pom.xml. Dar, de obicei, nu vrem să setăm aceste lucruri la momentul construirii. În schimb, configurația depinde de mediul de implementare (local, QA, producție). Aici vrem să setăm configurația Spring și dimensiunea JVM Heap.

  • Steaguri JVM: Folosim variabila de mediu JAVA_TOOL_OPTIONS pentru a adăuga steaguri JVM precum dimensiunea heap.
  • Configurare de primăvară: Montăm fișierul de configurare externă specific implementării în containerul Docker și trecem locația ca argument de program. Alternativ, puteți utiliza și variabile de mediu pentru aceasta.

Numere de versiune pentru livrare continuă cu Maven și Docker

Tutorial: Livrare continuă cu Docker și Jenkins

Construirea unui microserviciu Dropwizard cu Docker și Maven

Nu utilizați baze de date în memorie (H2, Fongo) pentru teste

Sunt Philipp Hauer și lucrez ca șef de echipă pentru Spreadshirt în Leipzig, Germania. Mă concentrez pe dezvoltarea aplicațiilor web bazate pe JVM și sunt entuziasmat de Kotlin, codul curat, sistemele distribuite, testarea și sociologia dezvoltării software-ului. Trimit un tweet sub @philipp_hauer și țin discuții din când în când.

  • Docker (11)
  • Kotlin (11)
  • Cele mai bune practici (8)
  • REST (8)
  • Construiți (7)
  • Cod curat (7)
  • Maven (7)
  • Vaadin (7)
  • MongoDB (6)
  • Testare (6)
  • Microservicii (5)
  • Recipiente de testare (5)