Për kë është e destinuar ky artikull
Ky artikull mund të jetë interesant për administratorët e sistemeve, të cilët përballen me detyrën për të krijuar një shërbim "vende pune të përkohshme".
Prologu
Departamenti i IT-së të një kompanie të re dinamike që po zhvillohet me shpejtësi, i është drejtuar për të organizuar "stacione vetë-shërbimi" për përdorim nga klientët e saj të jashtëm. Këto stacione parashikohej të përdoren për regjistrim në portalet e jashtme të kompanisë, ngarkimin e të dhënave nga pajisje të jashtme, punën me portalet shtetërore.
Një aspekt i rëndësishëm ishte fakti që shumica e softuerëve ishin "të orientuar" për MS Windows (p.sh., "Deklarata"); dhe megjithëse ka një lëvizje drejt formateve të hapura, MS Office mbetet standardi dominues për shkëmbimin e dokumenteve elektronike. Prandaj, ne nuk mund të heqim dorë nga MS Windows për të zgjidhur këtë problem.
Problemi kryesor ishte mundësia e akumulimit të të dhënave të ndryshme nga seancat e përdoruesve, të cilat mund të çojnë në rrjedhjen e tyre te palët e treta. . Por ndryshe nga MFC (institucioni autonom shtetëror), për organizatat jo-shtetërore, për këto gabime do të ketë dënime më të rënda. Problemi i dytë më kritik ishte kërkesa për punë me media të jashtme, të cilat, pa dyshim, do të kenë shumë malware. Probabiliteti i futjes së malware nga interneti u konsiderua si më pak i mundshëm, për shkak të kufizimit të aksesit në internet nëpërmjet një liste të bardhë adresh.
Kërkesat e sigurisë
- Pas përdorimit, të gjitha të dhënat e përdoruesve (përfshirë skedarët përkohës dhe çelësat e regjistrit) duhet të fshihen.
- Të gjitha proceset e nisura nga përdoruesi, pas përfundimit të punës, duhet të mbyllen.
- Aksesi në internet duhet të bëhet përmes një liste të bardhë adresh.
- Kufizime mbi mundësinë e nisjes së kodit të jashtëm.
- Në rast seanca është e papërdorur për më shumë se 5 minuta, seanca duhet të përfundojë automatikisht, dhe stacioni duhet të bëjë pastrimin.
Kërkesat e klientit
- Numri i stacioneve klientore nĂ« filial â maksimumi 4.
- Koha minimale e pritjes për gatishmërinë e sistemit, nga momenti "u ula në karrige" deri në fillimin e punës me softuerin e klientit.
- Mundësia e lidhjes së pajisjeve periferike (skanera, flash) direkt nga vendi i instaluar të "stacioneve të vetë-shërbimit".
- Dëshirat e klientit
- Demonstrimi i materialeve reklamues (imazhe) gjatë kohe që kompleksi është i papunë.
Mundime krijuese
Pasi u lodhëm mjaftueshëm me livecd-të e Windows-it, arritëm në një përfundim të përbashkët se zgjidhja që rezultoi nuk përmbushte të paktën 3 pika kritike. Ato ose ngarkoheshin gjatë, ose nuk ishin të vërteta live, ose personalizimi i tyre ishte i lidhur me dhimbje të mëdha. Ndoshta ne kërkuam keq, dhe mund të bëni ndonjë rekomandim për një grup mjetesh, do isha mirënjohës.
Pastaj, filluam të shikojmë në drejtimin e VDI-së, por për këtë detyrë shumica e zgjidhjeve janë ose shumë të shtrenjta, ose kërkojnë vëmendje të madhe. Do të donim një mjet të thjeshtë, me sa më pak magji, shumica e problemeve të cilit mund të zgjidheshin me një rindezje/ripërtritje shërbimi. Për fat të mirë, kishim pajisje serverike, klasën low end në filialet, që vinin nga një shërbim në daljen e përdorimit, që mund të përdornim si bazë teknologjike.
ĂfarĂ« rezultoi nĂ« fund? Nuk mund t'ju tregoj çfarĂ« rezultoi, pĂ«r shkak tĂ« NDA-sĂ«, por gjatĂ« kĂ«rkimeve zhvilluam njĂ« skemĂ« interesante qĂ« u tregua mirĂ« nĂ« provat laboratorike, megjithĂ«se nuk kaloi nĂ« prodhim masiv.
Pak disklajmerësh: autori nuk pretendon se zgjidhja e propozuar i zgjidh të gjitha detyrat e vendosura dhe e bën këtë vullnetarisht dhe me këngë. Autori është dakord paraprakisht me pohimin se Sein Englishe sprache is zehr schlecht. Duke qenë se zgjidhja nuk po zhvillohet më, nuk mund të llogaritet për rregullimin e gabimeve apo ndryshimin e funksionalitetit, gjithçka është në duart tuaja. Autori supozon se ju jeni pak a shumë të njohur me KVM dhe keni lexuar një artikull të përgjithshëm mbi protokollin Spice dhe keni punuar pak me Centos ose një tjetër shpërndarje të GNU Linux.
Në këtë artikull do doja të shqyrtoja skeletin e zgjidhjes përfundimtare, në veçanti ndërveprimin midis klientit dhe serverit dhe thelbin e proceseve në ciklin e jetës së makinave virtuale brenda kësaj zgjidhjeje. Nëse artikulli do të rezultojë interesant për publikun, do përshkruaj detajet e realizimit të imazheve live për krijimin e klientëve të hollë mbi bazën e Fedora dhe do flas për detajet e konfigurimit të makinave virtuale dhe serverët KVM për optimizimin e performancës dhe sigurisë.
Nëse marrim letërngjyrë,
Përveç bojrave, brushave dhe ngjitësit,
Dhe pak pĂ«rshtatshmĂ«riâŠ
Mund të bësh njëqind lekë!
Schema dhe përshkrimi i skenës testuese

