Docker Savjeti: Očistite svoj stroj od smeća

Docker Savjeti: Očistite svoj stroj od smeća

Bok, Habr! Predstavljam vam prijevod članka "Docker Savjeti: Očistite Vaš Lokalni Stroj" autor Luc Juggery.

Danas ćemo razgovarati o tome kako Docker koristi diskovni prostor domaćina, kao i kako osloboditi taj prostor od ostataka neiskorištenih slika i kontejnera.


Docker Savjeti: Očistite svoj stroj od smeća

Ukupna potrošnja

Docker je stvarno sjajna stvar, danas vjerojatno malo tko o tome sumnja. Prije nekoliko godina, ovaj proizvod nam je pružio potpuno novi način izgradnje, isporuke i pokretanja bilo kojeg okruženja, omogućujući nam da značajno uštedimo resurse procesora i radne memorije. Pored toga (a za neke će to biti čak i najvažnije), Docker nam je omogućio nevjerojatno pojednostavljenje i unifikaciju upravljanja životnim ciklom korištenih radnih okruženja.

Međutim, za sve te blagodati modernog života potrebno je platiti. Kada pokrećemo kontejnere, preuzimamo ili stvaramo vlastite slike, postavljamo složene ekosustave, moramo platiti. I plaćamo, između ostalog, diskovnim prostorom.

Ako nikada niste razmišljali o tome koliko prostora zapravo zauzima vaš Docker, moglo bi vas neugodno iznenaditi izlaz ove naredbe:

$ docker system df

Docker Savjeti: Očistite svoj stroj od smeća

Ovdje se prikazuje korištenje diska Docker-a u različitim segmentima:

  • slike (images) – ukupna veličina slika koje su preuzete iz spremišta slika i izgrađene u vašem sustavu;
  • kontejneri (containers) – ukupni volumen diskovnog prostora koji koriste pokrenuti kontejneri (misli se na ukupni volumen slojeva za čitanje i pisanje svih kontejnera);
  • lokalni volumeni (local volumes) – volumen lokalnih spremišta montiranih na kontejnere;
  • keš izgradnje (build cache) – privremene datoteke generirane procesom izgradnje slika (prilikom korištenja alata BuildKit, dostupnog od Docker verzije 18.09).

Sigurno se kockam da se već nakon ovog jednostavnog nabrajanja palite željom da očistite disk od smeća i vratite u život dragocjene gigabajte (napomena: posebno, ako mjesečno plaćate najam za te gigabajte).

Korištenje diska od strane kontejnera

Svaki put kada se stvori kontejner na domaćem stroju, u direktoriju /var/lib/docker stvara se nekoliko datoteka i direktorija, među kojima vrijedi istaknuti sljedeće:

  • Katalog /var/lib/docker/containers/ID_kontejnera – kada se koristi standardni driver za logiranje, upravo ovdje se pohranjuju dnevnici događaja u JSON formatu. Previše detaljni dnevnici, kao i dnevnici koje nitko ne čita i ne obrađuje na druge načine, često postaju uzrok preopterećenja diskova.
  • Katalog /var/lib/docker/overlay2 – sadrži slojeve za čitanje i pisanje kontejnera (overlay2 je preferirani driver u većini Linux distribucija). Ako kontejner pohranjuje podatke u vlastitom datotečnom sustavu, oni će biti smješteni upravo u ovom katalogu.

Zamislimo sustav na kojem je instaliran netaknut Docker, koji nikada nije pokrenuo kontejner niti sastavio slike. Njegov izvještaj o korištenju diska izgledat će ovako:

$ docker system df
TIPA           UKUPNO    AKTIVNO   VELIČINA    OSLOBODIVO
Slike          0         0         0B         0B
Kontejneri     0         0         0B         0B
Lokalni volumeni 0       0         0B         0B
Predmemorija    0       0         0B         0B

Pokrenimo neki kontejner, na primjer, NGINX:

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

Što se događa s diskom:

  • slike (images) zauzimaju 126 MB, to je onaj NGINX koji smo pokrenuli u kontejneru;
  • kontejneri (containers) zauzimaju smiješnih 2 bajta.

$ docker system df
TIPA           UKUPNO    AKTIVNO   VELIČINA    OSLOBODIVO
Slike          1         1         126M       0B (0%)
Kontejneri     1         1         2B         0B (0%)
Lokalni volumeni 0       0         0B         0B
Predmemorija    0       0         0B         0B

