Docker fra bakken forstå bilder

Dockercontainere stiger som en god praksis for distribusjon og styring av cloud-native distribuerte systemer. Beholdere er forekomster av Docker-bilder. Det viser seg at det er mye å vite og forstå om bilder. 

I denne todelte opplæringen vil jeg dekke Docker-bilder i dybden. I denne delen begynner jeg med de grunnleggende prinsippene, og så skal jeg gå videre for å designe hensyn og inspisere bildeplaner. I del to vil jeg dekke å bygge dine egne bilder, feilsøking og jobbe med bildebeholdere. 

Når du kommer ut på den andre siden, har du en solid forståelse av hva Docker-bilder er akkurat og hvordan du kan bruke dem effektivt i dine egne applikasjoner og systemer.

Forstå lag

Docker administrerer bilder ved hjelp av en back-end-lagringsdriver. Det finnes flere støttede drivere som AUFS, BTRFS og overlegg. Bilder er laget av bestilte lag. Du kan tenke på et lag som et sett med filsystemendringer. Når du tar alle lagene og stable dem sammen, får du et nytt bilde som inneholder alle akkumulerte endringene. 

Den bestilte delen er viktig. Hvis du legger til en fil i ett lag og fjerner det i et annet lag, kan du gjøre det i riktig rekkefølge. Docker holder oversikt over hvert lag. Et bilde kan bestå av dusinvis av lag (nåværende grense er 127). Hvert lag er veldig lett. Fordelen med lag er at bildene kan dele lag. 

Hvis du har mange bilder basert på lignende lag, som base OS eller vanlige pakker, blir alle disse vanlige lagene lagret bare én gang, og overhead per bilde blir bare de unike lagene i bildet.

Kopier på Skriv

Når en ny beholder er opprettet fra et bilde, er alle bildelagene skrivebeskyttet, og et tynt lese- og skrivelag legges øverst. Alle endringene som er gjort til den bestemte beholderen, lagres i det laget. 

Nå betyr det ikke at beholderen ikke kan endre filer fra bildelaget. Det kan absolutt. Men det vil lage en kopi i sitt øverste lag, og fra det tidspunktet vil alle som prøver å få tilgang til filen, få topplags kopien. Når filer eller kataloger blir fjernet fra lavere lag, blir de skjult. De opprinnelige bildelagene er identifisert av en kryptografisk innholdsbasert hash. Beholderens lese-skrive-lag er identifisert av en UUID.

Dette tillater en kopi-på-skriv-strategi for både bilder og containere. Docker gjenbruk de samme gjenstandene så mye som mulig. Først når et element er endret, vil Docker opprette en ny kopi.

Designhensyn for Docker-bilder

Den unike organisasjonen i lag og kopi-på-skriv-strategien fremmer noen gode metoder for å lage og sammensatte Docker-bilder.

Minimale bilder: Mindre er mer

Docker-bilder får enorme fordeler med utgangspunkt i stabilitet, sikkerhet og lastingstid, jo mindre de er. Du kan lage veldig små bilder for produksjon. Hvis du trenger å feilsøke, kan du alltid installere verktøy i en container. 

Hvis du skriver dataene dine, logger og alt annet bare til monterte volumer, kan du bruke hele arsenalet av feilsøkings- og feilsøkingsverktøy på verten. Vi ser snart hvordan du kontrollerer svært nøye hvilke filer som går inn i Docker-bildet ditt.

Kombiner lag

Lag er bra, men det er en grense, og det er overhead forbundet med lag. For mange lag kan skade filsystemtilgangen inne i beholderen (fordi hvert lag kan ha lagt til eller fjernet en fil eller katalog), og de roter bare ditt eget filsystem.

Hvis du for eksempel installerer en haug med pakker, kan du ha et lag for hver pakke, ved å installere hver pakke i en separat RUN-kommando i Dockerfile:

Kjør apt-get update KJØP apt-get -y installer package_1 Kjør apt-get -y installer package_2 Kjør apt-get -y installer package_3

Eller du kan kombinere dem til ett lag med en enkelt RUN-kommando.

Kjør apt-get oppdatering && \ apt-get -y installer package_1 && \ apt-get -y installer package_2 && \ apt-get -y installer package_3 

