Så fungerar Docker-avbildningar

Slutförd

Kom ihåg att vi sa att containeravbildningen blir den enhet vi använder för att distribuera program. Vi nämnde också att containern är i ett standardiserat format som både våra utvecklar- och driftteam använder.

Här tittar vi på skillnaderna mellan programvara, paket och avbildningar som används i Docker. Genom att känna till skillnaderna mellan dessa begrepp får vi bättre förståelse för hur Docker-avbildningar fungerar.

Vi kommer även att kort diskutera rollerna för det operativsystem som körs på värden samt det operativsystemet som körs i containern.

Programvara som paketeras i en container

Programvaran som paketeras i en container är inte begränsad till de program som våra utvecklare skapar. När vi pratar om programvara syftar vi på programkod, systempaket, binärfiler, bibliotek, konfigurationsfiler och det operativsystem som körs i containern.

Anta till exempel att vi utvecklar en orderspårningsportal som vårt företags olika butiker kan använda. Vi behöver titta på den fullständiga programvarustack som kommer att köra webbappen. Programmet vi skapar är en .NET Core MVC-app och vi planerar att distribuera programmet med nginx som en omvänd proxyserver på Ubuntu Linux. Alla dessa programvarukomponenter utgör en del av containeravbildningen.

Vad är en containeravbildning?

En containeravbildning är ett portabelt paket som innehåller programvara. Det är denna avbildning som när den körs blir vår container. Containern är en avbildnings minnesintern instans.

Containeravbildningar är oföränderliga. När du har skapat en avbildning kan du inte ändra den. Det enda sättet att ändra en avbildning är att skapa en ny. Den här funktionen är vår garanti att den avbildning som vi använder i produktion är samma avbildning som används i utveckling samt frågor och svar.

Vad är värdoperativsystemet?

Värdoperativsystemet är det operativsystem där Docker-motorn körs. Docker-containrar som körs på Linux delar värdoperativsystemets kernel och kräver inte ett containeroperativsystem så länge binärfilen kan komma åt OS-kerneln direkt.

Diagram som visar en Docker-avbildning utan basoperativsystem samt beroendet av värdoperativsystemets kernel.

Dock behöver Windows-containrar ett containeroperativsystem. Containern förlitar sig på operativsystemets kernel för hantering av tjänster såsom filsystem, nätverkshantering, processchemaläggning och minneshantering.

Vad är containerns operativsystem?

Containeroperativsystemet är det operativsystem som ingår i den paketerade avbildningen. Vi har flexibiliteten att inkludera olika versioner av Linux- eller Windows-operativsystem i en container. Den här flexibiliteten gör att vi kan komma åt specifika os-funktioner eller installera ytterligare programvara som våra program kan använda.

Diagram som visar en Docker-avbildning med ett Ubuntu-basoperativsystem samt beroendet av värdoperativsystemets kernel.

Containeroperativsystemet är isolerat från värdoperativsystemet och det är den miljö där vi distribuerar och kör vårt program. I kombination med avbildningens oföränderlighet innebär den här isoleringen att den miljö där vårt program körs under utveckling är samma som för produktion.

I vårt exempel använder vi Ubuntu Linux som containeroperativsystem och det här operativsystemet ändras inte från utveckling eller produktion. Den avbildning som vi använder är alltid densamma.

Vad är Stackable Unification File System (Unionfs)?

Vi använder Unionfs för att skapa Docker-avbildningar. Unionfs är ett filsystem som gör att du kan stapla flera kataloger, så kallade grenar, på ett sådant sätt att det ser ut som om innehållet sammanfogas. Innehållet förvaras dock fysiskt separat. Unionfs gör att du kan lägga till och ta bort grenar allteftersom du skapar filsystemet.

Diagram som visar staplingen av lager i en Docker-avbildning som skapats med unionfs.

