Docker-tip: Ryd din maskine for skrammel

Docker-tip: Ryd din maskine for skrammel

Hej Habr! Jeg præsenterer for din opmærksomhed oversættelsen af ​​artiklen "Docker-tip: Ryd op i din lokale maskine" forfatter Luc Juggery.

I dag vil vi tale om, hvordan Docker bruger diskpladsen på værtsmaskinen, og vi vil også finde ud af, hvordan man frigør denne plads fra stumper af ubrugte billeder og containere.


Docker-tip: Ryd din maskine for skrammel

Samlede forbrug

Docker er en fed ting, nok de færreste tvivler på det i dag. For blot et par år siden gav dette produkt os en helt ny måde at bygge, levere og køre ethvert miljø på, hvilket gav os mulighed for betydeligt at spare CPU- og RAM-ressourcer. Ud over dette (og for nogle vil dette være det vigtigste) har Docker givet os mulighed for utroligt at forenkle og ensrette livscyklusstyringen af ​​vores produktionsmiljøer.

Men alle disse lækkerier i det moderne liv har en pris. Når vi kører containere, downloader eller skaber vores egne billeder og implementerer komplekse økosystemer, skal vi betale. 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 outputtet af denne kommando:

$ docker system df

Docker-tip: Ryd din maskine for skrammel

Dette viser Dockers diskbrug i forskellige sammenhænge:

  • billeder – den samlede størrelse af billeder, der blev downloadet fra billedarkiver og bygget på dit system;
  • containere – den samlede mængde diskplads, der bruges af kørende containere (hvilket betyder det samlede volumen af ​​læse-skrive-lag for alle containere);
  • lokale volumener - mængden af ​​lokalt lager monteret på containere;
  • build cache – midlertidige filer genereret af billedopbygningsprocessen (ved hjælp af BuildKit-værktøjet, tilgængeligt fra Docker version 18.09).

Jeg vil vædde på, at du efter denne simple overførsel er ivrig efter at rense din disk for skrald og bringe dyrebare gigabyte til live igen (bemærk: især hvis du betaler husleje for disse gigabyte hver måned).

Diskbrug af containere

Hver gang du opretter en container på værtsmaskinen, oprettes flere filer og mapper i mappen /var/lib/docker, blandt hvilke følgende er værd at bemærke:

  • Katalog /var/lib/docker/containers/container_ID – når du bruger standardlogningsdriveren, er det her hændelseslogfiler gemmes i JSON-format. For detaljerede logfiler, samt logfiler, som ingen læser eller på anden måde behandler, får ofte diske til at blive fulde.
  • Mappen /var/lib/docker/overlay2 indeholder containerens læse-skrive-lag (overlay2 er den foretrukne driver i de fleste Linux-distributioner). Hvis containeren gemmer data i sit filsystem, er det i denne mappe, den vil blive placeret.

Lad os forestille os et system, hvorpå en uberørt Docker er installeret, som aldrig har været involveret i at opsende containere eller bygge billeder. Rapporten om brug af diskplads vil se sådan 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 starte en container, for eksempel NGINX:

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

Hvad sker der med disken:

  • billeder optager 126 MB, dette er den samme NGINX, som vi lancerede i containeren;
  • containere fylder latterlige 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

Efter konklusionen at dømme har vi endnu ikke plads, som vi kunne frigøre. Da 2 bytes er fuldstændig useriøst, lad os forestille os, at vores NGINX uventet skrev et eller andet sted 100 megabytes data og skabte en fil test.img af præcis denne størrelse inde i sig selv.

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

Lad os undersøge diskpladsforbruget på værten igen. Vi vil se, at containeren (containerne) fylder 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         0B

Jeg tror, ​​at din nysgerrige hjerne allerede spekulerer på, hvor vores test.img-fil er placeret. Lad os kigge efter det:

$ 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å i detaljer kan vi bemærke, at test.img-filen er bekvemt placeret på læse-skriveniveauet, styret af overlay2-driveren. Hvis vi stopper vores container, vil værten fortælle os, at denne plads i princippet kan frigø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         0B

Hvordan kan vi gøre dette? Ved at slette containeren, hvilket vil indebære, at den tilsvarende plads ryddes på læse-skriveniveau.

Med følgende kommando kan du fjerne alle installerede containere i ét hug og rydde din disk for alle læse-skrive-filer oprettet af dem:

$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Total reclaimed space: 104.9MB

Så vi frigjorde 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 slette og frigøre vores ressourcer:

$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          0          126M       126M (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B

Bemærk: Så længe billedet er i brug af mindst én beholder, vil du ikke kunne bruge dette trick.

Den sveske-underkommando, vi brugte ovenfor, har kun en effekt på stoppede beholdere. Hvis vi vil slette 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)

Sidebemærkninger: Hvis du bruger parameteren -rm, når du starter en container, vil al den diskplads, den optog, blive frigivet, når den stopper.

Brug af diskbilleder

For nogle år siden var en billedstørrelse på flere hundrede megabyte helt normal: Et Ubuntu-billede vejede 600 megabyte, og et Microsoft .Net-billede vejede flere gigabyte. I disse shaggy dage kunne download af kun ét billede tage en stor afgift på din ledige diskplads, selvom du delte niveauer mellem billeder. I dag vejer billeder meget mindre - priset være de store - men alligevel kan du hurtigt fylde de tilgængelige ressourcer op, hvis du ikke tager nogle forholdsregler.

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

  • mellembilleder, på grundlag af hvilke andre billeder indsamles - de kan ikke slettes, hvis du bruger containere baseret på disse "andre" billeder;
  • dinglende billeder er mellembilleder, der ikke refereres af nogen af ​​de kørende containere - de kan slettes.
  • Med følgende kommando kan du tjekke for hængende billeder på dit system:

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

Du kan fjerne dem på følgende måde:

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

Vi kan også bruge prune-underkommandoen:

$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f

Total reclaimed space: 12.9kB

Hvis vi pludselig vil slette alle billeder helt (og ikke bare dinglende) med én kommando, så kan vi gøre dette:

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

Diskbrug efter mængder

Volumen bruges til at gemme data uden for containerens filsystem. For eksempel hvis vi vil gemme resultaterne af en applikation for at kunne bruge dem på anden måde. Et almindeligt eksempel er databaser.

Lad os starte en MongoDB-container, montere en volumen eksternt i forhold til containeren og gendanne en database-backup 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 mappen /var/lib/docker/volumes. Men hvorfor ikke på containerens læse-skriveniveau? Fordi i Dockerfilen af ​​MongoDB-billedet er /data/db-mappen (hvor MongoDB gemmer sine data som standard) defineret som en volumen.

Docker-tip: Ryd din maskine for skrammel

Sidebemærkning: mange billeder, der skal producere data, bruger mængder til at gemme disse data.

Når vi spiller nok med MongoDB og stopper (eller måske endda sletter) containeren, slettes volumen ikke. Det vil fortsætte med at optage vores dyrebare diskplads, indtil vi eksplicit sletter det med en kommando som denne:

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

Nå, eller vi kan bruge prune-underkommandoen, der allerede er kendt for os:

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Total reclaimed space: 25.82GB
luc@saturn:~$

Bruger disk til image build cache

I Docker 18.09 har billedoprettelsesprocessen undergået nogle ændringer takket være BuildKit-værktøjet. Denne ting øger processens hastighed og optimerer datalagring og sikkerhedsstyring. Her vil vi ikke overveje alle detaljerne i dette vidunderlige værktøj; vi vil kun fokusere på, hvordan det løser problemer med diskpladsbrug.

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

  • index.js-filen starter en simpel HTTP-server, der svarer med en linje på hver modtaget anmodning:
  • 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"
      }
    }

Dockerfilen til at bygge billedet ser sådan 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 tjekker diskpladsforbruget, kan vi se, at kun basisbilledet (node:13-alpine) og målbilledet (app:1.0) optager plads:

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

Lad os bygge den anden version af vores applikation ved hjælp af BuildKit. For at gøre dette skal vi blot indstille DOCKER_BUILDKIT-variablen til 1:

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

Hvis vi nu tjekker diskbrugen, vil vi se, at build-cachen (buid-cache) nu er involveret der:

$ 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 det, brug 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.949kB

Slet alt!

Så vi så på at rydde op på diskplads optaget af containere, billeder og volumener. Sveske-underkommandoen hjælper os med dette. Men det kan også bruges på docker-systemniveau, og det vil rydde op i alt, hvad det 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 af en eller anden grund sparer diskplads på en maskine, der kører Docker, bør det blive en vane at køre denne kommando med jævne mellemrum.

Kilde: www.habr.com

Tilføj en kommentar