Docker кеңестері: машинаңызды қоқыстардан тазалаңыз

Docker кеңестері: машинаңызды қоқыстардан тазалаңыз

Эй Хабр! Назарларыңызға мақаланың аудармасын ұсынамын «Докер кеңестері: жергілікті машинаңызды тазалаңыз» автор Люк Жуггери.

Бүгін біз Docker хост машинасының дискілік кеңістігін қалай пайдаланатыны туралы сөйлесетін боламыз, сонымен қатар бұл кеңістікті пайдаланылмаған кескіндер мен контейнерлердің қалдықтарынан босату жолын анықтаймыз.


Docker кеңестері: машинаңызды қоқыстардан тазалаңыз

Жалпы тұтыну

Докер - керемет нәрсе, бәлкім, бүгінде аз адамдар күмәнданады. Бірнеше жыл бұрын бұл өнім бізге процессор мен жедел жад ресурстарын айтарлықтай үнемдеуге мүмкіндік беретін кез келген ортаны құрудың, жеткізудің және іске қосудың мүлдем жаңа әдісін берді. Бұған қоса (және кейбіреулер үшін бұл ең маңыздысы болады) Docker бізге өндірістік орталарымыздың өмірлік циклін басқаруды керемет жеңілдетуге және бірегейлендіруге мүмкіндік берді.

Дегенмен, қазіргі өмірдің барлық осы ләззаттарының бағасы бар. Контейнерлерді іске қосқанда, өз кескіндерімізді жүктеп алғанда немесе жасағанда және күрделі экожүйелерді орналастырғанда, біз төлеуіміз керек. Және біз басқа нәрселермен қатар дискілік кеңістікпен төлейміз.

Егер сіз Docker құрылғыңызда қанша орын алатыны туралы ешқашан ойламаған болсаңыз, бұл пәрменнің нәтижесі сізді таң қалдыруы мүмкін:

$ docker system df

Docker кеңестері: машинаңызды қоқыстардан тазалаңыз

Бұл Docker дискінің әртүрлі контексттерде қолданылуын көрсетеді:

  • кескіндер – кескін репозиторийлерінен жүктеп алынған және сіздің жүйеңізге салынған кескіндердің жалпы өлшемі;
  • контейнерлер – жұмыс істейтін контейнерлер пайдаланатын дискілік кеңістіктің жалпы көлемі (барлық контейнерлердің оқу-жазу қабаттарының жалпы көлемін білдіреді);
  • жергілікті көлемдер – контейнерлерге орнатылған жергілікті қойманың көлемі;
  • құрастыру кэш – кескінді құру процесі арқылы жасалған уақытша файлдар (BuildKit құралын пайдалану, Docker 18.09 нұсқасынан бастап қол жетімді).

Осы қарапайым аударымнан кейін сіз дискіңізді қоқыстан тазартып, қымбат гигабайттарды өмірге қайтарғыңыз келетініне сенімдімін (ескерту: әсіресе осы гигабайттарды ай сайын жалдау ақысын төлесеңіз).

Контейнерлер бойынша дискіні пайдалану

Хост машинасында контейнер жасаған сайын, /var/lib/docker каталогында бірнеше файлдар мен каталогтар жасалады, олардың арасында мыналарды атап өткен жөн:

  • Каталог /var/lib/docker/containers/container_ID – стандартты журнал жүргізу драйверін пайдаланған кезде оқиға журналдары JSON пішімінде сақталады. Тым егжей-тегжейлі журналдар, сондай-ақ ешкім оқымайтын немесе басқа жолмен өңдемейтін журналдар жиі дискілердің толып кетуіне әкеледі.
  • /var/lib/docker/overlay2 каталогында контейнердің оқу-жазу қабаттары бар (overlay2 Linux дистрибутивтерінің көпшілігінде таңдаулы драйвер болып табылады). Егер контейнер деректерді өзінің файлдық жүйесінде сақтаса, онда ол осы каталогта орналастырылады.

Контейнерлерді іске қосуға немесе кескіндерді құруға ешқашан қатыспаған таза 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

Дискпен не болады:

  • суреттер 126 МБ алады, бұл біз контейнерде іске қосқан бірдей NGINX;
  • контейнерлер күлкілі 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]

Хосттағы дискілік кеңістікті пайдалануды қайтадан қарастырайық. Онда контейнер (контейнер) 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 файлы қабат2 драйвері басқаратын оқу-жазу деңгейінде ыңғайлы орналасқанын атап өтуге болады. Егер біз контейнерімізді тоқтатсақ, хост бізге бұл кеңістікті босатуға болатынын айтады:

# 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! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Total reclaimed space: 104.9MB

Сонымен, біз контейнерді жою арқылы 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 кескіні бірнеше гигабайт болды. Сол қиын күндерде тек бір суретті жүктеп алу, тіпті кескіндер арасында деңгейлерді бөліскен болсаңыз да, бос дискілік кеңістікке үлкен шығын әкелуі мүмкін. Бүгін - ұлыларға мақтау - кескіндердің салмағы әлдеқайда аз, бірақ соған қарамастан, кейбір сақтық шараларын қолданбасаңыз, қол жетімді ресурстарды тез толтыра аласыз.

Соңғы пайдаланушыға тікелей көрінбейтін кескіндердің бірнеше түрі бар:

  • аралық кескіндер, олардың негізінде басқа суреттер жиналады - егер сіз осы «басқа» суреттерге негізделген контейнерлерді пайдалансаңыз, оларды жою мүмкін емес;
  • салбырап тұрған кескіндер жұмыс істеп тұрған контейнерлердің ешқайсысына сілтеме жасамайтын аралық кескіндер - оларды жоюға болады.
  • Келесі пәрмен арқылы жүйеде салбырап тұрған кескіндерді тексеруге болады:

$ 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

Егер біз кенеттен бір пәрменмен барлық кескіндерді толығымен жойғымыз келсе (және жай ғана салбырап тұрған жоқ), онда біз мұны істей аламыз:

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

Көлем бойынша дискіні пайдалану

Көлемдер деректерді контейнердің файлдық жүйесінен тыс сақтау үшін пайдаланылады. Мысалы, егер біз қолданбаның нәтижелерін басқа жолмен пайдалану үшін сақтағымыз келсе. Жалпы мысал мәліметтер базасы.

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 каталогында хост машинасында орналасады. Бірақ неге контейнердің оқу-жазу деңгейінде емес? Себебі MongoDB кескінінің Docker файлында /data/db каталогы (MongoDB өз деректерін әдепкі бойынша сақтайды) том ретінде анықталады.

Docker кеңестері: машинаңызды қоқыстардан тазалаңыз

Бүйірлік ескертпе: деректерді шығаруы керек көптеген кескіндер сол деректерді сақтау үшін көлемдерді пайдаланады.

Біз MongoDB-пен жеткілікті түрде ойнап, контейнерді тоқтатқанда (немесе тіпті жойғанда), дыбыс көлемі жойылмайды. Біз оны келесідей пәрмен арқылы анық жоймайынша, ол дискідегі құнды орынды алады:

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

Немесе бізге бұрыннан таныс prune ішкі командасын пайдалана аламыз:

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

Кескінді құру кэші үшін дискіні пайдалану

Docker 18.09 нұсқасында кескін жасау процесі BuildKit құралының арқасында кейбір өзгерістерге ұшырады. Бұл процесс жылдамдығын арттырады және деректерді сақтау мен қауіпсіздікті басқаруды оңтайландырады. Мұнда біз осы тамаша құралдың барлық егжей-тегжейлерін қарастырмаймыз, біз тек оның дискілік кеңістікті пайдалану мәселелерін шешу жолдарын қарастырамыз.

Бізде мүлдем қарапайым Node.Js қолданбасы бар делік:

  • index.js файлы әрбір алынған сұрауға жолмен жауап беретін қарапайым HTTP серверін іске қосады:
  • package.json файлы HTTP серверін іске қосу үшін тек expressjs пайдаланылатын тәуелділіктерді анықтайды:

$ 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 файлы келесідей:

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 .

Дискідегі кеңістікті пайдалануды тексеретін болсақ, тек негізгі кескін (түйін:13-альпі) және мақсатты кескін (қолданба: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

BuildKit көмегімен қолданбамыздың екінші нұсқасын құрастырайық. Мұны істеу үшін бізге 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 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 жұмыс істейтін құрылғыда дискілік кеңістікті үнемдеп жатсаңыз, онда бұл пәрменді мерзімді түрде орындау әдетке айналуы керек.

Ақпарат көзі: www.habr.com

пікір қалдыру