Anta till exempel att vi skapar en avbildning för vår webbapp från tidigare. Vi kommer att skikta Ubuntu-distributionen som en basavbildning ovanpå startfilsystemet. Nu ska vi installera nginx och vår webbapp. Vi lagrar nginx och webbappen ovanpå den ursprungliga Ubuntu-avbildningen.

Ett sista skrivbart lager skapas när containern väl körs från avbildningen. Det här lagret bevaras dock inte när containern förstörs.

Vad är en basavbildning?

En basavbildning är en avbildning som använder Docker-avbildningen scratch. Avbildningen scratch är en tom containeravbildning som inte skapar något filsystemslager. Den här avbildningen förutsätter att det program som du ska köra kan använda värdoperativsystemets kernel direkt.

Vad är en överordnad avbildning?

En överordnad avbildning är en containeravbildning som du skapar avbildningar från.

I stället för att till exempel skapa en avbildning från scratch och sedan installera Ubuntu använder vi en avbildning som redan baseras på Ubuntu. Vi kan till och med använda en avbildning som redan har nginx installerat. En överordnad avbildning innehåller vanligtvis ett containeroperativsystem.

Vad är den största skillnaden mellan basavbildningar och överordnade avbildningar?

Båda typerna av avbildningar ger möjligheten att skapa en återanvändningsbar avbildning. Basavbildningar ger oss dock mer kontroll över det slutliga bildinnehållet. Kom ihåg från tidigare att en bild är oföränderlig; du kan bara lägga till i en bild och inte subtrahera.

I Windows kan du bara skapa containeravbildningar som baseras på Windows-bascontaineravbildningar. Microsoft tillhandahåller och servar dessa Windows-bascontaineravbildningar.

Vad är en Dockerfile?

En Dockerfile är en textfil som innehåller de instruktioner vi använder för att skapa och köra en Docker-avbildning. Den definierar följande aspekter av bilden:

  • Den basavbildning eller överordnade avbildning som vi använder för att skapa den nya avbildningen
  • Kommandon för att uppdatera basoperativsystemet och installera ytterligare programvara
  • Byggartefakter som ska inkluderas, till exempel ett utvecklat program
  • Tjänster som ska exponeras, till exempel lagring och nätverkskonfiguration
  • Det kommando som ska köras när containern startas

Nu ska vi mappa dessa aspekter till ett Dockerfile-exempel. Anta att vi skapar en Docker-avbildning för vår ASP.NET Core-webbplats. Dockerfile kan se ut som i följande exempel:

# Step 1: Specify the parent image for the new image
FROM ubuntu:18.04

# Step 2: Update OS packages and install additional software
RUN apt -y update &&  apt install -y wget nginx software-properties-common apt-transport-https \
	&& wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
	&& dpkg -i packages-microsoft-prod.deb \
	&& add-apt-repository universe \
	&& apt -y update \
	&& apt install -y dotnet-sdk-3.0

# Step 3: Configure Nginx environment
CMD service nginx start

# Step 4: Configure Nginx environment
COPY ./default /etc/nginx/sites-available/default

# STEP 5: Configure work directory
WORKDIR /app

# STEP 6: Copy website code to container
COPY ./website/. .

# STEP 7: Configure network requirements
EXPOSE 80:8080

# STEP 8: Define the entry point of the process that runs in the container
ENTRYPOINT ["dotnet", "website.dll"]

Vi kommer inte att ta upp Dockerfile-filspecifikationen här, eller detaljinformationen för varje kommando i föregående exempel. Observera dock att det finns flera kommandon i den här filen som gör att vi kan ändra bildstrukturen. Kommandot kopierar till exempel COPY innehållet från en specifik mapp på den lokala datorn till containeravbildningen som vi skapar.

Vi nämnde tidigare att Docker-avbildningar unionfsanvänder . Vart och ett av dessa steg skapar en cachelagrad containeravbildning när vi skapar den slutliga containeravbildningen. De här tillfälliga bilderna läggs ovanpå föregående bild och visas som en enda bild när alla steg har slutförts.

