GNU/Linux >> Znalost Linux >  >> Linux

Urychlení vytváření obrazu kontejneru pomocí Buildah

Před několika měsíci jsem napsal článek o urychlení vytváření kontejnerů uvnitř kontejneru. Tento článek se soustředil na rychlost stahování obrázků kontejneru a různé způsoby, jak předem naplnit úložiště obrázků, pomocí připojení svazků od hostitele a konceptu Buildah „dalších obchodů“.

Buildah je nástroj příkazového řádku pro rychlé a snadné vytváření obrázků kompatibilních s Open Container Initiative (to znamená i kompatibilní s Dockerem a Kubernetes). Buildah lze snadno začlenit do skriptů a sestavovacích kanálů a nejlepší ze všeho je, že k vytvoření image nevyžaduje běžícího démona kontejneru.

Tento článek se bude zabývat druhým problémem s rychlostí sestavení při použití dnf /yum příkazy uvnitř kontejnerů. Všimněte si, že v tomto článku budu používat název dnf (což je název pro upstream) namísto toho, co používají některé downstreamy (yum ) Tyto komentáře platí pro oba dnf a yum .

Rychlost stahování

Všimli jste si někdy, že když spustíte dnf -y update? nebo dnf -y install poprvé po nějaké době se příkaz na dlouhou dobu pozastaví, než vůbec začne snižovat otáčky? Co se děje?

První věc, kterou dnf je stahování velkých souborů mezipaměti. Tyto soubory jsou napsány v XML a obsahují každý jednotlivý balíček ve vzdáleném úložišti, včetně spousty dat o balíčku. Dokonce obsahují všechny cesty v balíčku. Tato data jsou potřebná, abyste mohli spustit něco jako dnf -y install /usr/bin/httpd a poté dnf zjistí balíček, který se má nainstalovat. Mnoho balíčků obsahuje příkazy jako (requires: /usr/bin/sendmail ), které tuto funkci využívají a umožňují dnf vytáhnout vhodný balíček k uspokojení potřeby.

Vytažení těchto obrovských souborů – a co je důležitější, zpracování těchto souborů – může trvat i minutu. Tato data používá libsolv , takže musí být převeden na solv formátu, který je pomalý. Rychlost není velký problém, když to na svém hostiteli děláte jen pravidelně, ale pokud jde o stavbu kontejnerů, je to mnohem větší problém.

Syntaxe souboru Docker

Přestože Buildah umožňuje vytvářet obrazy kontejnerů přímo v prostředí, většina lidí používá soubory Dockerfiles a Containerfiles k vytváření kontejnerů a definování reprodukovatelných obrazových receptur. Buildah ve výchozím nastavení hledá Containerfile a Dockerfile Nyní. Každý sdílí stejnou syntaxi, takže použiji Containerfile pro zbytek tohoto dokumentu.

Běžná věc v Containerfile je použít syntaxi jako:

FROM ubi8  
RUN dnf -y update; dnf -y install nginx; dnf -y clean all  
…  
RUN dnf -y install jboss; dnf -y clean all  

Podívejme se na dnf linky. První dnf řádek:

(dnf -y update; dnf -y install nginx; dnf -y clean all ):

  1. Aktualizuje všechny balíčky v kontejneru.
  2. Nainstaluje vybraný balíček nginx .
  3. Vyčistí vše.

Od ubi8 obrázek byl pravděpodobně vytvořen před chvílí a jeho /var/cache/dnf adresář pravděpodobně neexistuje uvnitř obrazu kontejneru dnf musí stáhnout soubor mezipaměti XML a zpracovat jej. Poté dnf nainstaluje skutečné balíčky před dnf -y clean all odstraní všechna přebytečná data, která předchozí příkazy umístily do obrazu, jako jsou soubory protokolu a mezipaměti.

Uživatelům se doporučuje spustit clean all aby byl obrázek co nejmenší. Každý RUN vytvoří novou vrstvu, a to i v případě, že obsah odstraníte později RUN bude počáteční vrstva obsahovat veškerý obsah. To znamená, že každý, kdo kdy stáhne váš obrázek, skončí stahováním protokolů a souborů mezipaměti. Nyní, pokud váš Containerfile obsahuje jeden nebo více dnf příkazy, budete cenu platit znovu a znovu. Nejen to, ale pokaždé, když znovu postavíte tento obraz, zaplatíte tuto cenu znovu. Pokud jste na sestavení serveru, každý obrázek kontejneru, který vytvoříte, bude tyto soubory XML stahovat znovu a znovu, čímž se plýtvá spoustou zdrojů a času.

