Докер кеңештери: Машинаңызды таштандылардан тазалаңыз

Докер кеңештери: Машинаңызды таштандылардан тазалаңыз

Эй Хабр! Сиздердин назарыңыздарга макаланын котормосун сунуштайм "Докер кеңештери: жергиликтүү машинаңызды тазалаңыз" жазуучу Luc Juggery.

Бүгүн биз Docker хост-машинасынын диск мейкиндигин кантип колдоноору жөнүндө сүйлөшөбүз, ошондой эле бул мейкиндикти пайдаланылбаган сүрөттөрдүн жана контейнерлердин калдыктарынан кантип бошотууну чечебиз.


Докер кеңештери: Машинаңызды таштандылардан тазалаңыз

Жалпы керектөө

Докер - бул сонун нерсе, балким, бүгүнкү күндө аз адамдар шектениши мүмкүн. Болгону бир нече жыл мурун, бул продукт бизге CPU жана RAM ресурстарын олуттуу үнөмдөөгө мүмкүндүк берген ар кандай чөйрөнү куруунун, жеткирүүнүн жана иштетүүнүн жаңы ыкмасын берди. Мындан тышкары (жана кээ бирөөлөр үчүн бул эң маанилүү нерсе) Docker бизге өндүрүш чөйрөлөрүбүздүн жашоо циклин башкарууну укмуштуудай жөнөкөйлөтүүгө жана унификациялоого мүмкүндүк берди.

Бирок, азыркы жашоонун бардык бул ырахаттарынын баасы бар. Контейнерлерди иштеткенде, өзүбүздүн сүрөттөрүбүздү жүктөп алып же түзүп, татаал экосистемаларды орнотуп жатканда, биз төлөшүбүз керек. Жана биз, башкалардын арасында, диск мейкиндиги менен төлөйбүз.

Эгер сиз Docker сиздин машинаңызда канча орун ээлейт деп эч качан ойлобогон болсоңуз, анда бул буйруктун натыйжасы сизди таң калтырышы мүмкүн:

$ docker system df

Докер кеңештери: Машинаңызды таштандылардан тазалаңыз

Бул Докердин дисктин ар кандай контексттерде колдонулушун көрсөтөт:

  • сүрөттөр – сүрөттөрдүн репозиторийлеринен жүктөлүп алынган жана тутумуңузга курулган сүрөттөрдүн жалпы көлөмү;
  • контейнерлер – иштеп жаткан контейнерлер колдонгон диск мейкиндигинин жалпы көлөмү (бардык контейнерлердин окуу-жазуу катмарларынын жалпы көлөмүн билдирет);
  • жергиликтүү көлөмдөр – контейнерлерге орнотулган жергиликтүү сактоонун көлөмү;
  • куруу кэш – сүрөт түзүү процесси тарабынан түзүлгөн убактылуу файлдар (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 сүрөтүнүн Докерфайлында /data/db каталогу (Мында MongoDB демейки боюнча өз маалыматтарын сактайт) көлөм катары аныкталат.

Докер кеңештери: Машинаңызды таштандылардан тазалаңыз

Кошумча эскертүү: берилиштерди өндүрүү керек болгон көптөгөн сүрөттөр ошол маалыматтарды сактоо үчүн көлөмдү колдонушат.

Биз 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"
      }
    }

Сүрөттү куруу үчүн 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 машинаңызда диск мейкиндигин үнөмдөп жатсаңыз, анда бул буйрукту мезгил-мезгили менен аткаруу адатка айланышы керек.

Source: www.habr.com

Комментарий кошуу