Observera slutligen det sista steget, steg 8. ENTRYPOINT i filen anger vilken process som ska köras när vi kör en container från en avbildning. Om det inte finns någon ENTRYPOINT eller någon annan process som ska köras tolkar Docker det som att det inte finns något för containern att göra, och containern avslutas.

Så här hanterar du Docker-avbildningar

Docker-avbildningar är stora filer som ursprungligen lagras på datorn, och vi behöver verktyg för att hantera dessa filer.

Med Docker CLI och Docker Desktop kan vi hantera avbildningar genom att skapa, lista, ta bort och köra dem. Vi hanterar Docker-avbildningar med hjälp av docker-klienten. Klienten kör inte kommandona direkt och skickar alla frågor till daemonen dockerd .

Vi går inte igenom alla klientkommandon och kommandoflaggor här, men vi ska titta på några av de mest använda kommandona. Avsnittet Läs mer i den här modulens sammanfattningsenhet innehåller länkar till Docker-dokumentationen, som beskriver alla kommandon och kommandoflaggor i detalj.

Så här skapar du en avbildning

Vi använder kommandot docker build för att bygga Docker-avbildningar. Vi antar att vi använder Dockerfile-definitionen från tidigare för att bygga en avbildning. Här är ett exempel som visar build-kommandot:

docker build -t temp-ubuntu .

Här är utdata som byggkommandot genererar:

Sending build context to Docker daemon  4.69MB
Step 1/8 : FROM ubuntu:18.04
 ---> a2a15febcdf3
Step 2/8 : RUN apt -y update && apt install -y wget nginx software-properties-common apt-transport-https && wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && dpkg -i packages-microsoft-prod.deb && add-apt-repository universe && apt -y update && apt install -y dotnet-sdk-3.0
 ---> Using cache
 ---> feb452bac55a
Step 3/8 : CMD service nginx start
 ---> Using cache
 ---> ce3fd40bd13c
Step 4/8 : COPY ./default /etc/nginx/sites-available/default
 ---> 97ff0c042b03
Step 5/8 : WORKDIR /app
 ---> Running in 883f8dc5dcce
Removing intermediate container 883f8dc5dcce
 ---> 6e36758d40b1
Step 6/8 : COPY ./website/. .
 ---> bfe84cc406a4
Step 7/8 : EXPOSE 80:8080
 ---> Running in b611a87425f2
Removing intermediate container b611a87425f2
 ---> 209b54a9567f
Step 8/8 : ENTRYPOINT ["dotnet", "website.dll"]
 ---> Running in ea2efbc6c375
Removing intermediate container ea2efbc6c375
 ---> f982892ea056
Successfully built f982892ea056
Successfully tagged temp-ubuntu:latest

Oroa dig inte om du inte förstår föregående utdata. Observera dock de steg som anges i utdata. När varje steg körs läggs ett nytt lager till i den avbildning som skapas.

Observera även att vi kör ett antal kommandon för att installera programvara och hantera konfiguration. Till exempel kör vi i steg 2 kommandona apt -y update och apt install -y för att uppdatera operativsystemet. Dessa kommandon körs i en container som körs som skapats för det steget. När kommandot körs tas den mellanliggande containern bort. Den underliggande cachelagrade avbildningen bevaras på byggvärden och tas inte bort automatiskt. Den här optimeringen säkerställer att senare versioner återanvänder avbildningarna för att påskynda byggtiderna.

Vad är en avbildningstagg?

En bildtagg är en textsträng som används för att versionshanteras av en bild.

