Múlt hónapban előadást tartottam az ApacheCon-on a Cgroups-ról. Úgy tűnik, hogy nagyon kevés Linux-felhasználó (beleértve e sorok íróját is, egészen a közelmúltig) ismeri a Cgroups-t és annak erejét. Ez sajnálatos, mert a Cgroups nagyon erőteljes, és lehetővé teszi az erőforrások elosztását a szervereken sokkal finomabb felbontásban, mint bármely más, a Linux eszköztárban elérhető eszköz. Ráadásul közvetlenül a kernelbe van beépítve, és a legtöbértékűbb Linux disztribúcióval azonnal használható.
Ebben a cikkben bemutatom, hogyan használható a Cgroups a Dockerrel, mintegy folytatásaként egy másik előadásomnak, amelyet a Docker Meetup-on tartottam a texasi Austinban.
Ez a cikk igényel némi alapvető megértést a Cgroups-ról. Ha teljesen új vagy a Cgroups terén, javaslom, hogy nézd át a slide deck bemutatómat az ApacheCon-ról, valamint a végén található forrásokat. Ne aggódj, nem fogunk túl mélyre ásni. Ha csak átfutod a diákat, képes leszel elsajátítani az alapvető fogalmakat.
Docker és Cgroups
A Docker két különböző meghajtóval érkezik: az LXC-vel és a libcontainerrel. Az LXC a régi meghajtó, a libcontainer pedig az új és alapértelmezett meghajtó. A legtöbb esetben a libcontainer a preferált meghajtó, mivel ott történnek az újítások (például a docker exec nem működik az LXC meghajtóval).
Fontos azonban megjegyezni, hogy két különböző meghajtóról van szó, mivel még nem minden Cgroup-képességet portoltak át a libcontainerre (vagy legalábbis nem tették elérhetővé a Docker számára). Az LXC meghajtó használatakor egyszerűen közvetlenül adod át az LXC argumentumokat, míg a libcontainer esetében explicit Cgroup házirend-argumentumok vannak kitéve a Dockernek. A Docker démon indításakor explicit módon be kell állítanod egy meghajtót, így nem futtathatod a két meghajtót egyszerre.
Íme egy példa arra, hogyan ellenőrizheted:
[bash light=”true”] # Az LXC meghajtóval$ docker run -d –name=’lxc_test’ \
–lxc-conf="lxc.cgroup.cpu.shares=50" \
busybox
# A libcontainer meghajtóval
$ docker run -d –name=’libcontainer_test’ \
–cpu-shares=50 \
busybox
[/bash]
Íme egy áttekintés néhány Cgroup-funkcióról, és arról, hogyan képeződnek le a két meghajtó között:
| Funkció | Libcontainer | LXC |
|---|---|---|
| Relatív CPU részesedés | -c, –cpu-shares | –lxc-conf=”lxc.cgroup.cpu.shares” |
| Zárolás egy CPU maghoz | –cpuset-cpus | –lxc-conf=”lxc.cgroup.cpuset.cpus” |
| Memória korlátozása | -m, –memory | –lxc-conf=”lxc.cgroup.cpuset.mems” |
LXC
Ha az LXC meghajtót szeretnéd használni a Dockerhez, először engedélyezned kell azt. Ennek módja a Linux disztribúciótól függően eltérő lehet, de itt vannak az utasítások arra vonatkozóan, hogyan engedélyezhető az LXC meghajtó Ubuntu 14.04-en.
Mint fentebb említettük, ezzel számos funkcióról lemondasz. Ezért, hacsak nincs valóban szükséged olyan funkcióra, amely még nincs közzétéve a Dockerben a libcontainer használatával, érdemes az alapértelmezett meghajtónál maradnod.
Néhány hasznos Cgroup házirend, amely még nem érhető el a libcontainerben, magában foglalja az I/O fojtást (erről szó esik a bemutatóban), ami nagyon hasznos lehet bizonyos alkalmazásoknál.
Ha úgy döntöttél, hogy az LXC meghajtót használod, az argumentumok hozzáadása rendkívül egyszerű. Mindössze annyit kell tenned, hogy hozzáadod a(z) --lxc-conf argumentumot, és átadod a beállítani kívánt Cgroup házirendet.
Libcontainer
Amint a fenti táblázatban látható, az alapvető Cgroup házirendek már elérhetők a Docker jelenlegi verziójában (e cikk írásakor az 1.6-os verzióban).
Ezeknek a házirendeknek a használata nagyon egyszerű. Ha például egy Docker konténert az első CPU maghoz szeretnél láncolni, akkor a(z) --cpuset-cpus=0 részt kell hozzáfűznöd a docker run parancshoz.
Használhatod a(z) --cgroup-parent argumentumot is a libcontainerrel, és manuálisan beállíthatsz részletesebb erőforrás-korlátokat. Ezután az argumentum segítségével leképezheted azt az adott csoportra.
Demó: Docker Cgroups-szal
Az alábbi képernyővideóban két Docker konténert fogunk használni (‘low_prio’ és ‘high_prio’). A ‘busybox’ alapkonténert használjuk, és futtatjuk a md5sum /dev/urandom parancsot egy CPU-igényes folyamat szimulálására. Alapértelmezés szerint ez felemésztené az összes rendelkezésre álló CPU-erőforrást. Azonban két Cgroup-irányelvet fogunk alkalmazni az erőforrások kezelésére. Először a ‘cpuset.cpus’ beállítást használjuk, hogy a konténereket ugyanahhoz a CPU-maghoz (0. mag) rögzítsük.
Ezután a ‘cpu.shares’ beállítást használjuk egy relatív CPU-részesedés hozzárendeléséhez. A ‘low_prio’ konténernek 20-as értéket adunk, a ‘high_prio’ konténernek pedig 80-as értéket. Ez azt jelenti, hogy a CPU 20%-a lesz kiosztva a ‘low_prio’ konténernek, és a CPU 80%-a a ‘high_prio’ konténernek. Kérjük, vegye figyelembe, hogy a relatív részesedés egy tetszőleges skála (akár a 2-es és 8-as értékeket is használhattuk volna).
Miután bemutattuk, hogy az erőforrás-kezelés valóban működik, elindítjuk ugyanezeket a konténereket Cgroup-irányelvek nélkül is, hogy lássuk, hogyan viselkednek.
Referenciaként íme a konténerek elindításához használt parancsok.
[bash light=”true”] $ docker run -d \–name=’low_prio’ \
–cpuset-cpus=0 \
–cpu-shares=20 \
busybox md5sum /dev/urandom
$ docker run -d \
–name=’high_prio’ \
–cpuset-cpus=0 \
–cpu-shares=80 \
busybox md5sum /dev/urandom
[/bash]
Összegzés
Ha több Docker konténert kezel ugyanazon a gazdagépen, a Cgroups használata a konténerek közötti erőforrások kezelésére nagyon is ésszerű. Például előfordulhat, hogy az egyik konténerben háttérfolyamatok futnak, míg egy másik konténer a felhasználói tartalmakat szolgálja ki. Ebben az esetben az újonnan szerzett tudását felhasználva biztosíthatja, hogy a felhasználók felé irányuló konténereket részesítse előnyben a háttérfeladatokkal szemben.
Hozzászólások
Még nincsenek hozzászólások. Legyen Ön az első.