
Hei, Habr! Jeg presenterer for deg oversettelsen av artikkelen forfatter .
I dag skal vi snakke om hvordan Docker bruker diskplassen på vertsmaskinen, samt hvordan vi kan frigjøre denne plassen fra rester av ubrukte bilder og containere.

Totalt forbruk
Docker er en fantastisk teknologi, og det er det sikkert få som tviler på i dag. For bare noen år siden ga dette produktet oss en helt ny måte å bygge, levere og kjøre ethvert miljø på, noe som betydelig reduserte bruken av prosessor og minne. I tillegg til dette (og for mange vil dette være det mest viktige) har Docker gjort det utrolig enkelt å standardisere og forenkle styringen av livssyklusen til de brukte arbeidsmiljøene.
Men for alt det gode i dagens liv må vi betale. Når vi kjører containere, laster ned eller lager egne bilder, og setter opp komplekse økosystemer, må vi betale. Og vi betaler, delvis med diskplass.
Hvis du aldri har tenkt over hvor mye plass Docker faktisk tar opp på maskinen din, kan du bli ubehagelig overrasket over utfallet av denne kommandoen:
$ docker system df 
Her vises diskbruken av Docker i forskjellige kategorier:
- bilder (images) – total størrelse av bilder som er lastet ned fra bilde-lager og bygget i systemet ditt;
- containere (containers) – totalt volum diskplass brukt av kjørende containere (dette refererer til det totale volumet av skrive-lese lagene for alle containere);
- lokale volumer (local volumes) – volumet av lokale lagringsenheter som er montert til containere;
- bygg-cache (build cache) – midlertidige filer generert av byggeprosessen for bilder (når du bruker verktøyet BuildKit, tilgjengelig fra Docker versjon 18.09).
Jeg vil anta at etter denne enkle gjennomgangen, brenner du etter å rydde disken for søppel og gjenvinne dyrebare gigabyte (husk: spesielt hvis du betaler leie for disse gigabyte hver måned).
Diskbruk av containere
Hver gang du oppretter en container på vertsmaskinen, opprettes det flere filer og kataloger i katalogen /var/lib/docker, blant annet vil vi merke oss følgende:
- Katalogen /var/lib/docker/containers/ID_kontejneren – ved bruk av standard loggdrev lagres hendelsesloggene her i JSON-format. For detaljerte logger og logger som ingen leser eller behandler på andre måter, er det ofte grunnen til at diskene fylles opp.
- Katalogen /var/lib/docker/overlay2 – inneholder skrive-laglagene til containerne (overlay2 – den foretrukne drivermodellen i de fleste Linux-distribusjoner). Hvis en container lagrer data i filsystemet sitt, vil de plasseres i denne katalogen.
La oss forestille oss et system med en helt ren Docker-installasjon, som aldri har vært involvert i å kjøre containere eller bygge bilder. Det vil se slik ut når det gjelder diskplassbruk:
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BLa oss starte en container, for eksempel NGINX:
$ docker container run --name www -d -p 8000:80 nginx:1.16Hva skjer med disken:
- bilder (images) tar 126 MB, det er nettopp den NGINX som vi har kjørt i containeren;
- containere (containers) tar latterlige 2 byte.
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 1 2B 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BIfølge utskriften har vi fortsatt ikke noe rom å frigjøre. Siden 2 byte er helt ubetydelig, la oss anta at vår NGINX uventet skrev 100 megabyte med data og opprettet en fil test.img av akkurat den størrelsen.
$ docker exec -ti www
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]La oss undersøke diskplassbruken på verten på nytt. Vi vil se at containeren (containers) tar 100 megabyte der.
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 1 104.9MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BJeg tror tankene dine allerede spør hvor filen test.img befinner seg. La oss lete etter den:
$ find /var/lib/docker -type f -name test.img
/var/lib/docker/overlay2/83f177...630078/merged/test.img
/var/lib/docker/overlay2/83f177...630078/diff/test.imgUten å gå inn på detaljer kan vi merke oss at filen test.img ligger praktisk plassert på leseskrive-nivå, styrt av overlay2-driveren. Hvis vi stopper beholderen vår, vil verten indikere at dette stedet i prinsippet kan frigjøres:
# Stopping the www container
$ docker stop www
# Visualizing the impact on the disk usage
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 0 104.9MB 104.9MB (100%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BHvordan kan vi gjøre dette? Ved å slette beholderen, noe som vil føre til at det tilsvarende området på leseskrive-nivå blir ryddet.
Med følgende kommando kan du slette alle installerte beholdere i ett sveip og frigjøre disken din fra alle filene de har opprettet på leseskrive-nivå:
$ docker container prune
ADVARSEL! Dette vil fjerne alle stoppede beholdere.
Er du sikker på at du vil fortsette? [y/N] y
Slettede beholdere:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2
Totalt frigjort plass: 104,9MBSå, vi har frigjort 104,9 Megabyte ved å slette beholderen. Men siden vi ikke lenger bruker det nedlastede bildet, blir det også en kandidat for sletting og frigjøring av ressursene våre:
$ docker system df
TYPE TOTAL AKTIV STØRRELSE FRIGJORT
Bilder 1 0 126M 126M (100%)
Beholdere 0 0 0B 0B
Lokal Volumer 0 0 0B 0B
Bygg Cache 0 0 0B 0BMerk: så lenge bildet brukes av minst én beholder, kan du ikke bruke dette trikset.
Subkommandoen prune, som vi brukte ovenfor, har kun effekt på stoppede beholdere. Hvis vi ønsker å slette både stoppede og kjørende beholdere, bør vi bruke en av disse kommandoene:
# Historical command
$ docker rm -f $(docker ps –aq)
# More recent command
$ docker container rm -f $(docker container ls -aq)Merk: hvis du bruker parameteren —rm når du starter beholderen, vil alt diskplass som den opptok bli frigjort når den stoppes.
Bruk av diskplass av bilder
For noen år siden var størrelsen på et bilde på flere hundre megabyte helt normalt: Ubuntu-bildet veide 600 Megabyte, mens Microsoft .Net-bildet var flere Gigabyte. I de gamle dagene kunne nedlasting av ett eneste bilde forårsake stor skade på den ledige plasseringen på disken, selv om du delte nivåene mellom bildene. I dag – takk og pris – veier bildene mye mindre, men selv i dette tilfellet kan du raskt fylle opp de tilgjengelige ressursene hvis du ikke tar noen forholdsregler.
Det finnes flere typer bilder som ikke er direkte synlige for sluttbrukeren:
- intermediate bilder som andre bilder er basert på – de kan ikke slettes hvis du bruker containere basert på disse «andre» bildene;
- dangling bilder – er intermediate bilder som ikke refereres av noen kjørende containere – de kan slettes.
- Ved å bruke følgende kommando kan du sjekke om det finnes dangling bilder i systemet ditt:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
none none 21e658fe5351 12 minutes ago 71.3MBDe kan slettes på følgende måte:
$ docker image rm $(docker image ls -f dangling=true -q)Vi kan også bruke subkommandoen prune:
$ docker image prune
WARNING! Dette vil fjerne alle dangling bilder.
Er du sikker på at du vil fortsette? [y/N] y
Slettede bilder:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f
Totalt gjenvunnet plass: 12.9kBHvis vi plutselig ønsker å fjerne alle bilder (og ikke bare dangling) med én kommando, kan vi gjøre det slik:
$ docker image rm $(docker image ls -q)Bruk av disk med volumer
Volumer brukes for å lagre data utenfor containernes filsystem. For eksempel, hvis vi ønsker å lagre resultatene fra en applikasjon for å bruke dem på nytt senere. Et vanlig eksempel er databaser.
La oss starte en MongoDB-container, montere et volum som er eksternt i forhold til containeren, og gjenopprette en databasebackup fra en fil (bck.json):
# Running a mongo container
$ docker run --name db -v $PWD:/tmp -p 27017:27017 -d mongo:4.0
# Importing an existing backup (from a huge bck.json file)
$ docker exec -ti db mongoimport
--db 'test'
--collection 'demo'
--file /tmp/bck.json
--jsonArrayDataene vil befinne seg på vertsmaskinen i katalogen /var/lib/docker/volumes. Men hvorfor ikke på et lese-skrive-nivå i containeren? Fordi i Dockerfile for MongoDB-bildet er katalogen /data/db (hvor MongoDB som standard lagrer sine data) definert som et volum.

Notater: mange bilder som genererer data, bruker volumer for å lagre disse dataene.
Når vi er ferdige med MongoDB og stopper (eller kanskje til og med fjerner) containeren, vil ikke volumet bli slettet. Det vil fortsette å ta opp vårt dyrebare diskplass inntil vi eksplisitt sletter det med følgende kommando:
$ docker volume rm $(docker volume ls -q)Eller vi kan bruke den allerede kjente subkommandoen prune:
$ docker volume prune
WARNING! Dette vil fjerne alle lokale volumer som ikke brukes av minst én container.
Er du sikker på at du vil fortsette? [y/N] y
Slettede volumer:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da
Total tilbakekalt plass: 25.82GB
luc@saturn:~$Diskbruken for cache av bildesamlinger
I Docker 18.09 har prosessen for å opprette bilder gjennomgått noen endringer takket være verktøyet BuildKit. Med dette verktøyet økes hastigheten på prosessen, og datahåndtering og sikkerhet optimaliseres. Her vil vi ikke gå inn på alle detaljene rundt dette fantastiske verktøyet, men vil fokusere på hvordan det berører diskplassbruk.
Anta at vi har en helt enkel Node.Js-applikasjon:
- filen index.js kjører en enkel HTTP-server, som svarer med en streng på hver mottatt forespørsel:
- filen package.json definerer avhengighetene, hvor bare expressjs brukes for å kjøre HTTP-serveren:
$ cat index.js
var express = require('express');
var util = require('util');
var app = express();
app.get('/', function(req, res) {
res.setHeader('Content-Type', 'text/plain');
res.end(util.format("%s - %s", new Date(), 'Got Request'));
});
app.listen(process.env.PORT || 80);$ cat package.json
{
"name": "testnode",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.14.0"
}
}Dockerfile for å bygge bildet ser slik ut:
FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]La oss bygge bildet på vanlig måte, uten å bruke BuildKit:
$ docker build -t app:1.0 .Hvis vi sjekker diskplassbruken, vil vi se at plassen kun brukes av basen (node:13-alpine) og sluttbildet (app:1.0):
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 0 109.3MB 109.3MB (100%)
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BLa oss bygge den andre versjonen av applikasjonen vår, allerede med bruk av BuildKit. For dette må vi bare sette variabelen DOCKER_BUILDKIT til 1:
$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .Hvis vi nå sjekker diskbruken, vil vi se at nå deltar byggcache (build-cache):
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 0 109.3MB 109.3MB (100%)
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 11 0 8.949kB 8.949kBFor å rydde opp, bruker vi følgende kommando:
$ docker builder prune
WARNING! This will remove all dangling build cache.
Are you sure you want to continue? [y/N] y
Deleted build cache objects:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi
Total reclaimed space: 8.949kBRydd opp alt!
Så, vi har sett på hvordan vi rydder opp diskplass som brukes av containere, bilder og volumer. Dette er hjelpt av subkommandoen prune. Men den kan også brukes på systemnivå i Docker, og den vil rydde opp alt den kan:
$ docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N]Hvis du av en eller annen grunn sparer diskplass på en maskin med Docker, er det en god vane å kjøre denne kommandoen jevnlig.
Kilde: habr.com
