Mga Tip sa Docker: I-clear ang iyong makina ng junk

Mga Tip sa Docker: I-clear ang iyong makina ng junk

Hello, Habr! Ipinakita ko sa iyong pansin ang isang pagsasalin ng artikulo "Mga Tip sa Docker: Linisin ang Iyong Lokal na Makina" may-akda Luc Juggery.

Ngayon ay pag-uusapan natin kung paano ginagamit ng Docker ang disk space ng host machine, at malalaman din natin kung paano palayain ang puwang na ito mula sa mga scrap ng hindi nagamit na mga imahe at lalagyan.


Mga Tip sa Docker: I-clear ang iyong makina ng junk

Kabuuang pagkonsumo

Ang Docker ay isang cool na bagay, marahil ilang tao ang nagdududa ngayon. Ilang taon lang ang nakalipas, ang produktong ito ay nagbigay sa amin ng ganap na bagong paraan upang bumuo, maghatid at magpatakbo ng anumang kapaligiran, na nagbibigay-daan sa aming makabuluhang makatipid ng mga mapagkukunan ng CPU at RAM. Bilang karagdagan dito (at para sa ilan ay ito ang pinakamahalagang bagay) pinahintulutan kami ng Docker na pasimplehin at pag-isahin ang pamamahala ng lifecycle ng aming mga kapaligiran sa produksyon.

Gayunpaman, lahat ng mga kasiyahang ito ng modernong buhay ay may kapalit. Kapag nagpatakbo kami ng mga container, nag-download o gumawa ng sarili naming mga larawan, at nag-deploy ng mga kumplikadong ecosystem, kailangan naming magbayad. At nagbabayad kami, bukod sa iba pang mga bagay, gamit ang disk space.

Kung hindi mo naisip kung gaano karaming espasyo ang ginagamit ng Docker sa iyong makina, maaaring hindi ka kanais-nais na mabigla sa output ng command na ito:

$ docker system df

Mga Tip sa Docker: I-clear ang iyong makina ng junk

Ipinapakita nito ang paggamit ng disk ng Docker sa iba't ibang konteksto:

  • mga larawan – ang kabuuang sukat ng mga larawan na na-download mula sa mga imbakan ng imahe at binuo sa iyong system;
  • containers – ang kabuuang dami ng disk space na ginagamit ng mga tumatakbong container (ibig sabihin ang kabuuang dami ng read-write layer ng lahat ng container);
  • mga lokal na volume - ang dami ng lokal na imbakan na naka-mount sa mga lalagyan;
  • build cache – mga pansamantalang file na nabuo ng proseso ng pagbuo ng imahe (gamit ang tool na BuildKit, na magagamit simula sa bersyon ng Docker 18.09).

Pustahan ako na pagkatapos ng simpleng paglipat na ito ay sabik kang linisin ang iyong disk ng basura at buhayin ang mga mahalagang gigabyte (tandaan: lalo na kung magbabayad ka ng renta para sa mga gigabyte na ito bawat buwan).

Paggamit ng disk ng mga lalagyan

Sa tuwing gagawa ka ng container sa host machine, maraming file at direktoryo ang nalilikha sa /var/lib/docker directory, kung saan ang mga sumusunod ay dapat tandaan:

  • Direktoryo /var/lib/docker/containers/container_ID – kapag ginagamit ang karaniwang driver ng pag-log, dito naka-save ang mga log ng kaganapan sa JSON na format. Masyadong detalyadong mga log, pati na rin ang mga log na walang nagbabasa o kung hindi man ay pinoproseso, ay kadalasang nagiging sanhi ng mga disk upang maging puno.
  • Ang /var/lib/docker/overlay2 na direktoryo ay naglalaman ng container read-write layer (ang overlay2 ang gustong driver sa karamihan ng mga distribusyon ng Linux). Kung ang container ay nag-iimbak ng data sa file system nito, sa direktoryo na ito ito ilalagay.

Isipin natin ang isang sistema kung saan naka-install ang isang malinis na Docker, na hindi kailanman nasangkot sa paglulunsad ng mga lalagyan o pagbuo ng mga imahe. Ang ulat sa paggamit ng espasyo sa disk nito ay magiging ganito:

$ 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

Maglunsad tayo ng ilang lalagyan, halimbawa, NGINX:

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

Ano ang mangyayari sa disk:

  • ang mga imahe ay sumasakop sa 126 MB, ito ang parehong NGINX na inilunsad namin sa lalagyan;
  • ang mga lalagyan ay tumatagal ng katawa-tawang 2 byte.

$ 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

Sa paghusga sa konklusyon, wala pa tayong puwang na maaari nating palayain. Dahil ang 2 byte ay ganap na walang kabuluhan, isipin natin na ang aming NGINX ay hindi inaasahang nagsulat sa isang lugar ng 100 Megabytes ng data at lumikha ng isang file test.img na eksaktong ganito ang laki sa loob mismo.

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

Suriin natin muli ang paggamit ng espasyo sa disk sa host. Makikita natin na ang container (containers) ay sumasakop ng 100 Megabytes doon.

$ 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

Sa tingin ko ang iyong mausisa na utak ay nagtataka na kung saan matatagpuan ang aming test.img file. Hanapin natin ito:

$ 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

Nang hindi pumunta sa mga detalye, maaari naming tandaan na ang test.img file ay maginhawang matatagpuan sa antas ng read-write, na kinokontrol ng overlay2 driver. Kung ihihinto namin ang aming lalagyan, sasabihin sa amin ng host na ang espasyong ito, sa prinsipyo, ay maaaring mabakante:

# 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

Paano natin ito magagawa? Sa pamamagitan ng pagtanggal sa lalagyan, na mangangailangan ng pag-clear sa kaukulang espasyo sa antas ng read-write.

Gamit ang sumusunod na utos, maaari mong alisin ang lahat ng naka-install na lalagyan sa isang pagkakataon at i-clear ang iyong disk ng lahat ng read-write na file na nilikha ng mga ito:

$ 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

Kaya, nagbakante kami ng 104,9 Megabytes sa pamamagitan ng pagtanggal sa lalagyan. Ngunit dahil hindi na namin ginagamit ang naunang na-download na larawan, nagiging kandidato din ito para sa pagtanggal at pagpapalaya sa aming mga mapagkukunan:

$ 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

Tandaan: Hangga't ang larawan ay ginagamit ng hindi bababa sa isang lalagyan, hindi mo magagamit ang trick na ito.

Ang prune subcommand na ginamit namin sa itaas ay may epekto lamang sa mga tumigil na lalagyan. Kung gusto nating tanggalin ang hindi lamang huminto kundi pati na rin ang pagpapatakbo ng mga lalagyan, dapat nating gamitin ang isa sa mga utos na ito:

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

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

Mga tala sa gilid: kung gagamitin mo ang -rm parameter kapag nagsisimula ng isang lalagyan, pagkatapos ay kapag huminto ito, ang lahat ng espasyo sa disk na inookupahan nito ay malalaya.

Paggamit ng mga imahe sa disk

Ilang taon na ang nakalilipas, ang laki ng imahe na ilang daang megabytes ay ganap na normal: ang isang imahe ng Ubuntu ay tumitimbang ng 600 megabytes, at isang Microsoft .Net na imahe ay tumitimbang ng ilang gigabytes. Sa mga malabo na araw na iyon, ang pag-download ng isang larawan lang ay maaaring magdulot ng malaking pinsala sa iyong libreng espasyo sa disk, kahit na nagbabahagi ka ng mga antas sa pagitan ng mga larawan. Ngayon - papuri sa mahusay - mas mababa ang timbang ng mga imahe, ngunit kahit na gayon, maaari mong mabilis na punan ang mga magagamit na mapagkukunan kung hindi ka gumawa ng ilang mga pag-iingat.

Mayroong ilang mga uri ng mga larawan na hindi direktang nakikita ng end user:

  • mga intermediate na larawan, batay sa kung saan kinokolekta ang iba pang mga larawan - hindi matatanggal ang mga ito kung gumagamit ka ng mga lalagyan batay sa "iba pang" mga larawang ito;
  • Ang mga nakalawit na larawan ay mga intermediate na larawan na hindi nire-reference ng alinman sa mga tumatakbong lalagyan - maaari silang tanggalin.
  • Sa sumusunod na utos maaari mong suriin ang mga nakalawit na larawan sa iyong system:

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

