Docker Tips: Ryd din maskine for rod

Docker Tips: Ryd din maskine for rod

Hej, Habr! Jeg præsenterer for jer oversættelsen af artiklen "Docker Tips: Ryd op på din lokale maskine" forfatter til Luc Juggery.

I dag vil vi tale om, hvordan Docker bruger diskpladsen på værtsmaskinen, samt hvordan vi kan frigøre denne plads fra rester af ubrugte billeder og containere.


Docker Tips: Ryd din maskine for rod

Total forbrug

Docker er fantastisk, det er der nok ikke mange, der er i tvivl om i dag. For kun få år siden gav dette produkt os en helt ny måde at bygge, levere og køre ethvert miljø på, hvilket markant reducerede ressourceforbruget til CPU og hukommelse. Derudover (og for nogen vil dette være det vigtigste) har Docker gjort det utrolig nemt og ensartet at administrere livscyklussen for de anvendte arbejdsomgivelser.

Men for alle disse glæder i det moderne liv skal man betale. Når vi kører containere, downloader eller opretter egne billeder, ruller vi komplekse økosystemer ud, så betaler vi. Og vi betaler, blandt andet, med diskplads.

Hvis du aldrig har tænkt over, hvor meget plads Docker faktisk optager på din maskine, kan du blive ubehageligt overrasket over resultatet af denne kommando:

$ docker system df

Docker Tips: Ryd din maskine for rod

Her vises diskbrugen af Docker på forskellige måder:

  • billeder (images) – den samlede størrelse på billeder, der er downloadet fra billeddepoter og bygget på dit system;
  • containere (containers) – den samlede mængde diskplads, der bruges af kørende containere (det samlede volumen af alle skrive-læs lag for alle containere);
  • lokale volumener (local volumes) – mængden af lokale lagre, der er monteret til containere;
  • byg-cache (build cache) – midlertidige filer genereret af processen til at opbygge billeder (ved brug af BuildKit-værktøjet, som har været tilgængeligt siden Docker version 18.09).

Jeg vil væde med, at selv efter denne enkle opregning, brænder du efter at rydde disken for skrald og få de dyrebare gigabyte tilbage (note til oversætteren: især, hvis du betaler husleje for disse gigabytes hver måned).

Diskforbruget for containere

Hver gang en container oprettes på værtens maskine, oprettes flere filer og mapper i katalogen /var/lib/docker, blandt hvilke de følgende er værd at bemærke:

  • Katalogen /var/lib/docker/containers/ID_container – når den standard logdriver bruges, gemmes loggene for hændelser her i JSON-format. For detaljerede logs, samt logs som ingen læser eller behandler på andre måder, bliver ofte årsagen til diskplads overskud.
  • Katalogen /var/lib/docker/overlay2 – indeholder containerens læse-skrive-lag (overlay2 – den foretrukne driver i de fleste Linux-distributioner). Hvis containeren gemmer data i sit filsystem, vil de blive placeret i denne mappe.

Lad os forestille os et system, hvor Docker er installeret og aldrig har været involveret i lancering af containere eller opbygning af billeder. Dens rapport over diskpladsforbrug vil se sådan her ud:

$ 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         0B

Lad os køre en container, for eksempel NGINX:

$ docker container run --name www -d -p 8000:80 nginx:1.16

Hvad sker der med disken:

  • billeder (images) optager 126 MB, det er det NGINX, som vi kørte i containeren;
  • containere (containers) optager sjove 2 bytes.

$ 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         0B

Ifølge outputten har vi stadig ikke noget plads, som vi kan frigive. Da 2 bytes er helt ubetydeligt, lad os forestille os, at vores NGINX uventet har skrevet 100 megabytes data et sted og oprettet en fil test.img af netop den størrelse.

$ docker exec -ti www 
  dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]

Lad os undersøge brugen af diskplads på værten igen. Vi vil se, at containeren (containers) optager 100 megabytes 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         0B

Jeg tror, at din nysgerrige hjerne allerede spørger, hvor vores fil test.img er. Lad os lede efter 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.img

Uden at gå ind i detaljerne kan vi bemærke, at filen test.img bekvemt er placeret på det læse-skrive-niveau, der styres af overlay2-driveren. Hvis vi stopper vores container, vil værten indikere, at denne plads principielt kan frigives:

# 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         0B

Hvordan kan vi gøre det? Ved at slette containeren, hvilket vil medføre, at den relevante plads på læse-skrive-niveau ryddes.

Med følgende kommando kan du slette alle installerede containere i ét hug og rydde din disk for alle filer, de har oprettet på læse-skrive-niveau:

$ docker container prune
ADVARSEL! Dette vil fjerne alle stoppede containere.
Er du sikker på, at du vil fortsætte? [y/N] y
Slettede containere:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Total frigivet plads: 104,9MB

Så vi har frigivet 104,9 megabyte ved at slette containeren. Men da vi ikke længere bruger det tidligere downloadede billede, bliver det også en kandidat til at blive slettet og frigive vores ressourcer:

$ docker system df
TYPE           TOTAL      AKTIV     STØRRELSE   FRIGJORT
Billeder       1          0          126M       126M (100%)
Containere     0          0          0B         0B
Lokale volumner 0          0          0B         0B
Byggecache     0          0          0B         0B

Bemærk: Så længe billedet bruges af mindst én container, vil du ikke kunne bruge dette trick.

Subkommandoen prune, som vi brugte ovenfor, giver effekt kun på stoppede containere. Hvis vi ønsker at fjerne ikke kun stoppede, men også kørende containere, skal vi bruge en af disse kommandoer:

# Historical command
$ docker rm -f $(docker ps –aq)

# More recent command
$ docker container rm -f $(docker container ls -aq)

