Consells de Docker: esborreu la vostra màquina de brossa

Consells de Docker: esborreu la vostra màquina de brossa

Hola Habr! Presento a la vostra atenció la traducció de l'article "Consells de Docker: netegeu la vostra màquina local" l'autor Luc Juggery.

Avui parlarem de com Docker utilitza l'espai en disc de la màquina amfitrió i també descobrirem com alliberar aquest espai dels fragments d'imatges i contenidors no utilitzats.


Consells de Docker: esborreu la vostra màquina de brossa

Consum total

Docker és una cosa genial, probablement poca gent ho dubta avui. Fa només uns anys, aquest producte ens va oferir una manera completament nova de crear, oferir i executar qualsevol entorn, cosa que ens va permetre estalviar de manera significativa els recursos de CPU i RAM. A més d'això (i per a alguns això serà el més important) Docker ens ha permès simplificar i unificar increïblement la gestió del cicle de vida dels nostres entorns de producció.

Tanmateix, totes aquestes delícies de la vida moderna tenen un preu. Quan executem contenidors, descarreguem o creem les nostres pròpies imatges i despleguem ecosistemes complexos, hem de pagar. I paguem, entre altres coses, amb espai en disc.

Si mai no heu pensat en quant espai ocupa realment Docker a la vostra màquina, és possible que us sorprengui desagradablement la sortida d'aquesta ordre:

$ docker system df

Consells de Docker: esborreu la vostra màquina de brossa

Això mostra l'ús del disc de Docker en diferents contextos:

  • imatges: la mida total de les imatges que s'han baixat dels dipòsits d'imatges i es van crear al vostre sistema;
  • contenidors: la quantitat total d'espai de disc utilitzat pels contenidors en execució (és a dir, el volum total de capes de lectura i escriptura de tots els contenidors);
  • volums locals: el volum d'emmagatzematge local muntat als contenidors;
  • build cache: fitxers temporals generats pel procés de creació d'imatges (utilitzant l'eina BuildKit, disponible a partir de la versió 18.09 de Docker).

Aposto que després d'aquesta senzilla transferència esteu desitjant netejar el vostre disc d'escombraries i tornar a la vida preciosos gigabytes (nota: sobretot si pagueu el lloguer per aquests gigabytes cada mes).

Ús del disc per contenidors

Cada vegada que creeu un contenidor a la màquina host, es creen diversos fitxers i directoris al directori /var/lib/docker, entre els quals cal destacar els següents:

  • Directori /var/lib/docker/containers/container_ID: quan s'utilitza el controlador de registre estàndard, aquí és on es guarden els registres d'esdeveniments en format JSON. Els registres massa detallats, així com els registres que ningú llegeix o processa d'una altra manera, sovint fan que els discs s'omplin.
  • El directori /var/lib/docker/overlay2 conté les capes de lectura i escriptura del contenidor (overlay2 és el controlador preferit a la majoria de distribucions de Linux). Si el contenidor emmagatzema dades al seu sistema de fitxers, és en aquest directori on es col·locarà.

Imaginem un sistema en el qual s'instal·la un Docker prístina, que mai no ha participat en el llançament de contenidors o la construcció d'imatges. El seu informe d'ús d'espai en disc tindrà aquest aspecte:

$ 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

Llancem algun contenidor, per exemple, NGINX:

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

Què passa amb el disc:

  • les imatges ocupen 126 MB, aquest és el mateix NGINX que vam llançar al contenidor;
  • els contenidors ocupen 2 bytes ridículs.

$ 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

A jutjar per la conclusió, encara no tenim cap espai que puguem alliberar. Com que 2 bytes és completament frívol, imaginem que el nostre NGINX va escriure inesperadament en algun lloc 100 megabytes de dades i va crear un fitxer test.img d'aquesta mida exactament dins de si mateix.

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

Examinem de nou l'ús d'espai de disc a l'amfitrió. Veurem que el contenidor (contenidors) hi ocupa 100 Megabytes.

$ 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

Crec que el teu cervell curiós ja es pregunta on es troba el nostre fitxer test.img. Anem a buscar-ho:

$ 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

Sense entrar en detalls, podem observar que el fitxer test.img es troba convenientment al nivell de lectura-escriptura, controlat pel controlador overlay2. Si aturem el nostre contenidor, l'amfitrió ens dirà que aquest espai, en principi, es pot alliberar:

# 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

Com podem fer això? Esborrant el contenidor, la qual cosa implicarà esborrar l'espai corresponent a nivell de lectura-escriptura.

Amb l'ordre següent, podeu eliminar tots els contenidors instal·lats d'un sol cop i esborrar el vostre disc de tots els fitxers de lectura i escriptura creats per ells:

$ 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

Per tant, vam alliberar 104,9 megabytes suprimint el contenidor. Però com que ja no fem servir la imatge descarregada anteriorment, també esdevé candidata per esborrar i alliberar els nostres recursos:

$ 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

Nota: mentre la imatge estigui utilitzada per almenys un contenidor, no podreu utilitzar aquest truc.

La subordre prune que hem utilitzat anteriorment només té un efecte en els contenidors aturats. Si volem suprimir no només els contenidors aturats sinó també en execució, hauríem d'utilitzar una d'aquestes ordres:

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

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

Notes al marge: si utilitzeu el paràmetre -rm quan inicieu un contenidor, quan s'aturi, s'alliberarà tot l'espai de disc que ocupava.

Ús d'imatges de disc

Fa uns anys, una mida d'imatge de diversos centenars de megabytes era completament normal: una imatge d'Ubuntu pesava 600 megabytes, i una imatge de Microsoft .Net pesava diversos gigabytes. En aquells dies de mal humor, baixar només una imatge podria suposar un gran peatge a l'espai lliure del vostre disc, fins i tot si compartiu nivells entre imatges. Avui, elogis als grans, les imatges pesen molt menys, però tot i així, podeu omplir ràpidament els recursos disponibles si no preneu algunes precaucions.

Hi ha diversos tipus d'imatges que no són directament visibles per l'usuari final:

  • imatges intermèdies, sobre la base de les quals es recullen altres imatges; no es poden suprimir si utilitzeu contenidors basats en aquestes "altres" imatges;
  • Les imatges penjants són imatges intermèdies a les quals cap dels contenidors en execució no fa referència; es poden suprimir.
  • Amb l'ordre següent podeu comprovar si hi ha imatges penjants al vostre sistema:

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

Podeu eliminar-los de la següent manera:

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

També podem utilitzar la subordre prune:

$ 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

Si de sobte volem suprimir totes les imatges per complet (i no només penjant) amb una ordre, podem fer això:

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

Ús del disc per volums

Els volums s'utilitzen per emmagatzemar dades fora del sistema de fitxers del contenidor. Per exemple, si volem desar els resultats d'una aplicació per utilitzar-los d'una altra manera. Un exemple comú són les bases de dades.

Llencem un contenidor MongoDB, muntem un volum extern al contenidor i restaurem una còpia de seguretat de la base de dades (la tenim disponible al fitxer 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

Les dades es trobaran a la màquina host al directori /var/lib/docker/volumes. Però, per què no al nivell de lectura-escriptura del contenidor? Com que al Dockerfile de la imatge MongoDB, el directori /data/db (on MongoDB emmagatzema les seves dades per defecte) es defineix com a volum.

Consells de Docker: esborreu la vostra màquina de brossa

Nota al marge: moltes imatges que han de produir dades utilitzen volums per emmagatzemar aquestes dades.

Quan juguem prou amb MongoDB i aturem (o potser fins i tot eliminem) el contenidor, el volum no s'eliminarà. Continuarà ocupant el nostre preuat espai al disc fins que el suprimim explícitament amb una ordre com aquesta:

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

Bé, o podem utilitzar la subordre prune que ja ens és familiar:

$ 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:~$

S'utilitza el disc per a la memòria cau de creació d'imatges

A Docker 18.09, el procés de creació d'imatges ha sofert alguns canvis gràcies a l'eina BuildKit. Això augmenta la velocitat del procés i optimitza l'emmagatzematge de dades i la gestió de la seguretat. Aquí no considerarem tots els detalls d'aquesta meravellosa eina; només ens centrarem en com aborda els problemes d'ús de l'espai en disc.

Suposem que tenim una aplicació Node.Js completament senzilla:

  • el fitxer index.js inicia un servidor HTTP senzill que respon amb una línia a cada sol·licitud rebuda:
  • el fitxer package.json defineix les dependències, de les quals només s'utilitza expressjs per executar el servidor HTTP:

$ 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"
      }
    }

El Dockerfile per crear la imatge té aquest aspecte:

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

Construïm la imatge de la manera habitual, sense utilitzar BuildKit:

$ docker build -t app:1.0 .

Si comprovem l'ús d'espai en disc, podem veure que només la imatge base (node:13-alpine) i la imatge de destinació (app:1.0) ocupen espai:

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

Construïm la segona versió de la nostra aplicació, utilitzant BuildKit. Per fer-ho, només hem d'establir la variable DOCKER_BUILDKIT a 1:

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

Si ara comprovem l'ús del disc, veurem que la memòria cau de construcció (buid-cache) hi està involucrada:

$ 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

Per esborrar-lo, utilitzeu l'ordre següent:

$ 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

Esborra-ho tot!

Per tant, vam mirar la neteja de l'espai de disc ocupat per contenidors, imatges i volums. El subordre prune ens ajuda amb això. Però també es pot utilitzar al nivell del sistema docker i netejarà tot el que pugui:

$ 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]

Si per algun motiu esteu estalviant espai al disc en una màquina que executa Docker, l'execució periòdica d'aquesta ordre hauria de convertir-se en un hàbit.

Font: www.habr.com

Afegeix comentari