Hoe installeer je Istio Service Mesh: een uitgebreid stappenplan
Istio is een van de meest bekende Service Mesh tools. Het fungeert als een proxy tussen services. Istio Service Mesh maakt het mogelijk om communicatie tussen services makkelijk te beheren, bewaken, beveiligen en schalen, zonder dat je deze functionaliteiten in de applicatiecode hoeft te implementeren. In dit artikel laten we stap voor stap zien hoe je Istio Service Mesh installeert. We tonen ook verschillende voorbeelden van de werking van Istio Service Mesh.
In ons eerste blogartikel “Istio Service Mesh: wat is het en wat zijn de voordelen” hebben we uitgelegd wat Istio Service Mesh precies is en wat de voordelen ervan zijn. In dit artikel gaan we meer in detail en tonen we hoe je Istio in de praktijk implementeert en toepast.
Istio installeren via istioctl: stap voor stap
Er zijn twee door Istio ondersteunde manieren om Istio te installeren:
- Via istioctl
- Door gebruik te maken van Helm charts
In dit artikel richten we ons op de eerste methode.
STAP 1: Voorbereiding en documentatie
Voordat we in de installatie duiken, is het cruciaal om de officiële documentatie te raadplegen. Check ook de compatibiliteitsmatrix om te controleren welke versie van Istio compatibel is met je Kubernetes-versie.
Met behulp van de istioctl tool gaan we een configuratiebestand toepassen op de cluster. Dit configuratiebestand zorgt ervoor dat de nodige componenten geïnstalleerd worden:
- Een ingressgateway die de binnenkomende trafiek zal behandelen
- Een egressgateway die de uitgaande trafiek zal behandelen
- Istiod control plane die onder meer het afhandelen van certificaten zal behandelen
- Een istio-proxy sidecar container die wordt toegevoegd aan iedere pod die in de cluster draait
STAP 2: istioctl downloaden en installeren
Je kan Istioctl installeren
- Door de volgende oneliner uit te voeren. Dit zal de laatste versie voor jouw architectuur downloaden:
curl -L https://istio.io/downloadIstio | sh -
- Of door een specifieke versie te installeren. Dit kan door bepaalde environment variables mee te geven:
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.1 TARGET_ARCH=x86_64 sh -
STAP 3: IstioOperator.yaml file aanmaken
Een vereenvoudigde setup voor de aanmaak van een IstioOperator.yaml file met informatie over de gewenste configuratie van de Service Mesh zou er als volgt kunnen uitzien:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
finalizers:
- istio-finalizer.install.istio.io
name: istio-controlplane
namespace: istio-system
spec:
components:
base:
enabled: true
egressGateways:
- enabled: true
name: istio-egressgateway
namespace: istio-system
k8s:
replicaCount: 2
ingressGateways:
- enabled: true
name: istio-ingressgateway
namespace: istio-system
k8s:
replicaCount: 2
pilot:
enabled: true
profile: default
values:
global:
proxy:
resources:
limits:
memory: 100Mi
requests:
memory: 100Mi
pilot:
replicaCount: 2
Deze yaml file beschrijft de configuratie van dat volgende componenten:
- 2x istio-ingressgateway container
- 2x istio-egressgateway container
- 2x istiod container (in de yaml file wordt de oude naam gebruikt: "pilot")
- Voor proxy sidecars stellen we een limiet van 100Mi memory in, deze zal als extra container in je applicatie pods draaien
STAP 4: Configuratie toepassen met upgrade-mogelijkheid
Om bovenstaande configuratie toe te passen, voer je het volgende commando uit:
~/istio-1.20.1/bin/istioctl install --set revision=1-20-1 -f IstioOperator.yaml
We voegen een revisie toe aan ons installatiecommando om een nieuwere versie van Istio te installeren langs de bestaande versie. Nadat dit is gedeployed en gevalideerd, kunnen we volledig overschakelen naar de nieuwe versie. Dit is een cruciale stap om upgrades mogelijk te maken zonder downtime.
Het is belangrijk op te merken dat we het installatiecommando meerdere keren kunnen uitvoeren. Zelfs voor eenvoudige wijzigingen zullen we dit commando gebruiken. Dit komt doordat Istioctl de "reconciliation"-methode hanteert. De gevraagde configuratie in het IstioOperator.yaml-bestand wordt vergeleken met de huidige status op het cluster. Alleen de noodzakelijke wijzigingen om de beschreven situatie te bereiken, worden uitgevoerd.
Na het uitvoeren van het installatiecommando worden de volgende PODs toegevoegd aan de cluster:
NAME READY STATUS RESTARTS
istio-egressgateway-f66c5597-9t9g8 1/1 Running 0
istio-egressgateway-f66c5597-p4nsq 1/1 Running 0
istio-ingressgateway-58bcd84f68-fqxhz 1/1 Running 0
istio-ingressgateway-58bcd84f68-sdqjv 1/1 Running 0
istiod-1-20-1-5558b9b4f6-p8kw7 1/1 Running 0
istiod-1-20-1-5558b9b4f6-pchdv 1/1 Running 0
STAP 5: Sidecar containers toevoegen aan PODs
Nadat istiod, ingress-gateway en egress-gateway zijn geïnstalleerd, is het noodzakelijk om ervoor te zorgen dat de proxy sidecar-containers aan onze applicatie-POD's worden toegevoegd. Allereerst moeten we "istio-injection" configureren door een label toe te voegen aan de namespace waarin de applicatie wordt uitgevoerd.
apiVersion: v1
kind: Namespace
metadata:
name: maildev
labels:
istio-injection: enabled
Vervolgens kunnen we een rolling restart doen van de applicatie. Hierdoor start elke container opnieuw op met een sidecar container.
Merk op dat er 2 van de 2 containers ready zijn:
Bovenstaand proces dient uitgevoerd te worden voor elke applicatie:
NAME READY STATUS RESTARTS
maildev-544f69466b-lp4hg 2/2 Running 0
De volledige installatieflow
We kunnen de volledige installatieflow als volgt weergeven:
De volledige installatieflow volgt de volgende stappen:
- Trafiek komt binnen op de ingress gateway
- De ingress gateway stuurt trafiek door naar de proxy van applicatie 1
- Trafiek gaat door naar de proxy van applicatie 2
- Trafiek gaat via een egress gateway naar buiten
Merk op dat zowel de ingress-gateway, de proxy sidecar-containers als de egress-gateway gebruik maken van een Envoy proxy. Alle communicatie vindt plaats via mutual SSL, wat automatisch wordt geconfigureerd zodra de sidecar-containers zijn toegevoegd. De istiod-toepassing beschikt over een certificate authority die automatisch certificaten genereert om het verkeer tussen de verschillende Envoy proxies te versleutelen. Het versleutelen van het verkeer is een belangrijke reden om te kiezen voor Istio Service Mesh.
Trafiek tot bij onze applicatie krijgen
Nu we de Istio Service Mesh operationeel hebben, streven we er eerst naar om trafiek via de ingress-gateway naar onze applicaties te leiden. In dit geval maken we geen gebruik van de standaard "Ingress" resource die Kubernetes standaard biedt. Istio voegt namelijk enkele mogelijkheden op het gebied van traffic management toe die niet kunnen worden gerealiseerd met een Ingress-object. Daarom levert Istio zijn eigen Custom Resources.
In dit scenario zullen we een Gateway en een VirtualService object gebruiken. Wanneer deze resources aan de cluster worden toegevoegd, wordt op basis van de ingevoerde configuratie de Envoy-proxyconfiguratie gegenereerd. Deze configuratie zorgt ervoor dat trafiek naar de applicatie mogelijk is. In eerste instantie maken we een Gateway-object aan.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: default-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
Vervolgens maken we een VirtualService aan:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: maildev
namespace: maildev
spec:
hosts:
- "maildev.example.com"
gateways:
- istio-system/default-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: maildev
Deze verwijst naar een maildev service die vervolgens naar de PODs in kwestie zal verwijzen.
Volgend diagram stelt dit visueel voor:
Voorbeelden van Traffic Management met Istio
We zijn er nu in geslaagd om trafiek naar onze applicatie te sturen. Met behulp van Istio zijn er echter nog veel complexere scenario's mogelijk. Ik wil wat dieper ingaan op een deel van deze mogelijkheden. Een volledige lijst is te vinden in de officiële documentatie: https://istio.io/latest/docs/tasks/traffic-management/
In de volgende voorbeelden wordt het verkeer gerouteerd tussen verschillende versies van een applicatie. Voordat we deze versies van de applicatie kunnen benaderen, moeten de nodige resources worden aangemaakt. Er moet een deployment en bijbehorende service worden aangemaakt, zoals beschreven in de "reviews" sectie op https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml
Vervolgens moeten er DestinationRules worden aangemaakt voor elke versie, zoals beschreven in het gedeelte over "reviews" op https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/networking/destination-rule-all.yaml
Request Routing
Bij request routing leiden we een deel van de trafiek naar een andere versie van de applicatie. In onderstaand voorbeeld wordt standaard de trafiek naar "reviews v1" geleid. Dit verandert echter als de header "end-user" de waarde "jason" bevat; in dat geval wordt de trafiek naar versie 2 gestuurd. Het principe van request routing kan handig zijn wanneer je een nieuwe versie van een applicatie wil implementeren, maar deze eerst nog een laatste keer grondig wil testen voordat je deze openstelt voor het grote publiek.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
Traffic Shifting
Bij traffic shifting gaan we het principe van weighted routing toepassen.
We gaan een deel van de requests naar versie 1 sturen en een ander deel naar versie 2.
Dit kan nuttig zijn voor een geleidelijke migratie naar een nieuwe versie.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 50
- destination:
host: reviews
subset: v2
weight: 50
Fault Injection
Bij fault injection voegen we opzettelijk fouten toe, zoals vertragingen of foutcodes, om te onderzoeken hoe onze configuratie hierop reageert. Dit is nuttig om misconfiguraties te identificeren, bijvoorbeeld in de time-outs op load balancers versus time-outs in Envoy versus time-outs op het applicatieniveau, en om bottlenecks op te sporen.
In het volgende voorbeeld voegen we een delay van 7 seconden toe aan verzoeken naar versie 1 van de applicatie, maar alleen voor verzoeken met de header "end-user" en de waarde "jason". Alle andere requests worden niet beïnvloed door deze configuratie en worden zoals gebruikelijk afgehandeld.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- ratings
http:
- fault:
delay:
fixedDelay: 7s
percentage:
value: 100
match:
- headers:
end-user:
exact: jason
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
Een andere mogelijke fout die je kan introduceren, is het genereren van een foutcode door het fault block van het vorige voorbeeld te vervangen. Hierdoor zal de Envoy-proxy telkens een HTTP 500-fout teruggeven voor verzoeken met de "end-user" header en de waarde "jason".
- fault:
abort:
httpStatus: 500
percentage:
value: 100
Security Policies met Istio
Ook vanuit beveiligingsperspectief zijn er verschillende configuraties mogelijk met behulp van Istio. Hieronder behandelen we er enkele, maar voor meer details kan je terecht op: https://istio.io/latest/docs/tasks/security/.
Encryptie van verkeer binnen de mesh
Zoals eerder vermeld, bevat istiod een certificate authority. Zodra de Istio-sidecars zijn toegevoegd aan de applicatie-POD's, wordt het verkeer tussen de verschillende applicaties versleuteld. Dit heeft als bijkomend voordeel dat alles met betrekking tot encryptie niet langer door de applicatie zelf moet worden afgehandeld.
Authentication Policies
Wanneer de identiteit moet worden geverifieerd voordat iemand kan inloggen, kan dit proces via Istio verlopen. Istio controleert of de gebruiker een geldig JWT-token heeft om toegang te krijgen tot de applicatie. Dit wordt geconfigureerd met een RequestAuthentication-object en een aanpassing in de VirtualService. Het RequestAuthentication-object activeert JWT-validatie voor onze applicatie.
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: application-jwt-validation
namespace: application
spec:
selector:
matchLabels:
app: application
jwtRules:
- issuer: "https://customer-prd.eu.auth0.com/"
jwksUri: "https://customer-prd.eu.auth0.com/.well-known/jwks.json"
forwardOriginalToken: true
Daarna stellen we onze applicatie in zodat de gebruiker alleen toegang heeft wanneer de claim een specifieke waarde bevat.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: application
namespace: application
spec:
...
http:
- match:
- uri:
prefix: /v1/
headers:
"@request.auth.claims.groups":
exact: application-users
route:
- destination:
port:
number: 80
host: application
EOF
Merk op dat de configuratie van authenticatie niet langer rechtstreeks in de applicatie hoeft te worden geconfigureerd; dit wordt nu afgehandeld door Istio. Dit resulteert in minder complexiteit in de applicatie setup en meer consistentie in de afhandeling van authenticatie voor verschillende applicaties binnen de cluster.
Authorization Policies
Met AuthorizationPolicies hebben we de mogelijkheid om toegang tot de applicatie te beheren. Een eenvoudig voorbeeld is het weigeren van toegang tot een specifiek pad voor iedereen. Bijvoorbeeld, je zou een bepaald endpoint kunnen hebben dat niet beschikbaar moet zijn van buitenaf, maar wel intern toegankelijk moet zijn voor specifieke acties.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: application-deny-elasticsearch-clear
namespace: application
spec:
selector:
matchLabels:
app: application
action: DENY
rules:
- to:
- operation:
paths: ["/v1/services/elasticsearch/clear*"]
Andere voorbeelden:
- Toegang weigeren wanneer een bepaalde header ontbreekt.
- Toegang weigeren op basis van de inhoud van het verkregen JWT-token, bijvoorbeeld niet lid van groep "admin".
- Enkel bepaalde HTTP-methods toelaten op een endpoint, bijvoorbeeld enkel GET en geen POST.
Observability met Istio
De laatste belangrijke feature die we gaan bespreken is observability. Dit betekent het verzamelen van metrieken en logs en het toepassen van distributed tracing.
Hieronder focussen we specifiek op tracing; voor informatie over de andere aspecten kan je terecht in de documentatie: https://istio.io/latest/docs/tasks/observability/.
Distributed Tracing
Istio maakt gebruik van de distributed tracing mogelijkheden van Envoy om het verloop van de trafiek in kaart te brengen.
Dit proces werkt als volgt:
- De trafiek komt binnen via de ingress gateway, die een specifieke header voor tracing toewijst.
- Wanneer de trafiek vervolgens wordt doorgestuurd naar de applicatie-POD, wordt de tracing-header meegestuurd.
- Als de trafiek vervolgens nogmaals wordt doorgestuurd (bijvoorbeeld naar Kafka), wordt dezelfde header opnieuw meegestuurd.
Hierdoor is dezelfde header bekend tussen de ingress gateway, de applicatie en Kafka. De tracing-informatie tussen twee objecten, zoals de ingress gateway en de applicatie, wordt een "span" genoemd. Meerdere spans kunnen, wanneer ze dezelfde informatie in de header bevatten, worden gecombineerd tot een "trace".
In dit voorbeeld is er dus een trace die van de ingress gateway via de applicatie naar Kafka loopt.
De spans en traces kunnen visueel worden weergegeven in tools zoals Kiali en Jaeger. De onderstaande screenshot toont de visualisatie van tracing in Kiali.
Op basis van tracing-informatie werd automatisch de volgende flow in kaart gebracht:
- Er is een applicatie genaamd CRM.
- Er loopt trafiek tussen de ingress-gateway en de CRM-applicatie.
- Er loopt verkeer tussen de CRM-applicatie en Kafka.
- Kafka gebruikt zookeeper om te clusteren.
- De meerdere zookeeper nodes in de cluster praten ook met elkaar.
Dit voorbeeld illustreert hoe je met behulp van distributed tracing automatisch inzicht kan krijgen in de applicaties en connecties binnen de Service Mesh.
De Voordelen van Istio Service Mesh
Na het bespreken van de features van Istio Service Mesh, benadrukken we de belangrijkste voordelen:
- Versleuteling van trafiek: De trafiek binnen de cluster wordt geëncrypteerd en de benodigde certificaten worden automatisch beheerd door Istio.
- Uniformiteit en vereenvoudiging: Verantwoordelijkheden zoals login, authenticatie en encryptie worden weggenomen van de applicatie, wat leidt tot een uniforme en sterk vereenvoudigde setup.
- Versiebeheer: Routing rules maken het mogelijk om nieuwe versies van applicaties beschikbaar te stellen voor een beperkt publiek.
- Robuuste testing: Testmogelijkheden zoals traffic shifting en fault injection dragen bij aan robuustheid.
- Dynamisch overzicht: Distributed tracing biedt een automatisch en up-to-date overzicht van de gehele stack.
Meer Informatie over Istio
Wil je meer weten over Istio? Raadpleeg dan de officiële documentatie van Istio of lees het boek "Istio in action", een technisch diepgaande, maar heldere weergave van Istio.
Wil je snel antwoord op al je vragen over Istio Service Mesh?