
Naarmate je langer in de IT werkt, begin je te merken dat systemen een eigen karakter hebben. Ze kunnen meegaand, stil, onberekenbaar of streng zijn. Ze kunnen uitnodigend of afschrikwekkend zijn. Hoe dan ook, je moet 'onderhandelen' met hen, laveren tussen de 'onderwaterstenen' en hun interacties opbouwen.
Wij hebben de eer gekregen om een cloudplatform te bouwen, en daarvoor moesten we een paar subsystems 'overhalen' om met ons samen te werken. Gelukkig hebben we een 'API-taal', vaardige handen en een heleboel enthousiasme.
In dit artikel zal er geen technische hardcore zijn, maar wel een beschrijving van de problemen waarmee we zijn geconfronteerd bij het bouwen van de cloud. Ik besloot ons pad te beschrijven in de vorm van lichte technische fictie over hoe we een gemeenschappelijke taal met de systemen zochten en wat daaruit voortkwam.
Welkom onder de kat.
Het begin van de reis
Een tijdje geleden kreeg ons team de taak om een cloudplatform voor onze klanten op te zetten. We hadden de steun van het management, middelen, hardwarestack en de vrijheid om technologieën voor de softwarekant van de service te kiezen.
Er waren ook een aantal vereisten:
- de service heeft een gebruiksvriendelijk persoonlijk dashboard nodig;
- het platform moet geïntegreerd zijn in het bestaande factureringssysteem;
- de software-hardwarekant: OpenStack + Tungsten Fabric (Open Contrail), die onze ingenieurs behoorlijk goed leren 'klaarmaken'.
Over hoe het team werd samengesteld, het persoonlijk dashboard werd ontwikkeld en ontwerpbeslissingen werden genomen, zullen we een andere keer vertellen, als de Habr-gemeenschap geïnteresseerd is.
De tools die we besloten te gebruiken:
- Python + Flask + Swagger + SQLAlchemy – een vrij standaard Python-setup;
- Vue.js voor de frontend;
- de interactie tussen componenten en services besloten we te doen met behulp van Celery bovenop AMQP.
Terwijl ik de vragen over de keuze voor Python voorspel, zal ik uitleggen. De taal heeft zijn niche in ons bedrijf veroverd en er is een kleine maar hechte cultuur omheen ontstaan. Het werd daarom besloten om de service precies daarop te bouwen. Bovendien is de snelheid van ontwikkeling bij dergelijke taken vaak doorslaggevend.
Laten we dus beginnen met onze kennismaking.
Stille Bill – facturering
We have known this guy for a long time. He always sat next to us and silently calculated something. Sometimes he forwarded user requests to us, issued client invoices, and managed services. A regular hardworking guy. However, there were challenges. He is quiet, sometimes thoughtful, and often lost in his own thoughts.

Billing was the first system we tried to get along with. The first difficulty we encountered was during service processing.
For instance, when creating or deleting a task, it gets placed in the internal billing queue. This is how the asynchronous service processing system works. To handle our types of services, we needed to 'stack' our tasks into this queue. And here we ran into a problem: a lack of documentation.

According to the software API description, this task can be solved, but we didn't have time to engage in reverse engineering, so we externalized the logic and organized a task queue on top of RabbitMQ. The service operation is initiated by the client from the personal account, wrapped into a 'task' using Celery on the backend, and executed on the billing and OpenStack side. Celery allows for convenient task management, retries, and state monitoring. You can read more about 'celery', for example, .
Additionally, billing did not stop the project when funds ran out. Communicating with developers, we discovered that when calculating based on statistics (which is the logic we needed to implement), there is a complex interrelationship of stopping rules. However, these models do not fit well with our realities. We also implemented this through Celery tasks, transferring service management logic to the backend.
Both of the aforementioned problems led to the code becoming somewhat bloated and we will have to address refactoring in the future to separate the task management logic into its own service. We also need to store some user and service information in our own tables to support this logic.
Another problem is silence.
For some API requests, Billy silently replies 'Ok'. This occurred, for example, when we processed promised payments during a test (more on that later). The requests were executed correctly and we did not see any errors.

Ik moest de logs bestuderen terwijl ik met het systeem via de gebruikersinterface werkte. Het bleek dat de factureringsmodule dergelijke verzoeken uitvoert, waarbij de scope wordt gewijzigd naar een specifieke gebruiker, bijvoorbeeld, admin, die in de parameter su wordt doorgegeven.
Al met al, ondanks de hiaten in de documentatie en kleine tekortkomingen in de API, verliep alles redelijk goed. De logs zijn goed leesbaar, zelfs bij hoge belasting, als je begrijpt hoe ze zijn opgebouwd en wat je moet zoeken. De database-structuur is ingewikkeld, maar logisch en in zekere zin zelfs aantrekkelijk.
Samenvattend, de belangrijkste problemen die we ondervonden tijdens de interactiefase, hangen samen met de specifieke implementatie van het systeem:
- niet-gedocumenteerde 'features' die ons op de een of andere manier beïnvloedden;
- gesloten broncode (de factureringsmodule is in C++ geschreven), waardoor het onmogelijk was om probleem 1 op enige andere manier op te lossen dan via 'trial and error'.
Gelukkig heeft het product een uitgebreid API, en we hebben de volgende subsysteem geïntegreerd in ons persoonlijke dashboard:
- technische ondersteuning module — aanvragen vanuit het persoonlijke dashboard worden transparant doorgegeven aan de factureringsmodule voor de serviceklanten;
- financiële module — stelt ons in staat om facturen naar huidige klanten te sturen, afschrijvingen uit te voeren en betalingsdocumenten op te stellen;
- dienstenbeheer module — hiervoor moesten we onze eigen handler implementeren. De uitbreidbaarheid van het systeem kwam ons van pas en we 'trainden' Billy met een nieuw type diensten.
We moesten er wat tijd in steken, maar zoals het er nu uitziet, denk ik dat we goed met Billy kunnen samenwerken.
Wandelingen door de wolfraamvelden — Tungsten Fabric
Wolframvelden bezaaid met honderden draden die duizenden bits informatie doorgeven. Informatie wordt verzameld in 'pakketten', gedecodeerd, en complexe routes worden opgebouwd, als door magie.

Dit is het domein van het tweede systeem waarmee we moesten samenwerkingen — Tungsten Fabric (TF), voorheen OpenContrail. De taak ervan is het beheren van netwerkapparatuur, terwijl het ons, als gebruikers, een softwarematige abstractie biedt. TF is een SDN, het encapsuleert ingewikkelde logica voor het werken met netwerkapparatuur. Er is een goed artikel over de technologie, bijvoorbeeld, .
Het systeem is geïntegreerd met OpenStack (waarover later meer) via de Neutron-plugin.

Interacties tussen OpenStack-diensten.
Dit systeem is ons voorgesteld door de jongens van de operationele afdeling. We gebruiken de API van het systeem om het netwerkstack van onze diensten te beheren. Tot nu toe zijn er geen serieuze problemen of ongemakken geweest (ik kan niet voor de jongens van de O.E. spreken), maar er zijn wel een paar komische situaties geweest tijdens de interactie.
De eerste zag er als volgt uit: commando's die veel gegevens naar de console van de instantie vereisten, hingen simpelweg de verbinding op bij toegang via SSH, terwijl het via VNC goed werkte.

Voor degenen die niet bekend zijn met het probleem, ziet dit er behoorlijk grappig uit: ls /root werkt correct, terwijl bijvoorbeeld top volledig 'vastloopt'. Gelukkig hadden we al eerder met vergelijkbare problemen te maken gehad. Dit werd opgelost door de MTU te tunen op de route van de compute-nodes naar de routers. Overigens is dit geen probleem van TF.
Het volgende probleem wachtte om de hoek. Op een 'prachtig' moment verdween de magie van de routering, zo maar. TF stopte met het beheren van de routering op de apparatuur.

We werkten met OpenStack op admin-niveau en gingen daarna over naar het niveau van de gewenste gebruiker. SDN lijkt de scope van de gebruiker over te nemen waarmee acties worden uitgevoerd. Het probleem is dat dezelfde admin-account wordt gebruikt voor de communicatie tussen TF en OpenStack. Op het punt van overschakelen naar de gebruiker verdween de 'magie'. Het werd opgelost door een apart account aan te maken voor het werken met het systeem. Dit maakte het mogelijk om te werken zonder de integratiefuncties te breken.
Siliconen levensvormen — OpenStack
Het siliconenwezen van bizarre vorm leeft niet ver van de wolfraamvelden. Het lijkt het meest op een grote kinderen, die met één beweging ons kan verpletteren, maar er gaat geen duidelijke agressie van uit. Het wekt geen angst, maar zijn grootte wekt wel bezorgdheid. Net als de complexiteit van wat er omheen gebeurt.

OpenStack is de kern van ons platform.
OpenStack heeft verschillende subsysteem, waarvan we tot nu toe het actiefst Nova, Glance en Cinder gebruiken. Elk heeft zijn eigen API. Nova is verantwoordelijk voor compute-resources en het maken van instanties, Cinder voor het beheren van volumes en hun snapshots, Glance is de image service die de OS-sjablonen en metadata beheert.
Elke service draait in een container en de berichtenbroker is de 'witte konijn' — RabbitMQ.
Dit systeem heeft ons de meeste onverwachte problemen bezorgd.
Het eerste probleem liet niet op zich wachten toen we probeerden een extra volume aan de server toe te voegen. De Cinder API weigerde resoluut om deze taak uit te voeren. Sterker nog, als we OpenStack mogen geloven, wordt de verbinding tot stand gebracht, maar binnen de virtuele server ontbreekt het schijfapparaat.

We besloten 'om te gaan omleiden' en vroegen dezelfde actie aan de Nova API. Het resultaat — het apparaat wordt correct aangesloten en is beschikbaar binnen de server. Het lijkt erop dat het probleem zich voordoet wanneer block-storage niet naar Cinder reageert.
Een nieuwe complicatie wachtte ons bij het werken met de schijven. Het lukte niet om het systeemvolume van de server los te koppelen.
Opnieuw zwoer OpenStack dat de verbinding was verbroken en dat we nu correct met het volume apart konden werken. Maar de API weigerde categorisch om operaties op de schijf uit te voeren.

Hier besloten we om niet te veel te vechten en de kijk op de logica van de service aan te passen. Als er een instance is, moet er ook een systeemvolume zijn. Daarom kan de gebruiker voorlopig het systeem 'schijf' niet verwijderen of loskoppelen zonder de 'server' te verwijderen.
OpenStack is een behoorlijk complex systeem met zijn eigen logica van interactie en een ingewikkelde API. We worden goed geholpen door de vrij gedetailleerde documentatie en, natuurlijk, de methode van proberen en fouten maken (want wat zou je anders doen?).
Testlancering
De testlancering vond plaats in december van vorig jaar. De belangrijkste taak was om ons project zowel technisch als vanuit een UX-perspectief in de praktijk te testen. We nodigden selectief een publiek uit en de test was besloten. We lieten echter ook de mogelijkheid open om toegang tot de test aan te vragen via onze website.
De test ging natuurlijk niet zonder komische momenten, want hier beginnen onze avonturen pas echt.
Ten eerste hebben we de interesse in het project niet correct ingeschat en moesten we in allerijl compute nodes toevoegen tijdens de test. Een gebruikelijke situatie voor een cluster, maar zelfs hier waren er nuances. In de documentatie voor de specifieke versie van TF is een specifieke versie van de kernel aangegeven, die werd gebruikt voor de test met de vRouter. We besloten om nodes met nieuwere kernels te lanceren. Het resultaat — TF ontving geen routes van de nodes. We moesten een spoedterugrol van de kernels uitvoeren.

Een andere grappige situatie heeft te maken met de functionaliteit van de knop 'wachtwoord wijzigen' in het persoonlijke dashboard.
We hebben besloten om JWT te gebruiken voor het organiseren van de toegang tot het persoonlijke dashboard, om niet met sessies te hoeven werken. Aangezien de systemen uiteenlopend en wijd verspreid zijn, beheren we onze eigen token, waarin we sessies van de factureringsmodule en de token van OpenStack 'verpakken'. Bij het wijzigen van het wachtwoord verloopt de token uiteraard, omdat de gegevens van de gebruiker dan ongeldig zijn en deze opnieuw uitgegeven moet worden.

We hebben dit moment over het hoofd gezien, en we hadden gewoon niet genoeg resources om dit stuk snel af te schrijven. We moesten functionaliteit verwijderen vlak voor de teststart.
Op dit moment loggen we de gebruiker uit als het wachtwoord is gewijzigd.
Ondanks deze nuances is de test goed verlopen. In een paar weken hebben ongeveer 300 mensen een kijkje bij ons genomen. We hebben het product door de ogen van gebruikers bekeken, het in de praktijk getest en waardevolle feedback verzameld.
To be continued
Voor velen van ons is dit het eerste project van deze omvang. We hebben een aantal waardevolle lessen geleerd over teamwork, architecturale en ontwerpbeslissingen. Hoe complexe systemen met beperkte middelen te integreren en deze naar productie te brengen.
Natuurlijk is er nog veel werk aan de winkel, zowel qua code als op de raakvlakken van systeemintegratie. Het project is vrij jong, maar we zijn vastberaden om er een betrouwbare en gebruiksvriendelijke dienst van te maken.
We hebben de systemen al over kunnen halen. Bill houdt zich plichtsgetrouw bezig met het berekenen, factureren en het afhandelen van gebruikersvragen in zijn kamertje. De 'magie' van wolfraamvelden zorgt voor een stabiele verbinding. En alleen OpenStack gedraagt zich af en toe humeurig, roepend dat iets als 'WSREP heeft de node nog niet voorbereid voor applicatiegebruik'. Maar dat is een heel ander verhaal…
We hebben onlangs de dienst gelanceerd.
U kunt alle details vinden op onze .

CLO ontwikkelteam
Nuttige links
OpenStack
Tungsten Fabric
Bron: habr.com
