Inmiddels zijn Docker containers bijna niet meer weg te denken als standalone virtualisatie techniek tijdens ontwikkeling van software. Na de voorzichtige introductie inmiddels bijna 10 jaar geleden wordt containerisatie inmiddels als valide virtualisatie optie beschouwd. Dit omdat er inmiddels bewezen veel functionele en technische voordelen aan containers kleven waar wij voorheen als sector veel problemen mee hadden. Lees verder in dit blog van Patrick Bes, Technical Lead Consultant bij Bergler Software Solutions, om de voordelen te ontdekken.

Herbruikbaarheid- mogelijkheid om je code overal te draaien.

Het is een groot voordeel dat containers overal kunnen draaien, zolang de container-engine het onderliggende besturingssysteem ondersteunt. Waar Linux in veel gevallen het Operating System van voorkeur is kunnen ze ook draaien op Windows, MacOS en vele andere besturingssystemen. We kunnen één container creëren welke wij kunnen gebruiken van de ontwikkel-laptop tot aan de productieomgeving.

De term “It works on my machine” is inmiddels toch echt iets wat tot het verleden zou moeten behoren.

Container Isolatie maar toch delen resources

We zijn nu in staat meerdere containers op dezelfde server te laten draaien, terwijl deze toch volledig van elkaar geïsoleerd zijn. Wanneer containers crashen of applicaties erin falen, kan een andere container met dezelfde applicatie gewoon blijven werken. Containerisolatie heeft ook beveiligingsvoordelen, zolang containers veilig zijn geconfigureerd om te voorkomen dat aanvallers toegang krijgen tot het host besturingssysteem.

Efficiëntie

Aangezien containers geen apart besturingssysteem nodig hebben verbruiken ze hierdoor minder resources. Als wij Virtual Machines als tegenhanger nemen dan zijn deze doorgaans enkele GB groot, maar containers wegen gewoonlijk slechts tientallen megabytes, waardoor een server veel meer containers kan draaien dan VM’s. Containers hebben doorgaans minder hardware nodig, waardoor het mogelijk wordt om de serverdichtheid te verhogen en de datacenter- of cloudkosten te verlagen.

Hoge schaalbaarheid

Met containers maken wij het gemakkelijk om gedistribueerde applicaties horizontaal te schalen. We kunnen meerdere, identieke containers naast elkaar draaien om hiermee de beschikbaarheid en performance te kunnen verbeteren. Door de eerder genoemde efficiënte is dit redelijk straffeloos te doen zonder dat wij een enorme hoeveelheid hardware aan te schaffen.

Verschillende stromingen

Al vrij snel bleek er na de introductie van containers dat er voor de hosting grofweg 2 verschillende stromingen zijn ontstaan.  Aan de ene kant dat er een sterke behoefte was aan meer overkoepelende infrastructuur en beheermogelijkheden van onderlinge samenwerking van containers (Optie A container orchestratie). En aan de andere kant was er behoefte aan eenvoudige, kosteneffectieve en snelle oplossing om containers te hosten (Optie B).

Binnen deze verschillende stromingen zijn er weer veel verschillende differentiaties ontstaan. Laten wij ze eens wat nader bekijken.

Optie A (Container Orchestratie)

In veel scenario’s zal men meerdere met elkaar samenwerkende containers hebben. Het is vrij logisch dat als men bijvoorbeeld Microservices introduceert, het niet zal blijven bij de introductie van één service. Om deze service goed, snel en stabiel te kunnen laten samenwerken zonder hier veel maatwerk te introduceren is een container orchestratie een logische oplossing.  Een aantal zaken zal je hiermee uit handen genomen worden, denk aan:

  • Provisioning en deployment.
  • Configuratie en scheduling.
  • Resource allocation.
  • Container beschikbaarheid.
  • Op- en afschalen van containers op basis van het verdelen van werklasten over de infrastructuur.
  • Load balancing en traffic routing.
  • Bewaking container status.
  • Interacties tussen containers veilig houden.

Er zijn verschillende differentiaties ontstaan zoals: Docker Swarm, Apache Meso, Kubernetes en nog veel meer. Kubernetes is uiteindelijk de defacto marktstandaard geworden. Kubernetes is een opensource product uit de koker van Google welke perfect de bovenstaande zaken uit handen neemt. Maar het introduceert op zijn beurt ook weer een stuk complexiteit en overhead in het management van het Kubernetes cluster. Om deze complexiteit weer aan te pakken en te vereenvoudigen zijn de grote cloud leveranciers hierop ingesprongen en hebben hiervoor weer PaaS-services voor ontwikkeld. Zo zijn er bijvoorbeeld:

  • AKS Azure Kubernetes service van Microsoft
  • EKS elastic Kubernetes service van Amazon
  • GKE Google Kubernetes engine van Google

Deze PaaS-service neemt een gedeelte van het cluster management van Kubernetes van je over. Dit zorgt voor een aanzienlijk snellere en eenvoudigere uitrol van een Kubernetes-cluster. Er zijn wel wat onderlinge verschillen maar in de basis is het concept tussen deze PaaS-services gelijk. Ondanks het wegnemen van een gedeelte van het cluster management, is de leercurve van PaaS-services als deze nog best hoog en komt er veel bij kijken. Denk aan keuzes die men moet maken betreffende de automatische schaalbaarheid (KEDA vs KNative of helemaal niet),keuzes voor Ingress controller (NGINX, Traefik, Envoy ect.) keuzes voor service mesh implementatie (Istio, linkerd, enz. of geen service mesh). Daarnaast moet men ook nog zorg dragen voor het upgraden en onderhouden van de Kubernetes versies en nodes. Dit maakt het ondanks dat het een PaaS service is, nog best een opgave om te onderhouden.

Optie B (Eenvoudige container hosting)

In scenario’s waarbij je een snelle start wilt maken met containers of waarbij de verwachting is dat het aantal containers zeer beperkt blijft en de onderlinge communicatie vrij minimaal, is een eenvoudige hosting methode een optie. Deze keuze voor een self hosted docker omgeving is natuurlijk een optie, maar ook hier zijn de cloud leveranciers er snel op ingesprongen met talloze opties.  Zo zijn er bijvoorbeeld:

  • Containers on Compute Engine van Google cloud
  • Web App for Containers van Microsoft Azure
  • Azure Container Instances van Microsoft Azure
  • Amazon Elastic Container Service

In gevallen waar men als organisatie wat containers wil gebruiken om b.v. zaken te testen, een kort proces uit te voeren of een tijdelijke oplossing, zijn deze oplossingen prima. Indien men iets stabiel productie ready wil draaien waar schaalbaarheid, veiligheid en flexibiliteit belangrijk zijn dan schiet dit scenario vaak te kort.

Te veel of te weinig, dan Azure Container Apps

Wij constateren dat veel organisaties of in een “te veel” of een “te weinig” situatie verkeren. De keuze voor een managed container orchestratie is toch vaak iets te veel van het goede, en de keuze voor een eenvoudige single container hosting oplossing vaak te eenvoudig om aan alle wensen te voldoen.

Het is dan ook goed dat o.a. Microsoft in dit gat is gesprongen en de “Azure container Apps” oplossing heeft geïntroduceerd. Dit geeft een mogelijkheid om veel van de uitgebreide mogelijkheden van b.v. Kubernetes te combineren met de eenvoud van b.v. Azure Container Instance.

Azure Container Apps is dan ook een “Best of Both Worlds” oplossing.

Wat is dan “Best of Both worlds”?

Azure Container Apps (ACA) is een oplossing gemaakt boven op Kubernetes.  Om de eenvoud te bewaren heeft Microsoft een set aan keuzes al voor je gemaakt. Dit is aan de ene kant fijn omdat het de keuzestress beperkt, maar aan de andere heb je hierdoor wel minder keuzevrijheid. Maar welke functionaliteit biedt ACA en over welke gemaakte keuzes hebben wij het hier concreet?

Fully managed

ACA is fully managed, dit heeft als groot voordeel dat je team geen onderhoud op het Kubernetes cluster hoeft te doen. Zelfs een managed kubernetes cluster als AKS (Azure Kubernetes Service) heeft nog onderhoud op de nodes nodig voor b.v. een Kubernetes versie update. Dit alles is bij ACA niet aan de orde. Houd er wel rekening mee dat de keuze voor een fully managed platform ook betekent dat je geen toegang hebt tot Kubernetes API’s.  Door dat ACA fully managed is heb je er als organisatie veel minder omkijken naar dan bij een service als AKS. Hierdoor is dit ook voor een kleiner team goed beheersbaar.

Containers

ACA is natuurlijk bedoeld om containers te hosten. Hier heeft men wel een beperking dat alleen gebruik te maken is van Linux based containers. Windows containers worden niet ondersteund. Dit kan men als beperking zien.

ACA maakt gebruik van de Kubernetes standaard oplossingen om de “liveness” en “readiness” van een container te bepalen. Dit is een zeer krachtig mechanisme waarmee b.v. tijdens een release gekeken kan worden of de nieuwe container al klaar is om binnenkomend verkeer te ontvangen. Indien dit het geval is wordt er pas verkeer naar toe gerouteerd. Een dergelijke constructie zorgt voor een zeer stabiel platform met in potentie zero-down-time deployment mogelijkheden.

Bij een Kubernetes (b.v. AKS) oplossing is er altijd een maximum aan memory en SPU- specificaties die men kan opgeven, dit gekoppeld aan de specificaties van de onderliggende nodes. Als men bijvoorbeeld Kubernetes nodes gebruikt met 2 CPU cores en 8Gb aan memory dan kunnen de containers nooit meer dan deze 2 CPU core en 8Gb aan memory gebruiken.  Ditzelfde geldt ook voor ACA, maar je hebt bij ACA geen vrijheid om het aan CPU core en hoeveelheid memory van de onderliggende nodes te selecteren. Dit betekent concreet dat men afhankelijk van het consumption plan de onderstaande maxima heeft.

  vCPU Memory
Consumption plan 2.0 4.0Gi
Consumption workload profile 4.0 8.0Gi

Networking

Een container orchestratie oplossing zorgt voor een sterke vereenvoudiging van de netwerk problematiek. Dit is voor ACA niet anders, denk hier bijvoorbeeld aan de volgende zaken:

1.Service discovery

Om services onderling met elkaar kunnen laten communiceren is het van belang dat deze elkaar eenvoudig kunnen vinden. ACA biedt hier de mogelijkheden dat de containers elkaar altijd kunnen vinden op basis van de containernaam. Daarnaast zijn er mogelijkheden om gebruik te maken van een custom domain naam, een FQDN of het later nog aan bod komende DAPR.

2.Toegangsniveaus

Het is een veel voorkomend scenario dat niet alle containers die men zal hosten binnen ACA publiek benaderbaar zullen zijn. Hier zijn mogelijkheden voor om expliciet aan te geven dat een container of “Extern” of “Intern” benaderbaar is. In het geval men de keuze maakt om deze extern benaderbaar te maken dan kun je ook nog kiezen om dit te doen op een specifiek VNet. Hiermee kun je bijvoorbeeld verkeer van en naar een container alleen beschikbaar maken via een VPN.

3.Load balancing

ACA maakt intern out-of-the-box gebruik van Envoy proxy om te routeren naar de juiste revisie van een container. Deze keuze is reeds gemaakt en staat vast. En je kunt dit niet aanpassen naar b.v. Traefik of Nginx. In het geval men 2 of meer instanties van dezelfde container in ACA host dan zal de load automatisch gelijk verdeeld worden over deze instanties.

4.Security

Door het gebruik van het eerder genoemde Envoy proxy zullen ook zaken als TLS termination je uit handen worden genomen. Daarnaast biedt ACA nog opties op bijvoorbeeld mutual TLS verbindingen tussen containers onderling op te zetten middels het later nog aanbod komende DAPR.

Revisies

Een krachtige feature die ACA biedt zijn de revisies om meerdere versies van een container te beheren. Met een revisie wordt het mogelijk gemaakt om een nieuwe versie van je app neer te zetten en snel terug te rollen in geval van een calamiteit. Maar deze feature geeft ook de mogelijkheid om 2 versies naast elkaar te draaien en middels A/B testing de “beste” versie te selecteren.  Ook zijn er mogelijkheden om middels Blue/Green deployment b.v. 20% van het verkeer door te sturen naar een nieuwe versie om te kijken of alles nog blijft werken.

Managed Identities

Vanuit ACA is het mogelijk om met veel van Azure resources een connectie te maken op basis van een managed identity uit Azure AD. Je kunt hier role-based access controle op toepassen. Daarnaast kun je deze managed identities automatisch aanmaken en verwijden en het zorgt er tevens voor dat je geen gebruikersnamen en wachtwoorden hoeft op te nemen in secrets, pipelines of code. Dit alles is voor de security een goede stap voorwaarts. Een casus waarop men dit kan toepassen is bijvoorbeeld een connectie naar Azure SQL of KeyVault.

Schaalbaarheid

Het eerder genoemde schaalbaarheid is een belangrijke reden om überhaupt containers te overwegen. ACA heeft hier gekozen om de breed geadopteerde standaard oplossing KEDA te implementeren. Elke eerde genoemde revisie kan schalen van 0 naar meerdere replica’s. Hier zitten wel limieten aan welke hieronder staan beschreven:

Scale limit Default value Min Value Max Value
Minimum number of replicas per revision 0 0 300
Maximum number of replicas per revision 10 1 300

 

Het is met KEDA ook mogelijk om de replica’s te laten schalen op allemaal verschillende, zelf te configureren regels. Denk bijvoorbeeld aan hoeveel load, of aantal berichten in een message queue.

DAPR

En “last but not least” het reeds eerder aangehaalde DAPR. DAPR (Distributed Application Runtime) is een open-source framework dat de ontwikkeling van gedistribueerde applicaties vereenvoudigt. Het biedt een reeks bouwstenen en runtimeservices die de complexiteit van gedistribueerde systemen abstraheren, zodat ontwikkelaars zich kunnen concentreren op de bedrijfslogica in plaats van de infrastructuur. Zo zorgt DAPR bijvoorbeeld dat de service-to-service (lees container naar container) communicatie veel robuuster wordt door middel van (standaard) retries en andere reliable messaging patronen.  Daarnaast heeft DAPR een abstractie laag om pub/sub messaging waardoor het zeer gemakkelijk wordt om de onderliggende service bus te vervangen. Hierdoor stelt DAPR  de ontwikkelaars in staat zich te focussen op logica en veel minder op randzaken.  Tevens heeft DAPR mogelijkheden om out-of-the-box Mutual TLS te communiceren tussen containers, dit zorgt voor een extra secure omgeving.

Microsoft heeft er dan ook voor gekozen om DAPR een standaard onderdeel van ACA te maken en het is optioneel bij elke container app aan of uit te zetten.

To ACA, or not to ACA?

Er zijn al met al veel verschillende opties om containers te hosten in Azure. Zo zijn er o.a. dus:

  • ACI (Azure Container Instances)
  • Web Apps for Containers
  • AKS (Azure Kubernetes Services)
  • ACA (Azure Container Apps)

Wanneer kies je nu welke optie? Deze keuze is afhankelijk van de specifieke organisatorische wensen, eisen en randvoorwaardes. Een belangrijke factor hierin is de groei ambitie richting containers. Als je maar zeer beperkt iets gaat doen met containers (hoog uit handjevol containers) dan is een eenvoudige container hosting (Optie B: b.v. ACI of Web Apps for Containers) te overwegen. Daarnaast als je bij voorbaat al weet dat je tegen de limitaties van ACA gaat aanlopen (b.v. ondersteuning windows containers of verplicht andere ingress controller van Envoy) dan is een full container orchestratie oplossing (Optie A: AKS) wellicht een betere optie.

Maar voor alle gevallen waarbij je als organisatie ambities hebt om meer dan een handvol containers te gaan gebruiken in de cloud is ACA de meest valide optie. Dit geeft een zeer sterk platform voor eenvoudige container hosting. Daarnaast heb je toch de mogelijkheid om gebruik te maken van de geavanceerde features (b.v. DAPR of KEDA) zonder al te veel effort. Tevens zijn de kosten navenant het gebruik en er zijn geen up-front kosten en bij een kleine start dus ook laag. ACA heeft naar ons inzien een minimale leercurve ten opzichte van ACI of Web Apps for containers maar biedt het gelijksoortige functionaliteit als een veel complexer platform zoals AKS. Concluderend is Azure Container Apps een zeer sterke container hosting propositie van Microsoft in hun Azure portfolio met weinig nadelen. Wat ons betreft een aanrader om mee aan de slag te gaan.

Hartelijke groet,
Patrick Bes

Technical Lead Consultant
Bergler Software Solutions

Al dit soort onderwerpen, zoals futureproof software ontwikkelen, onze TechRadar en méér, kwamen ook terug in onze Managers Inspiratie Sessie van 21 maart. Via deze link kun je je inschrijven voor de nieuwe sessie. Je bent van harte welkom.