Kë përfshin ky artikull
Ky artikull mund të jetë i dobishëm për administratoret e sistemeve që përballen me nevojën për të krijuar një shërbim të «punës stacionare» të përkohshme.
Prologu
Departamenti i IT-së në një kompani të re dhe dinamike me një rrjet të vogël rajonal ka kërkuar ndihmë për të organizuar «stacionet e vetë-shërbimit» për klientët e saj. Këto stacione planifikoheshin të përdoren për regjistrim në portale të jashtme të kompanisë, për të ngarkuar të dhëna nga pajisje të jashtme dhe për të punuar me portalet qeveritare.
Një aspekt i rëndësishëm ishte fakti se shumica e softuerit ishte e optimizuar për MS Windows (p.sh. «Deklarata»), dhe ndonëse po ecet drejt formateve të hapura, MS Office mbetet standardi dominues për shkëmbimin e dokumenteve elektronike. Prandaj, nuk mund të hiqnim dorë nga MS Windows për të zgjidhur këtë problem.
Problemi kryesor ishte mundësia e grumbullimit të të dhënave nga seancat e përdoruesve, të cilat mund të çonin në shkëputje te palët e treta. . Por, ndryshe nga organizatat gjysmë shtetërore (institucione autonome shtetërore), organizatat jo-shtetërore do të ndëshkohen shumë më rëndë për mangësi të tilla. Problemi tjetër më kritik ishte kërkesa për punë me mediume të jashtme të dhënash, mbi të cilat, një numër të konsiderueshëm do të kishte malware. Probabiliteti i përhapjes së malware nga interneti u konsiderua si më pak i mundshëm, për shkak të kufizimeve të daljes në internet përmes një liste të bardhë adresash. Punonjësit e departamenteve të tjera u angazhuan në zhvillimin e kërkesave, duke shtuar kërkesat dhe dëshirat e tyre; kërkesat përfundimtare dukej si më poshtë:
Kërkesat e Sigurisë së Informacionit
- Pas përdorimit, të gjitha të dhënat e përdoruesit (përfshirë skedarët temp dhe çelësat e regjistrit) duhet të fshihen.
- Të gjitha proceset e nisura nga përdoruesi duhet të përfundojnë pas përfundimit të punës.
- Dalja në internet përmes një liste të bardhë adresash.
- Kufizime mbi mundësinë e ekzekutimit të kodit të jashtëm.
- Në rast seansit të papunë për më shumë se 5 minuta, seansi duhet të përfundojë automatikisht dhe stacioni duhet të kryejë pastrimin.
Kërkesat e klientit
- Numri i stacioneve tĂ« klientĂ«ve pĂ«r filialin â jo mĂ« shumĂ« se 4.
- Koha minimale e pritjes për të qenë e gatshme sistemi, nga momenti 'u ulën në karrige' deri në fillimin e punës me softuerin e klientit.
- Mundësia për të lidhur pajisje periferike (skanerë, flash drive) direkt nga vendi i instalimit të 'stacionit të vetë-shërbimit'.
- Kërkesat e klientit
- Demonstrimi i materialeve reklamuese (imazhe) gjatë kohës së pushimit të kompleksit.
Mërzia e krijimtarisë
Pas shumë eksperimenteve me livecd të Windows, arritëm në përfundimin e njëzëshëm se zgjidhja e arritur nuk përmbush të paktën 3 pika kritike. Ato ose ngarkohen ngadalë, ose nuk janë plotësisht live, ose personalizimi i tyre ishte i lidhur me dhimbje të mëdha. Ndoshta ne kërkuam keq dhe ju mund të sugjeroni një grup mjetesh, do të isha mirënjohës.
Më pas filluam të shikonim drejt VDI, por për këtë detyrë shumica e zgjidhjeve janë ose shumë të shtrenjta, ose kërkojnë vëmendje të madhe. Doja një mjet të thjeshtë, me minimal magji, ku shumica e problemeve të mund të zgjidheshin me një ristartim të thjeshtë të shërbimit. Fatmirësisht, kishim pajisje serveri, të klasës low end në degët, nga një shërbim që kishte dalë nga përdorimi, të cilat mund t'i përdornim si bazën teknologjike.
ĂfarĂ« rezultati kemi marrĂ«? Epo, çfarĂ« kemi arritur, nuk mund t'ju tregoj, sepse kam njĂ« NDA, por gjatĂ« kĂ«rkimeve, ne zhvilluam njĂ« skemĂ« interesante, e cila ka treguar rezultate tĂ« mira nĂ« testet laboratorike, edhe pse nuk kaloi nĂ« prodhim.
Pak të vogla: autori nuk pretendojë se zgjidhja e propozuar zgjidh të gjitha detyrat e vendosura dhe e bën këtë me volnet dhe këngë. Autori është paraprakisht dakord me pohimin se gjuhë angleze e tij është shumë e keqe. Duke qenë se zgjidhja nuk zhvillohet më, nuk mund të prisni për përmirësime ose ndryshime në funksionalitet, gjithçka është në duar tuaja. Autori supozon se jeni pak të njohur me KVM dhe keni lexuar një artikull për protokollin Spice dhe keni punuar pak me Centos ose një shpërndarje tjetër GNU Linux.
Në këtë artikull do të doja të shqyrtoja strukturën e zgjidhjes së arritur, veçanërisht ndërveprimin midis klientit dhe serverit, si dhe thelbin e proceseve në ciklin e jetës së makinave virtuale brenda zgjidhjes së shqyrtuar. Nëse artikulli do të jetë interesant për publikun, do të përshkruaj detajet e implementimit të imazheve live për krijimin e klientëve të hollë mbi bazën e Fedora dhe do të flas për detajet e konfigurimit të makinave virtuale dhe Serverin KVM për optimizimin e performancës dhe sigurisë.
Nëse merrni letërngjyrë,
Piktura, brushat dhe kola.
Dhe pak aftësi...
Mund të bëni njëqind rubla!
Skema dhe përshkrimi i testit të qëndresës

