Këshilla Docker: Pastrojeni kompjuterin tuaj nga mbeturinat

Këshilla Docker: Pastrojeni kompjuterin tuaj nga mbeturinat

Përshëndetje, Habr! Unë paraqes në vëmendjen tuaj një përkthim të artikullit "Këshilla Docker: Pastroni makinën tuaj lokale" autori Luc Juggery.

Sot do të flasim për mënyrën se si Docker përdor hapësirën e diskut të makinës pritëse, dhe gjithashtu do të kuptojmë se si ta çlirojmë këtë hapësirë ​​nga mbetjet e imazheve dhe kontejnerëve të papërdorur.


Këshilla Docker: Pastrojeni kompjuterin tuaj nga mbeturinat

Konsumi total

Docker është një gjë e lezetshme, ndoshta pak njerëz e dyshojnë sot. Vetëm pak vite më parë, ky produkt na dha një mënyrë krejtësisht të re për të ndërtuar, ofruar dhe drejtuar çdo mjedis, duke na lejuar të kursejmë ndjeshëm burimet e CPU dhe RAM. Përveç kësaj (dhe për disa kjo do të jetë gjëja më e rëndësishme) Docker na ka lejuar të thjeshtojmë dhe unifikojmë jashtëzakonisht menaxhimin e ciklit jetësor të mjediseve tona të prodhimit.

Megjithatë, të gjitha këto kënaqësi të jetës moderne kanë një çmim. Kur ne përdorim kontejnerë, shkarkojmë ose krijojmë imazhet tona dhe vendosim ekosisteme komplekse, ne duhet të paguajmë. Dhe ne paguajmë, ndër të tjera, me hapësirë ​​në disk.

Nëse nuk keni menduar kurrë se sa hapësirë ​​​​zë në të vërtetë Docker në kompjuterin tuaj, mund të befasoheni në mënyrë të pakëndshme nga dalja e kësaj komande:

$ docker system df

Këshilla Docker: Pastrojeni kompjuterin tuaj nga mbeturinat

Kjo tregon përdorimin e diskut të Docker në kontekste të ndryshme:

  • imazhe – madhësia totale e imazheve që janë shkarkuar nga depot e imazheve dhe janë ndërtuar në sistemin tuaj;
  • kontejnerët – sasia totale e hapësirës në disk të përdorur nga kontejnerët që funksionojnë (që do të thotë vëllimi i përgjithshëm i shtresave të leximit-shkrimit të të gjithë kontejnerëve);
  • vëllime lokale - vëllimi i ruajtjes lokale të montuar në kontejnerë;
  • build cache – skedarë të përkohshëm të krijuar nga procesi i ndërtimit të imazhit (duke përdorur mjetin BuildKit, i disponueshëm duke filluar me versionin Docker 18.09).

Vë bast se pas këtij transferimi të thjeshtë, ju jeni të etur të pastroni diskun tuaj nga mbeturinat dhe të ktheni në jetë gigabajt të çmuar (shënim: veçanërisht nëse paguani qiranë për këto gigabajt çdo muaj).

Përdorimi i diskut nga kontejnerët

Sa herë që krijoni një kontejner në makinën pritëse, krijohen disa skedarë dhe drejtori në drejtorinë /var/lib/docker, ndër të cilat vlen të përmenden sa vijon:

  • Drejtoria /var/lib/docker/containers/container_ID – kur përdorni drejtuesin standard të regjistrimit, këtu ruhen regjistrat e ngjarjeve në formatin JSON. Regjistrimet shumë të detajuara, si dhe regjistrat që askush nuk i lexon ose nuk i përpunon ndryshe, shpesh bëjnë që disqet të mbushen.
  • Drejtoria /var/lib/docker/overlay2 përmban shtresat e leximit-shkrimit të kontejnerit (overlay2 është drejtuesi i preferuar në shumicën e shpërndarjeve Linux). Nëse kontejneri ruan të dhënat në sistemin e tij të skedarëve, atëherë do të vendoset në këtë direktori.

Le të imagjinojmë një sistem në të cilin është instaluar një Docker i pacenuar, i cili kurrë nuk është përfshirë në hedhjen e kontejnerëve apo ndërtimin e imazheve. Raporti i përdorimit të hapësirës së tij në disk do të duket si ky:

$ 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

Le të lëshojmë disa kontejnerë, për shembull, NGINX:

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

Çfarë ndodh me diskun:

  • imazhet zënë 126 MB, ky është i njëjti NGINX që lëshuam në kontejner;
  • kontejnerët marrin një 2 bajt qesharake.

$ 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

Duke gjykuar nga përfundimi, ne nuk kemi ende asnjë hapësirë ​​që mund të lironim. Meqenëse 2 bajt janë krejtësisht joserioze, le të imagjinojmë që NGINX-i ynë papritmas shkroi diku 100 megabajt të dhëna dhe krijoi një skedar test.img pikërisht me këtë madhësi brenda vetes.

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

Le të shqyrtojmë përsëri përdorimin e hapësirës në disk në host. Do të shohim që kontejneri (kontejnerët) zë 100 Megabajt atje.

$ 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

Mendoj se truri juaj kureshtar tashmë po pyet se ku ndodhet skedari ynë test.img. Le ta kërkojmë:

$ 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

Pa hyrë në detaje, mund të vërejmë se skedari test.img ndodhet lehtësisht në nivelin e leximit-shkrimit, i kontrolluar nga drejtuesi i mbivendosjes2. Nëse ndalojmë kontejnerin tonë, hosti do të na thotë se kjo hapësirë, në parim, mund të lirohet:

# 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

Si mund ta bëjmë këtë? Duke fshirë kontejnerin, i cili do të sjellë pastrimin e hapësirës përkatëse në nivelin e leximit-shkrimit.

Me komandën e mëposhtme, ju mund të hiqni të gjithë kontejnerët e instaluar me një goditje dhe të pastroni diskun tuaj nga të gjithë skedarët e leximit-shkrimit të krijuar prej tyre:

$ 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

Pra, çliruam 104,9 Megabajt duke fshirë kontejnerin. Por meqenëse nuk përdorim më imazhin e shkarkuar më parë, ai gjithashtu bëhet një kandidat për fshirjen dhe çlirimin e burimeve tona:

$ 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

Shënim: Për sa kohë që imazhi është në përdorim nga të paktën një kontejner, nuk do të mund ta përdorni këtë truk.

Nënkomanda prune që përdorëm më sipër ka një efekt vetëm në kontejnerët e ndalur. Nëse duam të fshijmë jo vetëm kontejnerët e ndaluar, por edhe të ekzekutuar, duhet të përdorim një nga këto komanda:

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

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

Shënime anësore: nëse përdorni parametrin -rm kur nisni një kontejner, atëherë kur të ndalojë, e gjithë hapësira në disk që ka zënë do të lirohet.

Përdorimi i imazheve të diskut

Disa vjet më parë, një madhësi imazhi prej disa qindra megabajt ishte krejtësisht normale: një imazh i Ubuntu peshonte 600 megabajt dhe një imazh i Microsoft .Net peshonte disa gigabajt. Në ato ditë të ashpra, shkarkimi i vetëm një imazhi mund të marrë një taksë të madhe në hapësirën tuaj të lirë të diskut, edhe nëse po ndani nivele midis imazheve. Sot - lavdërim i madh - imazhet peshojnë shumë më pak, por edhe kështu, ju mund të plotësoni shpejt burimet e disponueshme nëse nuk merrni disa masa paraprake.

Ekzistojnë disa lloje imazhesh që nuk janë drejtpërdrejt të dukshme për përdoruesin përfundimtar:

  • imazhe të ndërmjetme, në bazë të të cilave janë mbledhur imazhe të tjera - ato nuk mund të fshihen nëse përdorni kontejnerë të bazuar në këto imazhe "të tjera";
  • Imazhet e varura janë imazhe të ndërmjetme që nuk referohen nga asnjë prej kontejnerëve që funksionojnë - ato mund të fshihen.
  • Me komandën e mëposhtme mund të kontrolloni për imazhe të varura në sistemin tuaj:

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

Ju mund t'i hiqni ato në mënyrën e mëposhtme:

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

Mund të përdorim gjithashtu nënkomandën 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