Buildah s překryvnými držáky

Viděli jsme výše popsaný problém a mysleli jsme si, že bychom to mohli zvládnout lépe. Nemohli bychom jednoduše stáhnout data XML do hostitele, zpracovat je na hostiteli a připojit je do kontejnerů? Možná bychom mohli nastavit úlohu cron nebo systemd časovač, který provádí dnf makecache jednou pro každou verzi OS, pro kterou budete vytvářet obrázky kontejnerů? Tuto úlohu byste mohli spustit jednou nebo vícekrát denně na hostiteli a poté nechat všechny svazky tvůrců kontejnerů připojit příslušné mezipaměti do kontejnerů buildah.

Buildah podporuje adresáře pro připojení svazku z hostitele do kontejnerů. To by mělo problém vyřešit a také se to řeší. ALE kontejnery často chtějí zapisovat do tohoto adresáře, pokud musí aktualizovat mezipaměť, takže je třeba mezipaměť namontovat do kontejnerů pro čtení/zápis. To způsobuje obrovskou bezpečnostní díru. Představte si situaci, kdy nepřátelské sestavení kontejneru zapsalo do této mezipaměti obsah, který přečetl pozdější tvůrce kontejnerů. Mohlo by to přimět druhý kontejner k instalaci napadeného softwaru. Potřebujeme řešení, kde je obsah namontován do kontejneru, nelze jej zapisovat kontejnerem, ale přesto do něj lze zapisovat z pohledu kontejneru. To je v podstatě to, co je bod připojení překrytí.

Překryvný souborový systém připojí lower adresář a poté připojí upper adresáře do merged montážní bod. Když proces zapisuje do nového souboru do merged nový soubor se zapíše do upper adresář. Když proces upraví existující soubor v lower jádro zkopíruje soubor z lower adresáře do upper adresář a umožňuje procesu upravit soubor v upper adresář.

Představili jsme koncept Overlay mount do Buildah. Nyní můžete spouštět sestavení pomocí

buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f /tmp/Containerfile /tmp  

Dnf uvnitř kontejneru bude stále kontrolovat, zda je v úložišti novější obsah, a pokud existuje, stáhne obsah dolů. Ale pokud je obsah na hostiteli aktuální, rychle použije mezipaměť hostitele. Doporučil bych vám aktualizovat mezipaměť hostitelů alespoň jednou denně.

Další funkcí, kterou jsme přidali pro držák Buildah Overlay, je zničit upper adresář na každém RUN směrnice. Připomeňme si, že v našem příkladu jsme použili více RUN příkazy, z nichž každý prováděl dnf -y clean all . dnf -y clean all příkaz způsobí upper adresář, aby se veškerý obsah z nižšího adresáře zobrazoval jako smazaný. Pokud je další dnf příkaz sdílel předchozí horní, viděl by mezipaměť jako prázdnou a musel by stáhnout datové úložiště XML a zpracovat jej. Odstranění upper adresář znamená, že každý dnf příkaz znovu uvidí lower adresář z hostitele a pokračujte ve sdílení mezipaměti hostitelů.

Rozdíl v rychlosti

Vytvořím jednoduchý Containerfile obsahující dva dnf spustit příkazy.

FROM fedora:31  
RUN dnf -y install net-utils; dnf -y clean all  
RUN dnf -y install iputils; dnf -y clean all  

Spouštím to lokálně na mém boxu Fedora 31

# time -f "Elapsed Time: %E" buildah bud -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Fedora Modular 31 - x86_64 2.0 MB/s | 5.2 MB 00:02  
Fedora Modular 31 - x86_64 - Updates 1.6 MB/s | 4.0 MB 00:02  
Fedora 31 - x86_64 - Updates 4.2 MB/s | 19 MB 00:04  
Fedora 31 - x86_64 1.8 MB/s | 71 MB 00:39  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:55:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 375 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 218 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
33 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Fedora Modular 31 - x86_64 741 kB/s | 5.2 MB 00:07  
Fedora Modular 31 - x86_64 - Updates 928 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 3.8 MB/s | 19 MB 00:05  
Fedora 31 - x86_64 7.9 MB/s | 71 MB 00:08  
Last metadata expiration check: 0:00:01 ago on Wed Feb 5 13:57:13 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 252 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 141 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
33 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 922380d685bc done  
Copying config 566e2afbb4 done  
Writing manifest to image destination  
Storing signatures  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb  
566e2afbb417f0119109578a87950250b566a3b4908868627975a4c7428accfb

Elapsed Time: 2:15.00  

Tento běh trval 2 minuty a 15 sekund, než se vytvořil nový obrázek kontejneru se dvěma novými balíčky.

Nyní to zkusme s překryvným držákem od hostitele.

# dnf -y makecache  
# time -f "Elapsed Time: %E" buildah bud -v /var/cache/dnf:/var/cache/dnf:O -f Containerfile .  
STEP 1: FROM fedora:31  
STEP 2: RUN dnf -y install procps-ng; dnf -y clean all  
Last metadata expiration check: 0:02:34 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
procps-ng x86_64 3.3.15-6.fc31 fedora 326 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 326 k  
Installed size: 966 k  
Downloading Packages:  
procps-ng-3.3.15-6.fc31.x86_64.rpm 496 kB/s | 326 kB 00:00  
--------------------------------------------------------------------------------  
Total 245 kB/s | 326 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : procps-ng-3.3.15-6.fc31.x86_64 1/1  
Running scriptlet: procps-ng-3.3.15-6.fc31.x86_64 1/1  
Verifying : procps-ng-3.3.15-6.fc31.x86_64 1/1

Installed:  
procps-ng-3.3.15-6.fc31.x86_64

Complete!  
285 files removed  
STEP 3: RUN dnf -y install iputils; dnf -y clean all  
Last metadata expiration check: 0:02:41 ago on Wed Feb 5 13:51:54 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 556 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 222 kB/s | 141 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
285 files removed  
STEP 4: COMMIT  
Getting image source signatures  
Copying blob ac0b803c5612 skipped: already exists  
Copying blob 524bb3b83d61 done  
Copying config 0f82aa6064 done  
Writing manifest to image destination  
Storing signatures  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
0f82aa6064814ff3dcb603c34c75e516e00817811681b83b8632f3e9b694e518  
Elapsed Time: 0.17.44  

Díky připojení Overlay jsme byli schopni vytvořit nový obraz se dvěma dalšími balíčky za 17 sekund místo 2 minut a 15 sekund. To je téměř 8krát rychlejší vytvořit stejný obrázek kontejneru.

Nyní to ukazuje, že pokud vytváříte obrazy na hostitelském operačním systému, který má dnf metadata předem uložená v mezipaměti můžete urychlit rychlost instalace o OBROVSKÉ množství. Ale co když váš systém sestavení vytváří obrazy pro jiné verze operačního systému? Řekněme, že chcete vytvářet obrázky pro Fedoru 30 i Fedoru 31. Poznámka:Toto by fungovalo také na systému RHEL8, kde možná budete chtít sestavit obrázky RHEL7 a možná i RHEL6.
Dnf obsahuje skvělou funkci, kde můžete určit různá vydání při stahování obsahu pomocí --releasever volba. Dnf také umožňuje zadat alternativní adresáře pro umístění cachedir, --setopt=cachedir .

V následujícím příkladu vytáhnu dvě mezipaměti na hostiteli a poté použiji Buildah v režimu příkazového řádku.

# dnf -y makecache --releasever=31 --setopt=cachedir=/var/cache/dnf/31  
# dnf -y makecache --releasever=30 --setopt=cachedir=/var/cache/dnf/30  
# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/31:/var/cache/dnf:O ${ctr31} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:41 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 192 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 107 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 0:06.85

# ctr30=$(buildah from fedora:30)  
# time -f 'Elapsed Time: %E' buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  
Last metadata expiration check: 0:00:15 ago on Wed Feb 5 14:17:47 2020.  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20180629-4.fc30 fedora 123 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 123 k  
Installed size: 351 k  
Downloading Packages:  
iputils-20180629-4.fc30.x86_64.rpm 370 kB/s | 123 kB 00:00  
--------------------------------------------------------------------------------  
Total 138 kB/s | 123 kB 00:00  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20180629-4.fc30.x86_64 1/1  
Running scriptlet: iputils-20180629-4.fc30.x86_64 1/1  
Verifying : iputils-20180629-4.fc30.x86_64 1/1

Installed:  
iputils-20180629-4.fc30.x86_64

Complete!  
Elapsed Time: 0:08.88  

Jak můžete vidět, byli jsme schopni spustit kontejnery Buildah pomocí dnf mezipaměť ze dvou různých verzí Fedory ze stejného hostitele sestavení a kontejnerů pro Fedoru 31 trvalo 6+ sekund a sestavení Fedory 30 trvalo 8+ sekund.

Poznámka:Vybral jsem podadresář /var/cache/dnf pro soubory mezipaměti, abyste se ujistili, že štítky SELinux jsou správné. Stačí spustit dnf clean all nevyčistí /var/cache/dnf/31 . Budete muset spustit dnf clean all --setopt=cachedir=/var/cache/dnf/31 správně vyčistit soubory v mezipaměti úložiště, ale některé artefakty stejně zůstanou (klíče gpg, prázdné adresáře).

Nyní se jen podívejte, jak dlouho by to zabralo spuštění sestavení na Fedoře 31 bez připojení Overlay.

# ctr31=$(buildah from fedora:31)  
# time -f 'Elapsed Time: %E' buildah run ${ctr31} dnf -y install iputils  
Fedora Modular 31 - x86_64 1.2 MB/s | 5.2 MB 00:04  
Fedora Modular 31 - x86_64 - Updates 875 kB/s | 4.0 MB 00:04  
Fedora 31 - x86_64 - Updates 2.4 MB/s | 19 MB 00:07  
Fedora 31 - x86_64 1.7 MB/s | 71 MB 00:41  
Dependencies resolved.  
================================================================================  
Package Architecture Version Repository Size  
================================================================================  
Installing:  
iputils x86_64 20190515-3.fc31 fedora 141 k

Transaction Summary  
================================================================================  
Install 1 Package

Total download size: 141 k  
Installed size: 387 k  
Downloading Packages:  
iputils-20190515-3.fc31.x86_64.rpm 279 kB/s | 141 kB 00:00  
--------------------------------------------------------------------------------  
Total 129 kB/s | 141 kB 00:01  
Running transaction check  
Transaction check succeeded.  
Running transaction test  
Transaction test succeeded.  
Running transaction  
Preparing : 1/1  
Installing : iputils-20190515-3.fc31.x86_64 1/1  
Running scriptlet: iputils-20190515-3.fc31.x86_64 1/1  
Verifying : iputils-20190515-3.fc31.x86_64 1/1

Installed:  
iputils-20190515-3.fc31.x86_64

Complete!  
Elapsed Time: 1:29.85  

V tomto případě trvalo spuštění stejného kontejneru téměř 1,5 minuty. Buildah s držáky Overlay běžel 14krát rychleji.

Kontejnery bez kořenů

Všechny mé příklady až dosud spouštěly sestavení pomocí Containerfiles jako kořen. Ale můžete to udělat i s bezkořenovými nádobami. V několika dalších příkladech budu mít Buildah spouštět kontejnery pomocí buildah run syntaxe k demonstraci použití mezipaměti.

Probíhá

$ buildah run -v /var/cache/dnf/30:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

funguje dobře. Pokud uživatel může číst /var/cache/dnf/30 adresář, lower adresář lze číst. Ale musíte se spolehnout na to, že hostitel bude mezipaměť pravidelně aktualizovat.

Pokud uživatelé chtějí, mohou dokonce použít dnf vytvořit mezipaměť ve svém domovském adresáři.

$ dnf -y makecache --releasever=30 --setopt=cachedir=$HOME/dnfcache  
$ chcon --reference /var/cache/dnf -R $HOME/dnfcache  
$ ctr30=$(buildah from fedora:30)  
$ buildah run -v $HOME/dnfcache:/var/cache/dnf:O ${ctr30} dnf -y install iputils  

Všimněte si, že jsem musel změnit štítek SELinux $HOME/dnfcache adresář, aby SELinux umožnil kontejnerům číst lower adresář pro připojení Overlay.

Závěr

Urychlení sestavování kontejnerů vyžaduje pochopení toho, co se děje při instalaci balíčků. Předběžné ukládání do mezipaměti dnf data na hostiteli a použití překryvných připojení k připojení mezipaměti do kontejneru pomocí Buildah může výrazně zvýšit rychlost sestavení a snížit počet zdrojů potřebných k podpoře sestavovací farmy.

Buildah se rovná jednoduchosti, ale má také několik skvělých funkcí, jako je Overlay mounts a additional stores což vám může pomoci urychlit vytváření obrázku kontejneru.

[ Jste v kontejnerech noví? Stáhněte si Containers Primer a naučte se základy linuxových kontejnerů. ]


Linux
  1. Jak vytvořit vlastní obrázek z kontejneru Docker

  2. Odevzdejte data v kontejneru mysql

  3. Který operační systém běží v mém kontejneru Docker?

  1. Sestavte si svůj vlastní kontejner na Linuxu

  2. Opravte bitovou kopii systému pomocí DISM

  3. Používejte stavy úloh se zobrazováním serveru

  1. Optimalizace obrázků pomocí webp

  2. Vypsat všechny soubory grafických obrázků s find?

  3. Co je uvnitř obrázku/kontejneru Dockeru?