
Բարև, Հաբր! Ջենեցի ձեր ուշադրությանը հոդվածի թարգմանությունը հեղինակ .
Այսօր մենք կխոսենք, թե ինչպես է Docker-ը օգտագործում հյուրընկալող մեքենայի սկավառակի տարածությունը, ինչպես նաև պարզ կմենք, թե ինչպես ազատել այդ տարածությունը օգտագործված պատկերների և կոնտեյների մնացորդներից:

Ընդհանուր օգտագործում
Docker-ը հիանալի բան է, և երբեք չի եղել մեկը, ով կասկածի տակ է դրել դա: Մի քանի տարի առաջ այս արտադրանքը մեզ տրամադրեց ամբողջովին նոր ճանապարհ, որպեսզի կառուցենք, տրամադրենք և գործարկենք ցանկացած միջավայր, թույլ տալով խնայել պրոցեսորի և օպերատիվ հիշողության ռեսուրսները: Այնուամենայնիվ, (և ինչ-որ մեկի համար սա կարող է նույնիսկ ամենակարևոր լինել) Docker-ը մեզ թույլ տվեց այնպես պարզեցնել և միավորել օգտագործվող աշխատանքային միջավայրերի կյանքի ցիկլի կառավարումը:
Սակայն, այս բոլորօրպետների համար պետք է վճարել: Երբ մենք կաղապարում ենք կոնտեյներներ, ներբեռնում կամ ստեղծում ենք սեփական պատկերներ, ձևավորում ենք բարդ էկոսիստեմներ, մենք ստիպված ենք վճարել: Եվ վճարում ենք, այդ թվում, սկավառակի տարածությամբ:
Եթե դուք երբեք չեք մտածել, թե որքան տարածք իրականում զբաղեցնում է ձեր մեքենայում Docker-ը, կարող եք անհանգստանալ այս հրամանով:
$ docker system df 
Այստեղ ցուցադրվում է Docker-ի սկավառակի օգտագործումը տարբեր անկյուններից:
- պատկերներ (images) – ընդհանուր չափսերը պատկերների, որոնք ներբեռնվել են պատկերների պահոցներից և կառուցվել են ձեր համակարգում;
- կանթեյներներ (containers) – ընդհանուր սկավառակի տարածություն, որը օգտագործում են գործարկված կանթեյներները (նշվում է բոլոր ասույթների ընդհանուր չափը);
- տեղական ծավալներ (local volumes) – տեղական պահոցների տարածքը, որոնք սնուցվում են կոնտեյներիներով;
- կառուցման կաշ (build cache) – ժամանակակից ֆայլեր, որոնք բերվել են պատկերների կառուցման գործընթացով (BuildKit գործիքի օգտագործման դեպքում, որը հասանելի է Docker-ի 18.09 տարբերակից սկսած):
Փաստորեն, արդեն այս պարզ ցուցակի ցուցադրման արդյունքում դուք փափագում եք մաքրել սկավառակը թափողներից ու վերականգնել ձեր թանկարժեք գիգաբայթները (նկ. թարգման.՝ հատկապես, եթե այդ գիգաբայթների համար ամսական գանձում եք վարձավճար):
Կոնտեյներների սկավառակի օգտագործում
Յուրաքանչյուր անգամ կոնտեյները ստեղծելիս հյուրընկալող մեքենայում կատալոգում /var/lib/docker ստեղծվում է մի քանի ֆայլեր և կատալոգներ, որոնցից պետք է նշել հետևյալը:
- Կատալոգ /var/lib/docker/containers/ID_կոնտեյների – ստանդարտ կայանքի ներկայացուցիչը այստեղ էլ պահպանվում են JSON ձևաչափից իրադարձությունների գրանցումները: Ցանկացած չափազանց մանրամասն լոգեր, ինչպես նաև այնպիսի լոգեր, որոնք ոչ ոք չէ, որպեսզի ընթերցի կամ այլ կերպ մշակվի, հաճախ դառնում են սկավառակի լրացման պատճառ:
- Каталог /var/lib/docker/overlay2 –_contains_read-write_layers_of_containers_(overlay2_–_preferred_driver_in_most_Linux_distributions)._Если_kонтейнер_сохраняет_данные_в_своей_файловой_системе, то_именно_в_этом_каталоге_они_и_будут_размещены.
Представим себе систему, на которой установлен новый Docker, ни разу не участвовавший в запуске контейнеров и создании образов. Его отчет об использовании дискового пространства будет выглядеть так:
$ 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Запустим контейнер, например, NGINX:
$ docker container run --name www -d -p 8000:80 nginx:1.16Что происходит с диском:
- образы (images) занимают 126 Мб, это тот самый NGINX, который мы запустили в контейнере;
- контейнеры (containers) занимают смешные 2 байта.
$ 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Судя по выводу, у нас еще нет пространства, которое мы могли бы высвободить. Так как 2 байта это совершенно несерьезно, давайте представим, что наш NGINX неожиданно для всех написал куда-то 100 Мегабайт данных и создал внутри себя файл test.img именно такого размера.
$ docker exec -ti www
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]Снова исследуем использование дискового пространства на хосте. Мы увидим, что контейнер (containers) занимает там 100 Мегабайт.
$ 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Думаю, ваш пытливый ум уже задается вопросом, где же находится наш файл test.img. Давайте попробуем его найти:
$ 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Не вдаваясь в подробности, можно отметить, что файл test.img удобно расположился на уровне чтения-записи, управляемом драйвером overlay2. Если же мы остановим наш контейнер, то хост подскажет нам, что это место, в принципе, можно высвободить:
# 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Как мы можем это сделать? Удалением контейнера, что приведет к очистке соответствующего пространства на уровне чтения-записи.
С помощью следующей команды вы можете удалить все установленные контейнеры одним махом и очистить ваш диск от всех созданных ими на уровне чтения-записи файлов:
$ docker container prune
WARNING! Это удалит все остановленные контейнеры.
Вы уверены, что хотите продолжить? [y/N] y
Удаленные контейнеры:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2
Всего освобождено пространства: 104.9МбИтак, мы освободили 104,9 Мегабайта удалением контейнера. Но так как мы уже не используем скачанный ранее образ, то он тоже становится кандидатом на удаление и высвобождение наших ресурсов:
$ 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Զգուշացում: այնքան ժամանակ, որքան դեկտորն օգտագործվում է առնվազն մեկ կոնտեյներով, Դուք չեք կարող օգտագործել այս հնարքը:
Մենք օգտագործած prune ենթաբառը, տալիս է ազդեցություն միայն կանգնած կոնտեյներով: Եթե ցանկանում ենք հեռացնել ոչ միայն կանգնած, այլ նաև գործող կոնտեյներները, պետք է օգտագործել այս հրամաններից մեկը:
# Historical command
$ docker rm -f $(docker ps –aq)
# More recent command
$ docker container rm -f $(docker container ls -aq)Նշումներ դաշտում: եթե կոնտեյրը գործարկելիս օգտագործել պարամետր —rm, ապա նրա կանգնայով՝ ազատվել են բոլոր այն մակերեսները, որոնք նա զբաղեցրել է:
Դատարկ լայն: օգտագործելով դեկտորն:
Քանի տարի առաջ, ընկալումն է, որ պատկերակների չափը մի քանի հարյուր մեգաբայթ էր լիովին բնական: Ubuntu-ն ուներ 600 մեգաբայթ, իսկ Microsoft .Net-ի պատկերակը՝ մի քանի գիգաբայթ: Այդ հնագույն ժամանակներում, միայն մի պատկերի ներբեռնումը մեծ վնաս կարող էր պատճառել Ձեր ազատ տարածքում, նույնիսկ եթե դուք բաժանել էինք մակարդակները պատկերակների միջև: Այսօր՝ շնորհիվ մեծերի, պատկերակները շատ ավելի փոքր են, բայց նույնիսկ այս դեպքում կարող է արագ սպառվել vorhandությունը, եթե որոշակի նախազգուշական միջոցներ չտարվեն:
Գոյություն ունեն մի քանի տեսակ պատկերակների, որոնք անմիջականորեն չպետք է լինեն վերջնական օգտագործողի համար:
- intermediate պատկերակներ, որոնց հիման վրա ավելանում են մյուս պատկերակները, դրանք չեն կարող հեռացվել, եթե դուք օգտագործում եք այս այլ պատկերակների հիման վրա կառուցված կոնտեյներներ:
- dangling պատկերակներ՝ այսպիսի intermediate պատկերակներ, որոնց վրա ոչ մի գործող կոնտեյներով չէ հղում՝ դրանք կարող են հեռացվել:
- Հետևյալ հրամանով կարող եք ստուգել ձեր համակարգում dangling պատկերակների առկայությունը:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
none none 21e658fe5351 12 minutes ago 71.3MBԴրանք կարելի է հեռացնել հետևյալ եղանակով:
$ docker image rm $(docker image ls -f dangling=true -q)Մենք կարող ենք օգտագործել նաև 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Եթե մենք հանկարծ ցանկանում ենք հեռացնել բոլոր պատկերակները (և ոչ միայն dangling) մեկ հրամանով, կարող ենք անել այսպես:
$ docker image rm $(docker image ls -q)Դիսկի օգտագործում աղբյուրներով:
Աղբյուրները (volumes) օգտագործվում են տվյալները պահելու համար, որոնք գտնվում են կոնտեյների ֆայլային համակարգից դուրս: Այսինքն, եթե մենք ցանկանում ենք պահպանել որևէ ծրագրի արդյունքները, որպեսզի օգտագործենք դրանք այլ նպատակներով: Կան aʻe կլինիկների օրինակ մատների ներքև:
Եկեք գործենք MongoDB կոնտեյներ, ամրանենք դրան արտաքին աղբյուր, և վերականգնենք նրանից տվյալների բազայի բակենք (այն մեզ հասանելի է 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Տվյալները կգտնվեն սերվերում ՝ /var/lib/docker/volumes կատալոգում: Բայց ինչու ոչ կոնտեյների կարդալ-գրել մակարդակում? Որովհար՝ Dockerfile-ի MongoDB պատկերում /data/db (որտեղ MongoDB-ն բնականաբար պահում է իր տվյալները) սահմանված է որպես ծավալ (volume):

Մեկնաբանություններ դաշտերում: Ունենք բազմաթիվ պատկերներ, որոնց արդյունքում պետք է ստեղծվեն տվյալներ, օգտագործում են ծավալներ (volumes) այդ տվյալները պահպանելու համար:
Երբ մենք կավարտենք MongoDB-ով աշխատանքը և կասեցնենք (կամ նույնիսկ կհեռացնենք) կոնտեյները, ծավալը չի կորալու: Նա շարունակելու է զբաղեցնել մեր արժեքավոր սկավառակի տարածքը մինչև իսկ հեռացնելը, այնպիսի հրամանով.
$ docker volume rm $(docker volume ls -q)Հասկացանք, կամ մենք կարող ենք օգտագործել արդեն ծանոթ մեզ ենթառակտում prune:
$ docker volume prune
ՀԱՆՐԵՈՒՄ! Սա կհանե բոլոր տեղական ծավալները, որոնք չի օգտագործվում առնվազն մեկ կոնտեյների կողմից.
ԱՆՀՐԱԺեշտ ԷՐ ՁԵԶ ՀԱՄԱՃՈՎԸ շարունակելու համար? [y/N] y
Հեռացրած ծավալները:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da
Բոլոր շտկված տարածքը: 25.82GB
luc@saturn:~$Օգտագործման սկավառակի կետը ներկառուցման պատկերների կոշտ կացնելը
Docker 18.09-ում պատկերների ստեղծման գործընթացը որոշակի փոփոխություններ է ենթարկվել BuildKit գործիքի շնորհիվ: Այս գործիքը կավելացնի գործընթացի արագությունը, օպտիմիզացնի տվյալների պահպանման և անվտանգության կառավարումը: Այստեղ մենք չենք դիտարկում այս հրաշալի գործիքի բոլոր մանրամասները, ուղղակի կանգ կառնենք այն հարցի վրա, թե ինչպես է դա ազդում սկավառակի տարածքի օգտագործման վրա:
Գնահատենք, որ ունենք մի շատ պարզ Node.Js հավելված:
- index.js ֆայլին запускает простой HTTP սերվեր, который отвечает строкой на каждый полученный запрос:
- package.json ֆայլին սահմանում է կախվածությունները, որոնցից օգտագործվում է միայն expressjs 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"
}
}Dockerfile-ը, որով կառուցվում է պատկեր, նման է այսպիսին.
FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]Եկեք հավաքենք պատկերն սովորական ձևով, առանց BuildKit-ի օգտագործման.
$ docker build -t app:1.0 .Եթե մենք ստուգենք սկավառակի գործածությունը, ապա կտեսնենք, որ տարածություն զբաղեցնում են միայն հիմքի պատկեր (node:13-alpine) և ավարտական պատկեր (app:1.0):
Տեսակը Ընդամենը Ակտիվ Տարածքը Վերականգնելի
Պատկերներ 2 0 109.3MB 109.3MB (100%)
Կոնտեյներներ 0 0 0B 0B
Տեղական ծավալներ 0 0 0B 0B
Ստեղծման պահեստ 0 0 0B 0BՀաջորդենք մեր հավելվածի երկրորդ տարբերակի հավաքմանը՝ արդեն օգտագործելով BuildKit-ը: Bunun համար մեզ պարզապես անհրաժեշտ է տեղադրել DOCKER_BUILDKIT փոփոխականը 1-ի արժեքով:
$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .Եթե հիմա մենք ստուգենք հասանելի տարածությունը, կտեսնենք, որ այժմ մասնակցում է հավաքման քեշը (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Վերամաքրելու համար օգտագործենք հետևյալ հրահանգը:
$ 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Մաքրեք ամեն ինչ!
Արդյունքում, մենք դիտեցինք գործարկման տարածքի մաքրումը, որը զբաղեցնում են կոնտեյներները, պատկերները և ծավալները: Այս հարցում մեզ օգնում է prune ենթահրամանը: Բայց այն կարելի է օգտագործել նաև Docker-ի համակարգային մակարդակին, և կմաքրի ամեն ինչ, ինչի կարող է:
$ 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]Եթե դուք որևէ պատճառով խնայում եք կրիչի տարածությունը Docker-ով մեքենայի վրա, ապա պարբերաբար այս հրահանգի գործարկելն արժե սովորության վերածել:
Ընտանիք: habr.com
