Docker Məsləhətləri: Maşınınızı zibildən təmizləyin

Docker Məsləhətləri: Maşınınızı zibildən təmizləyin

Hey Habr! Məqalənin tərcüməsini diqqətinizə təqdim edirəm "Docker Tips: Yerli Maşınınızı Təmizləyin" müəllif Luc Juggery.

Bu gün biz Docker-in ana maşının disk sahəsindən necə istifadə etdiyi haqqında danışacağıq və bu boşluğu istifadə olunmamış şəkillər və konteynerlərin qırıntılarından necə azad edəcəyimizi də anlayacağıq.


Docker Məsləhətləri: Maşınınızı zibildən təmizləyin

Ümumi istehlak

Docker gözəl bir şeydir, yəqin ki, bu gün az adam şübhələnir. Cəmi bir neçə il əvvəl bu məhsul bizə CPU və RAM resurslarını əhəmiyyətli dərəcədə qənaət etməyə imkan verən istənilən mühiti qurmaq, çatdırmaq və idarə etmək üçün tamamilə yeni üsul təqdim etdi. Bundan əlavə (və bəziləri üçün bu ən vacib şey olacaq) Docker bizə istehsal mühitlərimizin həyat dövrünün idarə edilməsini inanılmaz dərəcədə sadələşdirməyə və unifikasiya etməyə imkan verdi.

Ancaq müasir həyatın bütün bu ləzzətlərinin bir qiyməti var. Konteynerləri işə saldıqda, öz şəkillərimizi endirdikdə və ya yaratdıqda və mürəkkəb ekosistemləri yerləşdirdikdə ödəniş etməliyik. Və biz, digər şeylər arasında, disk sahəsi ilə ödəyirik.

Docker-in maşınınızda nə qədər yer tutduğunu heç düşünməmisinizsə, bu əmrin nəticəsi sizi xoşagəlməz şəkildə təəccübləndirə bilər:

$ docker system df

Docker Məsləhətləri: Maşınınızı zibildən təmizləyin

Bu, müxtəlif kontekstlərdə Docker-in disk istifadəsini göstərir:

  • şəkillər – şəkil anbarlarından yüklənmiş və sisteminizdə qurulmuş şəkillərin ümumi ölçüsü;
  • konteynerlər – işləyən konteynerlər tərəfindən istifadə olunan disk sahəsinin ümumi həcmi (bütün konteynerlərin oxuma-yazma təbəqələrinin ümumi həcmi deməkdir);
  • yerli həcmlər – konteynerlərə quraşdırılmış yerli anbarın həcmi;
  • keş qurmaq – şəkil yaratma prosesi tərəfindən yaradılan müvəqqəti fayllar (BuildKit alətindən istifadə etməklə, Docker versiyası 18.09-dan başlayaraq mövcuddur).

Əminəm ki, bu sadə köçürmədən sonra siz diskinizi zibildən təmizləmək və qiymətli gigabaytları canlandırmaq üçün can atırsınız (qeyd: xüsusən də hər ay bu gigabaytlar üçün icarə haqqı ödəyirsinizsə).

Konteynerlər tərəfindən disk istifadəsi

Hər dəfə host maşınında konteyner yaratdığınız zaman /var/lib/docker kataloqunda bir neçə fayl və qovluq yaradılır, bunlar arasında aşağıdakıları qeyd etmək lazımdır:

  • Kataloq /var/lib/docker/containers/container_ID – standart giriş sürücüsündən istifadə edərkən hadisə qeydləri JSON formatında saxlanılır. Həddindən artıq təfərrüatlı qeydlər, eləcə də heç kimin oxumadığı və ya başqa cür emal etmədiyi qeydlər çox vaxt disklərin dolmasına səbəb olur.
  • /var/lib/docker/overlay2 qovluğunda konteyner oxuma-yazma təbəqələri var (overlay2 əksər Linux paylamalarında üstünlük verilən sürücüdür). Konteyner məlumatı öz fayl sistemində saxlayırsa, o, məhz bu kataloqda yerləşdiriləcək.

Təsəvvür edək ki, heç vaxt konteynerlərin işə salınmasında və ya şəkillərin yaradılmasında iştirak etməyən, təmiz Docker-in quraşdırıldığı bir sistemi təsəvvür edək. Onun disk sahəsinin istifadəsi hesabatı belə görünəcək:

$ 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

Bəzi konteyneri işə salaq, məsələn, NGINX:

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

Disklə nə baş verir:

  • şəkillər 126 MB tutur, bu konteynerdə işə saldığımız eyni NGINX-dir;
  • konteynerlər gülünc 2 bayt yer tutur.

$ 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

Nəticəyə əsasən, hələ boşalda biləcəyimiz yer yoxdur. 2 bayt tamamilə qeyri-ciddi olduğundan, təsəvvür edək ki, bizim NGINX gözlənilmədən harasa 100 Meqabayt məlumat yazıb və öz daxilində tam olaraq bu ölçüdə test.img faylı yaradıb.

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

Hostda disk sahəsinin istifadəsini yenidən nəzərdən keçirək. Orada konteynerin (konteynerlərin) 100 Meqabayt tutduğunu görəcəyik.

$ 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

Düşünürəm ki, sizin maraqlanan beyniniz artıq test.img faylımızın harada yerləşdiyi ilə maraqlanır. 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

Təfərrüatlara varmadan qeyd edə bilərik ki, test.img faylı oxumaq-yazmaq səviyyəsində rahat şəkildə yerləşib, overlay2 sürücüsü tərəfindən idarə olunur. Konteynerimizi dayandırsaq, ev sahibi bizə bu məkanın, prinsipcə, boşaldıla biləcəyini söyləyə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ə, bu, oxuma-yazma səviyyəsində müvafiq boşluğun təmizlənməsinə səbəb olacaqdır.

Aşağıdakı əmrlə siz bütün quraşdırılmış konteynerləri bir anda silə və diskinizi onların yaratdığı bütün oxu-yazma fayllarından təmizləyə bilərsiniz:

$ 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

Beləliklə, konteyneri silməklə 104,9 Meqabayt boşaldıq. Ancaq əvvəllər yüklənmiş təsviri artıq istifadə etmədiyimiz üçün o, həm də resurslarımızı silmək və boşaltmaq üçü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

Qeyd: Şəkil ən azı bir konteyner tərəfindən istifadə edildiyi müddətdə bu hiylədən istifadə edə bilməyəcəksiniz.

Yuxarıda istifadə etdiyimiz prune alt əmri yalnız dayandırılmış konteynerlərə təsir göstərir. Yalnız dayandırılmış deyil, həm də işləyən konteynerləri silmək istəyiriksə, bu əmrlərdən birini istifadə etməliyik:

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

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

Yan qeydlər: konteyneri işə salarkən -rm parametrindən istifadə etsəniz, o dayandıqda onun tutduğu bütün disk sahəsi boşalacaq.

Disk şəkillərinin istifadəsi

Bir neçə il əvvəl bir neçə yüz meqabaytlıq təsvir ölçüsü tamamilə normal idi: Ubuntu şəkli 600 meqabayt, Microsoft .Net şəkli isə bir neçə giqabayt ağırlığında idi. O çətin günlərdə, şəkillər arasında səviyyələri paylaşsanız belə, yalnız bir şəkil yükləmək boş disk sahəsinə böyük ziyan vura bilər. Bu gün - böyüklərə həmd olsun - şəkillərin çəkisi daha azdır, lakin buna baxmayaraq, bəzi ehtiyat tədbirləri görməsəniz, mövcud resursları tez doldura bilərsiniz.

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

  • digər şəkillərin toplandığı aralıq şəkillər - bu "digər" şəkillərə əsaslanan konteynerlərdən istifadə etsəniz, onlar silinə bilməz;
  • sallanan şəkillər işləyən konteynerlərin heç biri tərəfindən istinad edilməyən ara şəkillərdir - onlar silinə bilər.
  • Aşağıdakı əmrlə sisteminizdə sallanan şəkilləri 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ı şəkildə silə bilərsiniz:

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

Prune alt əmrindən də 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 bütün şəkilləri bir əmrlə silmək istəsək (və sadəcə sallanan deyil), onda bunu edə bilərik:

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

Həcmlər üzrə disk istifadəsi

Həcmlər konteynerin fayl sistemindən kənarda məlumatları saxlamaq üçün istifadə olunur. Məsələn, bir tətbiqin nəticələrini başqa cür istifadə etmək üçün saxlamaq istəsək. Ümumi nümunə verilənlər bazalarıdır.

Gəlin MongoDB konteynerini işə salaq, konteynerə xarici həcm quraşdıraq və ondan verilənlər bazası ehtiyat nüsxəsini bərpa edək (bck.json faylında mövcuddur):

# 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 /var/lib/docker/volumes qovluğunda host maşınında yerləşdiriləcək. Bəs niyə konteynerin oxuma-yazma səviyyəsində olmasın? Çünki MongoDB şəklinin Dockerfile-də /data/db kataloqu (MongoDB-nin defolt olaraq məlumatlarını saxladığı yer) həcm kimi müəyyən edilir.

Docker Məsləhətləri: Maşınınızı zibildən təmizləyin

Yan qeyd: məlumat istehsal etməli olan bir çox şəkillər həmin məlumatları saxlamaq üçün həcmlərdən istifadə edir.

MongoDB ilə kifayət qədər oynadıqda və konteyneri dayandırdıqda (və ya hətta sildikdə), həcm silinməyəcək. Biz bunu belə bir əmrlə açıq şəkildə silənə qədər qiymətli disk sahəsimizi tutmağa davam edəcək:

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

Yaxşı, ya da bizə artıq tanış olan prune alt əmrindən istifadə edə bilərik:

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

Şəkil qurma keşi üçün diskdən istifadə

Docker 18.09-da BuildKit aləti sayəsində təsvirin yaradılması prosesi bəzi dəyişikliklərə məruz qalıb. Bu şey prosesin sürətini artırır və məlumatların saxlanmasını və təhlükəsizliyin idarə edilməsini optimallaşdırır. Burada biz bu gözəl alətin bütün təfərrüatlarını nəzərdən keçirməyəcəyik, yalnız onun diskdən istifadə məsələlərini necə həll etdiyinə diqqət yetirəcəyik.

Deyək ki, bizim tamamilə sadə Node.Js tətbiqimiz var:

  • index.js faylı alınan hər sorğuya sətirlə cavab verən sadə HTTP serverini işə salır:
  • package.json faylı HTTP serverini işə salmaq üçün yalnız expressjs istifadə edilən asılılıqları müəyyən edir:

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

Şəkil yaratmaq üçü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"]

BuildKit-dən istifadə etmədən şəkli adi şəkildə quraq:

$ docker build -t app:1.0 .

Disk sahəsinin istifadəsini yoxlasaq, görərik ki, yalnız əsas təsvir (qovşaq:13-alp) və hədəf təsvir (app:1.0) yer tutur:

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-dən istifadə edərək tətbiqimizin ikinci versiyasını yaradaq. Bunun üçün sadəcə DOCKER_BUILDKIT dəyişənini 1-ə təyin etməliyik:

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

İndi diskdən istifadəni yoxlasaq, onda qurma önbelleğinin (buid-cache) indi orada iştirak etdiyini görərik:

$ 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

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

$ 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

Hamısını sil, hamısını təmizlə!

Beləliklə, biz konteynerlərin, şəkillərin və həcmlərin tutduğu disk yerini təmizləməyə baxdıq. Prune alt əmri bu işdə bizə kömək edir. Lakin o, docker sistemi səviyyəsində də istifadə edilə bilər və o, bacardığı hər şeyi təmizləyəcək:

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

Əgər nədənsə Docker ilə işləyən maşında disk sahəsinə qənaət edirsinizsə, onda bu əmri vaxtaşırı icra etmək vərdiş halına gəlməlidir.

Mənbə: www.habr.com

Добавить комментарий