Hei Habr! Esitän huomionne artikkelin käännöksen
Tänään puhumme siitä, kuinka Docker käyttää isäntäkoneen levytilaa, ja selvitämme myös kuinka vapauttaa tämä tila käyttämättömien kuvien ja säiliöiden romuista.
Kokonaiskulutus
Docker on siisti asia, luultavasti harvat epäilevät sitä nykyään. Vain muutama vuosi sitten tämä tuote antoi meille täysin uuden tavan rakentaa, toimittaa ja käyttää mitä tahansa ympäristöä, minkä ansiosta voimme säästää merkittävästi CPU- ja RAM-resursseja. Tämän lisäksi (ja joillekin tämä tulee olemaan tärkeintä) Docker on antanut meille mahdollisuuden yksinkertaistaa ja yhtenäistää tuotantoympäristöjemme elinkaarihallintaa.
Kaikilla näillä modernin elämän iloilla on kuitenkin hintansa. Kun käytämme säiliöitä, lataamme tai luomme omia kuviamme ja otamme käyttöön monimutkaisia ekosysteemejä, meidän on maksettava. Ja maksamme muun muassa levytilalla.
Jos et ole koskaan ajatellut kuinka paljon tilaa Docker todella vie koneeltasi, saatat yllättyä ikävästi tämän komennon tuloksesta:
$ docker system df
Tämä näyttää Dockerin levyn käytön eri yhteyksissä:
- kuvat – kuvavarastoista ladattujen ja järjestelmääsi rakennettujen kuvien kokonaiskoko;
- kontit – käynnissä olevien säiliöiden käyttämän levytilan kokonaismäärä (eli kaikkien säiliöiden luku- ja kirjoituskerrosten kokonaismäärä);
- paikalliset tilavuudet – kontteihin asennetun paikallisen varaston tilavuus;
- build cache – kuvanrakennusprosessin luomat väliaikaiset tiedostot (BuildKit-työkalulla, joka on saatavilla Dockerin versiosta 18.09 alkaen).
Lyön vetoa, että tämän yksinkertaisen siirron jälkeen olet innokas puhdistamaan levysi roskista ja herättämään arvokkaat gigatavut takaisin henkiin (huom: varsinkin jos maksat vuokraa näistä gigatavuista joka kuukausi).
Levyjen käyttö säiliöiden mukaan
Joka kerta kun luot säilön isäntäkoneeseen, /var/lib/docker-hakemistoon luodaan useita tiedostoja ja hakemistoja, joista seuraavat ovat huomionarvoisia:
- Hakemisto /var/lib/docker/containers/container_ID – käytettäessä tavallista lokiohjainta, tähän tapahtumalokit tallennetaan JSON-muodossa. Liian yksityiskohtaiset lokit sekä lokit, joita kukaan ei lue tai muuten käsittele, aiheuttavat usein levyjen täyttymisen.
- /var/lib/docker/overlay2-hakemisto sisältää säilön luku- ja kirjoitustasot (overlay2 on suosituin ohjain useimmissa Linux-jakeluissa). Jos säilö tallentaa tietoja tiedostojärjestelmäänsä, se sijoitetaan tähän hakemistoon.
Kuvitellaanpa järjestelmä, johon on asennettu koskematon Docker, joka ei ole koskaan ollut mukana konttien laukaisussa tai kuvien rakentamisessa. Sen levytilan käyttöraportti näyttää tältä:
$ 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
Käynnistetään jokin kontti, esimerkiksi NGINX:
$ docker container run --name www -d -p 8000:80 nginx:1.16
Mitä levylle tapahtuu:
- kuvat vievät 126 Mt, tämä on sama NGINX, jonka julkaisimme säilössä;
- kontit vievät naurettavat 2 tavua.
$ 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
Päätelmän perusteella meillä ei ole vielä yhtään tilaa, jota voisimme vapauttaa. Koska 2 tavua on täysin turhaa, kuvitellaan, että NGINX kirjoitti yllättäen jonnekin 100 megatavua dataa ja loi sisäänsä juuri tämän kokoisen tiedoston test.img.
$ docker exec -ti www
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]
Tarkastellaan uudelleen isäntäkoneen levytilan käyttöä. Näemme, että kontti (säiliöt) vie siellä 100 megatavua.
$ 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
Luulen, että utelias aivosi ihmettelevät jo, missä test.img-tiedostomme sijaitsee. Etsitään se:
$ 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
Menemättä yksityiskohtiin voimme huomata, että test.img-tiedosto sijaitsee kätevästi luku-kirjoitustasolla overlay2-ohjaimen ohjaamana. Jos pysäytämme konttimme, isäntä kertoo meille, että tämä tila voidaan periaatteessa vapauttaa:
# 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
Kuinka voimme tehdä tämän? Poistamalla säilön, mikä edellyttää vastaavan tilan tyhjentämistä luku- ja kirjoitustasolla.
Seuraavalla komennolla voit poistaa kaikki asennetut säilöt yhdellä iskulla ja tyhjentää levyltä kaikki niiden luomat luku-kirjoitustiedostot:
$ 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
Joten vapautimme 104,9 megatavua poistamalla säilön. Mutta koska emme enää käytä aiemmin ladattua kuvaa, siitä tulee myös ehdokas resurssien poistamiseen ja vapauttamiseen:
$ 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
Huomaa: niin kauan kuin kuva on vähintään yhden säilön käytössä, et voi käyttää tätä temppua.
Yllä käyttämämme karsia-alikomento vaikuttaa vain pysäytettyihin säiliöihin. Jos haluamme poistaa pysäytettyjä, mutta myös käynnissä olevia säiliöitä, meidän tulee käyttää jotakin seuraavista komennoista:
# Historical command
$ docker rm -f $(docker ps –aq)
# More recent command
$ docker container rm -f $(docker container ls -aq)
Sivuhuomautukset: jos käytät -rm-parametria käynnistäessäsi säilön, sen pysähdyksissä kaikki sen käyttämä levytila vapautuu.
Levyjen kuvien käyttö
Muutama vuosi sitten useiden satojen megatavujen kuvakoko oli täysin normaali: Ubuntu-kuva painoi 600 megatavua ja Microsoft .Net -kuva useita gigatavuja. Näinä pörröisinä päivinä vain yhden kuvan lataaminen voi viedä paljon vapaata levytilaa, vaikka jakaisit tasoja kuvien välillä. Nykyään - ylistys suurille - kuvat painavat paljon vähemmän, mutta silti voit nopeasti täyttää käytettävissä olevat resurssit, jos et ryhdy varotoimiin.
On olemassa useita erilaisia kuvia, jotka eivät näy suoraan loppukäyttäjälle:
- välikuvat, joiden perusteella kerätään muita kuvia - niitä ei voi poistaa, jos käytät näihin "muihin" kuviin perustuvia säiliöitä;
- roikkuvat kuvat ovat välikuvia, joihin mikään käynnissä olevista säilöistä ei viittaa – ne voidaan poistaa.
- Seuraavalla komennolla voit tarkistaa, onko järjestelmässäsi roikkuvia kuvia:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
none none 21e658fe5351 12 minutes ago 71.3MB
Voit poistaa ne seuraavasti:
$ docker image rm $(docker image ls -f dangling=true -q)
Voimme myös käyttää prune-alikomentoa:
$ 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
Jos haluamme yhtäkkiä poistaa kaikki kuvat kokonaan (eikä vain roikkuvat) yhdellä komennolla, voimme tehdä tämän:
$ docker image rm $(docker image ls -q)
Levyn käyttö volyymin mukaan
Volyymeja käytetään tietojen tallentamiseen säilön tiedostojärjestelmän ulkopuolelle. Esimerkiksi, jos haluamme tallentaa sovelluksen tulokset käyttääksemme niitä jollain muulla tavalla. Yleinen esimerkki ovat tietokannat.
Käynnistetään MongoDB-säilö, liitetään säilön ulkoinen taltio ja palautetaan siitä tietokannan varmuuskopio (se on saatavilla bck.json-tiedostossa):
# 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
Tiedot sijaitsevat isäntäkoneella /var/lib/docker/volumes-hakemistossa. Mutta miksi ei säilön luku- ja kirjoitustasolla? Koska MongoDB-kuvan Docker-tiedostossa /data/db-hakemisto (johon MongoDB tallentaa tiedot oletuksena) on määritetty taltioksi.
Sivuhuomautus: monet kuvat, joiden on tuotettava dataa, käyttävät tilavuuksia näiden tietojen tallentamiseen.
Kun pelaamme tarpeeksi MongoDB:llä ja pysäytämme (tai ehkä jopa poistamme) säilön, levyä ei poisteta. Se vie arvokasta levytilaamme, kunnes poistamme sen komennolla, kuten seuraava:
$ docker volume rm $(docker volume ls -q)
No, tai voimme käyttää meille jo tuttua prune-alikomentoa:
$ 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:~$
Levyn käyttö kuvanmuodostuksen välimuistiin
Docker 18.09:ssä kuvanluontiprosessi on kokenut joitain muutoksia BuildKit-työkalun ansiosta. Tämä nopeuttaa prosessia ja optimoi tiedon tallennuksen ja tietoturvan hallinnan. Tässä emme käsittele tämän upean työkalun kaikkia yksityiskohtia; keskitymme vain siihen, kuinka se käsittelee levytilan käyttöä koskevia ongelmia.
Oletetaan, että meillä on täysin yksinkertainen Node.Js-sovellus:
- index.js-tiedosto käynnistää yksinkertaisen HTTP-palvelimen, joka vastaa rivillä jokaiseen vastaanotettuun pyyntöön:
- paketti.json-tiedosto määrittää riippuvuudet, joista vain expressjs:ää käytetään HTTP-palvelimen suorittamiseen:
$ 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"
}
}
Docker-tiedosto kuvan rakentamiseen näyttää tältä:
FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]
Rakennetaan kuva tavalliseen tapaan, ilman BuildKitin käyttöä:
$ docker build -t app:1.0 .
Jos tarkistamme levytilan käytön, voimme nähdä, että vain peruskuva (node:13-alpine) ja kohdekuva (app:1.0) vievät tilaa:
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
Rakennetaan toinen versio sovelluksestamme BuildKitillä. Tätä varten meidän on vain asetettava DOCKER_BUILDKIT-muuttujan arvoksi 1:
$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .
Jos nyt tarkistamme levyn käytön, näemme, että koontivälimuisti (buid-cache) on nyt mukana siellä:
$ 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
Tyhjennä se käyttämällä seuraavaa komentoa:
$ 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
Tyhjennä!
Tarkastelimme siis säiliöiden, kuvien ja taltioiden käyttämän levytilan puhdistamista. Luumun alakomento auttaa meitä tässä. Mutta sitä voidaan käyttää myös telakointijärjestelmätasolla, ja se puhdistaa kaiken, mitä voi:
$ 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]
Jos jostain syystä säästät levytilaa Dockeria käyttävässä koneessa, tämän komennon säännöllisestä suorittamisesta pitäisi tulla tapana.
Lähde: will.com