Maaari mong alisin ang mga ito sa sumusunod na paraan:

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

Maaari rin nating gamitin ang prune subcommand:

$ 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

Kung biglang gusto nating tanggalin ang lahat ng mga imahe nang buo (at hindi lang nakabitin) gamit ang isang utos, magagawa natin ito:

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

Paggamit ng disk ayon sa mga volume

Ang mga volume ay ginagamit upang mag-imbak ng data sa labas ng file system ng container. Halimbawa, kung gusto naming i-save ang mga resulta ng isang application upang magamit ang mga ito sa ibang paraan. Ang isang karaniwang halimbawa ay ang mga database.

Maglunsad tayo ng isang lalagyan ng MongoDB, mag-mount ng isang volume sa labas ng lalagyan, at mag-restore ng backup ng database mula dito (mayroon tayong available sa bck.json file):

# 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

Ang data ay matatagpuan sa host machine sa /var/lib/docker/volume na direktoryo. Ngunit bakit hindi sa antas ng read-write ng container? Dahil sa Dockerfile ng MongoDB na imahe, ang /data/db na direktoryo (kung saan iniimbak ng MongoDB ang data nito bilang default) ay tinukoy bilang isang volume.

Mga Tip sa Docker: I-clear ang iyong makina ng junk

Side note: maraming mga larawan na dapat gumawa ng data ang gumagamit ng mga volume upang iimbak ang data na iyon.

Kapag naglaro tayo ng sapat sa MongoDB at itinigil (o maaaring tanggalin pa) ang lalagyan, hindi matatanggal ang volume. Ito ay patuloy na kukuha ng aming mahalagang puwang sa disk hanggang sa tahasan namin itong tanggalin gamit ang isang utos na tulad nito:

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

Well, o maaari nating gamitin ang prune subcommand na pamilyar na sa atin:

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

Paggamit ng disk para sa cache ng build ng imahe

Sa Docker 18.09, ang proseso ng paglikha ng imahe ay sumailalim sa ilang mga pagbabago salamat sa tool na BuildKit. Ang bagay na ito ay nagpapataas ng bilis ng proseso at nag-o-optimize ng pag-iimbak ng data at pamamahala ng seguridad. Dito hindi namin isasaalang-alang ang lahat ng mga detalye ng kahanga-hangang tool na ito; tututuon lamang namin kung paano nito tinutugunan ang mga isyu ng paggamit ng disk space.

Sabihin nating mayroon tayong ganap na simpleng application na Node.Js:

  • ang index.js file ay nagsisimula ng isang simpleng HTTP server na tumutugon sa isang linya sa bawat kahilingang natanggap:
  • ang package.json file ay tumutukoy sa mga dependencies, kung saan expressjs lang ang ginagamit upang patakbuhin ang HTTP server:

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

Ang Dockerfile para sa pagbuo ng imahe ay ganito:

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

Buuin natin ang imahe sa karaniwang paraan, nang hindi gumagamit ng BuildKit:

$ docker build -t app:1.0 .

Kung susuriin natin ang paggamit ng espasyo sa disk, makikita natin na ang batayang larawan lamang (node:13-alpine) at ang patutunguhang larawan (app:1.0) ang kumukuha ng espasyo:

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

Buuin natin ang pangalawang bersyon ng ating application, gamit ang BuildKit. Upang gawin ito, kailangan lang nating itakda ang DOCKER_BUILDKIT variable sa 1:

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

Kung susuriin natin ngayon ang paggamit ng disk, makikita natin na ang build cache (buid-cache) ay kasangkot na doon:

$ 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

Upang i-clear ito, gamitin ang sumusunod na command:

$ 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

Alisin lahat!

Kaya, tiningnan namin ang paglilinis ng espasyo sa disk na inookupahan ng mga lalagyan, larawan at volume. Tinutulungan tayo ng prune subcommand dito. Ngunit maaari rin itong gamitin sa antas ng sistema ng docker, at lilinisin nito ang lahat ng magagawa nito:

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

Kung sa ilang kadahilanan ay nagse-save ka ng puwang sa disk sa isang makina na nagpapatakbo ng Docker, kung gayon ang pana-panahong pagpapatakbo ng utos na ito ay dapat na maging isang ugali.

Pinagmulan: www.habr.com

Magdagdag ng komento