Note til selv: hvis du bruger parameteren --rm ved opstart af containeren, vil al diskplads, den optager, blive frigivet, når den stoppes.

Brugsplads for billeder

For flere år siden var størrelsen på et billede på flere hundrede megabyte helt normalt: Ubuntu-billedet vejede 600 megabyte, og Microsoft .Net-billedet vejede flere gigabyte. I de gamle dage kunne download af blot ét billede forvolde stor skade på din ledige diskplads, selvom du delte niveauer mellem billederne. I dag – takket være de store – vejer billederne meget mindre, men selv i dette tilfælde kan man hurtigt fylde sine ressourcer, hvis man ikke træffer visse foranstaltninger.

Der er flere typer billeder, der ikke direkte er synlige for slutbrugeren:

  • intermediate billeder, som er grundlaget for andre billeder – de kan ikke slettes, hvis du bruger containere baseret på disse "andre" billeder;
  • dangling billeder – det er sådanne intermediate billeder, som ikke refereres af nogen kørende containere – de kan slettes.
  • Med følgende kommando kan du kontrollere for dangling billeder i dit system:

$ docker image ls -f dangling=true
REPOSITORY  TAG      IMAGE ID         CREATED             SIZE
none      none   21e658fe5351     12 minutes ago      71.3MB

De kan slettes på følgende måde:

$ docker image rm $(docker image ls -f dangling=true -q)

Vi kan også bruge subkommandoen prune:

$ docker image prune
WARNING! Dette vil fjerne alle dangling billeder.
Er du sikker på, at du vil fortsætte? [y/N] y
Slettede billeder:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f

Total genvundet plads: 12.9kB

Hvis vi pludselig ønsker at slette alle billeder (og ikke kun dangling) med ét kommando, kan vi gøre sådan:

$ docker image rm $(docker image ls -q)

Brug af disk med volume

Volumes bruges til at gemme data uden for containerens filsystem. For eksempel, hvis vi ønsker at gemme resultaterne fra en applikation for at bruge dem et andet sted. Et almindeligt eksempel er databaser.

Lad os starte en MongoDB-container, montere et eksternt volume til den, og gendanne en databasebackup fra den (vi har den tilgængelig i filen 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 
  --jsonArray

Dataene vil være placeret på værtsmaskinen i kataloget /var/lib/docker/volumes. Men hvorfor ikke på skrive-læse-niveau i containeren? Fordi i Dockerfile for MongoDB-billedet er kataloget /data/db (hvor MongoDB som standard gemmer sine data) defineret som et volume.

Docker Tips: Ryd din maskine for rod

Noter: mange billeder, som skal generere data, bruger volumes til at gemme disse data.

Når vi er færdige med MongoDB og stopper (eller måske endda sletter) containeren, vil volumet ikke blive slettet. Det vil fortsætte med at optage vores værdifulde diskplads, indtil vi eksplicit sletter det med en sådan kommando:

$ docker volume rm $(docker volume ls -q)

Eller vi kan bruge den allerede kendte subkommando prune:

$ docker volume prune
ADVARSEL! Dette vil fjerne alle lokale volumener, der ikke bruges af mindst én container.
Er du sikker på, at du vil fortsætte? [y/N] y
Slettede volumener:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Samlet genvundet plads: 25,82 GB
luc@saturn:~$

Brug af disk til caching af billedbygning

I Docker 18.09 er processen til at oprette billeder blevet ændret en smule takket være værktøjet BuildKit. Dette værktøj øger hastigheden i processen og optimerer datasikkerheder og opbevaring. Her vil vi ikke dykke ind i alle detaljerne af dette fremragende værktøj, men kun se på, hvordan det påvirker brugen af diskplads.

Lad os antage, at vi har en helt simpel Node.Js-applikation:

  • filen index.js starter en simpel HTTP-server, som svarer med en tekststreng på hver anmodning, den modtager:
  • filen package.json definerer afhængighederne, hvoraf kun expressjs bruges til at kø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 til oprettelse af billedet ser således ud:

FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]

Lad os bygge billedet på den sædvanlige måde, uden at bruge BuildKit:

$ docker build -t app:1.0 .

Hvis vi kontrollerer brugen af diskplads, vil vi se, at der kun optages plads af det grundlæggende billede (node:13-alpine) og det endelige billede (app:1.0):

TYPE           TOTAL      ACTIVE     STØRRELSE   GENNEMFÅRBART
Billeder       2          0          109,3MB    109,3MB (100%)
Containere     0          0          0B         0B
Lokale volumener 0          0          0B         0B
Byggecache     0          0          0B         0B

Lad os bygge den anden version af vores applikation, nu med brug af BuildKit. Vi skal blot sætte variablen DOCKER_BUILDKIT til 1:

$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .

Hvis vi nu kontrollerer diskbrugen, vil vi se, at der nu er involveret et bygge-cache (buid-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.949kB

For at rydde op bruger vi følgende kommando:

$ docker builder prune
WARNING! Dette vil fjerne al dangling build cache.
Er du sikker på, at du vil fortsætte? [y/N] y
Slettede build cache objekter:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi

Total frigivet plads: 8.949kB

Ryd alt!

Vi har nu set på, hvordan man rydder diskpladsen der er optaget af containere, billeder og volumener. Dette hjælper os subkommandoen prune med. Men den kan også bruges på systemniveau for docker og vil rydde alt, hvad den kan:

$ docker system prune
WARNING! Dette vil fjerne:
  - alle stoppede containere
  - alle netværk, der ikke bruges af mindst én container
  - alle dangling billeder
  - al dangling build cache

Er du sikker på, at du vil fortsætte? [y/N]

Hvis du af en eller anden grund sparer diskplads på din maskine med Docker, så bør du få en vane med at køre denne kommando med jævne mellemrum.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster