Vserver

A Unix/Linux szerverek üzemeltetése wikiből

A vserver egy pehelysúlyú oprendszerszintű virtualizációs megoldás, amellyel Linuxon tudunk egymás mellett, egymástól elszigetelve sok virtuális szervert futtatni.

Tartalomjegyzék

1 Mit tud?

  • A vserverben futó program és a natívan futó program sebessége között nincs mérhető eltérés.
  • Lényegében nincs overhead: egy vserverben futó apache pontosan annyi erőforrásba kerül, mintha a hoszton futtatnánk.
    • (A hoszton is betöltött shared libraryk memóriafoglalását leszámítva.)
  • A vserverek nem látják más vserverek ill. a hosztgép
    • fájlrendszerét,
    • processzeit,
    • SysV IPC objektumait,
    • hálózati csomagjait,
    • IP-címeit,
    • hardvereszközeit.
  • (De a hoszt routing-bejegyzéseit egyelőre igen.)
  • A vserverekben futó folyamatok még rootjoggal sem tudnak
    • fájlrendszert mountolni,
    • hálózati interfészt konfigurálni,
    • tűzfalszabályokat beállítani,
    • device node-ot létrehozni,
    • routingbejegyzéseket módosítani/létrehozni/törölni,
    • fájlrendszert átméretezni (sajnos).
    • Ezeket és más hasonló jogokat viszonylag rugalmasan kioszthatunk bizonyos vservereknek egy capability-rendszer segítségével.
  • Ha több vserver / ill. /usr fájlrendszerét ugyanazon a hoszt-fájlrendszeren tartjuk, akkor
    • az azonos tartalmú fájlokat automatikusan össze tudjuk hardlinkelni, így
    • egyrészt kevesebb helyet foglalnak a diszken, de - és ez a fontosabb -,
    • a cache-ben és a memóriában is: 20 db. libc6-példány helyett csak egy lesz a memóriában.
    • Egy vserver továbbra sem írhatja felül egy másik fájljait, mert
    • a kernel ezeket a hardlinkeket a fájlok módosítása esetén eltöri,
    • és abban a vserverben, amelyik írásra nyitotta meg a fájlt, létrejön egy új példány, ami már csak az övé.
    • Bajok ezzel a megoldással:
      • Nem tudja megkülönböztetni a vserveren belüli és a vserveren kívüli hardlinkeket.
      • xfs-en egyelőre nem működik a linkek eltörése; a létrejövő új példány csupa nullát tartalmaz, vagyis
        • vserverek olyan fájlrendszereit, ahol a hardlinkelést érdemes alkalmazni, ne xfs-en tartsuk (hanem pl. jfs-en).
  • Csak egy kernel fut,
    • de a virtuális gépek mindegyikében lehet pl. más disztribúció;
    • sőt, 64 bites hoszton futtathatunk 32 bites disztribúciót guestként, ami
      • pl. akkor jön jól, ha 64bites gépet desktopnak is szeretnénk használni (a 64bites desktop egyelőre kicsit szívás).
  • A hoszt elvileg teljesen el van szigetelve a vserverektől, a feltört vserver nem okoz gondot máshol,
    • ráadásul a hoszt segítségével biztonságosan megvizsgálhatjuk, mi változott benne (így pl. honeypotnak is jó lehet).
  • Könnyű migrálni, mivel egy vserverben semmi gépspecifikus konfiguráció (pl. fstab) nincs;
    • mi magunk is törekedjünk rá, hogy a vserver saját IP-jét ne írjuk bele configfájlokba stb.

2 Mikor érdemes használni?

  • Főként a "Gép, Ami Sokmindent Csinál" problémájára megoldás.
  • Egy funkció - egy vserver. Pl. külön vserverben lehet:
    • az Internet felé néző, reverse proxyként működő apache, benne SSL támogatással;
    • a php-s apache;
    • a trac- és svn-szerver (ebben két apache-példány is van);
    • a MySQL;
    • a PostgreSQL;
    • a Squid;
    • a Samba;
    • a fájlcserélő;
    • a DNS-szerver;
    • a Tomcat;
    • az IRC-szerver;
    • a Jabber-szerver;
    • a céges Nethack-szerver;
    • a backupokért felelős dirvish;
    • az a Debian Sarge, amiben az elvileg sarge-on is működő csomagjainkat fordítjuk és teszteljük;
    • az a Fedora, amiben ...;
    • a Lotus Domino (2.6-os kernellel, 64 bites hoszton futó 32 bites Debian sid vserverben, hogy a support örüljön :).
  • Elvileg kereskedelmi hosztingra is jó lehet, mert egy-egy vserver rootjelszavát megadhatjuk ügyfélnek is, de
    • az OpenVZ lehet, hogy erre jobb, amikor épp működik.
  • Játék: Ki szeretnénk próbálni a legújabb, rendkívül divatos disztribúciót
    • (a hozzá adott telepítőt viszont valószínűleg nem fogjuk tudni használni).
  • "Dual Seat": egy gép, két monitor, két egér, két billentyűzet, két X, "két Linux".
  • Akár bérelt virtuális gépen belül is, ha el tudjuk érni, hogy vserveres kernelt kapjunk.

