„Docker“ patarimai: išvalykite įrenginį nuo šiukšlių

„Docker“ patarimai: išvalykite įrenginį nuo šiukšlių

Sveiki, Habr! Jūsų dėmesiui pristatau straipsnio vertimą „Dokerio patarimai: išvalykite vietinį įrenginį“ autorius Lucas Juggery.

Šiandien kalbėsime apie tai, kaip „Docker“ naudoja pagrindinio kompiuterio disko vietą, taip pat išsiaiškinsime, kaip atlaisvinti šią vietą nuo nepanaudotų vaizdų ir konteinerių likučių.


„Docker“ patarimai: išvalykite įrenginį nuo šiukšlių

Bendras suvartojimas

„Dokeris“ yra šaunus dalykas, šiandien turbūt mažai kas tuo abejoja. Vos prieš kelerius metus šis produktas suteikė mums visiškai naują būdą kurti, pristatyti ir paleisti bet kokią aplinką, leidžiančią žymiai sutaupyti procesoriaus ir RAM išteklius. Be to (ir kai kuriems tai bus svarbiausias dalykas), „Docker“ leido mums neįtikėtinai supaprastinti ir suvienodinti gamybos aplinkos gyvavimo ciklo valdymą.

Tačiau visi šie šiuolaikinio gyvenimo malonumai turi savo kainą. Kai paleidžiame konteinerius, atsisiunčiame arba kuriame savo vaizdus ir diegiame sudėtingas ekosistemas, turime mokėti. O mes, be kita ko, mokame už vietos diske.

Jei niekada negalvojote, kiek vietos „Docker“ iš tikrųjų užima jūsų kompiuteryje, galite būti nemaloniai nustebinti šios komandos išvesties:

$ docker system df

„Docker“ patarimai: išvalykite įrenginį nuo šiukšlių

Tai rodo „Docker“ disko naudojimą įvairiuose kontekstuose:

  • vaizdai – bendras vaizdų, atsisiųstų iš vaizdų saugyklų ir sukurtų jūsų sistemoje, dydis;
  • konteineriai – bendras disko vietos kiekis, kurį naudoja veikiantys konteineriai (tai yra bendras visų konteinerių skaitymo ir rašymo sluoksnių tūris);
  • vietiniai tūriai – vietinės saugyklos, sumontuotos prie konteinerių, tūris;
  • build cache – laikinieji failai, sugeneruoti vaizdų kūrimo procese (naudojant BuildKit įrankį, pasiekiamą nuo 18.09 Docker versijos).

Lažinuosi, kad po šio paprasto perkėlimo trokštate išvalyti diską nuo šiukšlių ir sugrąžinti brangius gigabaitus (pastaba: ypač jei už šiuos gigabaitus mokate nuomą kas mėnesį).

Disko naudojimas konteineriuose

Kiekvieną kartą, kai pagrindiniame kompiuteryje sukuriate konteinerį, /var/lib/docker kataloge sukuriami keli failai ir katalogai, tarp kurių verta atkreipti dėmesį į šiuos dalykus:

  • Katalogas /var/lib/docker/containers/container_ID – naudojant standartinę registravimo tvarkyklę, įvykių žurnalai išsaugomi JSON formatu. Dėl pernelyg detalių žurnalų, taip pat žurnalų, kurių niekas neskaito ar kitaip neapdoroja, diskai dažnai prisipildo.
  • Kataloge /var/lib/docker/overlay2 yra konteinerio skaitymo ir rašymo sluoksniai (overlay2 yra pageidaujama tvarkyklė daugumoje Linux platinimų). Jei konteineris saugo duomenis savo failų sistemoje, tada jis bus patalpintas šiame kataloge.

Įsivaizduokime sistemą, kurioje įdiegtas nesugadintas Docker, kuris niekada nebuvo susijęs su konteinerių paleidimu ar vaizdų kūrimu. Jo disko vietos naudojimo ataskaita atrodys taip:

$ 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

Paleiskime kokį nors konteinerį, pavyzdžiui, NGINX:

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

Kas atsitiks su disku:

  • vaizdai užima 126 MB, tai yra tas pats NGINX, kurį paleidome konteineryje;
  • konteineriai užima juokingus 2 baitus.

$ 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

Sprendžiant iš išvados, dar neturime vietos, kurią galėtume atlaisvinti. Kadangi 2 baitai yra visiškai nerimtas, įsivaizduokime, kad mūsų NGINX netikėtai įrašė kažkur 100 megabaitų duomenų ir sukūrė būtent tokio dydžio failą test.img savyje.

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

Dar kartą išnagrinėkime vietos diske naudojimą pagrindiniame kompiuteryje. Pamatysime, kad konteineris (konteineriai) ten užima 100 megabaitų.

$ 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

Manau, kad jūsų smalsios smegenys jau galvoja, kur yra mūsų test.img failas. Paieškokime:

$ 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

Nesileidžiant į smulkmenas, galime pastebėti, kad failas test.img yra patogiai išdėstytas skaitymo ir rašymo lygiu, valdomas overlay2 tvarkykle. Jei sustabdysime savo konteinerį, šeimininkas mums pasakys, kad ši vieta iš esmės gali būti atlaisvinta:

# 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

Kaip mes galime tai padaryti? Ištrynus konteinerį, o tai reiškia, kad reikia išvalyti atitinkamą erdvę skaitymo ir rašymo lygiu.

Naudodami šią komandą galite vienu ypu pašalinti visus įdiegtus konteinerius ir išvalyti diską nuo visų jų sukurtų skaitymo ir rašymo failų:

$ 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