Të gjitha pajisjet janë brenda rrjetit të filiales, jashtë del vetëm kanali i internetit. Serveri proxy historikisht ka qenë tashmë, nuk paraqet diçka të jashtëzakonshme. Por pikërisht aty, ndër të tjera, do të ndodhi filtrimi i trafikut nga makinat virtuale (shkurt Vm më poshtë në tekst). N nothing mund të vendoset ky shërbim në serverin KVM, e vetmja gjë që duhet të shikohet është si do të ndryshojë ngarkesa nga ai në sistemin disk.
Stacioni i Klientit â nĂ« vetvete, "stacionet e vetĂ«-shĂ«rbimit", "frontend" i shĂ«rbimit tonĂ«. Ato paraqesin nettopĂ« Lenovo IdeaCentre. ĂfarĂ« Ă«shtĂ« mirĂ« nĂ« kĂ«tĂ« aparat? Po pothuajse çdo gjĂ«, sidomos gĂ«zon numri i madh i porteve USB dhe lexuesi i kartelave nĂ« panelin e pĂ«rparmĂ«. NĂ« skemĂ«n tonĂ«, nĂ« lexuesin e kartelave Ă«shtĂ« vendosur njĂ« kartĂ« SD me mbrojtje harduerike nga shkruajti, mbi tĂ« cilĂ«n Ă«shtĂ« regjistruar njĂ« imazh live tĂ« modifikuar tĂ« Fedora 28. Natyrisht, nettopi Ă«shtĂ« i lidhur me njĂ« monitor, tastierĂ« dhe maus.
Switch â njĂ« switch i zakonshĂ«m harduerik tĂ« nivelit tĂ« dytĂ«, ndodhet nĂ« dhomĂ«n e serverĂ«ve dhe ndizet me dritat. Nuk Ă«shtĂ« i lidhur me asnjĂ« rrjet, pĂ«rveç rrjetit tĂ« "stacioneve tĂ« vetĂ«-shĂ«rbimit".
KVM_Server â thelb i skemĂ«s, nĂ« provat e qĂ«ndrueshmĂ«risĂ« Core 2 Quad Q9650 me 8 GB RAM me besueshmĂ«ri mbante 3 makina virtuale me Windows10. Sistemi disk - adaptec 3405 2 disqe Raid 1 + SSD. NĂ« provat pĂ«r tĂ« dalĂ« Xeon 1220 me LSI 9260 mĂ« serioz + SSD lehtĂ«sisht mbante 5-6 Vm. ServerĂ«t na janĂ« dhĂ«nĂ« nga shĂ«rbimi i pĂ«rjashtuar, shpenzimet kapitale nuk do tĂ« ishin shumĂ« tĂ« mĂ«dha. NĂ« kĂ«tĂ« server (serverĂ«) Ă«shtĂ« zhvilluar sistemi i virtualizimit KVM me njĂ« grup makinash virtuale pool_Vm.
Vm - makina virtuale, backend i shërbimit tonë. Aty ndodhi puna e përdoruesit.
Enp5s0 â njĂ« ndĂ«rfaqe rrjeti qĂ« shikon nĂ« drejtim tĂ« rrjetit tĂ« «pjesĂ«ve tĂ« vet-shĂ«rbimit», ku jetojnĂ« dhcpd, ntpd, httpd, dhe xinetd dĂ«gjon portin «signal».
Lo0 â njĂ« ndĂ«rfaqe pseudo e rrethit kthyes. Standarde.
Spice_console â NjĂ« gjĂ« shumĂ« interesante, pasi qĂ« ndryshe nga RDP klasik, kur deployohet lidhja KVM+Spice protocol, krijohet njĂ« entitet shtesĂ« â porta e konsolĂ«s sĂ« makinat virtuale. Praktikisht, duke u lidhur nĂ« kĂ«tĂ« port TCP, ne marrim konsolĂ«n e Vm, pa pasur nevojĂ« tĂ« lidhim nĂ« Vm pĂ«rmes ndĂ«rfaqes sĂ« saj rrjetore. TĂ« gjitha ndĂ«rveprimet me Vm pĂ«rmes sinjalit, serveri i merr pĂ«rsipĂ«r. Analogjia mĂ« e afĂ«rt pĂ«r funksionin â IPKVM. Pra, nĂ« kĂ«tĂ« port kalon imazhi i monitorit tĂ« VM-sĂ«, tĂ« dhĂ«nat pĂ«r lĂ«vizjet e mausit, dhe (çfarĂ« Ă«shtĂ« mĂ« e rĂ«ndĂ«sishme) ndĂ«rveprimi pĂ«rmes protokollit Spice lejon qĂ« pajisjet USB tĂ« redirektohen pa problem nĂ« makinat virtuale, sikur kjo pajisje tĂ« jetĂ« lidhur me Vm vetĂ«. E testuar pĂ«r disqe flash, skanera, kamera web.
Vnet0, virbr0 dhe kartat virtuale rrjetore të Vm formojnë një rrjet të makinave virtuale.
Si FUNKSIONON kjo
Nga ana e Client Station
Stacioni klient ngarkohet në mënyrë grafike me një imazh live të modifikuar Fedora 28, merr adresën IP përmes dhcp nga hapësira adresore e rrjetit 169.254.24.0/24. Gjatë ngarkimit krijohen rregulla të firewall-it që lejojnë lidhjet në portet «signal» dhe «spice» të serverit. Pas përfundimit të ngarkimit, stacioni pret autorizimin e përdoruesit «Client». Pas autorizimit, niset menaxheri i desktopit «openbox» dhe ekzekutohet skripti i autostart-it autostart në emër të përdoruesit që është autorizuar. Mes të tjerash, skripti i autostart-it fillon skriptin 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 në skedarin client.conf
server_ip â adresa e KVM_Server
vdi_signal_port â porta e KVM_Server ku «ndodhet» xinetd
vdi_spice_port â porta rrjetore e KVM_Server, nga e cila do tĂ« ndodhĂ« redirektimi i kĂ«rkesĂ«s pĂ«r lidhje nga klienti remote-viewer nĂ« portin spice tĂ« Vm-sĂ« tĂ« dedikuar (detajet mĂ« poshtĂ«)
animation_folder â dosja nga e cila vijnĂ« imazhet pĂ«r demonstrimin e animacionit bullshit
background_folder â dosja nga e cila vijnĂ« imazhet pĂ«r demonstrimin e prezantimeve nĂ« modalitetin e pritjes. MĂ« shumĂ« nĂ« lidhje me animacionin nĂ« pjesĂ«n tjetĂ«r tĂ« artikullit.
Skirpti remote.sh merr konfigurimet nga skedari i konfigurimit /etc/client.conf dhe realizon një lidhje përmes nc në portin «vdi_signal_port» të serverit KVM, duke marrë një rrjedhë të dhënash nga serveri, mes të cilave pret rreshta «RULE ADDED, CONNECT NOW». Pasi të marrë rreshtin e kërkuar, aktivizohet procesi remote-viewer në modin kiosku duke vendosur një lidhje në portin «vdi_spice_port» të serverit. Ekzekutimi i skenarit ndalohet deri në përfundimin e ekzekutimit të remote-viewer.
Remote-viewer, duke u lidhur në portin «vdi_spice_port», përmes ridrejtimit në anën e serverit, arrin në portin «spice_console» të ndërfaqes lo0, dmth në konsolën e makinës virtuale dhe ndodh, në mënyrë të drejtpërdrejtë, puna e përdoruesit. Në procesin e pritjes së lidhjes, përdoruesit i paraqitet një animacion i pabesueshëm, në formën e një slajd-shou nga skedarë jpeg, rruga e folderit me imazhe përcaktohet nga vlera e variablit animation_folder nga skedari i konfigurimit.
Me humbjen e lidhjes me portin «spice_console» të makinës virtuale, që sinjalizon ndërlidhjen/në rilidhje të makinës virtuale (dmth përfundimin efektiv të sesionit të përdoruesit), përfundojnë të gjitha proceset që janë nisur në emër të përdoruesit të autorizuar, duke çuar në rinisjen e lightdm dhe rikthimin në ekranin e autorizimit.
Nga ana e Serverit KVM
Në portin «signal» të kartës së rrjetit enp5s0 pret lidhjen xinetd. Pas lidhjes në portin «signal», xinetd nis skenarin vm_manager.sh pa iu dhënë asnjë parametrat hyrës dhe redirekton rezultatin e ekzekutimit të skenarit në seancën nc të Stacionit të Klientit.
/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 në skedarin e konfigurimit vm_manager.conf
srv_scripts_dir â dosja e vendndodhjes sĂ« skenarĂ«ve vm_manager.sh, vm_connect.sh, vm_delete.sh, vm_create.sh, vm_clear.sh
srv_pool_size â madhĂ«sia e pishtarit Vm
srv_start_port_pool â porti fillestar, pas tĂ« cilit do tĂ« fillojĂ« vendosja e porteve tĂ« konsolave spice tĂ« makinave virtuale
srv_tmp_dir â dosja pĂ«r vendosjen e skedarĂ«ve tĂ« pĂ«rkohshĂ«m
base_host â Vm themelore (imazhi i artĂ«) nga e cila do tĂ« bĂ«hen klonĂ« tĂ« Vm nĂ« pishtar
input_iface â ndĂ«rfaqja e rrjetit tĂ« serverit, qĂ« shikon nĂ« drejtim tĂ« Stacioneve tĂ« Klientit
vdi_spice_port â porti rrjetor i serverit, nga i cili do tĂ« ndodhĂ« ridrejtimi i kĂ«rkesĂ«s pĂ«r lidhje nga klienti remote-viewer nĂ« portin spice tĂ« Vm-ve tĂ« dedikuara
count_conn_tryes â Ă«shtĂ« koha e pritjes, pas kalimit tĂ« sĂ« cilĂ«s konsiderohet se nuk ka ndodhur lidhja me Vm (pĂ«r detajet e funksionimit shihni vm_connect.sh)
Skripti vm_manager.sh lexon skedarin e konfigurimit nga skedari vm_manager.conf, vlerëson gjendjen e makinave virtuale në pool në bazë të disa parametrave, përkatësisht: sa VM janë nisur, nëse ka VM të pastra të lira. Për këtë, ai lexon skedarin clear.list në të cilin përmbahen numrat e porteve "spice_console" të "krijuara së fundmi" (shih ciklin e krijimit të VM më poshtë) dhe kontrollon pranishmërinë e një lidhjeje me to. Kur zbulohet një port me lidhje të vendosur, (arsimët e kuptueshme që nuk duhet të ndodhin) një paralajmërim shfaqet dhe porti transferohet në waste.list. Nëse zbulon portin e parë nga skedari clear.list me të cilin në momentin aktual nuk ka lidhje, vm_manager.sh thërret skriptin vm_connect.sh dhe i përcjell 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
Skripti vm_connect.sh vendos rregullat e firewall-it qĂ« krijojnĂ« njĂ« redirect tĂ« portit "vdi_spice_port" tĂ« serverit nĂ« ndĂ«rfaqen enp5s0 nĂ« "spice console port" tĂ« VM-sĂ«, e cila ndodhet nĂ« ndĂ«rfaqen lo0 tĂ« serverit, e kaluar si parametĂ«r gjatĂ« ekzekutimit. Porti transferohet nĂ« conn_wait.list, VM konsiderohet si nĂ« pritje pĂ«r lidhje. NĂ« sesionin e Client Station, nĂ« portin "signal" tĂ« serverit dĂ«rgohet vargu "RULE ADDED, CONNECT NOW", tĂ« cilin skripti remote.sh qĂ« Ă«shtĂ« aktiv e pret. Fillon njĂ« cikĂ«l pritjeje pĂ«r lidhje me numrin e pĂ«rpjekjeve, i pĂ«rcaktuar nga vlera e variablit "count_conn_tryes" nga skedari i konfigurimit. Ădo sekondĂ« nĂ« sesionin nc do tĂ« dĂ«rgohet vargu "RULE ADDED, CONNECT NOW" dhe do tĂ« kontrollohet prania e njĂ« lidhjeje tĂ« vendosur nĂ« portin "spice_console".
Nëse gjatë numrit të votimeve të përcaktuar, lidhja nuk ndodhi, porti "spice_console" transferohet përsëri në clear.list. Ekzekutimi i vm_connect.sh përfundon, dhe vazhdon ekzekutimi i vm_manager.sh, i cili iniciaton ciklin e pastrimit.
Nëse është e regjistruar lidhja e Client Station me portin «spice_console» në ndërfaqen lo0, rregullat e firewall-it që krijojnë ridrejtimin midis portit «spice» të serverit dhe portit «spice_console» hiqen dhe mbështetja e mëtejshme e lidhjes ndodh përmes mekanizmit të përcaktimit të gjendjes së firewall-it. Në rast të ndërprerjes së lidhjes, rikthimi i lidhjes me portin «spice_console» nuk do të jetë i mundur. Porti «spice_console» transferohet në waste.list, VM konsiderohet «e pistë» dhe nuk do të mund të kthehet në grupin e makinave virtuale «të pastra» pa kaluar procesin e pastrimit. Ekzekutimi i vm_connect.sh përfundon, rikthehet ekzekutimi i vm_manager.sh, i cili fillon ciklin e pastrimit.
Cikli i pastrimit fillon me kontrollin e skedarit waste.list në të cilin transferohen numrat e portave «spice_console» të makinave virtuale me të cilat është vendosur lidhja. Përcaktohet nëse ka një lidhje aktive në secilin port «spice_console» nga lista. Nëse lidhja mungon, konsiderohet se makina virtuale më nuk përdoret dhe porta transferohet në recycle.list dhe fillon procesi i eliminimit të makinës virtuale (shih më poshtë), e cila i përkiste këtij porti. Nëse zbulohet një lidhje aktive rrjet në port, konsiderohet se makina virtuale është në përdorim, për të cilën nuk ndërmerren veprime. Nëse porta nuk është duke u dëgjuar, konsiderohet se VM është fikur dhe nuk është më e nevojshme. Porta transferohet në recycle.list dhe fillon procesi i eliminimit të makinës virtuale. Për këtë, thirret skripti vm_delete.sh, i cili merr si parametër numrin e portit «spice_console» të VM 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
Eliminimi i makinĂ«s virtuale â Ă«shtĂ« njĂ« operacion mjaft trivial, skripti vm_delete.sh pĂ«rcakton emrin e makinĂ«s virtuale, e cila i pĂ«rket portit tĂ« kaluar si parametĂ«r nisjeje. NdĂ«rpritet me forcĂ« VM, bĂ«het fshirja e VM nga hipervizori, dhe fshihet diskun virtual tĂ« kĂ«saj VM. Porta «spice_console» fshihet nga recycle.list. Ekzekutimi i vm_delete.sh pĂ«rfundon, rikthehet ekzekutimi i vm_manager.sh.
Skripti vm_manager.sh, pas përfundimit të operacioneve për pastrimin e makinave virtuale të tepërta nga lista waste.list fillon ciklin e krijimit të makinave virtuale në grup.
Procesi fillon me përcaktimin e porteve "spice_console" që janë të disponueshëm për vendosje. Për këtë, duke u bazuar në parametrin e skedarit të konfigurimit "srv_start_port_pool" që përcakton portin fillestar për grupin "spice_console" të makinave virtuale dhe parametrin "srv_pool_size" që përcakton numrin maksimal të makinave virtuale, bëhet një kontroll sistematik i të gjitha mundësive të porteve. Për çdo port të caktuar, bëhet kërkimi i tij në clear.list, waste.list, conn_wait.list, recycle.list. Nëse porta gjendet në ndonjë nga këto skedarë, ajo konsiderohet e zënë dhe shkurtohet. Nëse porta nuk gjendet në skedarët e caktuar, ajo regjistrohet në skedarin recycle.list dhe fillon procesi i krijimit të një makine virtuale të re. Për këtë, thirret skripti vm_create.sh, të cilit i jepet si parametr numri "spice_console" i portit 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 lexon nga skedari i konfigurimit vlerën e variablës "base_host" që përcakton modelin e makinës virtuale, mbi të cilin do të bëhet kloni. Ai eksporton XML konfigurimin e VM nga baza e hipervizorit, kryen një seri kontrollesh mbi imazhin diskut të VM dhe nëse ato përfundohen me sukses, krijon një skedar XML të konfigurimit për VM të re dhe një imazh diskësh "linked clone" për VM të re. Pas kësaj, konfigurimi XML i VM të re ngarkohet në bazën e hipervizorit dhe VM fillon. Porta "spice_console" transferohet nga recycle.list në clear.list. Ekzekutimi i vm_create.sh përfundon dhe përfundon gjithashtu ekzekutimi i vm_manager.sh.
Me lidhjen e ardhshme, gjithçka fillon nga fillimi.
Për rastet urgjente, ekziston skripti vm_clear.sh, i cili detyron një përshkrim të të gjitha VM nga grupi dhe i fshin ato, duke rikthyer vlerat e listave. Thirrja e tij në fazën e ngarkimit lejon të filloni punën (me)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="
Këtu do të doja të përfundoj pjesën e parë të tregimit tim. Ajo që kam prezantuar duhet të jetë e mjaftueshme për administratorët sistemikë për të provuar ndëVDI në veprim. Nëse komuniteti e sheh këtë temë interesante, në pjesën e dytë do të flas për modifikimin e livecd Fedora dhe transformimin e saj në kioska.
Burimi: habr.com
