Маслиҳатҳои Docker: Мошини худро аз партовҳо тоза кунед

Маслиҳатҳои Docker: Мошини худро аз партовҳо тоза кунед

Салом, Хабр! Ман ба диққати шумо тарҷумаи мақоларо пешкаш мекунам "Маслиҳатҳои Docker: Мошини маҳаллии худро тоза кунед" муаллиф Люк Жуггери.

Имрӯз мо дар бораи он сӯҳбат хоҳем кард, ки чӣ тавр Docker фазои диски мошини ҳостро истифода мебарад ва мо инчунин мефаҳмем, ки чӣ гуна ин ҷойро аз пораҳои тасвирҳо ва контейнерҳои истифоданашуда озод кунем.


Маслиҳатҳои Docker: Мошини худро аз партовҳо тоза кунед

Истеъмоли умумӣ

Докер чизи аҷиб аст, шояд имрӯз кам одамон ба он шубҳа доранд. Ҳамагӣ чанд сол пеш, ин маҳсулот ба мо роҳи комилан нави сохтан, таҳвил додан ва идора кардани ҳама гуна муҳитро дод, ки ба мо имкон медиҳад, ки захираҳои CPU ва RAM-ро ба таври назаррас сарфа кунем. Илова бар ин (ва барои баъзеҳо ин чизи муҳимтарин хоҳад буд) Docker ба мо имкон дод, ки идоракунии давраи ҳаётии муҳити истеҳсолии моро бениҳоят содда ва муттаҳид созем.

Бо вуҷуди ин, ҳамаи ин лаззатҳои ҳаёти муосир бо нархи гарон меоянд. Вақте ки мо контейнерҳоро иҷро мекунем, тасвирҳои шахсии худро зеркашӣ мекунем ё эҷод мекунем ва экосистемаҳои мураккабро ҷойгир мекунем, мо бояд пардохт кунем. Ва мо дар байни чизҳои дигар, бо фазои диск пардохт мекунем.

Агар шумо ҳеҷ гоҳ дар бораи он фикр накарда бошед, ки Docker дар мошини шумо чӣ қадар ҷойро ишғол мекунад, шумо шояд аз натиҷаи ин фармон ба таври ногувор ҳайрон шавед:

$ docker system df

Маслиҳатҳои Docker: Мошини худро аз партовҳо тоза кунед

Ин истифодаи диски Docker-ро дар контекстҳои гуногун нишон медиҳад:

  • тасвирҳо - андозаи умумии тасвирҳое, ки аз анбори тасвирҳо бор карда шудаанд ва дар системаи шумо сохта шудаанд;
  • контейнерҳо – ҳаҷми умумии фазои диске, ки аз ҷониби контейнерҳо истифода мешавад (маънои ҳаҷми умумии қабатҳои хондан ва навиштани ҳама контейнерҳо);
  • ҳаҷмҳои маҳаллӣ – ҳаҷми нигаҳдории маҳаллӣ, ки дар зарфҳо васл карда шудаанд;
  • сохтани кэш - файлҳои муваққатӣ, ки тавассути раванди сохтани тасвир тавлид мешаванд (бо истифода аз абзори BuildKit, ки аз версияи Docker 18.09 дастрас аст).

Ман боварӣ дорам, ки пас аз ин интиқоли оддӣ шумо мехоҳед диски худро аз партовҳо тоза кунед ва гигабайтҳои қиматбаҳоро ба ҳаёт баргардонед (эътибор диҳед: хусусан агар шумо ҳар моҳ барои ин гигабайтҳо иҷора пардохт кунед).

Истифодаи диск аз ҷониби контейнерҳо

Ҳар дафъае, ки шумо дар мошини ҳост контейнер эҷод мекунед, дар феҳристи /var/lib/docker якчанд файлҳо ва директорияҳо сохта мешаванд, ки дар байни онҳо инҳоро бояд қайд кард:

  • Directory /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 дар сатҳи хондан-навиштан ҷойгир буда, аз ҷониби драйвери 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! 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 ҷойгир карда мешавад. Аммо чаро дар сатҳи хондан ва навиштани контейнер нест? Азбаски дар Dockerfile тасвири MongoDB, феҳристи /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 вобастагиҳоро муайян мекунад, ки аз онҳо танҳо 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 .

Агар мо истифодаи фазои дискро тафтиш кунем, мо мебинем, ки танҳо тасвири асосӣ (гиреҳ: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 кор мекунад, сарфа карда истода бошед, пас мунтазам иҷро кардани ин фармон бояд ба одат табдил ёбад.

Манбаъ: will.com

Илова Эзоҳ