Docker maslahatlari: Mashinangizni keraksiz narsalardan tozalang

Docker maslahatlari: Mashinangizni keraksiz narsalardan tozalang

Hey Xabr! E'tiboringizga maqolaning tarjimasini taqdim etaman "Docker maslahatlari: mahalliy mashinangizni tozalang" muallif Luc Juggery.

Bugun biz Docker xost-mashinaning disk maydonidan qanday foydalanishi haqida gaplashamiz, shuningdek, ushbu bo'sh joyni foydalanilmagan tasvirlar va konteynerlar qoldiqlaridan qanday bo'shatishni aniqlaymiz.


Docker maslahatlari: Mashinangizni keraksiz narsalardan tozalang

Umumiy iste'mol

Docker - bu ajoyib narsa, ehtimol bugungi kunda kam odam bunga shubha qiladi. Bir necha yil oldin ushbu mahsulot bizga protsessor va operativ xotira resurslarini sezilarli darajada tejash imkonini beruvchi har qanday muhitni yaratish, yetkazib berish va ishga tushirishning mutlaqo yangi usulini taqdim etdi. Bunga qo'shimcha ravishda (va ba'zilar uchun bu eng muhim narsa bo'ladi) Docker bizga ishlab chiqarish muhitlarining hayot aylanishini boshqarishni nihoyatda soddalashtirish va birlashtirish imkonini berdi.

Biroq, zamonaviy hayotning barcha lazzatlari qimmatga tushadi. Konteynerlarni ishga tushirganimizda, o'z rasmlarimizni yuklab olganimizda yoki yaratganimizda va murakkab ekotizimlarni o'rnatganimizda, biz to'lashimiz kerak. Va biz, boshqa narsalar qatori, disk maydoni bilan ham to'laymiz.

Agar siz Docker qurilmangizda qancha joy egallashi haqida hech qachon o'ylamagan bo'lsangiz, ushbu buyruqning chiqishi sizni hayratda qoldirishi mumkin:

$ docker system df

Docker maslahatlari: Mashinangizni keraksiz narsalardan tozalang

Bu turli kontekstlarda Dockerning diskdan foydalanishini ko'rsatadi:

  • tasvirlar - rasm omborlaridan yuklab olingan va tizimingizda o'rnatilgan tasvirlarning umumiy hajmi;
  • konteynerlar - ishlaydigan konteynerlar tomonidan ishlatiladigan disk maydonining umumiy miqdori (barcha konteynerlarning o'qish va yozish qatlamlarining umumiy hajmini anglatadi);
  • mahalliy hajmlar - konteynerlarga o'rnatilgan mahalliy saqlash hajmi;
  • Keshni yaratish - tasvirni yaratish jarayoni tomonidan yaratilgan vaqtinchalik fayllar (BuildKit vositasi yordamida, Docker 18.09 versiyasidan boshlab mavjud).

Ishonchim komilki, ushbu oddiy transferdan so'ng siz diskingizni axlatdan tozalash va qimmatbaho gigabaytlarni hayotga qaytarishni xohlaysiz (eslatma: ayniqsa, har oy bu gigabaytlar uchun ijara haqi to'layotgan bo'lsangiz).

Konteynerlar tomonidan diskdan foydalanish

Har safar xost mashinasida konteyner yaratganingizda, /var/lib/docker katalogida bir nechta fayl va kataloglar yaratiladi, ular orasida quyidagilarga e'tibor qaratish lozim:

  • Katalog /var/lib/docker/containers/container_ID – standart ro'yxatga olish drayveridan foydalanilganda, voqea jurnallari JSON formatida saqlanadi. Juda batafsil jurnallar, shuningdek, hech kim o'qimaydigan yoki boshqa usulda ishlov berilmaydigan jurnallar ko'pincha disklarning to'lib ketishiga olib keladi.
  • /var/lib/docker/overlay2 katalogi konteyner o'qish va yozish qatlamlarini o'z ichiga oladi (overlay2 ko'pchilik Linux distributivlarida afzal qilingan drayverdir). Agar konteyner ma'lumotlarni o'zining fayl tizimida saqlasa, u holda u shu katalogga joylashtiriladi.

Keling, hech qachon konteynerlarni ishga tushirish yoki tasvirlarni yaratishda ishtirok etmagan toza Docker o'rnatilgan tizimni tasavvur qilaylik. Uning disk maydonidan foydalanish hisoboti quyidagicha ko'rinadi:

$ 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

Keling, ba'zi konteynerni ishga tushiramiz, masalan, NGINX:

$ docker container run --name www -d -p 8000:80 nginx:1.16

Disk bilan nima sodir bo'ladi:

  • tasvirlar 126 MB hajmni egallaydi, bu biz konteynerda ishga tushirgan bir xil NGINX;
  • konteynerlar kulgili 2 baytni egallaydi.

$ 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

Xulosaga ko'ra, bizda hali bo'shatishimiz mumkin bo'lgan joy yo'q. 2 bayt mutlaqo befoyda bo'lgani uchun, tasavvur qilaylik, bizning NGINX kutilmaganda 100 megabayt ma'lumot yozdi va o'zida aynan shu hajmdagi test.img faylini yaratdi.

$ docker exec -ti www 
  dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]

Xostda disk maydonidan foydalanishni yana bir bor ko'rib chiqamiz. U erda konteyner (konteynerlar) 100 megabaytni egallashini ko'ramiz.

$ 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

O'ylaymanki, sizning qiziquvchan miyangiz test.img faylimiz qayerda joylashganligini allaqachon qiziqtirmoqda. Keling, qidiramiz:

$ 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

Tafsilotlarga kirmasdan, shuni ta'kidlashimiz mumkinki, test.img fayli o'qish-yozish darajasida qulay joylashgan bo'lib, u overlay2 drayveri tomonidan boshqariladi. Agar biz konteynerimizni to'xtatsak, uy egasi bizga bu bo'sh joyni bo'shatish mumkinligini aytadi:

# 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

Buni qanday qilishimiz mumkin? Konteynerni o'chirish orqali, bu o'qish-yozish darajasida tegishli bo'sh joyni tozalashni talab qiladi.

Quyidagi buyruq yordamida siz barcha o'rnatilgan konteynerlarni bir zumda olib tashlashingiz va ular tomonidan yaratilgan barcha o'qish-yozish fayllarini diskdan tozalashingiz mumkin:

$ 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

Shunday qilib, biz konteynerni o'chirish orqali 104,9 Megabaytni bo'shatib oldik. Ammo biz ilgari yuklab olingan rasmni endi ishlatmasligimiz sababli, u ham resurslarimizni o'chirish va bo'shatish uchun nomzod bo'ladi:

$ 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

Eslatma: Tasvir kamida bitta konteyner tomonidan ishlatilayotgan ekan, siz bu hiyladan foydalana olmaysiz.

Yuqorida biz ishlatgan prune kichik buyrug'i faqat to'xtatilgan konteynerlarga ta'sir qiladi. Agar biz nafaqat to'xtatilgan, balki ishlaydigan konteynerlarni ham o'chirmoqchi bo'lsak, biz quyidagi buyruqlardan birini ishlatishimiz kerak:

# Historical command
$ docker rm -f $(docker ps –aq)

# More recent command
$ docker container rm -f $(docker container ls -aq)

Yon eslatmalar: agar siz konteynerni ishga tushirishda -rm parametridan foydalansangiz, u to'xtaganda, u egallagan barcha disk maydoni bo'shatiladi.

Disk tasvirlaridan foydalanish

Bir necha yil oldin bir necha yuz megabaytlik tasvir hajmi mutlaqo normal edi: Ubuntu tasvirining og'irligi 600 megabayt, Microsoft .Net tasviri esa bir necha gigabayt edi. O'sha og'ir kunlarda faqat bitta rasmni yuklab olish diskdagi bo'sh joyingizga katta zarar etkazishi mumkin, hatto siz rasmlar orasidagi darajalarni almashsangiz ham. Bugungi kunda - buyuklarga hamdu sanolar bo'lsin - tasvirlarning og'irligi ancha past, ammo shunga qaramay, ba'zi ehtiyot choralarini ko'rmasangiz, mavjud resurslarni tezda to'ldirishingiz mumkin.

Yakuniy foydalanuvchiga bevosita ko'rinmaydigan tasvirlarning bir nechta turlari mavjud:

  • oraliq tasvirlar, ular asosida boshqa rasmlar to'planadi - agar siz ushbu "boshqa" rasmlarga asoslangan konteynerlardan foydalansangiz, ularni o'chirib bo'lmaydi;
  • osilgan tasvirlar oraliq tasvirlar bo'lib, ularga hech qanday ishlaydigan konteynerlar havola qilmaydi - ularni o'chirish mumkin.
  • Quyidagi buyruq yordamida siz tizimingizda osilgan tasvirlarni tekshirishingiz mumkin:

$ docker image ls -f dangling=true
REPOSITORY  TAG      IMAGE ID         CREATED             SIZE
none      none   21e658fe5351     12 minutes ago      71.3MB

Siz ularni quyidagi yo'llar bilan olib tashlashingiz mumkin:

$ docker image rm $(docker image ls -f dangling=true -q)

Prune kichik buyrug'idan ham foydalanishimiz mumkin:

$ 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

Agar biz to'satdan bitta buyruq bilan barcha tasvirlarni butunlay yo'q qilmoqchi bo'lsak (va shunchaki osilgan emas), unda biz buni qila olamiz:

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

Jildlar bo'yicha diskdan foydalanish

Hajmlar ma'lumotlarni konteyner fayl tizimidan tashqarida saqlash uchun ishlatiladi. Misol uchun, agar biz dastur natijalarini boshqa usulda ishlatish uchun saqlamoqchi bo'lsak. Umumiy misol - ma'lumotlar bazalari.

Keling, MongoDB konteynerini ishga tushiramiz, konteynerdan tashqari hajmni o'rnatamiz va undan ma'lumotlar bazasi zahirasini tiklaymiz (bizda u bck.json faylida mavjud):

# 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

Ma'lumotlar xost mashinasida /var/lib/docker/volumes katalogida joylashgan bo'ladi. Lekin nima uchun konteynerning o'qish-yozish darajasida emas? Chunki MongoDB tasvirining Docker faylida /data/db katalogi (MongoDB sukut bo'yicha o'z ma'lumotlarini saqlaydi) jild sifatida aniqlanadi.

Docker maslahatlari: Mashinangizni keraksiz narsalardan tozalang

Yon eslatma: ma'lumot ishlab chiqarishi kerak bo'lgan ko'plab tasvirlar ushbu ma'lumotlarni saqlash uchun hajmlardan foydalanadi.

MongoDB bilan etarlicha o'ynaganimizda va konteynerni to'xtatganimizda (yoki hatto o'chirib tashlaganimizda), tovush o'chirilmaydi. Biz uni quyidagi buyruq bilan aniq o'chirmagunimizcha, u qimmatli disk maydonini egallashda davom etadi:

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

Xo'sh, yoki bizga allaqachon tanish bo'lgan prune pastki buyrug'idan foydalanishimiz mumkin:

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

Tasvir yaratish keshi uchun diskdan foydalanish

Docker 18.09 da tasvir yaratish jarayoni BuildKit vositasi tufayli ba'zi o'zgarishlarga duch keldi. Bu narsa jarayon tezligini oshiradi va ma'lumotlarni saqlash va xavfsizlikni boshqarishni optimallashtiradi. Bu erda biz ushbu ajoyib vositaning barcha tafsilotlarini ko'rib chiqmaymiz, biz faqat disk maydonidan foydalanish muammolarini qanday hal qilishiga e'tibor qaratamiz.

Aytaylik, bizda mutlaqo oddiy Node.Js ilovasi bor:

  • index.js fayli har bir qabul qilingan soβ€˜rovga qator bilan javob beradigan oddiy HTTP serverini ishga tushiradi:
  • package.json fayli bog'liqliklarni belgilaydi, ulardan faqat HTTP serverini ishga tushirish uchun expressjs ishlatiladi:

$ 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"
      }
    }

Tasvirni yaratish uchun Dockerfile quyidagicha ko'rinadi:

FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]

Keling, BuildKit-dan foydalanmasdan tasvirni odatiy tarzda quramiz:

$ docker build -t app:1.0 .

Agar biz disk maydonidan foydalanishni tekshirsak, faqat asosiy tasvir (tugun: 13-alp) va maqsad tasviri (ilova: 1.0) joy egallashini ko'rishimiz mumkin:

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 yordamida ilovamizning ikkinchi versiyasini yaratamiz. Buning uchun DOCKER_BUILDKIT o'zgaruvchisini 1 ga o'rnatishimiz kifoya:

$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .

Endi biz diskdan foydalanishni tekshirsak, u erda qurilish keshi (buid-kesh) hozir ishtirok etganligini ko'ramiz:

$ 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

Uni tozalash uchun quyidagi buyruqdan foydalaning:

$ 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

Hammasini tozalamoq!

Shunday qilib, biz konteynerlar, tasvirlar va hajmlar egallagan disk maydonini tozalashni ko'rib chiqdik. Bunda bizga prune kichik buyrug'i yordam beradi. Ammo undan docker tizimi darajasida ham foydalanish mumkin va u qo'lidan kelgan hamma narsani tozalaydi:

$ 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]

Agar biron sababga ko'ra siz Docker-da ishlaydigan mashinada disk maydonini saqlayotgan bo'lsangiz, bu buyruqni vaqti-vaqti bilan bajarish odat tusiga kirishi kerak.

Manba: www.habr.com

a Izoh qo'shish