3 Mikor nem lehet/érdemes használni?

  • Ha ügyfeleknek olyan virtuális gépeket akarunk adni, amikben akár kernelt is cserélhetnek;
  • ha több különböző operációs rendszert akarunk futtatni egyszerre;
  • ha a virtuális gépeken belülről saját tűzfalszabályokat akarunk beállítani;
  • ha virtuális hálózatot szeretnénk létrehozni;
  • ha cél a buzzword compliance;
  • ha valamilyen alkalmazást (pl. Oracle, Domino, DB2, ...) mindenképpen támogatott platformon kell futtatnunk.

4 Fogalmak

Egy vserver elindításakor különféle "kernel-objektumok" jönnek létre.

  • Mindegyiknek van egy sorszáma, de fontos tudni, hogy igazából nincs közöttük összefüggés annak ellenére, hogy az util-vserver egy adott vserverhez mindegyikből az azonos sorszámút rendeli.

Ezek az "objektumok" a következők:

  1. security context
    • A futó kernel "partíciói"; csak az egy kontextusban futó processzek látják egymást.
    • Egy kontextustól el lehet venni capabilityket (mint pl. a mountolás képességét).
      • Az util-vserver alapértelmezés szerint is erősen csökkentett capability-halmazzal indítja a vservereket.
    • Két speciális kontextus van, ezek már bootkor létrejönnek:
      • context0: a hoszt processzei ebben futnak
      • context1: "spectator" context, minden PID-t lát
      • chcontext --xid 1 -- ps axfu vagy egyszerűen vps axfu mutatja az összes processzt, a guestekben futókat is; a hoszt kontextusában ezek nem látszanak
    • A többi kontextus akkor jön létre, amikor az adott context ID-jű vservert elindítjuk.
  2. mount/filesystem namespace
    • A mountolt fájlrendszerek listája, kontextusonként külön
      • (igazából ez nem vserver featúra, a vaníliás kernel is tudja; lehetséges házi feladat: pam_namespace).
    • Minden kontextus, amikor létrehozzuk, kap egy mount namespace-t;
      • ebben azok a fájlrendszerek szerepelnek, amelyek a hoszton mountolva vannak az adott pillanatban ("örökli" a hoszttól).
      • Ezután újabbakat mountolhatunk alá; ezek a hoszt namespace-ében már nem jelennek meg.
      • Ha a hoszton mountolunk később más fájlrendszereket, azok pedig a guest namespace-ében nem jelennek meg, ami csak akkor baj, ha utólag akarnánk őket a guestben bind mountolni.
      • A guestben futó folyamatok chrootolva vannak a guest gyökérkönyvtárába,
      • így pl. a hosztgép /proc/mounts fájlja nincs tele a vserverekben mountolt /proc-példányokkal (kozmetika)
      • A biztonságot is javítja: a vserverben a / egy rbind mount lesz ("mount --rbind /var/lib/vserver/foo /" jelleggel), így még nehezebb kijönni belőle (bár a barrier is elég)
      • Egy vserver indításakor bind mountolhatjuk a hoszt egyes fájlrendszereit, így azokat a guestben is elérjük.
    • Egy futó vserverben a /proc/mounts fájlban csak az adott vserver fájlrendszereit látjuk, de ez a namespace és a chroot együttes műve:
      • a kernel kiszűri azokat a fájlrendszereket, amiket nem látunk, mert nem az aktuális root alatt vannak, és
      • átírja a mount-pontokat úgy, hogy az aktuális roothoz legyenek relatívak.
  3. uts namespace
    • nagyjából a gép nevét tartalmazza (nyilván minden vservert hívhatnak másképp, mint a hosztot)
  4. ipc namespace
    • SysV IPC-mechanizmusok izolációjára
  5. network context
    • IP-címek és hálózati interfészek izolációjára
    • Vigyázat: a hoszton 0.0.0.0-ra bindolt szolgáltatások fogják a portot a vserverben indított szolgáltatások elől.
  6. hamarosan várható:
    • pid namespace (több vserverben is lehet egyszerre 42-es PID-jű processz)
    • network namespace (alighanem routing-bejegyzések izolációja végett)

