Dockercontainers zijn in opkomst als best practice voor het implementeren en beheren van cloud-native gedistribueerde systemen. Containers zijn exemplaren van Docker-afbeeldingen. Het blijkt dat er veel te weten en te begrijpen is over afbeeldingen.
In deze tweedelige zelfstudie behandel ik de Docker-afbeeldingen in de diepte. In deel een besprak ik de basisprincipes, ontwerpoverwegingen en het inspecteren van beeldinternals. In dit deel behandel ik uw eigen afbeeldingen, het oplossen van problemen en het werken met afbeeldingsrepositories.
Wanneer u aan de andere kant uitkomt, heeft u een goed begrip van wat Docker-afbeeldingen precies zijn en hoe u ze effectief kunt gebruiken in uw eigen toepassingen en systemen.
Er zijn twee manieren om afbeeldingen te maken. U kunt de bestaande container wijzigen en deze vervolgens als een nieuwe afbeelding toewijzen, of u kunt een Docker-bestand schrijven en het naar een afbeelding bouwen. We zullen beide bespreken en de voor- en nadelen uitleggen.
Met handmatige builds behandelt u uw container als een gewone computer. U installeert pakketten, u schrijft bestanden en als het allemaal gezegd en gedaan is, maakt u het en krijgt u een nieuwe afbeelding die u als sjabloon gebruikt om veel meer identieke containers te maken of zelfs andere afbeeldingen te baseren op.
Laten we beginnen met het alpine-beeld, een heel klein en spartaans beeld gebaseerd op Alpine Linux. We kunnen het in de interactieve modus gebruiken om in een shell te komen. Ons doel is om een bestand met de naam "yeah" toe te voegen met de tekst "it works!" naar de hoofdmap en maak er vervolgens een nieuwe afbeelding van met de naam "yeah-alpine".
Daar gaan we. Leuk, we zijn al in de roottribe. Laten we kijken wat er is.
> docker run -it alpine / bin / sh / # ls bin dev etc home lib linuxrc media mnt proc root run sbin srv sys tmp usr var
Welke editor is beschikbaar? Geen vim, geen nano?
/ # vim / bin / sh: vim: niet gevonden / # nano / bin / sh: nano: niet gevonden
Oh nou ja. We willen alleen een bestand maken:
/ # echo "het werkt!" > yeah / # cat yeah het werkt!
Ik ben uit de interactieve shell gekomen en ik zie de container met de naam 'vibrant_spenc' bij koppelaar ps - alles
. De --allemaal
vlag is belangrijk omdat de container niet meer wordt uitgevoerd.
> docker ps --all CONTAINER ID IMAGE COMMAND GECREËERDE STATUS NAMEN c8faeb05de5f alpine "/ bin / sh" 6 minuten geleden Exited vibrant_spence
Hier maak ik een nieuwe afbeelding van de container "vibrate_spence". Ik heb de commit-boodschap "mine, mine, mine" toegevoegd voor een goede maatregel.
> docker commit -m "mine, mine, mine" vibrant_spence yeah-alpine sha256: e3c98cd21f4d85a1428 ... e220da99995fd8bf6b49aa
Laten we het bekijken. Yep, er is een nieuwe afbeelding en in de geschiedenis kun je een nieuwe laag zien met de opmerking "Mijn, Mijne, Mijn".
> docker-afbeeldingen REPOSITORIELAGER IMAGE ID FORMAAT yeah-alpine nieuwste e3c98cd21f4d 4.8 MB python nieuwste 775dae9b960e 687 MB d4w / nsenter nieuwste 9e4f13a0901e 83.8 kB ubuntu-met-ssh nieuwste 87391dca396d 221 MB ubuntu nieuwste bd3d4369aebc 127 MB hello-world nieuwste c54a2cc56cbb 1.85 kB alpine nieuwste 4e38e38c8ce0 4.8 MB nsqio / nsq nieuwste 2a82c70fe5e3 70.7 MB> dokwerker geschiedenis yeah-alpine IMAGE Geopend formaat COMMENTAAR e3c98cd21f4d 40 seconden geleden 66 B mijne, mijne, mijne 4e38e38c8ce0 7 maanden geleden 4.8 MB
Nu voor de echte test. Laten we de container verwijderen en een nieuwe container uit de afbeelding maken. Het verwachte resultaat is dat het "ja" -bestand aanwezig zal zijn in de nieuwe container.
> docker rm vibrant_spence vibrant_spence> docker run -it yeah-alpine / bin / sh / # cat yeah het werkt! / #
Wat kan ik zeggen? Ja, het werkt!
Het maken van afbeeldingen uit aangepaste containers is cool, maar er is geen verantwoording. Het is moeilijk om de wijzigingen bij te houden en te weten wat de specifieke wijzigingen waren. De gedisciplineerde manier om afbeeldingen te maken is om ze te bouwen met behulp van een Docker-bestand.
Het Dockerfile is een tekstbestand dat lijkt op een shellscript, maar het ondersteunt verschillende opdrachten. Elke opdracht die het bestandssysteem wijzigt, maakt een nieuwe laag. In deel een bespraken we hoe belangrijk het is om je afbeelding goed in lagen te verdelen. Het Docker-bestand is een groot onderwerp op zich.
Hier zal ik slechts een paar commando's demonstreren om een ander beeld te creëren, "oh-yeah-alpine", gebaseerd op een Docker-bestand. In aanvulling op het beruchte "ja" -bestand maken, laten we ook VIM installeren. De alpine Linux-distributie maakt gebruik van een pakketbeheersysteem genaamd "apk". Hier is het Dockerbestand:
FROM alpine # Kopieer het "ja" -bestand van de host COPY yeah / yeah # Update en installeer vim met apk RUN apk update && apk add vim CMD cat / yeah
Het basisbeeld is alpine. Het kopieert het "yeah" -bestand uit dezelfde host-directory waar het Dockerfile is (het build-contextpad). Vervolgens wordt het uitgevoerd apk update
en installeert vim. Ten slotte wordt de opdracht ingesteld die wordt uitgevoerd wanneer de container wordt uitgevoerd. In dit geval zal het de inhoud van het "ja" -bestand naar het scherm afdrukken.
OK. Nu we weten waar we aan beginnen, laten we dit ding bouwen. De "-t" -optie stelt de repository in. Ik heb geen tag opgegeven, dus het is de standaard "nieuwste".
> docker gebouwd -t oh-yeah-alpine. Build-context verzenden naar Docker daemon 3.072 kB Stap 1/4: FROM alpine ---> 4e38e38c8ce0 Stap 2/4: COPY yeah / yeah ---> 1b2a228cc2a5 Tussenliggende container verwijderen a6221f725845 Stap 3/4: RUN apk-update && apk add vim ---> Rennen in e2c0524bd792 halen http://dl-cdn.alpinelinux.org/... /APKINDEX.tar.gz halen http: //dl-cdn.alpinelinux.org... /x86_64/APKINDEX.tar.gz v3 op. 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 / community] OK: 5977 verschillende pakketten beschikbaar (1/5) Installatie van lua5.2-libs (5.2.4-r2) (2/5) Installeren van ncurses-terminfo-base (6.0-r7) (3/5) Installeren ncurses-terminfo (6.0-r7) (4/5) Installatie van ncurses-libs (6.0-r7) (5/5) Installeren van vim (7.4.1831-r2) Bezigbox uitvoeren-1.24.2-r9.trigger OK: 37 MiB in 16 pakketten ---> 7fa4cba6d14f Tussencontainer verwijderen e2c0524bd792 Stap 4/4: CMD cat / yeah ---> Running in 351b4f1c1eb1 ---> e124405f28f4 Tussenliggende container verwijderen 351b4f1c1eb1 Successf ully gebouwd e124405f28f4
Ziet er goed uit. Laten we controleren of de afbeelding is gemaakt:
> koppelaarafbeeldingen | grep oh-yeah oh-yeah-alpine laatste e124405f28f4 Ongeveer een minuut geleden 30.5 MB
Merk op hoe het installeren van vim en de afhankelijkheden ervan de grootte van de container van de 4.8 MB van de basis alpine afbeelding opgeblazen tot een enorme 30.5 MB!
Het is allemaal heel leuk. Maar werkt het?
> havenarbeider rennen oh-ja-alpine het werkt!
Oh ja, het werkt!
In het geval dat je nog steeds achterdochtig bent, laten we dan naar de container gaan en het "ja" -bestand bekijken met onze nieuw geïnstalleerde vim.
> docker run -it oh-yeah-alpine / bin / sh / # vim ja het werkt! ~ ~ ... ~ "ja" 1L, 10C
Ik heb het je niet verteld, maar oorspronkelijk toen ik probeerde het oh-yeah-alpine beeld te bouwen, hing het gewoon een paar minuten. Het probleem was dat ik zojuist het Dockerbestand in mijn homedirectory heb gezet. Wanneer Docker een afbeelding maakt, verpakt deze eerst de hele map waar het Dockerfile zich bevindt (inclusief submappen) en stelt deze beschikbaar voor COPY-opdrachten in het Docker-bestand.
Docker probeert niet slim te zijn en analyseert uw COPY-opdrachten. Het pakt gewoon het hele ding in. Merk op dat de inhoud van de build niet eindigt in je afbeelding, maar het zal je build-commando vertragen als je build-context onnodig groot is.
In dit geval heb ik eenvoudigweg het Dockerbestand en het "ja" gekopieerd naar een submap en de opdracht docker build uitgevoerd in die submap. Maar soms hebt u een gecompliceerde mappenboom waaruit u specifieke submappen en bestanden wilt kopiëren en andere wilt negeren. Voer het .dockerignore-bestand in.
Met dit bestand kun je precies bepalen wat er in de build-context gaat. Mijn favoriete truc is om eerst alles uit te sluiten en vervolgens de stukjes en beetjes die ik nodig heb te integreren. In dit geval zou ik bijvoorbeeld het volgende .dockerignore-bestand kunnen maken en het Docker-bestand en het "ja" in mijn basismap kunnen bewaren:
# ALLEEN ALLES UITSLUITEN * # Neem nu selectief spullen op!
Het is niet nodig om het "Dockerfile" zelf of het ".dockerignore" -bestand op te nemen in de build-context.
Het kopiëren van bestanden naar de afbeelding is soms wat u nodig hebt, maar in andere gevallen wilt u misschien dat uw containers dynamischer worden en met bestanden op de host werken. Dit is waar volumes en mounts in het spel komen.
Het monteren van host-directory's is een ander balspel. De gegevens zijn eigendom van de host en niet van de container. De gegevens kunnen worden gewijzigd wanneer de container wordt gestopt. Dezelfde container kan worden gestart met verschillende host-directory's aangekoppeld.
Het labelen van afbeeldingen is erg belangrijk als u een op microservices gebaseerd systeem ontwikkelt en veel afbeeldingen genereert die soms aan elkaar zijn gekoppeld. U kunt zoveel tags toevoegen als u maar wilt aan een afbeelding.
U hebt de standaard 'nieuwste' tag al gezien. Soms is het zinvol om andere tags toe te voegen, zoals "tested", "release-1.4" of de git commit die overeenkomt met de afbeelding.
U kunt een afbeelding taggen tijdens een build of later. U kunt als volgt een tag toevoegen aan een bestaande afbeelding. Hoewel het een tag is genoemd, kunt u ook een nieuwe repository toewijzen.
> docker-tag oh-yeah-alpine oh-yeah-alpine: cool-tag> docker-tag oh-yeah-alpine oh-yeah-alpine-2> docker-afbeeldingen | grep oh-yeah oh-yeah-alpine-2 nieuwste e124405f28f4 30,5 MB oh-yeah-alpine cool-tag e124405f28f4 30,5 MB oh-yeah-alpine nieuwste e124405f28f4 30,5 MB
U kunt ook de markering ongedaan maken door een afbeelding te verwijderen met de tagnaam. Dit is een beetje eng, want als je de laatste tag per ongeluk verwijdert, verlies je de afbeelding. Maar als u afbeeldingen maakt van een Docker-bestand, kunt u de afbeelding gewoon opnieuw opbouwen.
> docker rmi oh-yeah-alpine-2 Niet gelabeld: oh-yeah-alpine-2: nieuwste> docker rmi oh-yeah-alpine: cool-tag Niet-tagged: oh-yeah-alpine: cool-tag
Als ik de laatst overgebleven getagde afbeelding probeer te verwijderen, krijg ik een foutmelding omdat deze door een container wordt gebruikt.
> docker rmi oh-yeah-alpine Foutreactie van daemon: conflict: kan referentie van de repository niet verwijderen "oh-yeah-alpine" (must force) - container a1443a7ca9d2 gebruikt de afbeelding waarnaar verwezen wordt e124405f28f4
Maar als ik de container verwijder ...
> Havenarbeider RMI oh-ja-alpine Untagged: oh-ja-alpine: latest Deleted: sha256: e124405f28f48e ... 441d774d9413139e22386c4820df Deleted: sha256: 7fa4cba6d14fdf ... d8940e6c50d30a157483de06fc59 Deleted: sha256: 283d461dadfa6c ... dbff864c6557af23bc5aff9d66de Deleted: sha256: 1b2a228cc2a5b4 ... 23c80a41a41da4ff92fcac95101e Deleted: sha256: fe5fe2290c63a0 ... 8af394bb4bf15841661f71c71e9a> koppelaarafbeeldingen | grep oh-yeah
Yep. Het is weg. Maar maak je geen zorgen. We kunnen het opnieuw opbouwen:
> docker gebouwd -t oh-yeah-alpine. > koppelaarafbeeldingen | grep oh-yeah oh-yeah-alpine laatste 1e831ce8afe1 1 minuut geleden 30.5 MB
Yay, het is terug. Dockerbestand voor de overwinning!
Afbeeldingen lijken in sommige opzichten sterk op git-archieven. Ze zijn ook opgebouwd uit een geordende set commits. U kunt twee afbeeldingen bedenken die dezelfde basisafbeeldingen gebruiken als takken (hoewel er geen samenvoeging of rebasing is in Docker). Een beeldregistratie is het equivalent van een centrale git-hostingservice zoals GitHub. Raad eens wat de naam is van het officiële Docker-afbeeldingsregister? Dat klopt, Docker Hub.
Wanneer u een afbeelding uitvoert en deze niet bestaat, probeert Docker deze te verwijderen uit een van uw geconfigureerde afbeeldingsregisters. Standaard gaat het naar Docker Hub, maar je kunt het besturen in je "~ / .docker / config.json" bestand. Als u een ander register gebruikt, kunt u hun instructies volgen. Meestal moet u zich aanmelden met hun inloggegevens.
Laten we de afbeelding "Hello-world" verwijderen en hem opnieuw trekken met de havenarbeider trek
commando.
> dockere-afbeeldingen | grep hello-world hello-world laatste c54a2cc56cbb 7 maanden geleden 1.85 kB> docker rmi hello-world hello-world
Het is weg. Laten we nu gaan.
> docker pull hello-world Standaardtag gebruiken: uiterlijk: halen uit bibliotheek / hello-world 78445dd45222: Pull complete Digest: sha256: c5515758d4c5e1e ... 07e6f927b07d05f6d12a1ac8d7 Status: Gedownload nieuwere afbeelding voor hello-world: laatste> havenfoto's | grep hello-world hallo-world laatste 48b5124b2768 2 weken geleden 1.84 kB
De nieuwste hello-wereld is vervangen door een nieuwere versie.
Het duwen van afbeeldingen is iets meer betrokken. Eerst moet je een account maken op Docker Hub (of een ander register). Vervolgens log je in. Dan moet je de afbeelding die je wilt duwen, taggen volgens je accountnaam ("g1g1" in mijn geval).
> docker login -u g1g1 -pLogin geslaagd> docker-tag hello-world g1g1 / hello-world> docker-afbeeldingen | grep hello g1g1 / hello-world laatste 48b5124b2768 2 weken geleden 1.84 kB hello-world laatste 48b5124b2768 2 weken geleden 1.84 kB
Nu kan ik de met g1g1 / hello-world getagde afbeelding pushen.
> docker push g1g1 / hello-world De push verwijst naar een repository [docker.io/g1g1/hello-world] 98c944e98de8: Mounted from library / hello-world latest: digest: sha256: c5515758d4c5e ... f6d12a1ac8d7 size: 524
Docker-afbeeldingen zijn de sjablonen voor uw containers. Ze zijn ontworpen om efficiënt te zijn en bieden maximaal hergebruik door gebruik te maken van een opslagstuurprogramma voor het opslaan van lagen.
Docker biedt veel hulpmiddelen voor het aanbieden, inspecteren, bouwen en labelen van afbeeldingen. U kunt afbeeldingen naar afbeeldingenregisters zoals Docker Hub slepen en duwen om uw afbeeldingen eenvoudig te beheren en te delen.