
Med stigende erfaring i IT begynder man at bemærke, at systemer har deres egen karakter. De kan være lydige, tavse, flamboyante, hårde. De kan tiltrække eller frastøde. På den ene eller den anden måde må man "forhandle" med dem, navigere gennem "undervandsklipper" og opbygge kæder af deres interaktion.
Og vi fik æren af at bygge en cloud-platform, og for dette krævede det, at vi "overtalte" et par undersystemer til at arbejde med os. Heldigvis har vi "API-sprog", dygtige hænder og en masse begejstring.
I denne artikel vil der ikke være teknisk hardcore, men der vil være en beskrivelse af de problemer, vi stødte på under opbygningen af skyen. Jeg har besluttet at beskrive vores rejse som en let teknisk fantasi om, hvordan vi fandt et fælles sprog med systemerne, og hvad der kom ud af det.
Velkommen under katten.
Starten på rejsen
For nogen tid siden blev vores team givet opgaven at lancere en cloud-platform til vores kunder. Vi havde støtte fra ledelsen, ressourcer, hardware og frihed til at vælge teknologier til implementeringen af den softwaredel.
Der var også en række krav:
- tjenesten har brug for et brugervenligt kontrolpanel;
- platformen skal integreres i det eksisterende faktureringssystem;
- den program- og hardwaremæssige del: OpenStack + Tungsten Fabric (Open Contrail), som vores ingeniører har lært at "tilberede" godt.
Om hvordan holdet blev samlet, der blev udviklet et brugergrænseflade til kontrolpanelet, og der blev truffet designbeslutninger, vil jeg fortælle om en anden gang, hvis Habr-fællesskabet viser interesse.
De værktøjer, vi har besluttet at bruge:
- Python + Flask + Swagger + SQLAlchemy – et ganske standard Python-sæt;
- Vue.js til frontend;
- interaktionen mellem komponenterne og tjenesterne besluttede vi at gøre gennem Celery ovenpå AMQP.
Forudseende spørgsmål om valget af Python, vil jeg præcisere. Sproget har fundet sin niche i vores virksomhed, og omkring det er der opstået en lille, men dog kultur. Derfor blev det besluttet at begynde at bygge tjenesten netop på det. Især fordi udviklingshastighed i sådanne opgaver ofte er afgørende.
Lad os så begynde vores bekendtskab.
Tavs Bill – fakturering
Vi har kendt denne fyr i lang tid. Han har altid siddet ved siden af og talt stille for sig selv. Nogle gange videresendte han brugernes forespørgsler til os, oprettede kundeudskrifter og styrede tjenesterne. En almindelig hårdtarbejdende fyr. Men der var problemer. Han var stille, tænksom nogle gange og ofte — i sine egne tanker.

Billing er det første system, som vi forsøgte at lave en relation til. Og den første vanskelighed mødte vi, da vi skulle håndtere tjenester.
For eksempel, når man opretter eller sletter, havner opgaven i billingens interne kø. På den måde er et system til asynkron behandling af tjenester realiseret. For at behandle vores tjenestetyper blev vi nødt til at 'lægge' vores opgaver i denne kø. Og her stødte vi på problemet: mangel på dokumentation.

Ifølge beskrivelsen af API'et kunne denne opgave dog løses, men vi havde ikke tid til at beskæftige os med reverse engineering, så vi flyttede logikken ud og organiserede en opgavekø oven på RabbitMQ. Operationen over en tjeneste initieres af kunden fra kontrolpanelet, pakkes ind i en 'opgave' i Celery på backend'en og udføres af billing og OpenStack. Celery gør det relativt let at administrere opgaver, organisere gentagelser og følge status. Man kan læse mere om 'celery' for eksempel hér, .
Desuden stoppede billing ikke projektet, hvor pengene var opbrugt. Ved at kommunikere med udviklerne fandt vi ud af, at der ved beregning af statistik (og vi havde brug for at implementere netop denne logik) er en kompleks sammenhæng mellem stopreglerne. Men disse modeller passer ikke godt til vores virkelighed. Vi implementerede også dette via opgaver i Celery, hvor vi tog logikken til styring af tjenester på backend-siden.
Begge ovenstående problemer førte til, at koden blev lidt opsvulmet, og at vi i fremtiden bliver nødt til at refaktorere for at flytte logikken omkring opgaver til en separat service. Vi skal også gemme en del information om brugerne og deres tjenester i vores tabeller for at opretholde denne logik.
Endnu et problem — tavsheden.
For nogle API-forespørgsler svarer Billy stille 'Okay'. Sådan var det for eksempel, da vi kreditere de lovede betalinger i testperioden (om det senere). Forespørgslerne blev udført korrekt, og vi så ingen fejl.

Jeg måtte studere loggene, mens jeg arbejdede med systemet gennem UI. Det viste sig, at selve faktureringssystemet udfører sådanne anmodninger ved at ændre omfanget til en specifik bruger, for eksempel admin, ved at sende denne bruger i parameteren su.
Generelt gik det ret godt, på trods af problemerne i dokumentationen og mindre fejl i API'et. Loggene kan læses selv under høj belastning, hvis man forstår, hvordan de er opbygget, og hvad der skal søges efter. Database-strukturen er indviklet, men ganske logisk og endda på nogle måde attraktiv.
Så for at opsummere, de vigtigste problemer, vi stødte på i interaktionsfasen, skyldtes de specifikke implementeringer af det givne system:
- underdokumenterede “features”, der på en eller anden måde påvirkede os;
- lukkede kildekoder (faktureringssystemet er skrevet i C++), hvilket resulterer i, at vi ikke kunne løse problem 1 på nogen anden måde end gennem 'trial and error'.
Heldigvis har produktet et ret omfattende API, og vi har integreret følgende undersystemer i vores personlige panel:
- teknisk supportmodul - forespørgsler fra det personlige panel 'prokseres' i faktureringen uden at kunderne opdager det;
- finansmodul - gør det muligt at sende fakturaer til nuværende kunder, foretage debiteringer og generere betalingsdokumenter;
- tjenestestyringsmodul - for det var vi nødt til at implementere vores egen behandler. Systemets udvidelsesmulighed var en fordel for os, og vi 'trænede' Billy i en ny typetjeneste.
Det var besværligt, men på en eller anden måde tror jeg, at vi vil komme overens med Billy.
Vandreture gennem wolframfelter - Tungsten Fabric
Wolframfelter, der er fyldt med hundredvis af kabler, der transporterer tusinder af bits information. Informationen samles i 'pakker', der analyseres og danner komplekse ruter, som ved magi.

Dette er domænet for det andet system, som vi måtte integrere os med - Tungsten Fabric (TF), tidligere OpenContrail. Dets opgave er at styre netværksudstyr og give os som brugere en software-abstraktion. TF - SDN, inkorporerer kompliceret logik til arbejde med netværksudstyr. Der er en god artikel om selve teknologien, for eksempel, .
Systemet er integreret med OpenStack (som der vil blive talt om nedenfor) gennem Neutron-plugin.

Interaktionen mellem OpenStack-tjenester.
Dette system blev introduceret for os af drengene fra driftsafdelingen. Vi bruger API'et til systemet til at styre netværksstakken for vores tjenester. Det har indtil videre ikke givet os alvorlige problemer eller ubehag (jeg vil ikke tale for drengene fra driftsafdelingen), men der har dog været nogle kuriøse interaktioner.
Den første så sådan ud: kommandoer, der skulle udskrive store mængder data til konsollen ved SSH-forbindelse, satte forbindelsen i stå, mens alt fungerede korrekt via VNC.

For dem, der ikke kender problemet, ser det ret komisk ud: ls /root fungerer korrekt, mens, for eksempel, top 'fryser' helt. Heldigvis har vi allerede været ude for lignende problemer. Det blev løst ved at justere MTU på ruten fra compute-noderne til routerne. For at sige det mildt, det er ikke et problem for TF.
Det næste problem ventede om hjørnet. På et 'smukt' tidspunkt forsvandt rutingmagien, bare sådan. TF stoppede med at styre ruting på udstyret.

Vi arbejdede med OpenStack fra admin-niveau, og efter det skiftede vi til det ønskede brugerniveau. SDN ser ud til at 'fange' brugerscope, hvormed handlinger udføres. Problemet er, at denne samme admin-konto bruges til at forbinde TF og OpenStack. Ved skiftet til brugeren forsvandt 'magien'. Det blev løst ved at oprette en separat konto til arbejdet med systemet. Dette gjorde det muligt at arbejde uden at bryde integrationsfunktionen.
Siliciumlivsformer – OpenStack
Det siliciumvæsen med sin underlige form lever tæt på wolframfelterne. Det mest ligner et overdimensioneret barn, der med et enkelt sving kan kaste os til side, men der kommer ikke nogen åbenlys aggression fra det. Det er ikke skræmmende, men dets størrelse giver anledning til bekymring. Ligesom kompleksiteten af det, der foregår omkring.

