
Përshëndetje, Habr! Po ju prezantoj një përkthim të artikullit autori .
Sot do flasim për mënyrën se si Docker përdor hapësirën diskore të makinës pritëse, si dhe do të shqyrtojmë se si ta çlironi atë hapësirë nga mbetjet e imazheve dhe kontejnerëve të papërdorur.

Konsum total
Docker është një gjë e shkëlqyer, ndoshta sot pak kush e dyshon këtë. Vetëm disa vite më parë, ky produkt na ofroi një mënyrë krejtësisht të re për të ndërtuar, shpërndarë dhe përgatitur çdo ambient, duke i lejuar të kursenim ndjeshëm burimet e procesorit dhe memorizimit. Përveç kësaj (dhe për disa do të jetë edhe më e rëndësishme), Docker na lehtësoi në mënyrë të jashtëzakonshme dhe standardizoi menaxhimin e ciklit të jetës së ambientet e punës që përdorim.
Megjithatë, për të gjitha këto komoditete të jetës moderne, na duhet të paguajmë. Kur aktivizojmë kontejnerë, shkarkojmë ose krijojmë imazhe tona, ndërtojmë ekosistema të komplikuara, na duhet të paguajmë. Dhe paguajmë me hapësirë diskore.
Nëse keni ndonjëherë menduar se sa hapësirë është realisht e zënë në makinën tuaj nga Docker, mund të jeni të papërshtatshëm kur të shihni rezultatin e kësaj komande:
$ docker system df 
Këtu shfaqet përdorimi i diskut nga Docker në dimensione të ndryshme:
- imazhet (images) â madhĂ«sia totale e imazheve qĂ« janĂ« shkarkuar nga depozitat dhe ndĂ«rtuar nĂ« sistemin tuaj;
- kontejnerĂ«t (containers) â vĂ«llimi total i hapĂ«sirĂ«s diskore tĂ« pĂ«rdorur nga kontejnerĂ«t e aktivizuar (kuptohet si vĂ«llimi total i shtresave tĂ« leximit-shkrimit tĂ« tĂ« gjithĂ« kontejnerĂ«ve);
- tumat lokale (local volumes) â vĂ«llimi i depozitave lokale tĂ« lidhura me kontejnerĂ«t;
- kĂ«shilla e ndĂ«rtimit (build cache) â skedarĂ« temporarĂ« tĂ« krijuar nga procesi i ndĂ«rtimit tĂ« imazheve (nĂ« pĂ«rdorimin e mjetit BuildKit, i disponueshĂ«m qĂ« nga Docker versioni 18.09).
Jam gati të betohem se pas këtij përshkrimi të thjeshtë ju ndiheni të etur për të pastruar diskun nga mbeturinat dhe për të rikthyer në jetë gigabajtët tuaj të çmuar (shënim: sidomos nëse për këto gigabajtë ju paguani çdo muaj një qira).
Përdorimi i diskut nga kontejnerët
Ădo herĂ« qĂ« krijohet njĂ« kontejner nĂ« makinĂ«n pritĂ«se, nĂ« katalogun /var/lib/docker krijohen disa skedarĂ« dhe katalogĂ«, ndĂ«r tĂ« cilĂ«t vlen tĂ« pĂ«rmenden kĂ«ta:
- Katalogu /var/lib/docker/containers/ID_kontejnerit â kur pĂ«rdoret drejtori standard i regjistrimit, pikĂ«risht kĂ«tu ruhen regjistrat e ngjarjeve nĂ« formatin JSON. Regjistrat shumĂ« tĂ« detajuar, si dhe regjistrat qĂ« askush nuk i lexon dhe nuk i pĂ«rpunon nĂ« mĂ«nyra tĂ« tjera, shpesh janĂ« shkak pĂ«r mbushjen e disqeve.
- Katalogu /var/lib/docker/overlay2 â pĂ«rmban shtresa leximi-shkruese tĂ« konteinerĂ«ve (overlay2 â drejtori mĂ« i preferuar nĂ« shumicĂ«n e shpĂ«rndarjeve tĂ« Linux). NĂ«se njĂ« kontejner ruan tĂ« dhĂ«na nĂ« sistemin e tij tĂ« skedarĂ«ve, atĂ«herĂ« pikĂ«risht nĂ« kĂ«tĂ« katalog do tĂ« vendosen ato.
Le të imagjinojmë një sistem në të cilin është instaluar një Docker tërësisht i pastër, që nuk ka marrë pjesë ndonjëherë në ekzekutimin e konteinerëve dhe ndërtimin e imazheve. Raporti i tij për përdorimin e hapësirës në disk do të duket kështu:
$ docker system df
TIPI TOTAL AKTIV TĂ DHĂNA RIKHET
Imazhet 0 0 0B 0B
Konteinerët 0 0 0B 0B
Vëllimet Lokale 0 0 0B 0B
Kosh Ndërtimi 0 0 0B 0BLe të nisëm një kontejner, për shembull, NGINX:
$ docker container run --name www -d -p 8000:80 nginx:1.16ĂfarĂ« ndodh me diskun:
- imazhet (images) zënë 126 MB, ky është NGINX-i që ne filluam në kontejner;
- konteinerët (containers) zënë vetëm 2 byte.
$ docker system df
TIPI TOTAL AKTIV TĂ DHĂNA RIKHET
Imazhet 1 1 126M 0B (0%)
Konteinerët 1 1 2B 0B (0%)
Vëllimet Lokale 0 0 0B 0B
Kosh Ndërtimi 0 0 0B 0BDuke parë rezultatin, ne ende nuk kemi hapësirë për ta liruar. Pasiqë 2 byte janë krejtësisht të papranueshëm, le të imagjinojmë se NGINX-i ynë papritur shkroi diku 100 Megabajt të dhënash dhe krijoi në brendësi të tij një skedar test.img me atë madhësi.
$ docker exec -ti www
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]Përsëri, le të shqyrtojmë përdorimin e hapësirës në disk në host. Do të shohim se kontejneri (containers) zë atje 100 Megabajt.
$ docker system df
TIPI TOTAL AKTIV TĂ DHĂNA RIKHET
Imazhet 1 1 126M 0B (0%)
Konteinerët 1 1 104.9MB 0B (0%)
Vëllimet Lokale 0 0 0B 0B
Kosh Ndërtimi 0 0 0B 0BMendoj se truri juaj i kureshtshëm tashmë po bën pyetje për vendndodhjen e skedarit tonë test.img. Le të shohim se ku ndodhet:
$ 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.imgPa përmendur shkurt, mund të theksohet se skedari test.img është pozicionuar lehtë në nivelin e leximit-shkrimit, të menaxhuar nga drejtuesi overlay2. Nëse e ndalim kontejnerin tonë, hosti do të na tregojë se ky vend mund të lirohet, në thelb.
# 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 0BSi mund ta bëjmë këtë? Duke eliminuar kontejnerin, i cili do të sjellë pastrimin e hapësirës përkatëse në nivelin e leximit-shkrimit.
Me komandën në vijim, mund të eliminoni të gjithë kontejnerët e instaluar njëherësh dhe të pastroni diskun tuaj nga të gjitha skedarët që ata krijuan në nivelin e leximit-shkrimit:
$ docker container prune
KĂSHILLĂ! Kjo do tĂ« heqĂ« tĂ« gjithĂ« kontejnerĂ«t e ndaluar.
A jeni të sigurt që dëshironi të vazhdoni? [y/N] y
Kontejnerët e Fshirë:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2
Hapësira totale e rikuperuar: 104.9MBKështu, ne kemi liruar 104,9 Megabajt duke eliminuar kontejnerin. Por pasi që nuk po e përdorim më imazhin e shkarkuar më parë, ai gjithashtu bëhet një kandidat për eliminim dhe lirimin e burimeve tona:
$ docker system df
LLOJI TOTAL AKTIV MDFAR RIKUPERUESHĂM
Imazhe 1 0 126M 126M (100%)
Kontejnerë 0 0 0B 0B
Volume Lokal 0 0 0B 0B
Cache të Ndërtimit 0 0 0B 0BVëmendje: derisa imazhi të përdoret nga të paktën një kontejner, nuk do të jeni në gjendje ta përdorni këtë truk.
Subkomanda prune, e cila u përdor më sipër, ka efekt vetëm në kontejnerë të ndaluar. Nëse dëshirojmë të eliminojmë jo vetëm kontejnerët e ndaluar, por edhe ata të aktivizuar, duhet të përdorim një nga këto komanda:
# Historical command
$ docker rm -f $(docker ps âaq)
# More recent command
$ docker container rm -f $(docker container ls -aq)ShĂ«nime nĂ« margjinĂ«: nĂ«se gjatĂ« fillimit tĂ« kontejnerit pĂ«rdorni parametrin ârm, atĂ«herĂ« kur ai ndalet, do tĂ« lirohet tĂ« gjithĂ« hapĂ«sira disk qĂ« ai zinte.
Përdorimi i diskut nga imazhet
Para disa vitesh, madhĂ«sia e njĂ« imazhi prej disa qindra megabajtĂ«sh ishte krejt normale: imazhi Ubuntu peshohej 600 Megabajt, ndĂ«rsa imazhi Microsoft .Net peshohej disa Gigabajt. NĂ« ato ditĂ«, shkarkimi i vetĂ«m njĂ« imazhi mund tĂ« shkaktonte njĂ« dĂ«m tĂ« madh nĂ« hapĂ«sirĂ«n tuaj tĂ« lirĂ« nĂ« disk, edhe nĂ«se ndaheshit nivelet midis imazheve. Sot â falĂ« Zotit â imazhet peshojnĂ« shumĂ« mĂ« pak, por edhe kĂ«shtu, mund tĂ« mbushen shpejt burimet ekzistuese, nĂ«se nuk merren disa masa paraprake.
Ka disa lloje imazhesh që nuk duken drejtpërdrejt për përdoruesin përfundimtar:
- imazhet ndĂ«rmjetĂ«se, mbi bazĂ«n e tĂ« cilave janĂ« grumbulluar imazhe tĂ« tjera â ato nuk mund tĂ« fshihen nĂ«se po pĂ«rdorni kontejnerĂ« tĂ« bazuar nĂ« kĂ«to "imazhe tĂ« tjera";
- imazhe tĂ« varura â janĂ« ato imazhe ndĂ«rmjetĂ«se, tĂ« cilat nuk referohen nga asnjĂ« nga kontejnerĂ«t e nisur â ato mund tĂ« fshihen.
- Me komandën e mëposhtme mund të kontrolloni praninë e imazheve të varura në sistemin tuaj:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
none none 21e658fe5351 12 minutes ago 71.3MBAto mund të fshihen në këtë mënyrë:
$ docker image rm $(docker image ls -f dangling=true -q)Mund të përdorim gjithashtu nënkomandën prune:
$ docker image prune
WARNING! Kjo do të fshijë të gjitha imazhet e varura.
A jeni i sigurt që dëshironi të vazhdoni? [y/N] y
Imazhet e fshira:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f
Hapsira totale e rikuperuar: 12.9kBNëse ndonjëherë dëshirojmë të fshijmë të gjitha imazhet (dhe jo vetëm imazhet e varura) me një komandë, mund ta bëjmë kështu:
$ docker image rm $(docker image ls -q)Përdorimi i diskut me volume
Volume-t (të dhënat) përdoren për të ruajtur të dhëna jashtë sistemit të skedarëve të kontejnerit. Për shembull, nëse duam të ruajmë rezultatet e funksionimit të ndonjë aplikacioni për t'i përdorur ndryshe. Një shembull i zakonshëm janë baze të dhënash.
Le të nisëm një kontejner MongoDB, të bashkëlidhim një volume të jashtëm të kontejnerit, dhe të rikuperojmë nga një backup të bazës të dhënash (e kemi të disponueshme në skedarin 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
--jsonArrayTë dhënat do të jenë në makinë pritëse në katalogun /var/lib/docker/volumes. Por pse jo në nivelin e leximit-shkrimit të kontejnerit? Sepse në Dockerfile-in e imazhit MongoDB katalogu /data/db (në të cilin MongoDB në mënyrë të paracaktuar ruan të dhënat e tij) është përcaktuar si volume.

Shënime në anë: shumë imazhe, si rezultat i të cilave duhet të krijohen të dhëna, përdorin volume (të dhënat) për të ruajtur këto të dhëna.
Kur të përfundojmë me MongoDB dhe të ndalim (ndoshta madje të fshijmë) kontejnerin, volumi nuk do të fshihet. Ai do të vazhdojë të marrë hapësirën tonë të çmuar diskore derisa ne ta fshijmë atë qartë me këtë komandë:
$ docker volume rm $(docker volume ls -q)Ose mund të përdorim nënkomandën tonë të njohur prune:
$ docker volume prune
WARNING! Kjo do të heqë të gjitha volumet lokale që nuk përdoren nga të paktën një kontejner.
A jeni të sigurt se dëshironit të vazhdoni? [y/N] y
Të fshirë Volumet:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da
Hapësira totale e rikuperuar: 25.82GB
luc@saturn:~$Përdorimi i diskut për cache të ndërtimit të imazheve
Në Docker 18.09, procesi i krijimit të imazheve kaloi disa ndryshime falë mjetit BuildKit. Me këtë mjet, rritet shpejtësia e procesit, optimizohet menaxhimi i ruajtjes së të dhënave dhe sigurisë. Nuk do të shqyrtojmë të gjitha detajet e këtij mjeti të mrekullueshëm, do të ndalemi vetëm te mënyra se si ai ndikon në çështjet e përdorimit të hapësirës disk.
Le të supozojmë se kemi një aplikacion shumë të thjeshtë Node.Js:
- Skedari index.js nis një server HTTP të thjeshtë që përgjigjet me një varg për çdo kërkesë të marrë:
- Skedari package.json përcakton varësitë, nga të cilat vetëm expressjs përdoret për të nisur serverin 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(), 'Kërkesa e Marrë'));
});
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 për ndërtimin e imazhit duket kështu:
FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]Le të ndërtoshim imazhin në mënyrë të zakonshme, pa përdorur BuildKit:
$ docker build -t app:1.0 .Nëse kontrollojmë përdorimin e hapësirës disk, do të shohim se hapësira zë vetëm imazhi bazë (node:13-alpine) dhe imazhi përfundimtar (app:1.0):
TIPI TOTAL AKTIV SIZE RIKUPERUESHĂM
Imazhet 2 0 109.3MB 109.3MB (100%)
Kontejnerët 0 0 0B 0B
Volumet Lokale 0 0 0B 0B
Cache e Ndërtimit 0 0 0B 0BLe të ndërtoshim versionin e dytë të aplikacionit tonë, tani me përdorimin e BuildKit. Për këtë, na duhet vetëm të vendosim variablen DOCKER_BUILDKIT në vlerën 1:
$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .Nëse tani kontrollojmë përdorimin e diskut, do të shohim se tani është përfshirë cache e ndërtimit (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.949kBPër ta pastruar atë, përdorim komandën në vijim:
$ docker builder prune
WARNING! Kjo do të heqë të gjithë ndihmësit e ndërtimit që s'kanë asnjë përdorim.
A jeni të sigurt që dëshironi të vazhdoni? [y/N] y
Objektet e pastruar të ndihmësit të ndërtimit:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi
Hapësira totale e rikuperuar: 8.949kBPastroni gjithçka!
Pra, ne shqyrtuam pastrimin e hapësirës së diskut të zënë nga kontejnerët, imazhet dhe volumet. Kjo na ndihmon subkomanda prune. Por mund të përdoret edhe në nivelin sistemor docker, dhe do të pastruar gjithçka që mundet:
$ docker system prune
WARNING! Kjo do të heqë:
- të gjithë kontejnerët e ndalur
- të gjithë rrjetet që nuk përdoren nga të paktën një kontejner
- të gjitha imazhet që s'kanë asnjë përdorim
- të gjitha ndihmësit e ndërtimit që s'kanë asnjë përdorim
A jeni të sigurt që dëshironi të vazhdoni? [y/N]Nëse për ndonjë arsye po kurseni hapësirë në disk në makinën tuaj me Docker, atëherë ekzekutimi periodic i kësaj komande është një zakon i mirë.
Burimi: habr.com