Observera det senaste versionsmeddelandet i exempelversionen från tidigare, där det står ”Successfully tagged temp-ubuntu: latest” (temp-ubuntu: latest har taggats). Vid skapandet av en avbildning namnger vi och taggar eventuellt avbildningen med hjälp av kommandoflaggan -t. I vårt exempel namngav vi avbildningen med hjälp av -t temp-ubuntu, medan det resulterande avbildningsnamnet taggades till temp-ubuntu: latest. En avbildning märks med taggen latest om du inte anger en tagg.

En enda avbildning kan ha flera taggar tilldelade till sig. Enligt konventionen tilldelas den senaste versionen av en avbildning taggen latest (senaste) samt en tagg som beskriver avbildningens versionsnummer. När du släpper en ny version av en avbildning kan du tilldela den taggen senaste för att referera till den nya avbildningen.

För Windows tillhandahåller Microsoft inte grundläggande containeravbildningar med den senaste taggen. För Windows-bascontaineravbildningar måste du ange en tagg som du vill använda. Till exempel är mcr.microsoft.com/windows/servercoreWindows-bascontaineravbildningen för Server Core . Bland taggarna finns ltsc2016, ltsc2019och ltsc2022.

Här är ett annat exempel. Anta att du vill använda Docker-avbildningarna av .NET Core-exempel. Här har vi fyra plattformar som vi kan välja mellan:

  • mcr.microsoft.com/dotnet/core/samples:dotnetapp

  • mcr.microsoft.com/dotnet/core/samples:aspnetapp

  • mcr.microsoft.com/dotnet/core/samples:wcfservice

  • mcr.microsoft.com/dotnet/core/samples:wcfclient

I den föregående bildlistan kan vi se att Microsoft tillhandahåller flera exempel på .NET Core. Taggar anger till vilka exempel bilden refererar till: ASP.NET, WCF-tjänsten och så vidare.

Så här visar du avbildningar

Docker-programvaran konfigurerar automatiskt ett lokalt avbildningsregister på datorn. Du kan visa avbildningarna i det här registret med kommandot docker images.

docker images

Utdata ser ut som i följande exempel:

REPOSITORY          TAG                     IMAGE ID            CREATED                     SIZE
tmp-ubuntu          latest             f89469694960        14 minutes ago         1.69GB
tmp-ubuntu          version-1.0        f89469694960        14 minutes ago         1.69GB
ubuntu              18.04                   a2a15febcdf3        5 weeks ago            64.2MB

Observera att avbildningen visas med Name (Namn), Tag (Tagg) och ett Image ID (Bild-ID). Det går som sagt att tillämpa flera etiketter på en avbildning. Föregående utdata visar ett exempel; Även om avbildningsnamnen skiljer sig åt kan vi se att ID:na är desamma.

Avbildnings-ID är ett bra sätt att identifiera och hantera avbildningar där namnen eller taggarna kan vara tvetydiga.

Så här tar du bort en avbildning

Du kan ta bort en avbildning från det lokala Docker-registret med kommandot docker rmi. Det här är användbart om du behöver spara utrymme på containervärddisken, eftersom containeravbildningsskikten ökar det totala tillgängliga utrymmet.

Ange namnet eller ID för den avbildning som ska tas bort. Det här exemplet tar bort avbildningen för exempelwebbappen med hjälp av avbildningens namn:

docker rmi temp-ubuntu:version-1.0

Du kan inte ta bort en avbildning om en container fortfarande använder avbildningen. Kommandot docker rmi returnerar ett felmeddelande som visar den container som är beroende av avbildningen.

Vi har utforskat grunderna i Docker-avbildningar, hur du hanterar dessa avbildningar och hur du kör en container från en avbildning. Härnäst ska vi titta på hur du hanterar containrar.

Kontrollera dina kunskaper

1.

Docker Desktop är en app för att skapa och dela containerbaserade appar och mikrotjänster. På vilka av följande operativsystem är den tillgänglig?

2.

Vilket är rätt Docker-kommando för att återskapa en containeravbildning?

3.

Vilken av följande meningar beskriver en containeravbildning på bästa sätt?