Docker-vinkkejä: Puhdista koneestasi roskat

Docker-vinkkejä: Puhdista koneestasi roskat

Hei Habr! Esitän huomionne artikkelin käännöksen "Dokkerin vinkit: puhdista paikallinen koneesi" kirjailija Luc Juggery.

Tänään puhumme siitä, kuinka Docker käyttää isäntäkoneen levytilaa, ja selvitämme myös kuinka vapauttaa tämä tila käyttämättömien kuvien ja säiliöiden romuista.


Docker-vinkkejä: Puhdista koneestasi roskat

Kokonaiskulutus

Docker on siisti asia, luultavasti harvat epäilevät sitä nykyään. Vain muutama vuosi sitten tämä tuote antoi meille täysin uuden tavan rakentaa, toimittaa ja käyttää mitä tahansa ympäristöä, minkä ansiosta voimme säästää merkittävästi CPU- ja RAM-resursseja. Tämän lisäksi (ja joillekin tämä tulee olemaan tärkeintä) Docker on antanut meille mahdollisuuden yksinkertaistaa ja yhtenäistää tuotantoympäristöjemme elinkaarihallintaa.

Kaikilla näillä modernin elämän iloilla on kuitenkin hintansa. Kun käytämme säiliöitä, lataamme tai luomme omia kuviamme ja otamme käyttöön monimutkaisia ​​ekosysteemejä, meidän on maksettava. Ja maksamme muun muassa levytilalla.

Jos et ole koskaan ajatellut kuinka paljon tilaa Docker todella vie koneeltasi, saatat yllättyä ikävästi tämän komennon tuloksesta:

$ docker system df

Docker-vinkkejä: Puhdista koneestasi roskat

Tämä näyttää Dockerin levyn käytön eri yhteyksissä:

  • kuvat – kuvavarastoista ladattujen ja järjestelmääsi rakennettujen kuvien kokonaiskoko;
  • kontit – käynnissä olevien säiliöiden käyttämän levytilan kokonaismäärä (eli kaikkien säiliöiden luku- ja kirjoituskerrosten kokonaismäärä);
  • paikalliset tilavuudet – kontteihin asennetun paikallisen varaston tilavuus;
  • build cache – kuvanrakennusprosessin luomat väliaikaiset tiedostot (BuildKit-työkalulla, joka on saatavilla Dockerin versiosta 18.09 alkaen).

Lyön vetoa, että tämän yksinkertaisen siirron jälkeen olet innokas puhdistamaan levysi roskista ja herättämään arvokkaat gigatavut takaisin henkiin (huom: varsinkin jos maksat vuokraa näistä gigatavuista joka kuukausi).

Levyjen käyttö säiliöiden mukaan

Joka kerta kun luot säilön isäntäkoneeseen, /var/lib/docker-hakemistoon luodaan useita tiedostoja ja hakemistoja, joista seuraavat ovat huomionarvoisia:

  • Hakemisto /var/lib/docker/containers/container_ID – käytettäessä tavallista lokiohjainta, tähän tapahtumalokit tallennetaan JSON-muodossa. Liian yksityiskohtaiset lokit sekä lokit, joita kukaan ei lue tai muuten käsittele, aiheuttavat usein levyjen täyttymisen.
  • /var/lib/docker/overlay2-hakemisto sisältää säilön luku- ja kirjoitustasot (overlay2 on suosituin ohjain useimmissa Linux-jakeluissa). Jos säilö tallentaa tietoja tiedostojärjestelmäänsä, se sijoitetaan tähän hakemistoon.

Kuvitellaanpa järjestelmä, johon on asennettu koskematon Docker, joka ei ole koskaan ollut mukana konttien laukaisussa tai kuvien rakentamisessa. Sen levytilan käyttöraportti näyttää tältä:

$ 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

Käynnistetään jokin kontti, esimerkiksi NGINX:

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

Mitä levylle tapahtuu:

  • kuvat vievät 126 Mt, tämä on sama NGINX, jonka julkaisimme säilössä;
  • kontit vievät naurettavat 2 tavua.

$ 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

Päätelmän perusteella meillä ei ole vielä yhtään tilaa, jota voisimme vapauttaa. Koska 2 tavua on täysin turhaa, kuvitellaan, että NGINX kirjoitti yllättäen jonnekin 100 megatavua dataa ja loi sisäänsä juuri tämän kokoisen tiedoston test.img.

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

Tarkastellaan uudelleen isäntäkoneen levytilan käyttöä. Näemme, että kontti (säiliöt) vie siellä 100 megatavua.

$ 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

Luulen, että utelias aivosi ihmettelevät jo, missä test.img-tiedostomme sijaitsee. Etsitään se:

$ 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

Menemättä yksityiskohtiin voimme huomata, että test.img-tiedosto sijaitsee kätevästi luku-kirjoitustasolla overlay2-ohjaimen ohjaamana. Jos pysäytämme konttimme, isäntä kertoo meille, että tämä tila voidaan periaatteessa vapauttaa:

# 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

Kuinka voimme tehdä tämän? Poistamalla säilön, mikä edellyttää vastaavan tilan tyhjentämistä luku- ja kirjoitustasolla.

Seuraavalla komennolla voit poistaa kaikki asennetut säilöt yhdellä iskulla ja tyhjentää levyltä kaikki niiden luomat luku-kirjoitustiedostot:

$ 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

Joten vapautimme 104,9 megatavua poistamalla säilön. Mutta koska emme enää käytä aiemmin ladattua kuvaa, siitä tulee myös ehdokas resurssien poistamiseen ja vapauttamiseen:

$ 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

Huomaa: niin kauan kuin kuva on vähintään yhden säilön käytössä, et voi käyttää tätä temppua.

Yllä käyttämämme karsia-alikomento vaikuttaa vain pysäytettyihin säiliöihin. Jos haluamme poistaa pysäytettyjä, mutta myös käynnissä olevia säiliöitä, meidän tulee käyttää jotakin seuraavista komennoista:

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

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

Sivuhuomautukset: jos käytät -rm-parametria käynnistäessäsi säilön, sen pysähdyksissä kaikki sen käyttämä levytila ​​vapautuu.

Levyjen kuvien käyttö

Muutama vuosi sitten useiden satojen megatavujen kuvakoko oli täysin normaali: Ubuntu-kuva painoi 600 megatavua ja Microsoft .Net -kuva useita gigatavuja. Näinä pörröisinä päivinä vain yhden kuvan lataaminen voi viedä paljon vapaata levytilaa, vaikka jakaisit tasoja kuvien välillä. Nykyään - ylistys suurille - kuvat painavat paljon vähemmän, mutta silti voit nopeasti täyttää käytettävissä olevat resurssit, jos et ryhdy varotoimiin.

On olemassa useita erilaisia ​​kuvia, jotka eivät näy suoraan loppukäyttäjälle:

  • välikuvat, joiden perusteella kerätään muita kuvia - niitä ei voi poistaa, jos käytät näihin "muihin" kuviin perustuvia säiliöitä;
  • roikkuvat kuvat ovat välikuvia, joihin mikään käynnissä olevista säilöistä ei viittaa – ne voidaan poistaa.
  • Seuraavalla komennolla voit tarkistaa, onko järjestelmässäsi roikkuvia kuvia:

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

Voit poistaa ne seuraavasti:

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

Voimme myös käyttää prune-alikomentoa:

$ 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

Jos haluamme yhtäkkiä poistaa kaikki kuvat kokonaan (eikä vain roikkuvat) yhdellä komennolla, voimme tehdä tämän:

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

Levyn käyttö volyymin mukaan

Volyymeja käytetään tietojen tallentamiseen säilön tiedostojärjestelmän ulkopuolelle. Esimerkiksi, jos haluamme tallentaa sovelluksen tulokset käyttääksemme niitä jollain muulla tavalla. Yleinen esimerkki ovat tietokannat.

Käynnistetään MongoDB-säilö, liitetään säilön ulkoinen taltio ja palautetaan siitä tietokannan varmuuskopio (se on saatavilla bck.json-tiedostossa):

# 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

Tiedot sijaitsevat isäntäkoneella /var/lib/docker/volumes-hakemistossa. Mutta miksi ei säilön luku- ja kirjoitustasolla? Koska MongoDB-kuvan Docker-tiedostossa /data/db-hakemisto (johon MongoDB tallentaa tiedot oletuksena) on määritetty taltioksi.

Docker-vinkkejä: Puhdista koneestasi roskat

Sivuhuomautus: monet kuvat, joiden on tuotettava dataa, käyttävät tilavuuksia näiden tietojen tallentamiseen.

Kun pelaamme tarpeeksi MongoDB:llä ja pysäytämme (tai ehkä jopa poistamme) säilön, levyä ei poisteta. Se vie arvokasta levytilaamme, kunnes poistamme sen komennolla, kuten seuraava:

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

No, tai voimme käyttää meille jo tuttua prune-alikomentoa:

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

Levyn käyttö kuvanmuodostuksen välimuistiin

Docker 18.09:ssä kuvanluontiprosessi on kokenut joitain muutoksia BuildKit-työkalun ansiosta. Tämä nopeuttaa prosessia ja optimoi tiedon tallennuksen ja tietoturvan hallinnan. Tässä emme käsittele tämän upean työkalun kaikkia yksityiskohtia; keskitymme vain siihen, kuinka se käsittelee levytilan käyttöä koskevia ongelmia.

Oletetaan, että meillä on täysin yksinkertainen Node.Js-sovellus:

  • index.js-tiedosto käynnistää yksinkertaisen HTTP-palvelimen, joka vastaa rivillä jokaiseen vastaanotettuun pyyntöön:
  • paketti.json-tiedosto määrittää riippuvuudet, joista vain expressjs:ää käytetään HTTP-palvelimen suorittamiseen:

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

Docker-tiedosto kuvan rakentamiseen näyttää tältä:

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

Rakennetaan kuva tavalliseen tapaan, ilman BuildKitin käyttöä:

$ docker build -t app:1.0 .

Jos tarkistamme levytilan käytön, voimme nähdä, että vain peruskuva (node:13-alpine) ja kohdekuva (app:1.0) vievät tilaa:

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

Rakennetaan toinen versio sovelluksestamme BuildKitillä. Tätä varten meidän on vain asetettava DOCKER_BUILDKIT-muuttujan arvoksi 1:

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

Jos nyt tarkistamme levyn käytön, näemme, että koontivälimuisti (buid-cache) on nyt mukana siellä:

$ 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

Tyhjennä se käyttämällä seuraavaa komentoa:

$ 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

Tyhjennä!

Tarkastelimme siis säiliöiden, kuvien ja taltioiden käyttämän levytilan puhdistamista. Luumun alakomento auttaa meitä tässä. Mutta sitä voidaan käyttää myös telakointijärjestelmätasolla, ja se puhdistaa kaiken, mitä voi:

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

Jos jostain syystä säästät levytilaa Dockeria käyttävässä koneessa, tämän komennon säännöllisestä suorittamisesta pitäisi tulla tapana.

Lähde: will.com

Lisää kommentti