Virtualizacija yra puikus būdas išnaudoti serverio išteklius, nes dažnai nemaža dalis tarnybinės stoties išteklių lieka nepanaudota, o kompiuteris vis viena eikvoja elektros energiją ir užima vietą. Žinoma, į vieną tarnybinę stotį galima įdiegti keletą servisų, tačiau ne visuomet tai yra paranku.
Pasitelkus virtualizaciją, iš vienos fizinės mašinos galima nesunkiai padaryti 2, 3 ar net daugiau sistemų, tinkle matomų, kaip savarankiški serveriai. O su įvertinus apkrovą ir itinkamai bei tinkamai paskirsčius išteklius - tarnybinių stočių teikiamų paslaugų spartos sumažėjimas nebus pastebimas. Apie tai, kaip įdiegti ir suderinti virtualizacijos programinę įrangą - galima rasti XEN, KVM, „Virtual Box“ ar „VMWare Server“ autorių tinklalapiuose ir daugelyje kitų Wiki ar tinklaraščių puslapiuose. Bet yra vienas niuansas, apie kurį šiuose vadovuose paprastai užsimenama tik keletu žodžių ir neatkreipus dėmesio į tai, kur bus saugomos virtualios mašinos - pirmieji virtualizacijos įspūdžiai gali būti labai ne kokie.
Nors straipsnyje bus rašoma apie XEN virtualizacijos sistemą Linux terpėje, tačiau tie patys principai galioja ir diegiant virtualius kompiuterius kitose OS.
Disko posistemio veiklos diagnostika
Kuriant virtualius kompiuterius, jų virtualūs diskiniai kaupikliai vienokiu ar kitokiu būdu turi būti įrašyti į realias fizinės mašinos laikmenas. Beveik visuose virtualių sistemų diegimo vadovuose (išskyrus, nebent, į „Enterprise“ lygio sistemas orientuotų programų) nurodoma galimybė sukurti virtualių diskinių kaupiklių konteinerius paprastuose failuose ar jų grupėje. Tai yra pats paprasčiausias būdas - tiesiog sukuriamas diskinio kaupiklio atvaizdo failas, kuriame virtualios mašinos procesas sukuria diskinio kaupiklio turinį. Ir dažniausiai pats prasčiausias.
Deja, tokia konfigūracija dažnai yra tinkama nebent principinei virtualizavimo galimybei patikrinti, bet jokiu būdu ne sistemos darbui ar, tuo labiau, virtualaus serverio našumui įvertinti! Problema ta, jog kuriant virtualų diskinį kaupiklį faile, susidaro failų sistemų „sumuštinis“. Virtuali mašina tvarko savo failų sistemą ir rašo failų duomenis į failų sistemą virtualaus kaupiklio skirsnyje, registruodama failų sistemos operacijas savame žurnale. Savo ruožtu fizinė mašina perima šias rašymo operacijas ir jas vėl pakartoja fizinės mašinos failų sistemoje ir atžymi operacijas failų sistemos operacijų žurnale. Grubiai, vienam virtualios mašinos duomenų bloko rašymui reikės 9 įvesties/išvesties operacijų fizinėje mašinoje, kurios papildomai apkraus procesorių. To pasėkoje procesorius užuot apdorojęs duomenis, tiesiog laukia, kol jie bus įrašyti ar nuskaityti iš kaupiklio.
Ypač tai pastebima, jei virtualus serveris atlieka daug mažų failinių operacijų, atlikdamas daug pakeitimų dideliuose failuose. Nors bendras rašomų skaitomų duomenų srautas nebus didelis (0.5-2 MBps), tačiau Linux sistema bus labai užsiėmusi, tvarka failinės sistemos įvykių žurnalą. Kažkiek gali padėti žaidimas su failų sistemos prijungimo parametrais, tokiais kaip noatime ar data=writeback, bet didelio pagerėjimo nebus.
Tokią situaciją galima nesunkiai atpažinti: sistema iš pažiūros lyg ir nėra apkrauta ir komandos įvykdomos sparčiai, tačiau reikia ilgokai palaukti, kol komanda bus pradėta vykdyti. Gerokai sulėtėja net ir nedidelių failų atvėrimas ar katalogo turinio parodymas. Serverio būklę tiksliai galima įvertinti pasitelkus iostat ir sar (sysstat paketo dalis) programas.
Komanda iostat 3 10, kas 3 sekundes parodys įvesties išvesties operacijų skaičių kiekvienam blokiniam įrenginiui ir bendrus sistemos apkrovos rodiklius. Jei kompiuteris atlieka daug įvesties ir išvesties operacijų parametras iowait bus gerokai didesnis už 0. Taip yra todėl, kad įvesties ir išvesties operacijos vykdomos labai ilgai, palyginus su kitomis instrukcijomis. Procesorius tiesiog laukia, kol duomenys bus įrašyti ar nuskaityti.
vm-serv:~# iostat 3 10
Linux 2.6.26-2-xen-amd64 (vm-serv) 2010.05.05 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0,02 0,00 0,04 42,55 1,06 56,32
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 14,81 99,58 378,45 271387618 1031415098
sdb 0,09 3,31 10,65 9021638 29026500
dm-0 0,22 2,51 1,55 6841834 4223704
dm-1 0,00 0,00 0,00 2298 2536
dm-2 0,00 0,00 0,00 3672 2768
dm-3 36,88 91,10 286,31 248275050 780294952
dm-4 0,01 0,27 0,51 746794 1394200
dm-5 0,10 0,13 5,29 343488 14419374
dm-6 2,31 5,31 84,79 14475468 231076968
avg-cpu: %user %nice %system %iowait %steal %idle
0,33 0,00 0,00 0,00 1,98 97,69
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 7,59 29,04 89,77 88 272
sdb 0,00 0,00 0,00 0 0
dm-0 0,00 0,00 0,00 0 0
avg-cpu: %user %nice %system %iowait %steal %idle
0,00 0,00 0,00 0,33 0,00 99,67
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 9,30 5,32 441,20 16 1328
sdb 0,00 0,00 0,00 0 0
dm-0 0,00 0,00 0,00 0 0
dm-1 0,00 0,00 0,00 0 0
dm-2 0,00 0,00 0,00 0 0
dm-3 31,89 0,00 255,15 0 768
dm-4 0,00 0,00 0,00 0 0
dm-5 0,00 0,00 0,00 0 0
dm-6 3,99 5,32 186,05 16 560
Jei iostat renka tik įvesties ir išvesties operacinjų statistiką, tai sar gali pateikti tiek realaus laiko duomenis (nurodant sekundes ir kiek matavimų atlikti), tiek ataskaitų rinkmenose sukauptus duomenis, naudingus įvertinti sistemos darbo pokyčius. Komanda sar -u parodo per dieną surinktus kompiuterio CPU apkrovos rodiklius.
vm-serv:~# sar -u
Linux 2.6.26-2-xen-amd64 (vm-serv) 2010.05.05 _x86_64_ (1 CPU)
00:00:01 CPU %user %nice %system %iowait %steal %idle
00:05:01 all 0,02 0,00 0,03 0,01 0,22 99,72
00:15:01 all 0,02 0,00 0,02 0,01 0,18 99,77
00:25:01 all 0,02 0,00 0,02 0,01 0,26 99,69
00:35:01 all 0,02 0,00 0,02 0,01 0,16 99,79
00:45:01 all 0,02 0,00 0,02 0,01 0,14 99,80
00:55:01 all 0,01 0,00 0,01 0,02 0,17 99,78
01:05:01 all 0,02 0,00 0,02 0,01 0,23 99,72
01:15:01 all 0,02 0,00 0,02 0,01 0,18 99,77
...
05:05:01 all 0,01 0,00 0,02 0,02 0,18 99,77
05:15:01 all 0,01 0,00 0,02 0,01 0,18 99,78
05:25:01 all 0,02 0,00 0,02 0,01 0,21 99,75
05:35:01 all 0,01 0,00 0,02 0,02 0,21 99,74
05:45:02 all 0,02 0,00 0,02 0,01 0,21 99,73
05:55:01 all 0,02 0,00 0,02 0,01 0,21 99,75
06:05:01 all 0,01 0,00 0,02 0,01 0,18 99,77
...
...
19:45:01 all 0,01 0,00 0,02 0,01 0,15 99,80
19:55:01 all 0,02 0,00 0,01 0,01 0,22 99,73
20:05:01 all 1,02 0,00 0,66 10,13 1,32 86,88
20:15:01 all 3,70 0,00 1,00 12,92 4,11 78,26
20:25:01 all 0,37 0,00 0,19 0,02 0,61 98,81
20:35:01 all 0,04 0,00 0,03 0,01 0,74 99,19
20:45:01 all 0,02 0,00 0,03 0,02 0,58 99,36
20:55:01 all 0,01 0,00 0,02 0,02 0,24 99,71
21:05:01 all 0,12 0,00 0,04 0,07 0,39 99,38
21:15:01 all 0,02 0,00 0,02 0,02 0,29 99,64
Average: all 0,06 0,00 0,03 0,21 0,26 99,44
vm-serv:~#
Nurodžius parametrą -f galima pasiimti seniau sukauptus duomenis iš paskutinių 30 dienų archyvo:
vm-serv:~# sar -u -f /var/log/sysstat/sa01
Linux 2.6.26-2-xen-amd64 (vm-serv) 2010.05.01 _x86_64_ (1 CPU)
00:00:01 CPU %user %nice %system %iowait %steal %idle
00:05:01 all 1,73 0,00 0,48 78,06 1,71 18,03
00:15:01 all 2,04 0,00 1,78 15,27 0,72 80,20
00:25:01 all 3,26 0,00 1,97 21,06 0,60 73,12
00:35:01 all 2,39 0,00 3,10 29,96 0,84 63,71
00:45:01 all 0,03 0,00 0,09 42,30 3,35 54,22
00:55:01 all 0,01 0,00 0,04 30,95 1,82 67,17
01:05:01 all 0,02 0,00 0,07 46,05 0,33 53,54
01:15:01 all 0,03 0,00 0,05 61,50 0,24 38,18
...
05:05:01 all 0,01 0,00 0,03 50,09 1,17 48,70
05:15:01 all 0,01 0,00 0,04 60,37 1,34 38,25
05:25:01 all 0,01 0,00 0,04 51,09 1,16 47,71
05:35:01 all 0,01 0,00 0,03 44,97 0,95 54,04
...
21:15:01 all 0,02 0,00 0,23 78,62 0,80 20,33
21:25:01 all 0,01 0,00 0,07 98,75 0,74 0,43
21:25:01 CPU %user %nice %system %iowait %steal %idle
21:35:01 all 0,02 0,00 0,10 83,22 0,62 16,04
21:45:01 all 0,01 0,00 0,09 68,67 0,64 30,59
21:55:01 all 0,01 0,00 0,09 79,92 0,47 19,51
22:05:01 all 0,01 0,00 0,09 93,31 0,72 5,87
22:15:01 all 0,01 0,00 0,03 96,77 0,82 2,36
22:25:01 all 0,01 0,00 0,04 98,55 1,22 0,18
22:35:01 all 0,01 0,00 0,03 95,33 0,79 3,84
22:45:01 all 0,02 0,00 0,06 98,74 1,18 0,00
22:55:01 all 0,02 0,00 0,07 56,43 2,23 41,26
23:05:01 all 0,01 0,00 0,04 51,37 2,14 46,44
23:15:01 all 0,01 0,00 0,05 57,03 2,41 40,50
23:25:01 all 0,02 0,00 0,04 68,07 2,48 29,39
23:35:01 all 0,01 0,00 0,05 69,98 2,35 27,61
23:45:01 all 0,02 0,00 0,04 73,77 2,42 23,75
23:55:01 all 0,02 0,00 0,03 65,78 2,65 31,52
23:59:01 all 0,03 0,00 0,05 89,52 1,94 8,46
00:00:01 all 0,02 0,00 0,05 15,15 0,98 83,80
Average: all 0,07 0,00 0,09 57,77 1,44 40,64
Pavyzdžiuose matomas akivaizdus skirtumas tarp to, kiek procentų laiko procesorius praleisdavo laukdamas diskinių operacijų mėnesio pirmą dieną, kol virtualios mašinos buvo saugomos failiniuose konteineriuose ir kiek jam tenka lūkuriuoti dabar. Atsisakius failinių konteinerių tiek virtuali mašina, tiek fizinė sistema tiesiog atsigavo ir komandų vykdymo ar katalogo turinio nebereikėjo laukti po 10 sekundžių.
LVM
Kaip ir daugelis kitų šiuolaikinių OS, Linux turi savo LVM („Logical Volume Manager“) disko tomų valdymo sistemos versiją. LVM yra naudingas tuo, jog leidžia labai lanksčiai išnaudoti ir valdyti diskinę ervdę. Diskinio kaupiklio skirsniai yra statinės struktūros, kurias po sukūrimo yra sunku pakeisti. Tuo tarpu LVM leidžia veikiant sistemai perkelti loginį tomą iš vieno diskinio kaupiklio į kitą, padidinti ar sumažinti tomo dydį, pridėti ar pašalinti kaupiklius iš tomų grupės ir t.t. Visa tai galima atlikti kompiuteriui veikiant ir jei tomuose sukurtos failų sistemos numato tokių pakeitimų galimybę - visiškai netrikdyti kompiuterio darbo.
Pasitelkus LVM galima padaryti aktyvių duomenų rezervines kopijas, kas kartais labai praverčia administruojant duomenų bazes ar kitus sparčiai kintančius duomenis. LVM yra geras dar ir tuo, kad šis papildomas „sluoksnis“ beveik nelėtina diskinių operacijų.
Išsamų LVM vadovą galima rasti šiuose puslapiuose:
- TLDP - LVM HowTo
- „HowTo Forge“ - A Beginners guide to LVM
Taigi, 1 TB kaupiklis buvo suskaidytas į 3 skirsnius: įkrovos /boot ir du skirsnius LVM tomų grupėms. Vienas paskirtas pačiai Linux sistemai, kitas duomenims.
vm-serv:~# fdisk -l /dev/sda
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000eb383
Device Boot Start End Blocks Id System
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 3849 30716280 8e Linux LVM
/dev/sda3 3850 121601 945842940 8e Linux LVM
vm-serv:~#
vm-serv:~# pvdisplay -C
PV VG Fmt Attr PSize PFree
/dev/sda2 rootvg lvm2 a- 29.28G 11.56G
/dev/sda3 datavg lvm2 a- 902.00G 238.06G
vm-serv:~#
Visi LVM tomai yra pasiekiami, kaip /dev/mapper/tomugrupe-tomovardas blokiniai įrenginiai. Taigi jei turime tokius tomus LVM tomų grupėse:
vm-serv:~# lvdisplay -C
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
storage datavg -wi-ao 390.62G
vmhold datavg -wi-ao 195.31G
xen-freenet-disk0 datavg -wi-ao 8.00G
xen-freenet-disk1 datavg -wi-ao 70.00G
root rootvg -wi-ao 11.72G
swap rootvg -wi-ao 4.00G
tmp rootvg -wi-ao 2.00G
vm-serv:~#
Tai sistemoje bus pasiekiami štai tokie blokiniai „įrenginiai“, kuriuos galima sužymėti, kaip savarankiškas failų sistemas ar pateikti, kaip virtualios mašinos talpyklą XEN virtualizavimo sistemai:
vm-serv:~# ls /dev/mapper/
control datavg-vmhold datavg-xen--freenet--disk1 rootvg-swap
datavg-storage datavg-xen--freenet--disk0 rootvg-root rootvg-tmp
vm-serv:~#
Sukūręs papildomus du tomus freenet virtualios mašinos kaupikliams - ėmiausi migracijos.
Virtualių mašinų migracija
Jei XEN virtualios mašinos kaupiklis buvo kuriamas, kaip vienas diskas, tai migracija yra gerokai paprastesnė. Tam tiesiog reikia sukurti identiško dydžio loginį tomą ir dd komandos pagalba perkopijuoti failo turinį į loginį tomą maždaug taip: dd if=/vm/domains/serveris/disk0.img of=/dev/mapper/datavg-server1--disk0. Visos rinkmenoje buvusios failinės srtuktūros bus sėkmingai atkartotos loginiame tome. Gana išsamus paaiškinimas, kaip tai padaryti yra šiame „HowTo Forge“ puslapyje.
Deja, mano XEN mašinos buvo aprašytos, nei kaip vienas diskas, o kaip skirsnių rinkinys, todėl vienai virtualiai mašinai man būtų reikėję sukurti 6 loginius tomus - po vieną kiekvienam skirsniui šioje XEN mašinoje. Numigravus antrą mašiną į LVM tomus, o vėliau eksperimentams susikūrus dar ir trečią - gautųsi jau gana didelis „zoologijos sodas“, kuriame sunku susigaudyti. Todėl buvo nuspręsta supaprastinti sistemą ir migruoti kiek kitaip. Nors šis būdas nėra labai elegantiškas, tačiau jis visai efektyvus.
Pirmiausia nauji LVM tomai, kurių dydis buvo parinktas pagal realių duomenų apimtį, buvo prijungti prie XEN mašinos, kaip papildomi diskiniai kaupikliai.
root = '/dev/sda2 ro'
disk = [
'file:/home/VM/domains/freenet/swap.img,sda1,w',
'file:/home/VM/domains/freenet/root.img,sda2,w',
'file:/home/VM/domains/freenet/var.img,sda3,w',
'file:/home/VM/domains/freenet/tmp.img,sda4,w',
'file:/home/VM/domains/freenet/home.img,sda5,w',
'phy:/dev/mapper/datavg-xen--freenet--disk0,sdb,w',
'phy:/dev/mapper/datavg-xen--freenet--disk1,sdc,w'
]
Perkrovus virtualią mašiną, diskiniai kaupikliai /dev/sdb ir /dev/sdc buvo suskaidyti į norimus skirsnius ir šie skirsniai buvo sužymėti ext3 failų sistemomis. Tuomet skirsniai buvo prijungti /mnt ir /mnt/home kataloguose ir sustabdžius aktyvias programas, visa Linux sistema su visais duomenimis buvo tiesiog perkopijuota į /mnt katalogą, kuriame buvo prijungti nauji diskai. Kopijuojant buvo nurodoma išsaugoti esamas failų nuosavybės teises. kadangi kopijuoti reikia ne viską, tai operacijos supaprastinimui viskas buvo daroma iš mc aplinkos. Kuria buvo palikti nepažymėti /proc, /sys ir aišku /mnt katalogai. Tiesa, failų sistemos buvo sužymėtos su specialiais parametrais. Namų katalogo skirsnis /dev/sdb1 buvo sužymėtas be vietos rezervavimo root vartotojui - tai naudinga tik sisteminiams skirsniams, o duomenų saugojimo skirsniuose tai tik veltui išmesti 5 proc. vietos. Taip pat šiems skirsniams buvo aktyvuotas writeback ext3 žurnalo darbo režimas, leidžiantis spartesnes failines operacijas duomenų saugojimo patikimumo sąskaita. Jei nesupratote apie ką čia -- data=writeback nuostatos nenaudokite. ;)
mkfs.ext3 -m 0 /dev/sdb1
mkfs.ext3 /dev/sda1
tune2fs -o journal_data_writeback /dev/sda1
tune2fs -o journal_data_writeback /dev/sdb1
Perkopijavus, buvo pataisytas /mnt/etc/fstab failas, iš kurio buvo išmesti visi nereikalingi skirsnių prijungimo taškai, nes naujoje sistemoje visa Linux sistema bus viename /dev/sda1 skirsnyje, o /home prijungtas, kaip /dev/sdb1. Galutinis fstab turinys atrodė štai taip:
freenet:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/sda2 none swap sw 0 0
/dev/sda1 / ext3 async,noatime,data=writeback,errors=remount-ro,commit=30 0 1
/dev/sdb1 /home ext3 async,noatime,nodev,nosuid,data=writeback,commit=30 0 1
Po visų šių operacijų /mnt/home ir /mnt buvo atjungtos ir virtuali mašina išjungta shutdown -h now komanda. Beliko tik pakeisti XEN virtualios mašinos aprašą ir pradėti naudoti naujus „kaupiklius“. Virtualios mašinos konfigūracijos failo diskinių kaupiklių dalis buvo pakeista taip:
root = '/dev/sda1 ro'
disk = [
'phy:/dev/mapper/datavg-xen--freenet--disk0,sda,w',
'phy:/dev/mapper/datavg-xen--freenet--disk1,sdb,w'
]
Kadangi XEN savo Linux virtualioms mašijoms OS branduolį „sustumia“ iš fizinės mašinos, tai OS migracijai visiškai pakako paprasčiausiai perkopijuoti failus ir pakeisti sistemos įkrovos įrenginį. Jei tai būtų kokia KVM ar Virtual Box mašina, tai po perkopijavimo tektų pažaisti su chroot komanda bei įkrovos tvarklyklės (GRUB arba LILO) diegimu į naują kaupiklį, antraip jos paprasčiausiai neįsikrautų.
Po šios operacijos XEN virtualios mašinos visiškai atlaisvino CPU ir laisvo laiko pakako paskirstytųjų skaičiavimų klientui įdiegti. Kviečiu ir jus prisidėti prie šių visuomeninių projektų ir paskirti nepanaudotą CPU laiką mokslinių tyrimų duomenims apdoroti. Berklio universiteto sukurta paskirstytųjų skaičiavimų sistema BOINC šiuo metu vienyja daugiau nei pusę milijono kompiuterių, kurie apdoroja dešimčių projektų duomenis. Tokių projektų pavyzdžiais gali būti „World Community Grid“ ar garsusis SETI@Home (https://www.launchknowledge.com/seti-at-home-alternatives/ SETI@Home užsidarė).