Nézzünk példát filesystem namespace-re!

# vserver-stat
CTX   PROC    VSZ    RSS  userTIME   sysTIME    UPTIME NAME
17      12 270.8M  57.9M   2h00m17  11m31s22  90d23h03 plonesandbox
21      73 249.1M  54.8M   3h06m30   1h03m55  90d23h03 webfrontend
# cat /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / xfs rw 0 0
tmpfs /lib/init/rw tmpfs rw,nosuid 0 0
proc /proc proc rw,nodiratime,nosuid,nodev,noexec 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec 0 0
tmpfs /dev tmpfs rw 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0
devpts /dev/pts devpts rw,nosuid,noexec 0 0
/dev/raid5-1/var /var xfs rw,nosuid,nodev 0 0
/dev/raid5-1/var_log_sv /var/log/sv xfs rw,nosuid,nodev,noexec 0 0
/dev/raid5-1/tmp /tmp xfs rw,nosuid,nodev 0 0
/dev/crypt5-1/vservers /var/lib/vservers jfs rw 0 0
/dev/crypt5-1/shared_tmp /shared/tmp xfs rw,nosuid,nodev 0 0
/dev/crypt5-1/shared_var /shared/var xfs rw,noatime,nosuid,nodev 0 0
/dev/crypt5-1/shared_var_log_sv /shared/var_log_sv xfs rw,noatime,nosuid,nodev,noexec 0 0
/dev/crypt5-1/shared_webapps /shared/webapps jfs rw,noatime,nosuid,nodev,noexec 0 0
/dev/crypt5-1/shared_home /shared/home jfs rw,noatime,nosuid,nodev 0 0
/dev/crypt5-1/shared_var_backups /shared/var_backups jfs rw,noatime,nosuid,nodev 0 0
# ls /vservers/webfrontend/proc
# 

Tehát a "webfrontend" vserver /proc könyvtárát a hoszt namespace-éből üresnek látjuk. Nézzük meg a webfrontend vserver namespace-éből:

# vnamespace -e 21 ls -l /vservers/webfrontend/proc
total 0
dr-xr-xr-x  5 root     root             0 Dec  6 23:29 1
dr-xr-xr-x  5 root     root             0 Dec  6 23:29 10
[...]
dr-xr-xr-x  5 root     root             0 Dec  6 23:29 992
dr-xr-xr-x  5 root     root             0 Dec  6 23:29 acpi
[...]
-r--r--r--  1 root     root             0 Dec  6 23:29 zoneinfo
# vnamespace -e 21 cat /vservers/webfrontend/proc/mounts
rootfs / rootfs rw 0 0
/dev/root / xfs rw 0 0
proc /proc proc rw,nodiratime,nosuid,nodev,noexec 0 0
tmpfs /dev tmpfs rw 0 0
/dev/root /dev/.static/dev xfs rw 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0
devpts /dev/pts devpts rw,nosuid,noexec 0 0
/dev/raid5-1/var /var xfs rw,nosuid,nodev 0 0
/dev/crypt5-1/vservers /var/lib/vservers xfs rw 0 0
/dev/raid5-1/tmp /tmp xfs rw,nosuid,nodev 0 0
none /var/lib/vservers/webfrontend/proc proc rw,nodiratime,nodev 0 0
none /var/lib/vservers/webfrontend/dev/pts devpts rw 0 0
/dev/crypt5-1/shared_var /var/lib/vservers/webfrontend/var xfs rw,nodev 0 0
/dev/crypt5-1/shared_tmp /var/lib/vservers/webfrontend/tmp xfs rw,nodev 0 0
/dev/crypt5-1/shared_var_log_sv /var/lib/vservers/webfrontend/var/log/sv xfs rw,nodev 0 0
/dev/crypt5-1/shared_home /var/lib/vservers/webfrontend/home jfs rw,nodev 0 0
/dev/crypt5-1/vservers / jfs rw,nodev 0 0
none /proc proc rw,nodiratime,nodev 0 0
none /dev/pts devpts rw 0 0
/dev/crypt5-1/shared_var /var xfs rw,nodev 0 0
/dev/crypt5-1/shared_var_log_sv /var/log/sv xfs rw,nodev 0 0
/dev/crypt5-1/shared_tmp /tmp xfs rw,nodev 0 0
/dev/crypt5-1/shared_home /home jfs rw,nodev 0 0