Të gjitha pajisjet ndodhen brenda rrjetit të degës, vetëm kanali i internetit del jashtë. Serveri proxy ka qenë historikisht aty, nuk paraqet ndonjë gjë jashtëzakonisht të veçantë. Por pikërisht mbi të, mes të tjerash, do të ndodhi filtrimi i trafikut nga makinat virtuale (shkurt. VM më poshtë në tekst). Asgjë nuk e pengon vendosjen e këtij shërbimi në serverin KVM, e vetmja gjë që duhet të shikohet është se si do të ndryshojë ngarkesa nga ai në sistemin disk.
Client Station â nĂ« thelb, "stacionet e vetĂ«-shĂ«rbimit", "frontend" i shĂ«rbimit tonĂ«. PĂ«rfaqĂ«sojnĂ« nettop-et Lenovo IdeaCentre. ĂfarĂ« e bĂ«n kĂ«tĂ« aparat tĂ« mirĂ«? Pralmost gjithçka, veçanĂ«risht kĂ«naqĂ«sia nga numri i madh i porteve USB dhe lexuesit e kartave nĂ« panelin e pĂ«rparmĂ«. NĂ« skemĂ«n tonĂ«, nĂ« lexuesin e kartave Ă«shtĂ« vendosur njĂ« kartĂ« SD me mbrojtje harduerike tĂ« aktivizuar nga shkrimi, nĂ« tĂ« cilĂ«n Ă«shtĂ« regjistruar njĂ« imazh live tĂ« modifikuar tĂ« Fedora 28. Sigurisht, nettop-i Ă«shtĂ« i lidhur me njĂ« monitor, tastierĂ« dhe maus.
Switch â njĂ« switch hardueri i nivelit tĂ« dytĂ«, i cili ndodhet nĂ« dhomĂ«n e serverĂ«ve dhe ndĂ«rron dritat. Nuk Ă«shtĂ« i lidhur me asnjĂ« rrjet tjetĂ«r pĂ«rveç rrjetit tĂ« "stacioneve tĂ« vetĂ«-shĂ«rbimit".
KVM_Server â bĂ«rthama e skemĂ«s, nĂ« provat e qĂ«ndrueshmĂ«risĂ« Core 2 Quad Q9650 me 8 GB memorie RAM me siguri mbante 3 makina virtuale me Windows 10. Nsubsysi i diskut â adaptec 3405 2 diskĂ« Raid 1 + SSD. NĂ« provat nĂ« terren, Xeon 1220 me LSI 9260 mĂ« tĂ« fuqishĂ«m + SSD lehtĂ«sisht mbanin 5-6 VM. ServerĂ«t na u dhanĂ« nga njĂ« shĂ«rbim tĂ«rhequr, shpenzimet kapitale do ishin tĂ« pakta. NĂ« kĂ«to serverĂ« Ă«shtĂ« instaluar sistemi i virtualizimit KVM me grupin e makinave virtuale pool_Vm.
Vm â makina virtuale, backend-i i shĂ«rbimit tonĂ«. Aty ndodh puna e pĂ«rdoruesit.
Enp5s0 â ndĂ«rfaqja rrjetit qĂ« ndihmon nĂ« lidhjen me rrjetin e «stacioneve tĂ« vetĂ«-shĂ«rbimit», aty jetojnĂ« dhcpd, ntpd, httpd dhe xinetd dĂ«gjon portin «signal».
Lo0 â ndĂ«rfaqja pseudo e petĂ«s sĂ« kthimit. Standarde.
Spice_console â NjĂ« gjĂ« shumĂ« interesante, pasi ndryshe nga RDP klasike, kur aktivizohet lidhja KVM+Spice protocol, krijohet njĂ« njĂ«si shtesĂ« â porta e konsolĂ«s sĂ« makinĂ«s virtuale. Faktikisht, duke u lidhur nĂ« kĂ«tĂ« port TCP, ne marrim konsolĂ«n e Vm, pa nevojĂ«n pĂ«r t'u lidhur me Vm pĂ«rmes ndĂ«rfaqes sĂ« saj rrjetore. TĂ«rĂ« ndĂ«rveprimi me Vm pĂ«rmes transferimit tĂ« sinjalit, serveri e merr pĂ«rsipĂ«r. Analogji mĂ« e afĂ«rt pĂ«r funksion Ă«shtĂ« IPKVM. KĂ«shtu, nĂ« kĂ«tĂ« port dĂ«rgohet imazhi i monitorit tĂ« VM, gjithashtu dĂ«rgohen tĂ« dhĂ«nat pĂ«r lĂ«vizjen e mausit, dhe (çka Ă«shtĂ« mĂ« e rĂ«ndĂ«sishme) ndĂ«rveprimi pĂ«rmes protokollit Spice lejon redirektimin e pajisjeve USB nĂ« makinĂ«n virtuale pa ndĂ«rprerje, sikur kjo pajisje tĂ« jetĂ« lidhur me VetĂ« Vm. E provuar pĂ«r memoria flash, skanerĂ«, webcam.
Vnet0, virbr0 dhe kartat e rrjetit virtual të Vm formojnë një rrjet virtual makinash.
Si FUNKSIONON KJO
Nga ana e Client Station
Stacioni i klientit ngarkohet në modin grafik nga një imazh live të modifikuar të Fedora 28, merr adresën IP përmes DHCP nga hapësira adresore e rrjetit 169.254.24.0/24. Gjatë ngarkimit krijohen rregulla skajsh të çarjes, duke lejuar lidhjet me portet "signal" dhe "spice" të serverit. Pas përfundimit të ngarkimit, stacioni pret autorizimin e përdoruesit "Client". Pas autorizimit të përdoruesit nis menaxheri i desktopit "openbox" dhe ekzekutohet skripti i autoshkarkimit autostart në emër të përdoruesit të autorizuar. Ndër të tjera, skripti i autoshkarkimit nis skripti remote.sh.
$HOME/.config/openbox/scripts/remote.sh
#!/bin/sh
server_ip=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "server_ip"
|/usr/bin/cut -d "=" -f2)
vdi_signal_port=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "vdi_signal_port"
|/usr/bin/cut -d "=" -f2)
vdi_spice_port=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "vdi_spice_port"
|/usr/bin/cut -d "=" -f2)
animation_folder=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "animation_folder"
|/usr/bin/cut -d "=" -f2)
process=/usr/bin/remote-viewer
while true
do
if [ -z `/usr/bin/pidof feh` ]
then
/usr/bin/echo $animation_folder
/usr/bin/feh -N -x -D1 $animation_folder &
else
/usr/bin/echo
fi
/usr/bin/nc -i 1 $server_ip $vdi_signal_port |while read line
do
if /usr/bin/echo "$line" |/usr/bin/grep "RULE ADDED, CONNECT NOW!"
then
/usr/bin/killall feh
pid_process=$($process "spice://$server_ip:$vdi_spice_port"
"--spice-disable-audio" "--spice-disable-effects=animation"
"--spice-preferred-compression=auto-glz" "-k"
"--kiosk-quit=on-disconnect" | /bin/echo $!)
/usr/bin/wait $pid_process
/usr/bin/killall -u $USER
exit
else
/usr/bin/echo $line >> /var/log/remote.log
fi
done
done
/etc/client.conf
server_ip=169.254.24.1
vdi_signal_port=5905
vdi_spice_port=5906
animation_folder=/usr/share/backgrounds/animation
background_folder=/usr/share/backgrounds2/fedora-workstation
Përshkrimi i variablave të skedarit client.conf
server_ip â adresa e KVM_Server
vdi_signal_port â porta e KVM_Server ku gjendet "xinetd"
vdi_spice_port â porta rrjetore e KVM_Server, nga e cila do tĂ« bĂ«het redirektimi i kĂ«rkesĂ«s pĂ«r lidhje nga klienti remote-viewer nĂ« portin spice tĂ« VM tĂ« dedikuar (detaje mĂ« poshtĂ«)
animation_folder â dosja nga e cila merren imazhet pĂ«r demonstruar bullshit animation
background_folder â dosja nga e cila shkarkohen imazhet pĂ«r tĂ« demonstruar prezantimet nĂ« modalitetin e pritjes. MĂ« shumĂ« rreth animacionit nĂ« seksionin e ardhshĂ«m tĂ« artikullit.
Skripta remote.sh merr konfigurimet nga skedari i konfigurimit /etc/client.conf dhe përdor nc për të lidhur në portin «vdi_signal_port» të serverit KVM, duke marrë një rrjedhë të dhënash nga serveri, mes të cilave pret rreshtin «RULE ADDED, CONNECT NOW». Pasi të marrë rreshtin e kërkuar, procesi remote-viewer aktivizohet në modalitetin kioske, duke lidhur në portin «vdi_spice_port» të serverit. Ekzekutimi i skriptës pezullohet deri në përfundimin e ekzekutimit të remote-viewer-it.
Remote-viewer, duke u lidhur në portin «vdi_spice_port», përmes ridirektimit në anën e serverit, arrin në portin «spice_console» të ndërfaqes lo0, pra në konsolën e makinës virtuale dhe ndodh, konkretisht, puna e përdoruesit. Gjatë procesit të pritjes së lidhjes, përdoruesi i demonstrohet një animacion i pavlerë, në formën e një slajd-shou nga skedarët jpeg; rruga në dosjen me imazhe përcaktohet nga vlera e variablës animation_folder në skedarin e konfigurimit.
Kur humbet lidhja me portin «spice_console» të makinës virtuale, i cili sinjalizon për fikjen/ridëshimin e makinës virtuale (dmth, përfundimin real të sesionit të përdoruesit), përfundojnë të gjithë proceset që janë nisur në emër të përdoruesit të autorizuar, çka rezulton në riçeljen e lightdm dhe rikthimin në ekranin e autentifikimit.
Nga ana e Serverit KVM
Në portin «signal» të kartës rrjet ën p5s0, xinetd pret lidhjen. Pas lidhjes në portin «signal», xinetd nis skriptin vm_manager.sh pa i kaluar asnjë parametër hyrës dhe drejton rezultatin e ekzekutimit të skriptit në seancën nc të Client Station.
/etc/xinetd.d/test-server
shërbimi vdi_signal
{
port = 5905
socket_type = stream
protocol = tcp
wait = no
user = root
server = /home/admin/scripts_vdi_new/vm_manager.sh
}
/home/admin/scripts_vdi_new/vm_manager.sh
#!/usr/bin/sh
#<SET LOCAL VARIABLES FOR SCRIPT>#
SRV_SCRIPTS_DIR=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_scripts_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR"
export SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR
SRV_POOL_SIZE=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_pool_size" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_POOL_SIZE=$SRV_POOL_SIZE"
export "SRV_POOL_SIZE=$SRV_POOL_SIZE"
SRV_START_PORT_POOL=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_start_port_pool" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo SRV_START_PORT_POOL=$SRV_START_PORT_POOL
export SRV_START_PORT_POOL=$SRV_START_PORT_POOL
SRV_TMP_DIR=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_tmp_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_TMP_DIR=$SRV_TMP_DIR"
export SRV_TMP_DIR=$SRV_TMP_DIR
date=$(/usr/bin/date)
#</SET LOCAL VARIABLES FOR SCRIPT>#
/usr/bin/echo "# $date START EXECUTE VM_MANAGER.SH #"
make_connect_to_vm() {
#<READING CLEAR.LIST AND CHECK PORT FOR NETWORK STATE>#
/usr/bin/echo "READING CLEAN.LIST AND CHECK PORT STATE"
#<CHECK FOR NO ONE PORT IN CLEAR.LIST>#
if [ -z `/usr/bin/cat $SRV_TMP_DIR/clear.list` ]
then
/usr/bin/echo "NO AVALIBLE PORTS IN CLEAN.LIST FOUND"
/usr/bin/echo "Will try to make housekeeper, and create new vm"
make_housekeeper
else
#<MINIMUN ONE PORT IN CLEAR.LIST FOUND>#
/usr/bin/cat $SRV_TMP_DIR/clear.list |while read line
do
clear_vm_port=$(($line))
/bin/echo "FOUND PORT $clear_vm_port IN CLEAN.LIST. TRY NETSTAT"
"CHECK FOR PORT=$clear_vm_port"
#<NETSTAT LISTEN CHECK FOR PORT FROM CLEAN.LIST>#
if /usr/bin/netstat -lnt |/usr/bin/grep ":$clear_vm_port" > /dev/null
then
/bin/echo "$clear_vm_port IS LISTEN"
#<PORT IS LISTEN. CHECK FOR IS CONNECTED NOW>#
if /usr/bin/netstat -nt |/usr/bin/grep ":$clear_vm_port"
|/usr/bin/grep "ESTABLISHED" > /dev/null
then
#<PORT LISTEN AND ALREADY CONNECTED! MOVE PORT FROM CLEAR.LIST
# TO WASTE.LIST>#
/bin/echo "$clear_vm_port IS ALREADY CONNECTED, MOVE PORT TO WASTE.LIST"
/usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
/usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/waste.list
else
#<PORT LISTEN AND NO ONE CONNECT NOW. MOVE PORT FROM CLEAR.LIST TO
# CONN_WAIT.LIST AND CREATE IPTABLES RULES>##
/usr/bin/echo "OK, $clear_vm_port IS NOT ALREADY CONNECTED"
/usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
/usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/conn_wait.list
$SRV_SCRIPTS_DIR/vm_connect.sh $clear_vm_port
#<TRY TO CLEAN VM IN WASTE.LIST AND CREATE NEW WM>#
/bin/echo "TRY TO CLEAN VM IN WASTE.LIST AND CREATE NEW VM"
make_housekeeper
/usr/bin/echo "# $date STOP EXECUTE VM_MANAGER.SH#"
exit
fi
else
#<PORT IS NOT A LISTEN. MOVE PORT FROM CLEAR.LIST TO WASTE.LIST>#
/bin/echo " "$clear_vm_port" is NOT LISTEN. REMOVE PORT FROM CLEAR.LIST"
/usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
/usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/waste.list
make_housekeeper
fi
done
fi
}
make_housekeeper() {
/usr/bin/echo "=Execute housekeeper="
/usr/bin/cat $SRV_TMP_DIR/waste.list |while read line
do
/usr/bin/echo "$line"
if /usr/bin/netstat -lnt |/usr/bin/grep ":$line" > /dev/null
then
/bin/echo "port_alive, vm is running"
if /usr/bin/netstat -nt |/usr/bin/grep ":$line"
|/usr/bin/grep "ESTABLISHED" > /dev/null
then
/bin/echo "port_in_use can't delete vm!!!"
else
/bin/echo "port_not in use. Deleting vm"
/usr/bin/sed -i "/$line/d" $SRV_TMP_DIR/waste.list
/usr/bin/echo $line >> $SRV_TMP_DIR/recycle.list
$SRV_SCRIPTS_DIR/vm_delete.sh $line
fi
else
/usr/bin/echo "posible vm is already off. Deleting vm"
/usr/bin/echo "MOVE VM IN OFF STATE $line FROM WASTE.LIST TO"
"RECYCLE.LIST AND DELETE VM"
/usr/bin/sed -i "/$line/d" $SRV_TMP_DIR/waste.list
/usr/bin/echo $line >> $SRV_TMP_DIR/recycle.list
$SRV_SCRIPTS_DIR/vm_delete.sh "$line"
fi
done
create_clear_vm
}
create_clear_vm() {
/usr/bin/echo "=Create new VM="
while [ $SRV_POOL_SIZE -gt 0 ]
do
new_vm_port=$(($SRV_START_PORT_POOL+$SRV_POOL_SIZE))
/usr/bin/echo "new_vm_port=$new_vm_port"
if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/clear.list > /dev/null
then
/usr/bin/echo "$new_vm_port port is already defined in clear.list"
else
if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/waste.list > /dev/null
then
/usr/bin/echo "$new_vm_port port is already defined in waste.list"
else
if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/recycle.list > /dev/null
then
/usr/bin/echo "$new_vm_port PORT IS ALREADY DEFINED IN RECYCLE LIST"
else
if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/conn_wait.list > /dev/null
then
/usr/bin/echo "$new_vm_port PORT IS ALREADY DEFINED IN CONN_WAIT LIST"
else
/usr/bin/echo "PORT IN NOT DEFINED IN NO ONE LIST WILL CREATE"
"VM ON PORT $new_vm_port"
/usr/bin/echo $new_vm_port >> $SRV_TMP_DIR/recycle.list
$SRV_SCRIPTS_DIR/vm_create.sh $new_vm_port
fi
fi
fi
fi
SRV_POOL_SIZE=$(($SRV_POOL_SIZE-1))
done
/usr/bin/echo "# $date STOP EXECUTE VM_MANAGER.SH #"
}
make_connect_to_vm |/usr/bin/tee -a /var/log/vm_manager.log
/etc/vm_manager.confsrv_scripts_dir=/home/admin/scripts_vdi_new
srv_pool_size=4
srv_start_port_pool=5920
srv_tmp_dir=/tmp/vm_state
base_host=win10_2
input_iface=enp5s0
vdi_spice_port=5906
count_conn_tryes=10
Përshkrimi i variablave të skedarit të konfigurimit vm_manager.conf
srv_scripts_dir â folderi ku ndodhen skriptet vm_manager.sh, vm_connect.sh, vm_delete.sh, vm_create.sh, vm_clear.sh
srv_pool_size â madhĂ«sia e pool-it tĂ« VM
srv_start_port_pool â porta fillestare, pas sĂ« cilĂ«s do tĂ« fillojĂ« vendosja e portave tĂ« spice konsolave tĂ« makinave virtuale
srv_tmp_dir â folderi pĂ«r vendosjen e skedarĂ«ve temporarĂ«
base_host â Vm bazĂ« (imazhi i artĂ«) nga i cili do tĂ« krijohen klonĂ«t e Vm nĂ« grupin e pĂ«rbĂ«rĂ«
input_iface â ndĂ«rfaqja rrjeti e serverit qĂ« shikon kah Stacionet e KlientĂ«ve
vdi_spice_port â porta rrjeti e serverit nga e cila do tĂ« ndodhi ridirektimi i kĂ«rkesĂ«s pĂ«r lidhje nga klienti remote-viewer nĂ« portin spice tĂ« Vm tĂ« dedikuar
count_conn_tryes â timeri i pritjes, pas pĂ«rfundimit tĂ« tĂ« cilit konsiderohet se lidhja me Vm nuk ndodhi (detajet e funksionimit shihni vm_connect.sh)
Skripti vm_manager.sh lexon konfigurimin nga skedari vm_manager.conf, vlerëson gjendjen e makinave virtuale në grup në disa parametra, konkretisht: sa VM janë të implementuara, a ka VM të lira të pastra. Për këtë, ai lexon skedarin clear.list, i cili përmban numrat e porteve "spice_console" të makinave virtuale "të sapokrijuara" (shih më poshtë ciklin e krijimit të VM), dhe kontrollon nëse ekziston një lidhje e vendosur me to. Kur zbulohet një port me një lidhje të vendosur në rrjet, (çka nuk duhej të ndodhte) shfaqet një paralajmërim dhe porti transferohet në waste.list. Kur zbulohet porta e parë nga skedari clear.list me të cilën aktualisht nuk ka lidhje, vm_manager.sh thërret skriptin vm_connect.sh dhe i kalon si parametër numrin e këtij porti.
/home/admin/scripts_vdi_new/vm_connect.sh
#!/bin/sh
date=$(/usr/bin/date)
/usr/bin/echo "#" "$date" "START EXECUTE VM_CONNECT.SH#"
#<SET LOCAL VARIABLES FOR SCRIPT>#
free_port="$1"
input_iface=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep "input_iface"
|/usr/bin/cut -d "=" -f2)
/usr/bin/echo "input_iface=$input_iface"
vdi_spice_port=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "vdi_spice_port" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "vdi_spice_port=$vdi_spice_port"
count_conn_tryes=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "count_conn_tryes" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "count_conn_tryes=$count_conn_tryes"
#</SET LOCAL VARIABLES FOR SCRIPT>#
#<CREATE IPTABLES RULES AND SEND SIGNAL TO CONNECT>#
/usr/bin/echo "create rule for port" $free_port
/usr/sbin/iptables -I INPUT -i $input_iface -p tcp -m tcp --dport
$free_port -j ACCEPT
/usr/sbin/iptables -I OUTPUT -o $input_iface -p tcp -m tcp --sport
$free_port -j ACCEPT
/usr/sbin/iptables -t nat -I PREROUTING -p tcp -i $input_iface --dport
$vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
/usr/bin/echo "RULE ADDED, CONNECT NOW!"
#</CREATE IPTABLES RULES AND SEND SIGNAL TO CONNECT>#
#<WAIT CONNECT ESTABLISHED AND ACTIVATE CONNECT TIMER>#
while [ $count_conn_tryes -gt 0 ]
do
if /usr/bin/netstat -nt |/usr/bin/grep ":$free_port"
|/usr/bin/grep "ESTABLISHED" > /dev/null
then
/bin/echo "$free_port NOW in use!!!"
/usr/bin/sleep 1s
/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i $input_iface --dport
$vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
/usr/sbin/iptables -D INPUT -i $input_iface -p tcp -m tcp --dport
$free_port -j ACCEPT
/usr/sbin/iptables -D OUTPUT -o $input_iface -p tcp -m tcp --sport
$free_port -j ACCEPT
/usr/bin/sed -i "/$free_port/d" $SRV_TMP_DIR/conn_wait.list
/usr/bin/echo $free_port >> $SRV_TMP_DIR/waste.list
return
else
/usr/bin/echo "$free_port NOT IN USE"
/usr/bin/echo "RULE ADDED, CONNECT NOW!"
/usr/bin/sleep 1s
fi
count_conn_tryes=$((count_conn_tryes-1))
done
#</WAIT CONNECT ESTABLISED AND ACTIVATE CONNECT TIMER>#
#<IF COUNT HAS EXPIRED. REMOVE IPTABLES RULE AND REVERT
# VM TO CLEAR.LIST>#
/usr/bin/echo "REVERT IPTABLES RULE AND REVERT VM TO CLEAN
LIST $free_port"
/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i $input_iface --dport
$vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
/usr/sbin/iptables -D INPUT -i $input_iface -p tcp -m tcp --dport $free_port
-j ACCEPT
/usr/sbin/iptables -D OUTPUT -o $input_iface -p tcp -m tcp --sport
$free_port -j ACCEPT
/usr/bin/sed -i "/$free_port/d" $SRV_TMP_DIR/conn_wait.list
/usr/bin/echo $free_port >> $SRV_TMP_DIR/clear.list
#</COUNT HAS EXPIRED. REMOVE IPTABLES RULE AND REVERT VM
#TO CLEAR.LIST>#
/usr/bin/echo "#" "$date" "END EXECUTE VM_CONNECT.SH#"
# Attention! Must Be! sysctl net.ipv4.conf.all.route_localnet=1
Skripta vm_connect.sh vendos rregulla tĂ« firewall-it qĂ« krijojnĂ« njĂ« ridrejtim tĂ« portit «vdi_spice_port» tĂ« serverit nĂ« ndĂ«rfaqen enp5s0 nĂ« portin «spice console» tĂ« VM-sĂ«, e cila ndodhet nĂ« ndĂ«rfaqen lo0 tĂ« serverit, e kaluar si parametr i lançimit. Porti transferohet nĂ« conn_wait.list, VM konsiderohet e pritur pĂ«r lidhje. NĂ« sesionin Client Station nĂ« portin «signal» tĂ« serverit dĂ«rgohet vargu «RULE ADDED, CONNECT NOW», qĂ« pritet nga skripti remote.sh i ekzekutuar atje. Fillon njĂ« cikĂ«l pritjeje pĂ«r lidhje me numrin e pĂ«rpjekjeve tĂ« pĂ«rcaktuar nga vlera e variablit «count_conn_tryes» nga skedari i konfigurimit. Ădo sekondĂ« nĂ« seancĂ«n nc do t'i jepet vargu «RULE ADDED, CONNECT NOW» dhe do tĂ« kontrollohet nĂ«se ka njĂ« lidhje tĂ« vendosur me portin «spice_console».
Nëse pas numrit të caktuar të përpjekjeve, nuk ka ndodhur lidhja, porti «spice_console» transferohet përsëri në clear.list. Ekzekutimi i vm_connect.sh përfundon dhe vazhdohet ekzekutimi i vm_manager.sh, i cili nismon ciklin e pastrimit.
Nëse regjistrohet një lidhje e Stacionit të Klientit me portin «spice_console» në ndërfaqen lo0, rregullat e firewall-it që krijojnë një ridrejtim midis portit «spice» të serverit dhe portit «spice_console» hiqen, dhe mbajtja e mëtejshme e lidhjes ndodh përmes mekanizmit të përcaktimit të gjendjes së firewall-it. Në rast të një ndërprerjeje të lidhjes, nuk do të jetë e mundur të rivendoset lidhja me portin «spice_console». Porta «spice_console» transferohet në waste.list, VM konsiderohet «e papastër» dhe nuk mund të kthehet në grupin e «virtualeve të pastra» pa kaluar procesin e pastrimit. Ekzekutimi i vm_connect.sh përfundon, dhe vazhdon ekzekutimi i vm_manager.sh, i cili niset në ciklin e pastrimit.
Cikli i pastrimit fillon me shqyrtimin e skedarit waste.list, i cili përmban numrat e porteve «spice_console» të makinave virtuale me të cilat është vendosur lidhja. Këtu identifikohet prania e një lidhjeje aktive në çdo port «spice_console» nga lista. Nëse lidhja është e munguar, konsiderohet se makina virtuale nuk përdoret më dhe porta transferohet në recycle.list, duke aktivizuar procesin e fshirjes së makinës virtuale (shih më poshtë), të cilës i përkiste ky port. Nëse një lidhje rrjetore aktive zbulohet në port, atëherë konsiderohet se makina virtuale është në përdorim dhe nuk ndërmerren veprime për të. Nëse porta nuk është në dëgjim, konsiderohet se VM është e fikur dhe më nuk është e nevojshme. Porta transferohet në recycle.list dhe aktivizohet procesi i fshirjes së makinës virtuale. Për këtë, thirret skripti vm_delete.sh, i cili merr si parametrin numrin e portit «spice_console» të VM-së që duhet të fshihet.
/home/admin/scripts_vdi_new/vm_delete.sh
#!/bin/sh
#<Set local VARIABLES>#
port_to_delete="$1"
date=$(/usr/bin/date)
#</Set local VARIABLES>#
/usr/bin/echo "# $date START EXECUTE VM_DELETE.SH#"
/usr/bin/echo "TRY DELETE VM ON PORT: $vm_port"
#<VM NAME SETUP>#
vm_name_part1=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep 'base_host'
|/usr/bin/cut -d'=' -f2)
vm_name=$(/usr/bin/echo "$vm_name_part1""-""$port_to_delete")
#</VM NAME SETUP>#
#<SHUTDOWN AND DELETE VM>#
/usr/bin/virsh destroy $vm_name
/usr/bin/virsh undefine $vm_name
/usr/bin/rm -f /var/lib/libvirt/images_write/$vm_name.qcow2
/usr/bin/sed -i "/$port_to_delete/d" $SRV_TMP_DIR/recycle.list
#</SHUTDOWN AND DELETE VM>#
/usr/bin/echo "VM ON PORT $vm_port HAS BEEN DELETE AND REMOVE"
"FROM RECYCLE.LIST. EXIT FROM VM_DELETE.SH"
/usr/bin/echo "# $date STOP EXECUTE VM_DELETE.SH#"
exit
Fshirja e një maƥinerie virtuale është një operacion mjaft trivial; skripti vm_delete.sh identifikon emrin e maƥinerisë virtuale, e cila i përket portit të dhënë si parametër fillimi. Kryhet ndalimi i detyruar i VM, fshirja e VM nga hipervizori, dhe disks virtualë të kësaj VM fshihen. Porta "spice_console" fshihet nga recycle.list. Ekzekutimi i vm_delete.sh përfundon dhe ekzekutimi i vm_manager.sh rinis.
Skripti vm_manager.sh, pas përfundimit të operacioneve të pastrimit të maƥinave virtuale të panevojshme nga lista waste.list, fillon ciklin e krijimit të maƥinave virtuale në pool.
Procesi fillon me përcaktimin e porteve "spice_console" të disponueshme për vendosje. Për këtë qëllim, në bazë të parametrave të skedarit të konfigurimit "srv_start_port_pool", i cili caktton portin fillestar për grupin "spice_console" të makinave virtuale, dhe parametrin "srv_pool_size", i cili përcakton numrin maksimal të makinave virtuale, bëhet një përshkrim i radhës të të gjitha mundësive për porte. Për secilin port të caktuar, bëhet një kërkim në clear.list, waste.list, conn_wait.list, dhe recycle.list. Nëse porti zbulon në ndonjë nga këto skedarë, atëherë ai konsiderohet i zënë dhe lihet jashtë. Nëse porti nuk gjendet në skedarët e specifikuar, ai merret në skedarin recycle.list dhe fillon procesi i krijimit të një makine virtuale të re. Për këtë, thirret skenari vm_create.sh, të cilit i kalon si parameter numrin e portit "spice_console" për të cilin duhet të krijohet VM.
/home/admin/scripts_vdi_new/vm_create.sh
#!/bin/sh
/usr/bin/echo "#" "$date" "START RUNNING VM_CREATE.SH#"
new_vm_port=$1
date=$(/usr/bin/date)
a=0
/usr/bin/echo SRV_TMP_DIR=$SRV_TMP_DIR
#<SET LOCAL VARIABLES FOR SCRIPT>#
base_host=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep "base_host"
|/usr/bin/cut -d "=" -f2)
/usr/bin/echo "base_host=$base_host"
#</SET LOCAL VARIABLES FOR SCRIPT>#
hdd_image_locate() {
/bin/echo "Run STEP 1 - hdd_image_locate"
hdd_base_image=$(/usr/bin/virsh dumpxml $base_host
|/usr/bin/grep "source file" |/usr/bin/grep "qcow2" |/usr/bin/head -n 1
|/usr/bin/cut -d "'" -f2)
if [ -z "$hdd_base_image" ]
then
/bin/echo "base hdd image not found!"
else
/usr/bin/echo "hdd_base_image found is a $hdd_base_image. Run next step 2"
#< CHECK FOR SNAPSHOT ON BASE HDD >#
if [ 0 -eq `/usr/bin/qemu-img info "$hdd_base_image" | /usr/bin/grep -c "Snapshot"` ]
then
/usr/bin/echo "base image haven't snapshot, run NEXT STEP 3"
else
/usr/bin/echo "base hdd image have a snapshot, can't use this image"
exit
fi
#</ CHECK FOR SNAPSHOT ON BASE HDD >#
#< CHECK FOR HDD IMAGE IS LINK CLONE >#
if [ 0 -eq `/usr/bin/qemu-img info "$hdd_base_image" |/usr/bin/grep -c "backing file"
then
/usr/bin/echo "base image is not a linked clone, NEXT STEP 4"
/usr/bin/echo "Base image check complete!"
else
/usr/bin/echo "base hdd image is a linked clone, can't use this image"
exit
fi
fi
#</ CHECK FOR HDD IMAGE IS LINK CLONE >#
cloning
}
cloning() {
# <Step_1 turn the base VM off >#
/usr/bin/virsh shutdown $base_host > /dev/null 2>&1
# </Step_1 turn the base VM off >#
#<Create_vm_config>#
/usr/bin/echo "Free port for Spice VM is $new_vm_port"
#<Setup_name_for_new_VM>#
new_vm_name=$(/bin/echo $base_host"-"$new_vm_port)
#</Setup_name_for_new_VM>#
#<Make_base_config_as_clone_base_VM>#
/usr/bin/virsh dumpxml $base_host > $SRV_TMP_DIR/$new_vm_name.xml
#<Make_base_config_as_clone_base_VM>#
##<Setup_New_VM_Name_in_config>##
/usr/bin/sed -i "s%<name>$base_host</name>%<name>$new_vm_name</name>%g" $SRV_TMP_DIR/$new_vm_name.xml
#</Setup_New_VM_Name_in_config>#
#<UUID Changing>#
old_uuid=$(/usr/bin/cat $SRV_TMP_DIR/$new_vm_name.xml |/usr/bin/grep "<uuid>")
/usr/bin/echo old UUID $old_uuid
new_uuid_part1=$(/usr/bin/echo "$old_uuid" |/usr/bin/cut -d "-" -f 1,2)
new_uuid_part2=$(/usr/bin/echo "$old_uuid" |/usr/bin/cut -d "-" -f 4,5)
new_uuid=$(/bin/echo $new_uuid_part1"-"$new_vm_port"-"$new_uuid_part2)
/usr/bin/echo $new_uuid
/usr/bin/sed -i "s%$old_uuid%$new_uuid%g" $SRV_TMP_DIR/$new_vm_name.xml
#</UUID Changing>#
#<Spice port replace>#
old_spice_port=$(/usr/bin/cat $SRV_TMP_DIR/$new_vm_name.xml
|/usr/bin/grep "graphics type='spice' port=")
/bin/echo old spice port $old_spice_port
new_spice_port=$(/usr/bin/echo "<graphics type='spice' port='$new_vm_port' autoport='no' listen='127.0.0.1'>")
/bin/echo $new_spice_port
/usr/bin/sed -i "s%$old_spice_port%$new_spice_port%g" $SRV_TMP_DIR/$new_vm_name.xml
#</Spice port replace>#
#<MAC_ADDR_GENERATE>#
mac_new=$(/usr/bin/hexdump -n6 -e '/1 ":%02X"' /dev/random|/usr/bin/sed s/^://g)
/usr/bin/echo New Mac is $mac_new
#</MAC_ADDR_GENERATE>#
#<GET OLD MAC AND REPLACE>#
mac_old=$(/usr/bin/cat $SRV_TMP_DIR/$new_vm_name.xml |/usr/bin/grep "mac address=")
/usr/bin/echo old mac is $mac_old
/usr/bin/sed -i "s%$mac_old%$mac_new%g" $SRV_TMP_DIR/$new_vm_name.xml
#<GET OLD MAC AND REPLACE>#
#<new_disk_create>#
/usr/bin/qemu-img create -f qcow2 -b $hdd_base_image /var/lib/libvirt/images_write/$new_vm_name.qcow2
#</new_disk_create>#
#<attach_new_disk_in_confiig>#
/usr/bin/echo hdd base image is $hdd_base_image
/usr/bin/sed -i "s%<source file='$hdd_base_image'/>%<source file='/var/lib/libvirt/images_write/$new_vm_name.qcow2'/>%g" $SRV_TMP_DIR/$new_vm_name.xml
#</attach_new_disk_in_confiig>#
starting_vm
#</Create_vm config>#
}
starting_vm() {
/usr/bin/virsh define $SRV_TMP_DIR/$new_vm_name.xml
/usr/bin/virsh start $new_vm_name
while [ $a -ne 1 ]
do
if /usr/bin/virsh list --all |/usr/bin/grep "$new_vm_name" |/usr/bin/grep "running" > /dev/null 2>&1
then
a=1
/usr/bin/sed -i "/$new_vm_port/d" $SRV_TMP_DIR/recycle.list
/usr/bin/echo $new_vm_port >> $SRV_TMP_DIR/clear.list
/usr/bin/echo "#" "$date" "VM $new_vm_name IS STARTED #"
else
/usr/bin/echo "#VM $new_vm_name is not ready#"
a=0
/usr/bin/sleep 2s
fi
done
/usr/bin/echo "#$date EXIT FROM VM_CREATE.SH#"
exit
}
hdd_image_locate
Procesi i krijimit të një makine virtuale të re
Skripti vm_create.sh lexhon nga skedari i konfigurimit vlerën e variablës "base_host", e cila përcakton modelin e makinerisë virtuale mbi të cilin do të bëhet një klon. Ai eksporton konfigurimin XML të VM nga baza e hipervizorit, kryen një sërë kontrollesh të imazhit qcow të disku të VM dhe, në përfundim të suksesshëm të tyre, krijon një skedar konfiguruese XML për VM-në e re dhe një imazh disku "linked clone" të VM-së së re. Më pas, konfigurimi XML i VM-së së re ngarkohet në bazën e hipervizorit dhe VM aktivizohet. Porta "spice_console" transferohet nga recycle.list në clear.list. Ekzekutimi i vm_create.sh përfundon dhe ekzekutimi i vm_manager.sh mbyllet.
Me lidhjen e ardhshme, gjithçka fillon nga e para.
Për rastet emergjente në paketë ka skriptin vm_clear.sh, i cili detyron për të kaluar të gjitha VM nga puli dhe i eliminon ato duke i zerozuar vlerat e listave. Thirrja e tij në fazën e ngarkimit lejon që të fillohet puna (ndoshta) VDI nga një fletë e pastër.
/home/admin/scripts_vdi_new/vm_clear.sh
#!/usr/bin/sh
#set VARIABLES#
SRV_SCRIPTS_DIR=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_scripts_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR"
export SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR
SRV_TMP_DIR=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_tmp_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_TMP_DIR=$SRV_TMP_DIR"
export SRV_TMP_DIR=$SRV_TMP_DIR
SRV_POOL_SIZE=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_pool_size" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_POOL_SIZE=$SRV_POOL_SIZE"
SRV_START_PORT_POOL=$(/usr/bin/cat /etc/vm_manager.conf
|/usr/bin/grep "srv_start_port_pool" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo SRV_START_PORT_POOL=$SRV_START_PORT_POOL
#Set VARIABLES#
/usr/bin/echo "= Cleanup ALL VM="
/usr/bin/mkdir $SRV_TMP_DIR
/usr/sbin/service iptables restart
/usr/bin/cat /dev/null > $SRV_TMP_DIR/clear.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/waste.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/recycle.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/conn_wait.list
port_to_delete=$(($SRV_START_PORT_POOL+$SRV_POOL_SIZE))
while [ "$port_to_delete" -gt "$SRV_START_PORT_POOL" ]
do
$SRV_SCRIPTS_DIR/vm_delete.sh $port_to_delete
port_to_delete=$(($port_to_delete-1))
done
/usr/bin/echo "= EXIT FROM VM_CLEAR.SH="
Me këtë do të doja të përfundoja pjesën e parë të tregimit tim. Sasia e përshkruar duhet të jetë e mjaftueshme për administratorët e sistemeve që të provojnë (ndë-VDI) në praktikë. Nëse komuniteti e gjen këtë temë interesante, në pjesën e dytë do të flas për modifikimin e livecd Fedora dhe transformimin e saj në një kiosk.
Burimi: habr.com
