Odată cu apariția primelor servicii de tip cloud, dezvoltarea software a intrat într-o etapă nouă privind gestionarea, mentenanța și utilizarea resurselor aflate la distanță. În acest context, o mare parte din serviciile IT a cunoscut schimbări majore în această perioadă. Gestionarea aplicațiilor a devenit mai ușoară datorită serviciilor oferite de către distribuitori, anumite implementări de tipul custom made au putut fi înlocuite cu aplicații propriu-zise ș.a.m.d. Totuși, aceste facilități nu vin fără responsabilități, fiecare astfel de facilitate reprezentând un cost în plus. Așadar, cum realizăm migrarea unui proiect dintr-un environment de on prem într-un environment de cloud, astfel încât să simplificăm procesul și mentenanța proiectului, dar, în același timp, să avem și un echilibru al costurilor? Răspunsul la această întrebare constă tot într-o întrebare și anume: cât de mult alegem să folosim serviciile puse la dispoziție de către un furnizor de cloud și când alegem o soluție custom made?
Migrarea unui proiect în cloud reprezintă de cele mai multe ori un proces complex cu diverse obstacole și nu de puține ori, poate, compromisuri. Avem posibilitatea de a alege între diferite strategii de migrare, în funcție de necesitatea clientului: putem să rescriem proiectul de la zero (situație mai puțin plăcută), să mutăm pe rând fiecare aplicație folosind parțial sau în totalitate serviciile oferite de un furnizor de cloud etc. În acest context, scenariul pe care vi-l propun pentru a fi dezbătut este următorul: un proiect cu mai multe aplicații de tip microserviciu (dezvoltate în Java și Spring) care urmează a fi migrat în cloud. Pe lângă microservicii, proiectul, de altfel foarte comun, folosește multe tehnologii adiționale: un messaging system (să zicem Apache Kafka), o bază de date relațională (Postgress, de ce nu?) și eventual alte tooluri adiționale de monitorizare și notificare (Prometheus, un server de email) etc. Furnizorul de cloud spre care dorim să migrăm este, după cum anticipați, unul dintre următorii: Amazon Web Services, Microsoft Azure și Google Cloud Platform. Prin urmare, cum am putea să realizăm migrarea respectivă?
În primul rând, vom începe cu migrarea microserviciilor menționate anterior. Dacă aceste aplicații nu necesită refactorizare sau eventuale modificări la nivel de cod în vederea migrării, deși acest lucru este puțin probabil, ele pot fi migrate și executate drept containere de Docker (presupunând că așa sunt deployate în momentul de față), fie pe servere (VM/-uri), fie într-un cluster de Kubernetes, sau, în ultimă instanță, folosind un serviciu de deployment specializat în acest scop. Pentru cazul de față ne vom opri la primele două soluții, deoarece cei trei mari giganți pe piață (AWS, Azure, și Goolge) oferă atât servicii de VM-uri cât și de Kubernetes sub diverse denumiri, iar soluția unor servicii specializate ar genera și mai multă dezbatere.
De ce să alegem VM-uri, de ce să alegem Kuberentes sau, mai bine spus, când alegem VM-uri și când alegem altă soluție? Primul criteriu de comparație dintre cele două variante este cel legat de costurile utilizării lor. Ambele soluții pot fi avantajoase dacă alegem ceea ce este potrivit situației noastre. Am menționat în cadrul scenariului că aplicația noastră rulează pe baza frameworkului Spring care, din punct de vedere al cerințelor hardware, va necesita un minim de 500 MB de RAM plus cel puțin un procesor (CPU core). O singură instanță, un VM cu resursele minime necesare, costă în oferta unui furnizor aproximativ 15 dolari per lună, dar trebuie să avem în vedere faptul că, în cadrul proiectului propus, există mai multe microservicii de migrat. În comparație, un CPU în Kubernetes modul standard al aceluiași distribuitor costă în jur de 6 dolari. La prima vedere acest lucru pare avantajos, însă furnizorul nu menționează în oferta respectivă prețul de mentenanță a clusterului, memoria RAM sau setupul inițial și configurările adiționale necesare pentru a simplifica munca developerului. Toate acestea le primești implicit dacă folosești versiunea mai avansată a acestui serviciu de Kubernetes care costă în jur de 42 dolari per lună. Prețurile pot suferi modificări în funcție de regiunea unde folosim aceste servicii/resurse, perioada pentru care ne angajăm să le folosim etc. La prima vedere, suntem tentați (sau cel puțin unii dintre noi) să afirmăm că opțiunea de a alege un cluster de Kubernetes în mod standard este decizia potrivită pentru scenariul nostru deoarece, dacă ar fi să ne decidem să migrăm aplicațiile pe VM-uri, ar însemna să avem mai multe instanțe de mașini care ar impune costuri mai ridicate. De asemenea, nici opțiunea de a avea un singur VM cu resurse hardware adecvate nu ar fi indicată, scenariu în care probabil din punct de vedere al costurilor ne-am apropia de cele din Kubernetes, dar vom avea alte dezavantaje. Acestea nu țin neapărat de costuri, dar vor impune o dificultate mai ridicată în a asigura mentenanța proiectului. Un altfel de exemplu este faptul că un VM nu poate fi scalat din punct de vedere hardware la infinit. De asemenea, odată ce îi atingem limita de resurse va trebui să distribuim aplicațiile pe mai multe VM-uri.
Următorul criteriu de comparație între cele două este ușurința de a realiza deploymentul și mentenanța aplicațiilor. Din acest punct de vedere, dacă am fi avut o singură aplicație care ar fi trebuit migrată într-un environment de cloud, probabil balanța ar fi mai echilibrată între cele două opțiuni. Doar că majoritatea scenariilor de migrare dinspre On Prem spre Cloud presupune mai multe aplicații/microservicii de migrat. De aceea și în acest scenariu, varianta optimă este reprezentată de Kubernetes. Într-adevăr, sunt necesare anumite cunoștințe pentru a configura un cluster de Kubernetes și pentru a seta deploymentul aplicațiilor într-un astfel de cluster, dar cea mai mare parte a furnizorilor de cloud oferă interfețe user friendly în cadrul serviciilor de Kubernetes pentru efectuarea acestor configurări. Referitor la partea de mentenanță, remarcăm că, spre deosebire, de un VM clasic unde trebuie să realizezi o conexiune de tip ,,ssh", pe mașina respectivă, pentru a vedea de exemplu starea sau logurile aplicației, clusterele de Kuberentes sunt conectate contra cost la serviciul de monitoring și logging al proiectului. De asemenea, tot în Kubernetes putem configura și autoscalarea aplicațiilor în funcție de loadul acestora. Aceste facilități pot fi implementate și în cazul unor perechi de VM-uri, însă ar trebui să analizăm dacă acest efort este rentabil. În momentul în care ai o aplicație de autoscalare gratuită sau o soluție custom, riscul ca aceasta să prezinte eventuale erori este unul ridicat. Același lucru s-ar putea afirma și despre alte sisteme adiționale și necesare unor aplicații: sisteme de monitorizare, alertare etc. Dacă există eventuale constrângeri impuse de client (un anumit buget), atunci ele rămân o soluție potrivită, însă dacă furnizorul oferă astfel de servicii la un preț decent, ar fi indicat să folosim serviciile sale din cloud. Țin să menționez că acest lucru nu se datorează comodității, respectiv dorinței de a reduce volumul de lucru doar că, pe termen lung, am putut observa o îmbunătățire a mentenanței privind starea aplicațiilor. Pentru susținerea acestui argument prezint următoarea situație: pentru notificarea echipei în cazul în care o aplicație întâmpină vreo problemă, foloseam diverse scripturi de Python care să transmită aceste notificări pe diferite canale (Teams, Mail, SMS). În această situație a fost de ajuns un simplu upgrade al versiunii de Python pentru ca aceste scripturi să nu mai funcționeze și să fie nevoie de modificări adiționale, ca să nu mai menționăm că vom avea nevoie și de un tool/software de automatizare gen Jenkins care, de asemenea, va necesita upgrade de-a lungul timpului. Aș zice că în această situație este mult mai simplu și mai practic să folosim soluții oferite deja de către furnizor în acest sens. Astfel de soluții pot veni cu opțiuni de tipul ,,auto-upgrade", situație în care furnizorul își asumă răspunderea că duce la bun sfârșit upgrade-ul unei componente. Drept concluzie pentru prima parte din acest proces de migrare, o soluție potrivită pentru migrarea aplicațiilor o reprezintă utilizarea unui cluster de Kubernetes în mod standard, pentru a reduce din costuri. Această soluție va necesita anumite cunoștințe pentru efectuarea configurărilor, dar efortul suplimentar va duce la un câștig atât din punct de vedere al mentenanței cât și din punct de vedere al costurilor pe termen lung.
Continuând cu următoarea componentă de migrat și anume partea de messaging system, pentru scenariul curent s-a menționat cum că se folosește Apache Kafka. Însă puteam avea și alte aplicații drept înlocuitor pentru Kafka, cum ar fi RabbitMQ. Aceste tipuri de software nu au în momentul de față implementări sau servicii corespondente direct în nici unul dintre cei mai populari furnizori de cloud. Aceștia au în schimb servicii care pot replica funcționalitățile lor de messaging menționate anterior și aici, fără a promova un anumit furnizor, putem aminti de Google Pub/Sub, Azure Event Hubs și Amazon Kinesis. Pe lângă aceste implementări, putem achiziționa din secțiunea de market, eventuale implementări ale unor servicii, iar printre acestea am regăsit și Apache Kafka. Însă serviciile achiziționate din market, de multe ori, prezintă constrângeri de configurări, costuri mai ridicate și, din păcate, nu se garantează un uptime la fel de ridicat ca în cazul serviciilor oferite de furnizori. Excluzând ultima opțiune, rămânem din nou cu două soluții posibile: fie configurăm un VM pe care vom instala software-ul de care avem nevoie, fie vom trece la unul dintre produsele amintite anterior. În cazul primei soluții, va fi nevoie de efort adițional după cum este de așteptat pentru setupul serverului precum și instalarea software-ului propriu-zis. Pentru o instalare mai ușoară, aș recomanda rularea Apache Kafka fie drept container de Docker, fie drept serviciu de tipul systemd. Instalarea fiind relativ ușor de efectuat, rămâne doar să configurăm setările clusterului de Kafka. Bineînțeles, va trebui să asigurăm faptul că noul cluster este o copie fidelă a celui original, că este securizat și, un alt aspect la fel de important, faptul că este accesibil prin internet pentru aplicațiile migrate la pasul anterior. De asemenea, cel mai probabil vom avea nevoie și de tooluri adiționale prin care să putem monitoriza starea software-ului, tooluri prin care să aflăm în timp real dacă apare vreo problemă. Pentru Apache Kafka există soluții precum Kafka-Manager, Kafdrop etc. În cazul unui VM, furnizorul oferă implicit doar metrici de observare a resurselor hardware, precum și accesul la logurile sistemului de operare. Pe baza acestor metrici se pot seta diverse notificări, dar ele nu acoperă cazurile în care apar erori la nivel de aplicație. Este posibil ca acestea, în cele din urmă, să genereze o creștere de resurse hardware. În momentul în care un VM ajunge la limita superioară a resurselor sale, este posibil ca utilizatorul, fie că vorbim despre o persoană sau despre o altă aplicație, să fie afectat deja.
Dacă alegem să utilizăm o tehnologie pusă la dispoziție de către furnizori, în primul rând, ar trebui să testăm și să analizăm compatibilitatea acesteia cu proiectul nostru, atât din punct de vedere al tehnicii, cât și al businessului. Cel mai simplu mod de a afla acest lucru este acela de a efectua un mic proof of concept sau un test la o scară mai mică. În caz de compatibilitate, acest lucru presupune că vom avea de efectuat modificări la nivel de cod. În funcție de importanța software-ului de mesaje în cadrul proiectului, trebuie să efectuăm modificări minime sau, după caz, majore. Dacă ne raportăm la primul caz în care avem de efectuat doar mici ajustări atunci totul este bine. Majoritatea variantelor înlocuitoare oferă soluții atât pentru partea de cod (dependințe, librării), dar și pentru partea de mentenanță (scalare, backup, vizualizarea mesajelor, monitorizare lag). Pe de altă parte, dacă la baza proiectului stă acest software de mesaje care controlează transmiterea datelor în orice micro serviciu, atunci migrarea spre o tehnologie înlocuitoare devine o provocare mai dificil de executat. Implicit crește și efortul pentru testare. Într-o astfel de situație, pentru a fi cât mai sigur de funcționalitatea proiectului, respectiv a facilităților oferite, ar fi recomandat să ne întoarcem la prima variantă. Chiar dacă efortul necesar este mai mare din punct de vedere al mentenanței, avantajele oferite sunt pe măsură, și anume: asigurarea stabilității aplicațiilor, reducerea erorilor, scăderea timpului necesar procesului de a migra și diminuarea costurilor.
Am terminat de migrat sistemul de mesaje, urmând baza de date. În cazul acestora, după cum bine știți, majoritatea furnizorilor oferă servicii care sunt corespondentele bazelor de date pe care le foloseam până acum într-un environment de On Prem : Cloud Sql (GCP), Aurora PostgreSql (AWS), Azure Cosmos DB (Microsoft Azure). Din punctul de vedere al costurilor, nu regăsim diferențe semnificative între produsele anterioare și configurarea unor VM-uri care să mențină o bază de date. Mai mult, din punctul de vedere al compatibilității, fiind aceleași tipuri de baze de date, nu există nici o problemă sau diferență în a conecta aplicațiile migrate la noile DB-uri din cloud sau la cele existente din On Prem. În opinia mea, avantajul soluțiilor oferite de către furnizori este reprezentat de multitudinea de facilități care vin cu acestea. Drept exemplu putem menționa metrici care ne oferă informații despre: numărul de conexiuni la baza de date, durata și numărul interogărilor efectuate, loguri despre acțiunile efectuate asupra unui tabel sau asupra bazei de date, interfață pentru interogarea DB-ului, operații de migrare, importul de date din diverse surse etc. Multe dintre aceste facilități sunt incluse din punctul de vedere al costurilor în prețul standard. Așadar efortul de a configura și menține anumite VM-uri doar pentru a economisi (sau nu) nu este neapărat, rentabil. O altă facilitate importantă a versiunilor de DB-uri date de furnizori este aceea de a avea posibilitatea de a face backup după date în mod automat. Toate aceste facilități sunt ușor de activat, cei mai mulți furnizori oferă interfețe user friendly. De asemenea, în cazul serviciilor de DB, avem posibilitatea de a seta un interval în care furnizorul să efectueze eventuale upgrade-uri de versiuni, fără să fie necesară intervenția noastră. Un aspect ce nu a fost discutat până acum în cadrul procesului de migrare este legat de securitatea datelor. Din acest punct de vedere nu este nici o diferență între a avea datele stocate într-o bază de date pe un VM sau o bază de date ce ține de un serviciu specializat, ambele variante putând fi ulterior criptate pe baza unei chei deținută numai de către membrii proiectului.
Pentru migrarea toolurilor adiționale necesare proiectului, mai întâi, ar trebui să trecem în revistă pe scurt ce s-a recomandat până acum. Microserviciile în Spring vor fi migrate într-un cluster de Kubernetes, iar Apache Kafka va fi instalat fie ca serviciu, fie montat cu rolul de container de Docker pe mașini virtuale. Totodată, pentru baza de date relațională vom folosi un serviciu preexistent oferit de către furnizorul de cloud. Așa cum s-a menționat anterior, anumite tooluri pot fi înlocuite cu servicii din cloud. De exemplu, pentru a centraliza și monitoriza logurile aplicațiilor, există servicii prin intermediul cărora sunt centralizate toate logurile ce țin de un proiect. Aici reamintim loguri ce țin de aplicațiile din Kubernetes, logurile sistemelor de operare ale unor VM-uri, logurile bazei de date ș.a.m.d. În mod normal, aceste servicii de tipul logs viewer pot fi configurate pentru a putea capta și informațiile unor containere de Docker, putând fi integrate astfel containerele de Apache Kafka. Avantajul acestor servicii constă în reducerea timpului necesar pentru a investiga eventuale probleme. Spre exemplu, aceste tooluri permit filtrarea unor anumite loguri în funcție de timp, apariția anumitor cuvinte cheie sau au unor erori specifice etc. Tot pe baza acestor loguri, pot fi setate notificări astfel încât, în momentul în care apare un anumit log de eroare să primim un email pentru a putea lua măsuri din timp.
De asemenea, pentru componenta hardware a proiectului, furnizorii de cloud oferă în mod standard soluții al căror cost de utilizare este gratuit. Aici reamintim metrici de măsurare a resurselor CPU, memorie RAM, trafic de rețea etc. Pentru metrici mai avansate (de exemplu, operații de I/O, observarea spațiului de stocare) vom avea nevoie de instalarea unor agenți specializați în acest sens, desigur contra cost. Tot în acest sector, putem reaminti și de posibilitatea de backup a tuturor resurselor de infrastructură, fie că vorbim de VM, Kubernetes Cluster sau DB. Prin diverse configurări putem să avem backup atât după configurările unor VM-uri sau al unui cluster de Kubernets sau chiar după datele ce sunt stocate pe aceste componente. Nu în ultimul rând, furnizorii de cloud ne oferă posibilitatea de a stoca diverse secrete necesare aplicațiilor noastre în locuri precum storage-uri, config maps, secrets etc. Așadar, observăm că eventualele software sau tooluri necesare pot fi înlocuite cu ușurință. Dacă există îngrijorări privind depășirea unui buget alocat pentru un anumit proiect, în această situație o posibilă soluție este notificarea prin alerte în momentul în care este depășită limita setată.
Nu aș dori să închei cu o concluzie concretă, deoarece această discuție sau dezbatere este subiectivă. Foarte posibil ca și pentru scenariul prezentat de mai sus să existe soluții optime atât din punct de vedere al efortului necesar, cât și al costurilor. Cert este că, înainte de a începe procesul de migrare a unui proiect înspre un environment de cloud (considerând, bineînțeles, că acest lucru este rentabil), trebuie să analizăm soluțiile puse la dispoziție de către furnizorul respectiv. În urma acestei analize, putem constata ce tehnologii putem folosi și care dintre componentele existente deja în proiect trebuie migrate așa cum sunt. Nu consider că trebuie impusă o țintă, precum obținerea unor costuri cât mai mici în detrimentul unei mentenanțe dificile pe termen lung, sau simplificarea cât mai mult a proiectului prin intermediul serviciilor oferite de către furnizor, ajungând la niște costuri care depășesc valorile din On Prem. De preferat ar fi să încercăm ca soluția aleasă să prezinte un echilibru din punctul de vedere al costurilor, efortului necesar precum și al mentenanței pe termen lung, ținând cont de dificultatea și complexitatea proiectului ce urmează a fi migrat.