OpenStack er kernen i vores platform.
OpenStack har flere undersystemer, hvoraf vi indtil videre bruger Nova, Glance og Cinder mest aktivt. Hver af dem har sit eget API. Nova står for compute-ressourcer og oprettelse af instanser, Cinder – administration af volumener og deres snapshots, Glance – billedtjeneste, der administrerer OS-skabeloner og metadata om dem.
Hver service kører i en container, og beskedbrokeren er 'den hvide kanin' – RabbitMQ.
Dette system har givet os flest uventede problemer.
Og den første udfordring dukkede hurtigt op, da vi forsøgte at tilslutte et ekstra volume til serveren. Cinder API nægtede konsekvent at udføre denne opgave. Mere præcist, hvis man skal tro OpenStack selv, så oprettes forbindelsen, men inde i den virtuelle server mangler disk-enheden.

Vi besluttede os for at "gå en omvej" og anmodede om den samme handling fra Nova API. Resultatet — enheden tilsluttes korrekt og er tilgængelig inde i serveren. Det ser ud til, at problemet opstår, når block-storage ikke svarer Cinder.
Endnu en kompleksitet ventede os, da vi arbejdede med diskene. Systemvolumen kunne ikke frakobles fra serveren.
Igen hævder OpenStack, at den har ødelagt forbindelsen, og nu kan man arbejde korrekt med volume separat. Men API'en nægtede kategorisk at udføre operationer på disken.

Her besluttede vi ikke at kæmpe for meget, men ændrede perspektivet på logikken bag tjenesten. Da der er en instans, skal der også være et systemvolume. Derfor kan brugeren ikke slette eller frakoble "disk" uden at slette "serveren".
OpenStack er et ret komplekst systemkompleks med sin egen logik for interaktion og indviklet API. Vi får hjælp fra ret detaljeret dokumentation og selvfølgelig metoden med prøver og fejl (hvordan kunne det være anderledes?).
Testkørsel
Vi udførte testkørslen i december sidste år. Hovedopgaven var at kontrollere vores projekts tekniske side i driftsmiljøet og UX-siden. Publikum blev inviteret udvalgt, og testningen var lukket. Vi gav dog også mulighed for at anmode om adgang til testningen på vores hjemmeside.
Selve testen blev naturligvis ikke uden komiske øjeblikke, da vores eventyr kun lige var begyndt.
For det første undervurderede vi interessen for projektet, og vi måtte hurtigt tilføje compute-noder midt i testen. En almindelig sag for et klynge, men der var også nuancer her. I dokumentationen for den specifikke version af TF er der angivet en bestemt version af kernen, hvorpå arbejdet med vRouter blev testet. Vi besluttede at starte noder med nyere kerner. Resultatet — TF modtog ikke ruter fra noderne. Vi måtte hastigt nedgradere kernerne.

En anden komisk situation er relateret til funktionen af knappen "ændre adgangskode" i den personlige konto.
Vi har besluttet at bruge JWT til at organisere adgangen til brugerens konto, så vi ikke skal arbejde med sessioner. Da systemerne er forskellige og bredt distribuerede, styrer vi vores egen token, hvor vi "pakket" sessionerne fra fakturering og token fra OpenStack. Ved ændring af passwordet "udløber" tokenet selvfølgelig, da brugerens data ikke længere er gyldige, og det skal genudstedes.

Vi glemte dette punkt, og vi havde simpelt hen ikke ressourcer til hurtigt at skrive denne del. Vi måtte skære funktionalitet fra lige før testlanceringen.
I øjeblikket logger vi brugeren ud, hvis passwordet er blevet ændret.
På trods af disse nuancer gik testningen godt. I løbet af et par uger havde vi omkring 300 besøgende. Vi fik mulighed for at se produktet gennem brugernes øjne, teste det i praksis og indsamle kvalitetsfeedback.
Fortsættes
For mange af os er dette det første projekt af denne størrelse. Vi har lært en række værdifulde lektioner om, hvordan man arbejder i et team, træffer arkitektoniske og designbeslutninger. Hvordan man integrerer komplekse systemer med begrænsede ressourcer og ruller dem ud i produktionen.
Selvfølgelig er der stadig meget at arbejde på både med koden og i grænsefladerne mellem systemerne. Projektet er stadig ungt, men vi er fulde af ambitioner om at gøre det til en pålidelig og brugervenlig service.
Vi har allerede formået at overbevise systemerne. Bill hjælper lydigt med opgørelser, fakturering og brugeranmodninger fra sit lille kontor. "Magien" med wolframfelter giver os stabil forbindelse. Og kun OpenStack sætter sig indimellem på tværs og råber noget som "'WSREP has not yet prepared node for application use". Men det er en helt anden historie...
Vi har for nylig lanceret tjenesten.
Du kan finde alle detaljer på vores .

CLO udviklingsteam
Nyttige links
OpenStack
Tungsten Fabric
Kilde: habr.com