Nëse papritmas duam të fshijmë të gjitha imazhet krejtësisht (dhe jo vetëm të varura) me një komandë, atëherë mund ta bëjmë këtë:

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

Përdorimi i diskut sipas vëllimeve

Vëllimet përdoren për të ruajtur të dhënat jashtë sistemit të skedarëve të kontejnerit. Për shembull, nëse duam të ruajmë rezultatet e një aplikacioni në mënyrë që t'i përdorim ato në ndonjë mënyrë tjetër. Një shembull i zakonshëm janë bazat e të dhënave.

Le të hapim një kontejner MongoDB, të montojmë një vëllim jashtë kontejnerit dhe të rivendosim një kopje rezervë të bazës së të dhënave prej tij (e kemi të disponueshme në skedarin 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

Të dhënat do të vendosen në kompjuterin pritës në drejtorinë /var/lib/docker/volumes. Por pse jo në nivelin e leximit-shkrimit të kontejnerit? Sepse në Dockerfile të imazhit MongoDB, drejtoria /data/db (ku MongoDB ruan të dhënat e saj si parazgjedhje) përcaktohet si një vëllim.

Këshilla Docker: Pastrojeni kompjuterin tuaj nga mbeturinat

Shënim anësor: shumë imazhe që duhet të prodhojnë të dhëna përdorin vëllime për të ruajtur ato të dhëna.

Kur luajmë mjaftueshëm me MongoDB dhe ndalojmë (ose ndoshta edhe fshijmë) kontejnerin, vëllimi nuk do të fshihet. Do të vazhdojë të zërë hapësirën tonë të çmuar në disk derisa ta fshijmë në mënyrë të qartë me një komandë si kjo:

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

Epo, ose mund të përdorim nënkomandën prune që është tashmë e njohur për ne:

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

Përdorimi i diskut për cache-in e ndërtimit të imazhit

Në Docker 18.09, procesi i krijimit të imazhit ka pësuar disa ndryshime falë mjetit BuildKit. Kjo gjë rrit shpejtësinë e procesit dhe optimizon ruajtjen e të dhënave dhe menaxhimin e sigurisë. Këtu nuk do të shqyrtojmë të gjitha detajet e këtij mjeti të mrekullueshëm; ne do të përqendrohemi vetëm në mënyrën se si ai trajton çështjet e përdorimit të hapësirës në disk.

Le të themi se kemi një aplikacion krejtësisht të thjeshtë Node.Js:

  • skedari index.js fillon një server të thjeshtë HTTP që i përgjigjet me një rresht çdo kërkese të marrë:
  • skedari package.json përcakton varësitë, nga të cilat vetëm expressjs përdoret për të ekzekutuar serverin HTTP:

$ 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 për ndërtimin e imazhit duket kështu:

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

Le ta ndërtojmë imazhin në mënyrën e zakonshme, pa përdorur BuildKit:

$ docker build -t app:1.0 .

Nëse kontrollojmë përdorimin e hapësirës në disk, mund të shohim se vetëm imazhi bazë (nyja:13-alpine) dhe imazhi i destinacionit (app:1.0) po zënë hapësirë:

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

Le të ndërtojmë versionin e dytë të aplikacionit tonë, duke përdorur BuildKit. Për ta bërë këtë, ne vetëm duhet të vendosim variablin DOCKER_BUILDKIT në 1:

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

Nëse tani kontrollojmë përdorimin e diskut, do të shohim se cache-ja e ndërtimit (buid-cache) tani është përfshirë atje:

$ 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

Për ta pastruar atë, përdorni komandën e mëposhtme:

$ 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

Pastroji të gjitha!

Pra, ne shikuam pastrimin e hapësirës së diskut të zënë nga kontejnerët, imazhet dhe vëllimet. Nënkomanda Prune na ndihmon për këtë. Por mund të përdoret gjithashtu në nivelin e sistemit docker dhe do të pastrojë gjithçka që mundet:

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

Nëse për ndonjë arsye po kurseni hapësirë ​​në disk në një makinë që funksionon Docker, atëherë ekzekutimi periodik i kësaj komande duhet të bëhet zakon.

Burimi: www.habr.com

Shto një koment