Docker Tips: Rydd opp maskinen din for rot

Docker Tips: Rydd opp maskinen din for rot

Hei, Habr! Jeg presenterer for deg oversettelsen av artikkelen "Docker Tips: Ryd opp den lokale maskinen din" forfatter Luc Juggery.

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.


Docker Tips: Rydd opp maskinen din for rot

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

Docker Tips: Rydd opp maskinen din for rot

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

La oss starte en container, for eksempel NGINX:

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

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

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

Jeg 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.img

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

Hvordan 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,9MB

Så, 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         0B

Merk: 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.3MB

De 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.9kB

Hvis 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 
  --jsonArray

Dataene 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.

Docker Tips: Rydd opp maskinen din for rot

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

La 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.949kB

For å 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.949kB

Rydd 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

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster