Voting app architectuur
Deze directory bevat alle bestanden die nodig zijn om een voting app te deployen in een kubernetes cluster. De deployments voldoen niet aan de richtlijnen van het FD en zullen dan ook alleen deployen in een namespace waarop de juiste labels zijn geplakt om de PSA tolerant te maken.
Daarnaast kan er nog veel meer verbeterd worden aan deze deployments. Daarover later meer.
Vanuit een user perspectief zijn er twee web interfaces waarop of een stem kan worden uitgebracht of waarop de uitslag van de stemmen wordt getoond.
Praktisch gezien ziet de totale app, opgebouwd uit microservices, er als volgt uit:
┌──────────────┐ ┌───────────┐
│ voting app │ │result app │
│ (Python) │ │(NodeJS) │
└──────┬───────┘ └────▲──────┘
│ │
│ │
│ │
┌──────▼───────┐ ┌────┴───────┐
│ in-memory DB │ │db │
│ (redis) ├────┐ ┌──────►│(PostgresQL)│
└──────────────┘ │ │ └────────────┘
│ │
│ │
│ │
│ │
┌─▼───────┴─┐
│worker │
│(dotNet) │
└───────────┘
Opdracht 1, uitchecken en deployen in een namespace
Het doel is om deze app werkend te krijgen in het ontwikkel cluster in een namespace met je eigen naam. Deze is onderdeel van project LAB en moet zo ingesteld zijn dat de PSA heel tolerant is.
- Check de repo uit
- Pas de URL's aan in de
ingressdefinities. - Probeer deze met
kubectl applyte deployen in de namespace met jouw naam. - Als stap 3 niet lukt pas dan dingen aan zodat het wel lukt.
- Test de URL's.
Opdracht 2, maak de database persistent
Het doel is om de postgres database data te laten persisteren. Eigenlijk is een deployment niet geschikt voor databases. Een statefulset past beter.
- Zet de manifest file voor de database om in een manifest voor een statefulset met een PVC. Laat je inspireren door deze: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#components.
- Als alles goed gaat kun je de database pod deleten zonder dat de stemmen verloren gaan.
Opdracht 3, zorg dat de containers een readonly filesystem hebben
Een van de, vaak eenvoudige, dingen om te doen is containers te laten draaien met een readonly root filesystem. Binnen het FD is dat een vereiste.
- Verander de deployments en statefulsets zodanig dat de pods allemaal een readonly root filesystem hebben. Waar schrijfacties toch nodig blijken mount je een
emptyDir. Hier staat iets uitgelegd: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ en hier ook: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir. Ook het commandodocker diffkan waardevolle informatie verschaffen.
Opdracht 4, voeg een seccompProfile toe
Dit is een vereiste voor deployments in FD clusters. Het beperkt wat een proces in een container aan calls naar de kernel mag maken.
- Verander alle deployments zodat deze profiel
RuntimeDefaultgaat gebruiken. Zie https://kubernetes.io/docs/tutorials/security/seccomp/#create-a-pod-that-uses-the-container-runtime-default-seccomp-profile
Opdracht 5, non root....
Wellicht de moeilijkste opdracht is om de containers met een andere uid dan 0 te laten draaien. Root privileges zijn vaak nodig om lage netwerkpoorten te openen. Ook zullen sommige containers root vereisen om scripts uit te voeren en vervolgens zelf omschakelen naar een andere uid.
Hou er bij deze opdracht rekening mee dat poortnummers door services gemapt worden. Bij dotNet containers kun je gebruik maken van omgevingsvariabelen om naar een non privilegd poort te switchen. Er is geen eenduidige manier om het voor elkaar te krijgen.
- Waar mogelijk pas je de deployment aan zodat deze zonder
rootrechten draait. Aangezien je een readonly root filesystem hebt ben je al een eind met permissies. Eventieel kun je deze aanpassen volgens https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
Opdracht 6, probes
Goede probes mogen niet ontbreken. Er zijn twee scripts die gebruikt kunnen worden voor redis en postgresql. Voor de overige containers is http(s) wellicht voldoende? Scripts zijn relatief duur (in termen van resources) dus misschien iets minder vaak gebruiken?
- Voeg de scripts toe aan de deployment door ze in een configmap te verpakken en deze te mounten binnen de container.
- Configureer alle readiness probes op netwerk niveau, waar mogelijk met http(s) en anders op tcp socket. 1 foutieve poging zou gelijk not ready moeten triggeren. 1 succesvolle check is ready. Het interval voor de services waar gebruikers direct mee te maken hebben stel je in op 1 seconde. Het interval voor de overige services op 5 seconden.
- Voeg een livenessprobe toe op basis van de scripts. Voer deze iedere 10 seconden uit. 2 failures betekent een restart van de pod, 1 keer succes betekent een reset. Lukt het om de pod te starten? Ook met een lege PVC zonder database? Wellicht heb je een startup probe nodig?
Opdracht 7, resource management
Goede deployments houden rekening met defecten in applicaties. Een memory leak op een VM of BM systeem kan desastreus zijn. Hieren spelen resource limits een belangrijke rol. Tegelijkertijd willen we geen pods plaatsen op nodes met (te) weinig vrije resources of resources claimen die nooit gebruikt gaan worden.
- Benchmark je applicaties. Dit kan met
ab,siegeof een andere applicatie. Metsiege:siege -v -b -r 10 https://xxxxxxxx.ont-cluster-1.fiod.fd.local/ - Kijk naar het resource gebruik. Prometheus is hier een goede tool voor.
- Stel op basis van je bevindingen de
requestsenlimitsin voor geheugen en CPU. - Test je applicatie nu steviger en kijk of deze overeind blijft.
- Is het gegeven voorbeeld van het
siegecommando wel juist? Een test met eenGEToperatie is misschien niet de beste test?
Opdracht 8, nieuwere versies van images
De gebruikte images zijn niet allemaal recent en bevatten mogelijk meer CVE's dan wenselijk.
- Kijk of er nieuwe images beschikbaar zijn. Haal deze eventueel binnen mbv Harbor als ze lokaal nog niet bestaan.
- Pas deployments aan waar nodig.
Opdracht 9, helm templating
In de huidige deployment is vrijwel alles hard coded. Templating van deze code kan de uitwisselbaarheid vergroten. Ook kan de applicatie dan meerdere keren worden gedeployed op hetzelfde cluster door alleen maar een verandering in naam en eventueel wat aanpassingen in parameters.
- Zet de deployment om in een helm chart waarbij minimaal de volgende items parameters worden:
a. DNS naam voting ingress b. DNS naam result ingress c. image namen d. image tags
Let op dat de PVC's ook flexibele namen krijgen...