Docker Տվյալներ: Չմոռացեք ազատել ձեր համակարգը ավելորդ բաներից

Docker Տվյալներ: Չմոռացեք ազատել ձեր համակարգը ավելորդ բաներից

Բարև, Հաբր! Ջենեցի ձեր ուշադրությանը հոդվածի թարգմանությունը "Docker Tips: Clean Up Your Local Machine" հեղինակ Լյուկ Յուգերի.

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


Docker Տվյալներ: Չմոռացեք ազատել ձեր համակարգը ավելորդ բաներից

Ընդհանուր օգտագործում

Docker-ը հիանալի բան է, և երբեք չի եղել մեկը, ով կասկածի տակ է դրել դա: Մի քանի տարի առաջ այս արտադրանքը մեզ տրամադրեց ամբողջովին նոր ճանապարհ, որպեսզի կառուցենք, տրամադրենք և գործարկենք ցանկացած միջավայր, թույլ տալով խնայել պրոցեսորի և օպերատիվ հիշողության ռեսուրսները: Այնուամենայնիվ, (և ինչ-որ մեկի համար սա կարող է նույնիսկ ամենակարևոր լինել) Docker-ը մեզ թույլ տվեց այնպես պարզեցնել և միավորել օգտագործվող աշխատանքային միջավայրերի կյանքի ցիկլի կառավարումը:

Սակայն, այս բոլորօրպետների համար պետք է վճարել: Երբ մենք կաղապարում ենք կոնտեյներներ, ներբեռնում կամ ստեղծում ենք սեփական պատկերներ, ձևավորում ենք բարդ էկոսիստեմներ, մենք ստիպված ենք վճարել: Եվ վճարում ենք, այդ թվում, սկավառակի տարածությամբ:

Եթե դուք երբեք չեք մտածել, թե որքան տարածք իրականում զբաղեցնում է ձեր մեքենայում Docker-ը, կարող եք անհանգստանալ այս հրամանով:

$ docker system df

Docker Տվյալներ: Չմոռացեք ազատել ձեր համակարգը ավելորդ բաներից

Այստեղ ցուցադրվում է 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):

Docker Տվյալներ: Չմոռացեք ազատել ձեր համակարգը ավելորդ բաներից

Մեկնաբանություններ դաշտերում: Ունենք բազմաթիվ պատկերներ, որոնց արդյունքում պետք է ստեղծվեն տվյալներ, օգտագործում են ծավալներ (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

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster