Docker İpuçları: Maşınınızı Gereksiz Dosyalardan Temizleyin

Docker İpuçları: Maşınınızı Gereksiz Dosyalardan Temizleyin

Salam, Habr! Sizi məqalənin tərcüməsi ilə tanış edirəm "Docker İpuçları: Yerel Makinenizi Temizleyin" yazıçısı Luc Juggery.

Bugün Docker'ın ana makinenin disk alanını nasıl kullandığını konuşacağız ve bu alanı kullanılmayan görüntülerin ve konteynerlerin kalıntılarından nasıl boşaltacağımıza bakacağız.


Docker İpuçları: Maşınınızı Gereksiz Dosyalardan Temizleyin

Toplam Tüketim

Docker harika bir şey, artık bu konuda şüphe eden pek kimse yok. Sadece birkaç yıl önce bu ürün, her ortamı oluşturma, dağıtma ve başlatma konusunda bize tamamen yeni bir yol sunarak işlemci ve RAM kaynaklarından önemli ölçüde tasarruf etmemizi sağladı. Bunun yanında (bazıları için bu en önemli nokta olabilir) Docker, kullanılan çalışma ortamlarının yaşam döngüsünü inanılmaz derecede basitleştirmeyi ve standartlaştırmayı mümkün kıldı.

Ancak, tüm bu modern yaşam güzelliklerinin bir bedeli var. Konteynerleri çalıştırdığımızda, kendi görüntülerimizi indirdiğimizde veya oluşturduğumuzda, karmaşık ekosistemler kurduğumuzda, bir bedel ödemek zorundayız. Bu bedelin bir kısmı da disk alanı ile ödeniyor.

Eğer Docker'ın makinenizde gerçekten ne kadar yer kapladığını hiç düşünmediyseniz, bu komutun çıktısıyla kötü bir şekilde şaşırabilirsiniz:

$ docker system df

Docker İpuçları: Maşınınızı Gereksiz Dosyalardan Temizleyin

Burada, Docker'ın disk kullanımını çeşitli yönlerden gösterilmektedir:

  • görüntüler (images) – sisteminizde indirilmiş ve oluşturulmuş görüntülerin toplam boyutu;
  • konteynerler (containers) – çalışan konteynerler tarafından kullanılan toplam disk alanı (tüm konteynerlerin okuma-yazma katmanlarının toplam boyutu);
  • yerel hacimler (local volumes) – konteynerlere bağlanmış yerel depolama alanlarının boyutu;
  • derleme önbelleği (build cache) – görüntülerin oluşturulması sürecinde üretilen geçici dosyalar (Docker versiyonu 18.09'dan itibaren mevcut olan BuildKit aracını kullanırken).

Zaten bu basit liste sonrası diskinizi gereksizliklerden temizleme ve değerli gigabaytları geri kazanma isteğiyle yanıp tutuştuğunuzdan eminim (not: bu gigabaytlar için her ay kiralama bedeli ödüyorsanız özellikle de).

Konteynerlerin Disk Kullanımı

Herhangi bir konteyner oluşturulduğunda ana makinede /var/lib/docker dizininde bir dizi dosya ve dizin oluşturulmakta olup, bunlar arasında aşağıdaki noktaları belirtmek önemlidir:

  • /var/lib/docker/containers/ID_konteyneri dizini – standart kayıt sürücüsü kullanıldığında olay günlükleri JSON formatında tam olarak buraya kaydedilir. Aşırı detaylı günlükler ve kimsenin okumadığı veya başka şekillerde işlenmeyen günlükler genellikle disklerin dolmasına sebep olur.
  • Kataloq /var/lib/docker/overlay2 – konteynerlərin oxu-yazma qatlarını ehtiva edir (overlay2 – əksər Linux paylamalarında tövsiyə olunan sürücüdür). Əgər konteyner fayl sistemində məlumat saxlayırsa, məhz bu kataloqda yerləşəcək.

Gəlin, nəzarət edilməmiş bir Docker sistemini təsəvvür edək ki, heç bir konteyner işə salmır və imicləri yaratmır. Disk sahəsi istifadəsi haqqında hesabat bu cür görünəcək:

$ docker system df
NÖV           ÜMUMİ      AKTİV     BOYUT      TƏKRAR OLUNA BİLƏN
İmcələr       0          0          0B         0B
Konteynerlər   0          0          0B         0B
Yerli Həcm    0          0          0B         0B
İnşa Keşi    0          0          0B         0B

Gəlin, bir konteyner işə salaq, məsələn, NGINX:

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

Diskdə nə baş verir:

  • imcələr (images) 126 Mb yer tutmağa başlayır, bu, konteynerdə işə saldığımız həmin NGINX-dir;
  • konteynerlər (containers) isə 2 bayt yer tutur.

$ docker system df
NÖV           ÜMUMİ      AKTİV     BOYUT      TƏKRAR OLUNA BİLƏN
İmcələr       1          1          126M       0B (0%)
Konteynerlər   1          1          2B         0B (0%)
Yerli Həcm    0          0          0B         0B
İnşa Keşi    0          0          0B         0B

Verilənlərdən göründüyü kimi, bizim ərizəmizdə boşaltmaq üçün hələ sahə yoxdur. 2 bayt tamamilə ciddi deyil, gəlin, NGINX-in gözlənilmədən 100 megabayt məlumat yazdığını və özündə test.img adlı belə bir fayl yaratdığını təsəvvür edək.

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

Hostda disk sahəsi istifadəsini yenidən araşdıraq. Görəcəyik ki, konteyner (containers) orada 100 megabayt yer tutacaq.

$ docker system df
NÖV           ÜMUMİ      AKTİV     BOYUT      TƏKRAR OLUNA BİLƏN
İmcələr       1          1          126M       0B (0%)
Konteynerlər   1          1          104.9MB    0B (0%)
Yerli Həcm    0          0          0B         0B
İnşa Keşi    0          0          0B         0B

Düşünürəm ki, maraqlı ağlınız artıq test.img faylının harada olduğunu soruşur. Gəlin onu axtaraq:

$ 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

Detallara girmədən qeyd etmək olar ki, test.img faylı overlay2 sürücüsü tərəfindən idarə olunan oxu-yazma səviyyəsində rahatca yerləşir. Əgər konteynerimizi dayandırsaq, host bizə bu yerin prinsipcə boşaldılmasının mümkün olduğunu bildirəcək:

# 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

Bunu necə edə bilərik? Konteyneri silməklə ki, bu da oxu-yazma səviyyəsində müvafiq sahənin təmizlənməsinə səbəb olacaq.

Aşağıdakı komanda ilə siz bütün quraşdırılmış konteynerləri bir anda silə bilərsiniz və diskinizi onlardan yaranan oxu-yazma səviyyəsindəki fayllardan azad edə bilərsiniz:

$ docker container prune
XƏBƏRDARLIQ! Bu, bütün dayandırılmış konteynerləri siləcək.
Davamat etmək istədiyinizə əminsiniz? [y/N] y
Silinmiş Konteynerlər:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Ümumi bərpa olunan sahə: 104.9MB

Beləliklə, konteyneri silməklə 104,9 megabayt yer azad etdik. Ancaq daha əvvəl endirilmiş imici artıq istifadə etmədiyimiz üçün, o da silinmə və resurslarımızın azad edilməsi üçün namizəd olur:

$ 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

Diqqət: bir konteyner tərəfindən istifadədə olan bir görüntü mövcud olduğu müddətcə bu üsulu istifadə edə bilməzsiniz.

Yuxarıda istifadə etdiyimiz prune subkomandası yalnız dayandırılan konteynerlər üzərində təsir göstərir. Dayandırılanlardan əlavə, aktiv olan konteynerləri də silmək istəyiriksə, aşağıdakı komandaları istifadə etməliyik:

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

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

Konteyneri başlamada —rm parametrini istifadə edərək işlədirsinizsə, dayandırıldıqda onun tutduğu bütün disk alanı azad olunacaq.

Görüntülərin disk istifadəsi

Bir neçə il əvvəl bir neçə yüz megabaytlıq görüntü ölçüsü tamamilə normal hesab olunurdu: Ubuntu görüntüsü 600 Megabayt, Microsoft .Net görüntüsü isə bir neçə Gigabayt ağırlığına sahib idi. O vaxtlar bir görüntünün yüklənməsi sizin diskdəki boş yerə böyük zərər verə bilərdi, hətta görüntülər arasında səviyyələri paylaşsanız belə. Bugün isə — böyüklərə şükr — görüntülər çox daha yüngüldür, amma buna baxmayaraq, bəzi ehtiyat tədbirləri görmədiyinizdə mövcud resursları tez bir zamanda doldura bilərsiniz.

Son istifadəçiyə birbaşa görünməyən bir neçə növ görüntü var:

  • başqa görüntülər əsasında qurulmuş intermediate görüntülər — bu görüntülərin əsasında olan konteynerlər varsa, onları silmək mümkün deyil;
  • dangling görüntülər — bunlar, işə salınan konteynerlər tərəfindən istinad edilməyən intermediate görüntülərdir — silinə bilər.
  • Aşağıdakı komanda ilə sisteminizdə dangling görüntülərin olub olmadığını yoxlaya bilərsiniz:

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

Onları aşağıdakı üsulla silə bilərsiniz:

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

Eyni zamanda prune subkomandasını da istifadə edə bilərik:

$ 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

Əgər birdən-birə bütün görüntüləri (yalnız dangling deyil) bir komanda ilə silmək istəsək, bunu edə bilərik:

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

Tomasların disk istifadəsi

Tomaslar (volumes) konteynerin fayl sistemindən kənarda məlumatları saxlamaq üçün istifadə olunur. Məsələn, bir proqramın işləməsi nəticəsində əldə olunan nəticələri başqa cür istifadə etmək istədikdə. Tez-tez misal verilənlərdən biri verilənlər bazalarıdır.

Gəlin MongoDB konteynerini işə salaq, ona konteynerdən kənar bir tom montaj edək və verilənlər bazasının ehtiyat nüsxəsini (bck.json faylında mövcuddur) bərpa edək:

# 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

Məlumatlar host maşınında /var/lib/docker/volumes kataloqunda olacaq. Amma niyə konteynerin oxuma-yazma səviyyəsində deyil? Çünki MongoDB görüntüsünün Dockerfile-da /data/db kataloqu (MongoDB standart olaraq məlumatlarını saxladığı yer) həcmi (volume) olaraq müəyyən edilib.

Docker İpuçları: Maşınınızı Gereksiz Dosyalardan Temizleyin

Kənar qeydlər: bir çox görüntü, nəticədə məlumat yaradan, bu məlumatları saxlamaq üçün həcmlər (volumes) istifadə edir.

MongoDB ilə oynamağı bitirdikdə və konteyneri dayandırdıqda (bəlkə də, silsək) həcm silinməyəcək. O, bizim dəyərli disk sahəmizi tutmağa davam edəcək, ta ki, biz onu aydın şəkildə silmək üçün aşağıdakı əmri verməyincə:

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

Yaxud isə biz artıq tanış olduğumuz prune alt əmrini istifadə edə bilərik:

$ docker volume prune
WARNING! Bu, ən az bir konteyner tərəfindən istifadə edilməyən bütün yerli həcmləri siləcək.
Davamaq istədiyinizə əminsiniz? [y/N] y
Silinmiş Həcm:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Ümumi bərpa olunan sahə: 25.82GB
luc@saturn:~$

İşləmə sahəsinin diskdən istifadəsi üçün keşin istifadəsi

Docker 18.09-da görüntülərin yaradılması prosesi BuildKit aləti sayəsində bəzi dəyişikliklərə uğradı. Bu vasitə sayəsində prosesin sürəti artır, məlumatların saxlanması və təhlükəsizliyi optimallaşdırılır. Burada bu möhtəşəm vasitənin bütün detalları ilə tanış olmayacağıq, yalnız onun disk sahəsinin istifadəsini necə təsir etdiyinə fokuslanacağıq.

Təsəvvür edək ki, bizdə tamamilə sadə bir Node.Js tətbiqi var:

  • index.js faylı, aldığı hər bir sorğuya cavab verən sadə bir HTTP serverini işə salır:
  • package.json faylı asılılıqları müəyyən edir, onlardan yalnız expressjs HTTP serverini işə salmaq üçün istifadə olunur:

$ 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(), 'Sorğu Alındı'));
});
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"
      }
    }

Görüntünü qurmaq üçün Dockerfile belə görünür:

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

Gəlin görüntünü adi üsulla, BuildKit istifadə etmədən yığaq:

$ docker build -t app:1.0 .

Disk sahəsinin istifadəsini yoxlayanda görərik ki, yalnız əsas görüntü (node:13-alpine) və son görüntü (app:1.0) yer tutur:

NÖV           CƏM       AKTİV      ÖLÇÜ      BƏRPA OLUNAN
Görüntülər    2         0          109.3MB   109.3MB (100%)
Konteynerlər   0         0          0B        0B
Yerli Həcm    0         0          0B        0B
Quraşdırma Keşi 0         0          0B        0B

Gəlin BuildKit-dən istifadə edərək proqramımızın ikinci versiyasını yığaq. Bunun üçün yalnız DOCKER_BUILDKIT mühit dəyişənini 1 dəyərinə təyin etməliyik:

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

İndi disk istifadəsini yoxlasaq, yığma keşinin (build-cache) artıq iştirak etdiyini görəcəyik:

$ docker system df
TIP            CƏM     AKTİV    BOYUT      BƏYƏNİLƏN
Şəkillər       2       0        109.3MB    109.3MB (100%)
Konteynerlər   0       0        0B         0B
Yerel Həcmlər 0       0        0B         0B
Yığma Kəşfi   11      0        8.949kB    8.949kB

Onu təmizləmək üçün aşağıdakı əmrdən istifadə edəcəyik:

$ docker builder prune
XƏBƏRDARLIQ! Bu, bütün asılı (dangling) yığma keşini siləcək.
Davama əminsinizmi? [y/N] y
Silinmiş yığma keş obyekti:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi

Təmizlənmiş toplam yer: 8.949kB

Hər şeyi təmizləyin!

Beləliklə, konteynerlər, şəkillər və həcmlər tərəfindən tutulan disk sahəsini təmizləməyi nəzərdən keçirdik. Bu işdə bizə prune alt komandası kömək edir. Ancaq bunu docker sistem səviyyəsində də istifadə edə bilərik və bu, yalnız edə biləcəyi hər şeyi təmizləyəcək:

$ docker system prune
XƏBƏRDARLIQ! Bu, siləcək:
  - bütün dayandırılmış konteynerlər
  - ən az bir konteyner tərəfindən istifadə edilməyən bütün şəbəkələr
  - bütün asılı şəkillər
  - bütün asılı yığma keşləri

Davama əminsinizmi? [y/N]

Əgər hər hansı bir səbəbdən Docker olan maşınınızda disk yerini qənaət edirsinizsə, bu əmri dövri olaraq işə salmağı vərdiş halına gətirmək faydalıdır.

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster