Blog

Ontwikkel Multicloud Ready Microservices met DAPR

introductie

We weten allemaal hoe snel je een cloud native web applicatie kunt schrijven en deployen naar elke public cloud. Met een paar klikken heb je zo een leeg .NET Core project gemaakt, dependency injectie geimplementeerd, een aantal APIs ontsloten en gedeployed naar je favoriete compute service. Maar wat als je over de Microservice route wilt gaan? Dan moet je eerst je Kubernetes cluster opzetten en je Service Bus of Message queue configuration voor de service-to-service communicatie en dan heb je nog geen regel code geschreven.

Heb je wel eens nagedacht over de afhankelijkheid van je software architectuur op je cloud infrastructuur? In de meeste gevallen is je container setup specifiek voor de cloud provider die je op dit moment gebruikt en hebben je microservices een tight coupling met cloud provider specifieke endpoints of met andere PaaS diensten van deze cloud provider. Wat als je dan wilt switchen naar een andere cloud proivder? Wat als je een nieuwe service nodig hebt die enkel wordt aangeboden door de concurrent? Dan heb je een software architectuur nodig welke klaar is voor multicloud!

Het multicloud ready maken van jouw architectuur kan nu vereenvoudigd worden door DAPR te gebruiken. Een middleware laag en applicatie runtime welke is ontworpen om jouw microservice ontwikkeling en deployment cloud agnostisch te maken. Zonder tight coupling tussen je applicatie code en jouw cloud infrastructuur.

Met david sparren over dapr?

geschiedenis van dapr

Als gezegd DAPR is een middleware laag en applicatie runtime, daarom staat de afkorting ook voor “Distributed Application Runtime”. Distributed betekent in deze dat DAPR decentraal draait en perfect past binnen een microservices architectuur. De key functionaliteit van DAPR is om ondersteuning te biedden voor cloud native and serverless cloud diensten in een microservices architectuur.

Au contraire wat de meeste mensen denken is DAPR niet ontwikkeld of onderhouden door Microsoft. Het is een volledig open-source project gelanceerd onder de MIT license. Micorsoft heeft echter wel redelijk wat publiciteit vergaard met DAPR en draagt ook financieel bij aan het project. Verder worden er ook bijdragen geleverd aan het project door developers van Microsoft en developers die in het verleden voor Microsoft hebben gewerkt. Deze inmenging van Microsoft heeft er toegeleid dat er binnen het .NET ecosysteem er goede ondersteuning is voor DAPR vanaf eigenlijk begin af aan. Er is een specifieke SDK voor .NET Core, volledige support in Visual Studio en goede documentatie volgens de Microsoft standaarden. Maar DAPR is niet enkel Microsoft specifiek. De runtime zelf is geschreven in Go en is platform agnostisch.

Dit geldt voor zowel de infrastructuur laag waar DAPR mee praat als de applicatie laag die je bovenop DAPR draait. Naast .NET Core is er ook ondersteuning voor Node.js, Java, Pyhton, C++ en Go zelf. Op de infrastrucuur laag is er out-of-the-box support voor natuurlijk Microsoft Azure maar ook voor AWS, Google Cloud Platform en zelfs nieuwkomers in de markt zoals Alibaba Cloud en Camunda Cloud.

dapr bouwstenen

DAPR acteert als een interface tussen je applicatie en je container infrastructuur. Het gebruik van containers is overigens verplicht als je DAPR wil gebruiken. De onderliggende orchestrator staat vrij. Dit kan zowel Kubernetes zijn maar ook Docker Swarm en de cloud provider die de infrastructuur levert is ook niet van belang. Het belangrijkste voordeel van DAPR uit oogpunt van de developer is dat het zorgt voor een single-contract interface om the interacteren met elke cloud infrastructuur, elke andere microservice in je cluster en zelfs interacties met exteren applicaties of API’s op het internet, buiten je cluster. Je hoeft niet meer bang te zijn voor breaking changes in je infrastrucutuur laag. Zolang je jouw contract met de DAPR runtime respecteert is er niets aan de hand.

![DAPR Architecture]

De DAPR runtine is modulair ontwikkeld. Dit betekent dat je zelf kunt kiezen welke services in jouw software life cycle door DAPR geregeld moeten worden en welke je zelf regelt. Op deze manier blijft DAPR lichtgewicht en heeft het geen impact op de snelheid van jouw microservices. Ook neemt DAPR zo minder resources in binnen je Kubernetes cluster.

Er zijn onder andere DAPR modules voor: State Management, Service-to-Service Invocation, Pub-Sub, Resource Bindings, Observables en Secrets. Vanwege de open-source licentie van DAPR kun je ook een van de velen modules gebruiken die ontwikkeld zijn en onderhouden worden door de community.

sidecar architectuur

DAPR gebruikt het sidecar pattern om zichzelf beschikbaar te maken voor jouw microservice. Dit is hetzelfde pattern dat Service Meshes zoals Istio gebruiken binnen het Java Ecosysteem. Alhoewel DAPR is geen Service Mesh omdat DAPR geen diensten of features aanbied op de netwerk laag, het is puur en alleen een applicatie runtime.

![DAPR Sidecar]

Wanneer je een DAPR resource injecteert in je microservice wordt er een sidecar opgespint in een aparte pod of container in jouw cluster. Deze pod wordt van verbonden met de pod welke je microservice draait op eenzelfde manier als meerdere karretjes samenwerken in een trein van een achtbaan. Afhaneklijk van de hoeveelheid DAPR diensten die je gebruikt in je microservices kunnen er één of meerdere karretjes aangehaakt worden bij je service pod. The karrtjes onderling communiceren over mTLS.

black-box interface

Het grote voordeel van DAPR is de enkele interfact die je gebruikt vanuit het perspectief van je microservice code. Je kunt met DAPR communiceren over HTTP(S) of gPRC afhankelijk van jouw voorkeur en de stack die je gebruikt. Elke DAPR service die je gebruikt wordt gedefinieerd als een component in je source code. Componenten zijn beschreven in YAML en kunnen gebruikt worden om te interacteren met elk van de DAPR modules. Voor elke module is er een [lijst](https://docs.dapr.io/concepts/components-concept/) met ondersteunde componenten van elke cloud provider.

“`yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: demosecrets
namespace: default
spec:
type: secretstores.local.file
metadata:
– name: secretsFile
value: secrets.json
“`

_Code Sample 1. Voorbeeld van een secret component die een secret leest uit het local filesystem._

Het DAPR component dat hierboven staat bevat relevante metadata over het type componnent en de infrastructuur achter het component. In dit geval hebben we het component **_demosecrets_** van het type **_secretstores_** dat leest uit een lokaal bestand dus een bestandsnaam en pad zijn verplicht.

“`C
public static IHostBuilder CreateHostBuilder(string[] args)
{
// Create DAPR Client
var client = new DaprClientBuilder()
.Build();

return Host.CreateDefaultBuilder(args)
.ConfigureServices((services) =>
{
// Add the DAPR Client to Host.
services.AddSingleton(client);
})
.ConfigureAppConfiguration((configBuilder) =>
{
// Add the secret store Configuration Provider to the configuration builder.
configBuilder.AddDaprSecretStore(“demosecrets”, client);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
“`

_Code Sample 2. DAPR Client toevoegen aan je ASP.NET Core webapplicatie._

De DAPR client wordt geinjecteerd als een singleton en daarna voegen we een SecretStore toe aan de client. De DAPR client weet alleen dat hij praat tegen de **_demosecrets_** secret store en weet niets over de fysieke locatie van de store of de specificieke implementatie. De client weet alleen dat het secrets kan ophalen van dit specifieke DARP endpoint wat in dit geval `http://localhost:/v1.0/secrets/demosecrets/` zou zijn. Dit betekent dat je de inhoud van het DAPR component op elk moment kunt veranderen zonder het contract met de interface van je applicatie te breken. Dus stel ik wil mijn secrets verplaatsen van een lokaal bestand naar zeg Azure Key Vault, dan kan ik dat doen door enkel mijn DAPR component te wijzigen.

“`yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: demosecrets
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
– name: vaultName
value: david07-e-kv
– name: spnClientId
value: b49cdb50-a668-4c57-913d-21b45bf89e4d
“`

_Code Sample 3. DAPR component wijzingen naar Azure Key Vault met MSI authenticatie._

Mijn applicatie en DAPR client praten nog steeds tegen de **_demosecrets_** secret store. De client weet niet dat de secrets niet langer in het lokale bestandsysteem leven en verplaatst zijn naar Azure Key Vault. Mijn applicatie weet ook niet dat hij nu secrets moet ophalen over het publieke internet en zich eerst tegen Azure moet authenticeren, de DAPR runtime regelt dit allemaal voor mijn microservice. Dit betekent dat je resources kunt verplaatsen of kunt wisselen tussen publieke cloud providers zonder dat je applicatie hier van weet en zonder dat je de configuratie van je applicatie hoeft aan te passen of code changes hoeft door te voeren in je microservice.

 

componenten voor elke cloud

DAPR heeft een heleboel off-the-shelve componenten voor alle ondersteunden cloud platformen. Vorr een beter inzicht in deze componenten zie de graph hieronder welke de verschillende componenten van elk cloud platform laat zien. Sommige componenten kunnen gebruikt worden op elk cloud platform zolang je maar het gestandaardiseerde wire protocol gebruikt voor deze componenten.

![DAPR Components for different Public Clouds]

Natuurlijk kun je gebruik maken van Azure native services zoals Cosmos DB, SignalR of Event Grid maar er is ook support voor vergelijkbare diensten in AWS en GCP. Ook kun je kiezen voor diensten die beschikbaar zijn op elke cloud zoals Cassandra, Kafka of RabbitMQ. Mocht het component dat jij wilt gebruiken toch nog niet bestaan dan kun je deze zelf maken en makkelijk toevoegen aan de [DAPR Components Contrib](https://github.com/dapr/components-contrib).

cloud agnostisch betekent multicloud ready

Omdat DAPR zelf cloud agnostisch is, i.e. voor elke module is er een component voor bijna alle Publieke Clouds (Azure, AWS, GCP, Alibaba Cloud, Camunda Cloud) en het er voor zorgt dat jouw microservice niet weet tegen welke cloud hij praat is DAPR ideaal om te gebruiken in een multicloud omgeving of zelfs een must in een multicloud architectuur. Met DAPR kun je jouw infrastructuur wijzigen onafhankelijk van je applicatie code en makkelijker switchen naar een andere cloud provider of verschillende cloud providers door elkaar heen gebruiken zonder dat jouw microservice dit hoeft te weten. Verder kan je zelfs een hybride cloud oplossing maken met resources die ook nog steeds on-premises leven.

Voor puur op PaaS gebaseerde applicaties draaiend op Azure App Service of AWS Lambda was dit al tijden mogelijk met de SDKs die er beschikbaar zijn voor deze platformen binnen .NET Core. Maar voor microservices architecturen op de .NET Stack vult DAPR een gat om multicloud ook makkelijk te maken voor deze architectuur. Voor andere talen zoals Java kan DAPR ook een goede keus zijn maar binnen het Java Ecosysteem bestaan ook al andere bewezen oplossingen om service code te scheiden van de cloud infrastructuur met Service Meshes zoals Istio maar ook met nieuwe ontwikkelingen binnen het Spring framework met [Spring Cloud Skipper](https://spring.io/projects/spring-cloud-skipper) en ook de Spring Cloud native implementaties op Azre, AWS, GCP en Alibaba cloud zorgen er voor dat er veel meer concurrentie is voor DAPR binnen de Java stack. Ik voorzie dus een grotere shift in interesse en ondersteuning voor DAPR op het Microsoft platform en de .NET Core community zo dat DAPR de go to middleware layer wordt om op .NET Core gebasseerde microservices te draaien op elke cloud.

Met david sparren over dapr?

waarom multicloud belangrijk is

Het public cloud landschap is veranderlijk en als afnemer wil je geen last hebben van vendor lock-in. Op IT management niveau commiteren aan één enkele leverancier voor cloud infrastructuur kan best stresvol zijn. Niet alleen verlies je flexibiliteit maar je moet ook een commitment op de lange termijn aangaan met een specifieke leverancier, helemaal als je software architectuur slechts rekening houd met één enkel cloud platform. Op deze manier heb je een harde afhankelijkheid op deze leverancier, misschien ben je wel minder blij met de support die deze leverancier bied, misschien is er wel een service die je wilt gebruiken die deze leverancier nog niet heeft of misschien verhoogd deze leverancier simpelweg haar prijzen omdat je er toch al aan vast zit.

In deze gevallen wil je de mogelijkheid hebben om (deels) te veranderen van cloud proivder zonder je business continuiteit van je applicaties op het spel te zetten. Het hebben van een multicloud architectuur maakt dit mogelijk omdat je jouw applicatie ontkoppeld van de cloud infrastructuur. Dit zorgt er voor dat je niet langer overgeleverd bent aan de grillen van die éne cloud provider waarmee je in zee bent gegaan en maakt het mogelijk om nieuwe diensten van andere leveranciers uit te proberen. Het zorgt er ook voor dat jouw CTO niet langer slapenloze nachten krijgt over dat megacontract met die éne cloud provider welke anders een single point of failure zou worden binnen je IT strategie. Als je overweegt om te migreren richting public cloud, dan moet je ook overwegen om je software architectuur multicloud ready te maken. Doe dit voor het te laat is en je vast zit in de gouden kooi van de cloud provider waarmee je niet meer mee kunt leven, maar ook niet langer zonder kan.

Geïnspireerd? Deel dit artikel

Ga naar de bovenkant