Így még látjuk a hoszt fájlrendszereit is; igazából akár a /proc/mounts-ot is kilistázhattam volna, ugyanez lett volna benne. Most nézzük meg úgy, hogy chrootolunk is:

# vnamespace -e 21 chroot /vservers/webfrontend cat /proc/mounts                     
rootfs / rootfs rw 0 0
/dev/crypt5-1/vservers /var/lib/vservers xfs rw 0 0
none /proc proc rw,nodiratime,nodev 0 0
none /dev/pts devpts rw 0 0
/dev/crypt5-1/shared_var /var xfs rw,nodev 0 0
/dev/crypt5-1/shared_tmp /tmp xfs rw,nodev 0 0
/dev/crypt5-1/shared_var_log_sv /var/log/sv xfs rw,nodev 0 0
/dev/crypt5-1/shared_home /home jfs rw,nodev 0 0

Ez még mindig nem teljes kép; nézzük meg, mi tartozik ehhez a guest fstab fájljában!

# cat /etc/vservers/webfrontend/fstab 
none                            /proc                   proc    defaults        0 0
none                            /dev/pts                devpts  gid=5,mode=620  0 0
/shared/var/webfrontend         /var                    none    bind            0 0
/shared/tmp/webfrontend         /tmp                    none    bind            0 0
/shared/var_log_sv/webfrontend  /var/log/sv             none    bind            0 0
/shared/home                    /home                   none    bind            0 0

5 Hogyan érdemes vservert csinálni?

  1. Döntsük el, hogyan szeretnénk kezelni a fájlrendszereit. Nagyjából a következő lehetőségeink vannak:
    • Mindenből legyen neki saját, külön logikai köteten (ez a xenhez szokott rendszergazda reflexe).
      • Előnyök:
        • teljes szeparáció;
        • nem kell kvóta ahhoz, hogy az egyik vserver ne használhassa el a másik elől a helyet.
      • Hátrányok:
        • sok vserver esetén rengeteg logikai kötetünk lesz (nehezen áttekinthető);
        • nem tudjuk összehardlinkelni a sok azonos /usr-t és /lib-et;
        • ha a köteteket csak az egyes vserverekben mountoljuk be, körülményes a megnövelésük (readonly mountolt xfs esetén egyelőre nem is lehetséges);
        • ha a hoszton is, belefulladunk egy df kimenetébe.
    • Minden legyen egyben, a /vservers alatt (esetleg a hoszt rootjával közös köteten). Ez a desktoplinuxos reflexe.
      • Előnyök, hátrányok értelemszerűek.
    • A /vservers legyen közös, de legyen külön /var, /usr, /tmp mindegyiknek.
      • Előnyök, hátrányok értelemszerűek.
    • Legyen a hoszton néhány nagy közös kötet, és mindegyik alatt minden vservernek egy alkönyvtár (ilyen felállás látható fentebb).
      • Persze ilyenkor is lehet egy-egy vservernek olyan fájlrendszere, ami csak az övé...
  2. Döntsük el, hogyan lesz elérhető a hálózatról!
    • A hosztnak van egy eth0-ja, azon egy darab IP; ezt odaadjuk a vservernek is.
      • Előnye: egyszerű.
      • Hátrányok:
        • Nincs izoláció:
          • a vserver is látja a teljes hálózati forgalmat (bár sniffelni nem tud, ha nem adtunk neki olyan capabilityt);
          • az egyik vserver elhappolhat portot a másik elől;
          • ha mindegyikbe akarunk tudni ssh-zni, mindegyikben más porton kell futtatnunk az sshd-t.
        • Ha óvatlanok vagyunk, egy vserver leállításakor leszedhetjük az IP-t az eth0-ról.
    • A hoszt eth0-jára húzatunk fel a vserverek számára új IP-ket.
      • Hátrány: sok globálisan egyedi IP kell hozzá.
    • A hoszton csinálunk egy (vagy egy-egy) dummy interfészt a vservereknek, és NATtal írjuk át a nyilvános IP-re érkező kéréseket úgy, hogy a megfelelő vserver kapja meg.
      • Hátrány: connection tracking és tűzfalkonfiguráció kell hozzá.

(folyt. köv.)

6 Ajánlott irodalom

Személyes eszközök