Taigi, ištrynę konteinerį, atlaisvinome 104,9 megabaitų. Tačiau kadangi mes nebenaudojame anksčiau atsisiųsto vaizdo, jis taip pat gali būti pašalintas ir atlaisvintas išteklius:

$ 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

Pastaba: kol vaizdą naudoja bent vienas sudėtinis rodinys, negalėsite naudoti šio triuko.

Aukščiau naudota genėjimo antrinė komanda turi įtakos tik sustabdytiems konteineriams. Jei norime ištrinti ne tik sustabdytus, bet ir veikiančius konteinerius, turėtume naudoti vieną iš šių komandų:

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

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

Šalutinės pastabos: jei paleisdami konteinerį naudosite parametrą -rm, tada, kai jis sustos, bus atlaisvinta visa jo užimta vieta diske.

Disko vaizdų naudojimas

Prieš keletą metų kelių šimtų megabaitų vaizdo dydis buvo visiškai normalus: Ubuntu vaizdas svėrė 600 megabaitų, o Microsoft .Net vaizdas – kelis gigabaitus. Tomis niūriomis dienomis atsisiunčiant tik vieną vaizdą gali sumažėti laisvos vietos diske, net jei dalijatės lygiais tarp vaizdų. Šiandien – pagirkite – vaizdai sveria daug mažiau, tačiau net ir tokiu atveju galite greitai užpildyti turimus išteklius, jei nesiimsite atsargumo priemonių.

Yra keli vaizdų tipai, kurių galutinis vartotojas tiesiogiai nemato:

  • tarpiniai vaizdai, kurių pagrindu renkami kiti vaizdai - jų negalima ištrinti, jei naudojate konteinerius pagal šiuos „kitus“ vaizdus;
  • kabantys vaizdai yra tarpiniai vaizdai, kurių nenurodo jokie veikiantys konteineriai – juos galima ištrinti.
  • Naudodami šią komandą galite patikrinti, ar jūsų sistemoje nėra kabančių vaizdų:

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

Galite juos pašalinti šiais būdais:

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

Taip pat galime naudoti subkomandą slyvėti:

$ 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

Jei staiga norime ištrinti visus vaizdus (o ne tik kabančius) viena komanda, galime tai padaryti:

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

Disko naudojimas pagal tūrį

Tomai naudojami duomenims saugoti už konteinerio failų sistemos ribų. Pavyzdžiui, jei norime išsaugoti programos rezultatus, kad galėtume juos panaudoti kitu būdu. Dažnas pavyzdys yra duomenų bazės.

Paleiskime MongoDB konteinerį, sumontuosime išorinį tomą ir atkurkime iš jo duomenų bazės atsarginę kopiją (ją turime bck.json faile):

# 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

Duomenys bus pagrindinio kompiuterio kataloge /var/lib/docker/volumes. Bet kodėl gi ne konteinerio skaitymo ir rašymo lygiu? Kadangi MongoDB vaizdo Docker faile / data/db katalogas (kur MongoDB saugo savo duomenis pagal numatytuosius nustatymus) yra apibrėžtas kaip tomas.

„Docker“ patarimai: išvalykite įrenginį nuo šiukšlių

Šalutinė pastaba: daugelis vaizdų, kuriuose turi būti pateikti duomenys, naudoja apimtis tiems duomenims saugoti.

Kai pakankamai žaidžiame su MongoDB ir sustabdome (o gal net ištriname) konteinerį, tomas nebus ištrintas. Jis ir toliau užims mūsų brangios vietos diske, kol jį aiškiai ištrinsime naudodami tokią komandą:

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

Na, arba galime naudoti mums jau pažįstamą subkomandą „slyvėti“:

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

Disko naudojimas vaizdo kūrimo talpyklai

„Docker 18.09“ vaizdo kūrimo procesas buvo šiek tiek pakeistas dėl „BuildKit“ įrankio. Šis dalykas padidina proceso greitį ir optimizuoja duomenų saugojimą bei saugos valdymą. Čia nenagrinėsime visų šio nuostabaus įrankio detalių; sutelksime dėmesį tik į tai, kaip jis sprendžia disko vietos naudojimo problemas.

Tarkime, kad turime visiškai paprastą Node.Js programą:

  • failas index.js paleidžia paprastą HTTP serverį, kuris atsako eilute į kiekvieną gautą užklausą:
  • failas package.json apibrėžia priklausomybes, iš kurių tik expressjs naudojamas HTTP serveriui paleisti:

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

Vaizdo kūrimo Dockerfile atrodo taip:

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

Sukurkime vaizdą įprastu būdu, nenaudodami BuildKit:

$ docker build -t app:1.0 .

Jei patikrinsime vietos diske naudojimą, pamatysime, kad vietos užima tik pagrindinis vaizdas (mazgas: 13-alpine) ir tikslinis vaizdas (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

Sukurkime antrąją programos versiją naudodami „BuildKit“. Norėdami tai padaryti, tiesiog turime nustatyti DOCKER_BUILDKIT kintamąjį į 1:

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

Jei dabar patikrinsime disko naudojimą, pamatysime, kad dabar ten yra kūrimo talpykla (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

Norėdami jį išvalyti, naudokite šią komandą:

$ 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

Išvalyti viską!

Taigi, mes stengėmės išvalyti vietą diske, kurią užima konteineriai, vaizdai ir tomai. Slyvų antrinė komanda mums padeda tai padaryti. Tačiau jis taip pat gali būti naudojamas dokerių sistemos lygiu ir išvalys viską, ką gali:

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

Jei dėl kokių nors priežasčių taupote vietos diske kompiuteryje, kuriame veikia „Docker“, periodinis šios komandos vykdymas turėtų tapti įpročiu.

Šaltinis: www.habr.com

Добавить комментарий