Sudeći prema izlazu, još uvijek nemamo prostora koji bismo mogli osloboditi. Budući da je 2 bajta sasvim neozbiljno, zamislimo da je naš NGINX iznenada zapisao negdje 100 Megabajta podataka i stvorio unutar sebe datoteku test.img upravo te veličine.

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

Ponovno istražujemo korištenje diska na hostu. Vidjet ćemo da kontejner (containers) zauzima 100 Megabajta.

$ docker system df
TIPA           UKUPNO    AKTIVNO   VELIČINA    OSLOBODIVO
Slike          1         1         126M       0B (0%)
Kontejneri     1         1         104.9MB    0B (0%)
Lokalni volumeni 0       0         0B         0B
Predmemorija    0       0         0B         0B

Mislim da se vaš znatiželjni um već pita, gdje se nalazi naša datoteka test.img. Potražimo je:

$ 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

Ne ulazeći u detalje, može se primijetiti da se datoteka test.img praktično smjestila na razini čitanja i pisanja, kojom upravlja overlay2 drajver. Ako zaustavimo naš kontejner, domaćin će nas obavijestiti da se to mjesto, u osnovi, može osloboditi:

# 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

Kako to možemo učiniti? Brisanjem kontejnera, što će uzrokovati čišćenje odgovarajućeg prostora na razini čitanja i pisanja.

Pomoću sljedeće komande možete odjednom ukloniti sve instalirane kontejnere i očistiti vaš disk od svih datoteka koje su stvorili na razini čitanja i pisanja:

$ docker container prune
WARNING! Ovo će ukloniti sve zaustavljene kontejnere.
Da li ste sigurni da želite nastaviti? [y/N] y
Uklonjeni kontejneri:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Ukupno oslobođeni prostor: 104.9MB

Dakle, oslobodili smo 104,9 megabajta brisanjem kontejnera. No, budući da više ne koristimo ranije preuzetu sliku, ona također postaje kandidat za brisanje i oslobađanje naših resursa:

$ docker system df
TIP            TOTAL      ACTIVE     SIZE       RECLAIMABLE
Slike          1          0          126M       126M (100%)
Kontejneri     0          0          0B         0B
Lokalni volumeni 0         0          0B         0B
Cache gradnje   0          0          0B         0B

Pažnja: sve dok se slika koristi barem od jedne kontejnera, nećete moći koristiti ovu foru.

Podkomanda prune, koju smo koristili gore, daje učinak samo na zaustavljenim kontejnerima. Ako želimo ukloniti ne samo zaustavljene, već i pokrenute kontejnere, trebali bismo koristiti jednu od ovih komandi:

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

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

Bilješke na margini: ako prilikom pokretanja kontejnera koristite parametar --rm, tada će pri njegovom zaustavljanju biti oslobođen sav prostor na disku koji je zauzimao.

Korištenje diska slikama

Prije nekoliko godina veličina slike od nekoliko stotina megabajta bila je sasvim normalna: slika Ubuntu-a je težila 600 megabajta, a slika Microsoft .Net nekoliko gigabajta. U to doba, preuzimanje jedne slike moglo je znatno naštetiti vašem slobodnom prostoru na disku, čak i ako ste dijelili nivoe između slika. Danas – hvala velikim – slike su mnogo manje, ali čak i tada može brzo doći do zasićenja raspoloživih resursa ako se ne poduzmu određene mjere opreza.

Postoji nekoliko tipova slika koje nisu izravno vidljive krajnjem korisniku:

  • intermediate slike, na temelju kojih su prikupljene druge slike - ne mogu se izbrisati ako koristite kontejnere koji se temelje na tim drugim slikama;
  • dangling slike - to su intermediate slike na koje se ne poziva nijedan pokrenuti kontejner - mogu se izbrisati.
  • Pomoću sljedeće naredbe možete provjeriti postoje li dangling slike u vašem sustavu:

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

Možete ih izbrisati na sljedeći način:

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

Također možemo koristiti podnaredbu prune:

$ docker image prune
WARNING! Ovo će ukloniti sve dangling slike.
Jeste li sigurni da želite nastaviti? [y/N] y
Izbrisane slike:
izbrisano: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
izbrisano: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
izbrisano: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
izbrisano: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
izbrisano: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f

Ukupno povraćeno prostora: 12.9kB

Ako bismo željeli izbrisati sve slike (ne samo dangling) s jednom naredbom, možemo to učiniti na sljedeći način:

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

Korištenje diska putem volumena

Volumeni se koriste za pohranu podataka izvan datotečnog sustava kontejnera. Na primjer, ako želimo sačuvati rezultate rada neke aplikacije kako bismo ih kasnije koristili. Čest primjer su baze podataka.

Pokrenimo MongoDB kontejner, povežimo mu vanjski volumen i obnovimo iz njega backup baze podataka (dostupan nam je u datoteci 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

Podaci će se nalaziti na domaćem stroju u katalogu /var/lib/docker/volumes. Zašto ne na razini čitanja-pisanja kontejnera? Zato što je u Dockerfile-u MongoDB slike katalog /data/db (gdje MongoDB po defaultu pohranjuje svoje podatke) definiran kao volumen.

Docker Savjeti: Očistite svoj stroj od smeća

Napomene: mnoge slike koje bi trebale generirati podatke koriste volumene za pohranu tih podataka.

Kada se zasitimo MongoDB-a i zaustavimo (ili čak obrišemo) kontejner, volumen se neće obrisati. Nastavit će zauzimati naš dragocjeni prostor na disku sve dok ga izričito ne obrišemo tom naredbom:

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

Ili možemo koristiti već poznatu podnaredbu prune:

$ docker volume prune
UPOZORENJE! Ovo će ukloniti sve lokalne volumene koji nisu korišteni od strane barem jednog kontejnera.
Jeste li sigurni da želite nastaviti? [y/N] y
Izbrisani volumeni:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Ukupno povraćeno prostora: 25.82GB
luc@saturn:~$

Korištenje diska za keširanje gradnje slika

U Dockeru 18.09 proces stvaranja slika pretrpio je promjene zahvaljujući alatu BuildKit. Ovaj alat povećava brzinu procesa, optimizira upravljanje pohranom podataka i sigurnosti. Ovde se nećemo zadržavati na svim detaljima ovog sjajnog alata, već ćemo se fokusirati na to kako utječe na korištenje diska.

Pretpostavimo da imamo potpuno jednostavnu aplikaciju Node.Js:

  • datoteka index.js pokreće jednostavni HTTP server koji odgovara na svaki primljeni zahtjev sa stringom:
  • datoteka package.json definira ovisnosti, od kojih se samo expressjs koristi za pokretanje HTTP servera:

$ 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(), 'Primljen Zahtjev'));
});
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 za izgradnju slike izgleda ovako:

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

Hajde da izgradimo sliku na uobičajen način, bez korištenja BuildKit:

$ docker build -t app:1.0 .

Ako proverimo korištenje diska, vidjet ćemo da samo osnovna slika (node:13-alpine) i finalna slika (app:1.0) zauzimaju prostor:

TIP           UKUPNO     AKTIVNO     VELIČINA       MOGUĆE POVRATITI
Slike         2          0          109.3MB    109.3MB (100%)
Kontejneri     0          0          0B         0B
Lokalni volumeni  0          0          0B         0B
Keš gradnje    0          0          0B         0B

Hajde da izgradimo drugu verziju naše aplikacije, već s korištenjem BuildKit-a. Sve što trebamo je da postavimo varijablu DOCKER_BUILDKIT na 1:

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

Ako sada proverimo korištenje diska, vidjet ćemo da sada sudjeluje keš gradnje (build-cache):

$ docker system df
TIP          UKUPNO     AKTIVNO     VELIČINA   OBNOVLJIVO
Slike        2          0           109.3MB    109.3MB (100%)
Kontejneri   0          0           0B         0B
Lokalni volumeni 0       0           0B         0B
Predmemorija 11         0           8.949kB    8.949kB

Za njegovo čišćenje koristit ćemo sljedeću naredbu:

$ docker builder prune
UPOZORENJE! Ovo će ukloniti sve viseće predmemorije za gradnju.
Da li ste sigurni da želite nastaviti? [y/N] y
Objekti predmemorije za gradnju su obrisani:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi

Ukupno obnovljen prostor: 8.949kB

Očistiti sve!

Dakle, razmotrili smo čišćenje diskovnog prostora koji zauzimaju kontejneri, slike i volumeni. U tome nam pomaže podkomanda prune. Ali se može koristiti i na sistemskom nivou docker, i očistiti će sve što može:

$ docker system prune
UPOZORENJE! Ovo će ukloniti:
  - sve zaustavljene kontejnere
  - sve mreže koje nije koristio nijedan kontejner
  - sve viseće slike
  - sve viseće predmemorije za gradnju

Da li ste sigurni da želite nastaviti? [y/N]

Ako iz nekog razloga štedite diskovni prostor na računaru sa Dockerom, povremeno pokretanje ove naredbe treba postati navika.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster