Dit artikel is geschreven door René Santing en oorspronkelijk gepubliceerd op Devhouse Spindle op 25 juni 2022. Wil je graag de Engelse versie lezen, bekijk dan de blog op onze Engelse site.
In het begin van 2022 maakten onze developers de agenda’s leeg om een maand lang te werken aan nieuwe uitdagingen op het gebied van productontwikkeling. In een online hackathon testten we nieuwe technieken voor onze toekomstige producten. De maand werd afgetrapt met verschillende masterclasses, om dieper in te gaan op de technieken waarmee we gingen werken.
De eerste masterclass legde de verschillen uit tussen ons huidige VoIP-telefonieplatform als monolithisch platform en ons nieuw te bouwen microservices platform. Dit blog geeft je een indruk van de tools en technieken die we hebben gebruikt om een microservice platformarchitectuur op te bouwen.
Op zoek naar een nieuwe manier van softwareontwikkeling kwamen we uit bij een microservice platform. De vergelijking van tiny houses met appartementen werkt hier goed, waarbij het microservice platform staat voor tiny houses met hun eigen voorzieningen voor elektriciteit en water, in vergelijking met een appartementengebouw met gecentraliseerde elektriciteit en water.
Een equivalent in de tech stack zou kunnen zijn dat microservices hun eigen database hebben, tegenover één grote database in een monolithische setup. Deze microservices praten met elkaar via een API die je bijvoorbeeld gegevens kan geven over wie met wie belt.
Hieronder zie je in het kort de voor- en nadelen van elk platform:
We geloven dat een microservice platform ons ten opzichte van een monolithisch platform twee belangrijke dingen oplevert:
Het development event werd in het leven geroepen om, door middel van veel testen, te ontdekken of we inderdaad sneller kunnen ontwikkelen met een microservice platform.
Het afgelopen jaar hebben we verschillende iteraties doorgevoerd aan het microservice platform en voerden we diverse verbeteringen door. In het begin experimenteerden we met Kubernetes en combineerden we dit met projecten van de Cloud Native Computing Foundation (CNCF). Vervolgens gebruikten we deze combinatie om een begin te maken met het microservice platform.
Langzaam maar zeker sloten meer collega’s aan om aan het nieuwe platform te werken. We onderzochten een event-based architectuur, wat een veelbelovende architectuur lijkt voor microservice platformen. We besloten NATS te gebruiken als central messaging bus en het platform op die manier te bouwen.
Een event-based architectuur kan worden uitgelegd als een bus die tussen alle microservices loopt, en berichten doorgeeft aan alle microservices die de informatie willen hebben.
Tijdens dit proces kwamen we erachter dat het ecosysteem rond NATS en event-based architectuur nog niet echt klaar was voor onze usecase. Dit zou betekenen dat we meer onderdelen van het platform zelf zouden moeten bouwen, waardoor de benodigde ontwikkeltijd zou toenemen. Uiteindelijk besloten we te gaan voor een service mesh en kozen we voor Istio. Er is veel dat een service mesh voor ons kan doen en ook veel dat we waarschijnlijk niet nodig hebben. We zullen in deze blog niet ingaan op alle details van een service mesh, maar er zijn online veel bronnen over beschikbaar.
In het kort bestaat de microservice platform architectuur uit:
Hieronder belichten we elk onderdeel van de microservice platform architectuur.
Routeert naar en maakt onze service gateways beschikbaar, en voert standaardlogica uit zoals authenticatie, herschrijven van headers en rate limiting. Hiervoor hebben we Istio Gateway gekozen, vanwege de integratie met Istio en de geavanceerde functies die in de toekomst handig kunnen zijn. Istio is een service mesh die microservices helpt om op een veilige manier met elkaar te praten.
Deze service mesh is een sidecar op elke container, die geïnjecteerd wordt om ervoor te zorgen dat deze containers met andere containers kunnen praten (met TLS bijvoorbeeld). Met Istio hebben we twee versies van een container, waarbij een ervan een andere code draait omdat we A/B-tests willen doen. Istio kan ook worden omschreven als een speciale infrastructuurlaag voor het faciliteren van service-to-service communicatie tussen diensten of microservices, met behulp van een proxy.
Dit is ook wel bekend onder de afkorting IAM: identity and access management. Het biedt ontwikkelaars het gemak van gecentraliseerde authenticatie, omdat ze er niet echt over na hoeven te denken. Een van de belangrijkste voordelen van IAM is dat er één specifieke plek is waar alles beveiligd moet worden.
Keycloak is gekozen vanwege de mogelijkheid om er ondersteuning voor te kopen, maar ook omdat het open-sourced en ‘battle-tested’ is. Daarnaast heeft Keycloak ook flexibiliteit, is het out-of-the-box en ondersteunt het identity providers zoals Google. We kunnen Keycloak ook in onze eigen set-up draaien waardoor het zelf gehost is, wat we prettig vinden omdat het dan dichter bij de rest van ons platform staat. Tot slot hoeven we ons geen zorgen te maken over waar het wordt gehost en of die locatie veilig genoeg is wat betreft de privacywetgeving.
We hebben GitLab gekozen voor onze continuous integration. We gebruiken het al voor het VoIP-telefonieplatform, waarvoor het goed werkt en doet wat we willen en nodig hebben. De geïntegreerde functies zijn ook een bonus, omdat het de functies zijn die we nodig hebben. Het feit dat we het kunnen gebruiken als een SSO-provider voor een aantal van de andere tools, zoals Argo CD, is ook een pré.
We willen continuous delivery doen op dit nieuwe platform en de tool die we daarvoor gekozen hebben is Argo CD. Er zijn een paar redenen om aan continuous delivery te doen. Het belangrijkste voordeel van continuous delivery is dat deployments gemakkelijker worden en het dus minder werk is om kleine veranderingen te deployen, waardoor we sneller kunnen ontwikkelen. Verder is de deployment ook consistent, vanwege het automatische karakter. Deze automatisering betekent dat er minder makkelijk iets wordt vergeten, en maakt het ook eenvoudiger om terug te draaien als er een fout is gemaakt. Nu pusht iemand het naar de staging-omgeving, en met een druk op de knop ook naar productie.
Een andere nuttige functie is dat Argo CD declaratief is en kan integreren met Istio om automatisch blue/green deployments te doen met behulp van Argo Rollouts. Het heeft ook ondersteuning voor Helm, de tool die we gebruiken om pakketten voor Kubernetes te beheren.
Als je een service hebt draaien, moet je ook weten wat er is gebeurd als er iets misgaat. Er zijn verschillende tools die we daarvoor gebruiken.
Voor metrics hebben we gekozen voor Prometheus, een tool die we al jaren gebruiken en tegenwoordig dé standaard is in open source software monitoring. We maken er graag gebruik van en het is een krachtige tool. Omdat het de standaard is, hebben veel open source tools vaak Prometheus endpoints. Het integreert bovendien goed met Grafana om metrics te visualiseren.
Iets anders dat noodzakelijk is, is foutrapportage. Hiervoor hebben we Sentry gekozen. We hebben eerst geprobeerd om iets anders te vinden, omdat Sentry soms moeilijk zelf gehost kan worden. Maar omdat er op dat moment geen goede alternatieven waren en het wel alle functies heeft die we nodig hebben en we er ervaring mee hebben, zijn we er toch voor gegaan.
Voor logging kozen we Loki, een logaggregatiesysteem van Grafana. Met Loki hebben we een gecentraliseerde plaats met alle logs van de microservices voor het geval er iets fout gaat. Voor het VoIP-telefonieplatform gebruiken we Graylog, maar we ontdekten dat Loki lichter is en dat de query-syntax vergelijkbaar is met die van Prometheus. Deze gemeenschappelijke syntax betekent dat we er maar één hoeven te leren, wat troubleshooting krachtiger maakt. Loki integreert ook goed met Grafana om metrics te visualiseren.
Dit onderdeel van de platformarchitectuur geeft een ID aan een verzoek, wat ons helpt om te zien wat er met dit ID is gebeurd vanaf het begin tot het eindpunt. Dit kan worden achterhaald via de microservices, om te begrijpen waar het verzoek heen ging, welke microservices het raakte en wat waar gebeurde. Met gedistribueerde tracing kunnen gebruikers een verzoek volgen door de mesh die over meerdere diensten is verdeeld.
Wij slaan deze traces op in de Jaeger backend voor traces, die een eigen frontend heeft. We gebruiken echter ook Kiali om ontwikkelaars inzicht te geven in hun microservices. Deze integreert ook mooi met Jaeger en kan van daaruit de traces tonen.
Wanneer we een microservice maken, hebben we een gemakkelijke manier nodig voor ontwikkelaars om een database te deployen zonder ons infrateam nodig te hebben. Hiervoor hebben we Crossplane gekozen, dat kan worden omschreven als een declaratieve manier om databases in te zetten. Het maakt de inzet van een managed database met een aangepaste resource definitie in Kubernetes mogelijk. Crossplane maakt snellere ontwikkeling zonder system engineers mogelijk, maar is niet ideaal omdat het voortdurend in ontwikkeling is.
Voor het dev event waren vooraf een aantal zaken bepaald om de development soepel te laten verlopen. Er was een Python-template beschikbaar om gemakkelijk te beginnen met de ontwikkeling van een nieuwe dienst, en er was een API-standaard. Verder is de lokale ontwikkelomgeving gebaseerd op Docker en was er centrale documentatie beschikbaar in Notion, een tool die we gebruiken als onze bedrijfskennisbank.
Om de architectuur te testen, bouwden we al een eerste dienst voordat we aan het dev event begonnen. Deze dienst heet Flowie en doet aan (belplan) routing. Om onze developers bij de start van het evenement te helpen, hebben we ook twee voorbeelddiensten gemaakt die alle bewegende delen van het platform laten zien.
In grote lijnen zijn dit de technieken die we gebruikten om onze nieuwe microservice platformarchitectuur te ontwikkelen. In ons volgende artikel over de tweede masterclass van het dev event duiken we in het maken van een developer-vriendelijk Kubernetes platform met GitOps. Je leest ‘m hier.
In de afgelopen jaren hebben we veel geschreven over ondernemen, zelfsturend werken, de handigste tools en nog veel meer. Dus leef je uit!
Ga naar het blogoverzicht