Velge et grunnbilde

Ditt basebilde (praktisk talt ingen bygger bilder fra grunnen av) er ofte en viktig beslutning. Det kan inneholde mange lag og legge til mange evner, men også mye vekt. Kvaliteten på bildet og forfatteren er også kritisk. Du vil ikke basere bildene dine på noe flakket bilde der du ikke er sikker på hva som er der inne, og hvis du kan stole på forfatteren.

Det er offisielle bilder for mange distribusjoner, programmeringsspråk, databaser og runtime-miljøer. Noen ganger er alternativene overveldende. Ta deg tid og ta et klokt valg.

Inspisere bilder

La oss se på noen bilder. Her er en liste over bildene som er tilgjengelige på min maskin:

REPOSITORY TAG IMAGE ID CREATED SIZE python siste 775dae9b960e 12 dager siden 687 MB d4w / nsenter nyeste 9e4f13a0901e 4 måneder siden 83,8 kB ubuntu-with-ssh siste 87391dca396d 4 måneder siden 221 MB ubuntu nyeste bd3d4369aebc 5 måneder siden 127 MB hello-world latest c54a2cc56cbb 7 måneder siden 1,85 kB alpine siste 4e38e38c8ce0 7 måneder siden 4.8 MB nsqio / nsq sist 2a82c70fe5e3 8 måneder siden 70.7 MB

Lageret og taggen identifiserer bildet for mennesker. Hvis du bare prøver å løpe eller trekke ved hjelp av et depotnavn uten å spesifisere taggen, brukes den "siste" taggen som standard. Bildet ID er en unik identifikator.

La oss dykke inn og inspisere hello-world image:

> Docker inspiser hallo verden ["Id": "sha256: c54a2cc56cbb2f ... e7e2720f70976c4b75237dc", "RepoTags": ["hallo verden: siste"], "RepoDigests": ["hallo world @ sha256: 0256e8a3 ... 411de4cdcf9431a1feb60fd9" ] "," Parent ":" "," Kommentar ":" "," Laget ":" 2016-07-01T19: 39: 27.532838486Z "," Container ":" 562cadb4d17bbf30b58a ... bf637f1d2d7f8afbef666 "," ContainerConfig " ":" cxbc554a4b7 "," Domenenavn ":" "," Bruker ":" "," AttachStdin ": Falskt," AttachStdout ": Falskt," AttachStderr ": Falskt," Tty ": Falskt," OpenStdin " "StdinOnce": falsk, "Env": ["PATH = / usr / bin: / usr / sbin: / usr / bin: / sbin: / bin"], "Cmd": ["/ bin / sh" -c "," # (nop) CMD [\ "/ hello \"] "," Bilde ":" sha256: 0f9bb7da10de694 ... 5ab0fe537ce1cd831e "," Volumer ": null," WorkingDir ":" "," Entrypoint " null, "OnBuild": null, "Labels": , "DockerVersion": "1.10.3", "Forfatter": "", "Config": "Vertsnavn": "c65bc554a4b7", "Domenenavn" "", "Bruker": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": falskt, "Tty": false, "Open Stdin ": falsk," StdinOnce ": falsk," Env ": [" PATH = / usr / sbin: / usr / bin: / sbin: / bin "]," Cmd ": [" / hei "]," Bilde ":" sha256: 0f9bb7da10de694b ... b0fe537ce1cd831e "," Volumer ": null," WorkingDir ":" "," Entrypoint ": null," OnBuild ": null," Etiketter ": ," Arkitektur ":" amd64 " , "Os": "Linux", "Størrelse": 1848, "VirtualSize": 1848, "GraphDriver": "Name": "aufs", "Data": null, "RootFS": "Type": "lag", "lag": ["sha256: a02596fdd012f22b03a ... 079c3e8cebceb4262d7"]]

Det er interessant å se hvor mye informasjon som er knyttet til hvert bilde. Jeg vil ikke gå over hvert element. Jeg skal bare nevne en interessant godbit at "container" og "containerConfig" oppføringene er for en midlertidig container som Docker oppretter når den bygger bildet. Her vil jeg fokusere på den siste delen av "RootFS". Du kan få bare denne delen ved hjelp av Go-templerende støtten til inspektørkommandoen:

> docker inspect -f '.RootFS' hei-verden lag [sha256: a02596fdd012f22b03af6a ... 8357b079c3e8cebceb4262d7]

Det fungerer, men vi mistet den fine formatering. Jeg foretrekker å bruke jq:

> Docker inspiser hello-world | jq. [0] .RootFS "Type": "lag", "Lag": ["sha256: a02596fdd012f22b03af6a ... 7507558357b079c3e8cebceb4262d7"] 

Du kan se at typen er "Layers", og det er bare ett lag. 

La oss inspisere lagene i Python-bildet:

> docker inspisere python | jq [0] .RootFS  "Type":. "lag", "lag": [ "SHA256: a2ae92ffcd29f7ede ... e681696874932db7aee2c", "SHA256: 0eb22bfb707db44a8 ... 8f04be511aba313bdc090", "SHA256: 30339f20ced009fc3 ... 6b2a44b0d39098e2e2c40", "SHA256: f55f65539fab084d4 ... 52932c7d4924c9bfa6c9e "," sha256: 311f330fa783aef35 ... e8283e06fc1975a47002d "," sha256: f250d46b2c81bf76c ... 365f67bdb014e98698823 "," sha256: 1d3d54954c0941a8f ... 8992c3363197536aa291a "]

Wow. Syv lag. Men hva er de lagene? Vi kan bruke historikkkommandoen til å finne ut det:

IMAGE CREATED CREATED BY SIZE 775dae9b960e 12 dager siden / bin / sh -c # (nop) CMD ["python3"] 0 B  12 dager siden / bin / sh-c cd / usr / local / bin && ... 48 B  12 dager siden / bin / sh -c set -ex && buildDeps = '... 66.9 MB  12 dager siden / bin / sh-c # (nop) ENV PYTHON_PIP_V ... 0 B  12 dager siden / bin / sh-c # (nop) ENV PYTHON_VERSI ... 0 B  12 dager siden / bin / sh-c # (nop) ENV GPG_KEY = 0D96 ... 0 B  12 dager siden / bin / sh -c apt-get update && apt-ge ... 7.75 MB  12 dager siden / bin / sh-c # (nop) ENV LANG = C.UTF-8 0 B  12 dager siden / bin / sh-c # (nop) ENV PATH = / usr / lo ... 0 B  13 dager siden / bin / sh -c apt-get update && apt-ge ... 323 MB  13 dager siden / bin / sh -c apt-get update && apt-ge ... 123 MB  13 dager siden / bin / sh -c apt-get update && apt-ge ... 44,3 MB  13 dager siden / bin / sh-c # (nop) CMD ["/ bin / bash" ... 0 B  13 dager siden / bin / sh-c # (nop) ADD fil: 89ecb642 ... 123 MB

OK. Ikke vær redd. Ingenting mangler. Dette er bare et forferdelig brukergrensesnitt. Lagene pleide å ha en bilde-ID før Docker 1.10, men ikke lenger. IDen til topplaget er egentlig ikke ID for det laget. Det er ID av Python-bildet. "CREATED BY" er avkortet, men du kan se hele kommandoen hvis du passerer --no-AVKORT. Jeg lagrer deg fra utskriften her på grunn av sidebreddsbegrensninger som krever ekstremt linjeinnpakning.

Hvordan får du bilder? Det er tre måter:

  • Trekk / Run
  • Laste
  • Bygge

Når du kjører en container, spesifiserer du bildet. Hvis bildet ikke finnes på systemet, blir det trukket fra et Docker-register (som standard DockerHub). Alternativt kan du trekke direkte uten å kjøre containeren.

Du kan også laste inn et bilde som noen sendte deg som tarfil. Docker støtter det nativt.

Til slutt, og mest interessant, kan du bygge dine egne bilder, som er temaet i del to.

Konklusjon

Docker-bilder er basert på et lagdelt filsystem som gir mange fordeler og fordeler for brukstilfeller som containere er designet for, for eksempel å være lette og dele vanlige deler, så mange beholdere kan distribueres og kjøre på samme maskin økonomisk. 

.