~~META: title = Voorwaarden voor hosting in CHP ~~ {{htmlmetatags> metatag-keywords=(voorwaarden hosting CHP technisch procedureel) metatag-og:title=(Voorwaarden voor hosting in CHP) metatag-og:description=( FIXME ) }} ====== Voorwaarden voor hosting in CHP ====== Team H&S raadt aan om een aantal punten in acht te nemen bij het draaien van websites of applicaties in CHP. Deze vallen onder te verdelen in technisch en procedureel: ====== Technische Voorwaarden ====== * Open Source of .NET runtime, containerized * Static assets afsplitsbaar naar apart CDN * Draai databases en andere stateful componenten als service in AWS * Caching * Pas op met persistent volumes * 1 [[https://kubernetes.io/docs/concepts/workloads/pods/|pod]] is geen pod. * Versturen van mail ===== Open Source of .NET runtime, containerized ===== CHP is gebouwd op [[https://docs.openshift.com/container-platform/4.12/welcome/index.html|Redhat Openshift]], wat weer gebouwd is op [[https://kubernetes.io/docs/concepts/overview/|Kubernetes]], wat geinspireerd is op [[https://en.wikipedia.org/wiki/Docker_(software)|Docker]], wat een [[https://www.aquasec.com/cloud-native-academy/container-platforms/container-platforms-6-best-practices-and-15-top-solutions/|containerplatform]] is. Op [[https://hub.docker.com/|dockerhub]] zijn vele vele containers te vinden voor allerhande runtimes (php, java, node.js, enz enz). Vanwege de vereiste van Openshift dat containers [[https://developers.redhat.com/blog/2020/10/26/adapting-docker-and-kubernetes-containers-to-run-on-red-hat-openshift-container-platform#|rootless]] draaien kunnen niet alle docker hub containers 1-op-1 draaien in Openshift, maar het geeft wel een idee van wat er allemaal beschikbaar is. De volgende runtimes worden veel gebruikt: * PHP * Node.JS * Ruby * Python * Java * .NET Ondersteunend daaraan zijn onderstaande componenten: * Apache * Nginx * Mysql / MariaDB * PostgresQL * Redis * Elasticsearch Ook andere programmeertalen en databases kunnen gebruikt worden, maar zijn wel wat minder alomtegenwoordig. ===== Static assets afsplitsbaar naar apart CDN ===== Static assets zijn alle onderdelen van een website of applicatie die niet on-the-fly door de code gegenereerd worden. Denk hierbij aan plaatjes, css en javascript. Wij adviseren om deze assets onder te brengen bij het image CDN (Scalia) en **niet** om ze in een "persistent volume" (PVC) in een pod op te slaan. De redenen hiervoor zijn: - Het datatraffic vanuit het image CDN is een factor 10 goedkoper dan wanneer dezelfde images vanuit PVC geserveerd worden (want dan komt het vanuit AWS en dat datatraffic is duur) - Opslag is goedkoper per Gbyte. - Het image CDN schaalt beter bij grote aantallen plaatjes - Backup is beter geregeld Het "afsplitsbaar zijn" houdt in dat de assets vanaf een andere URL geserveerd moeten kunnen worden. Stel de site in CHP draait op www.xrtv.nl, dan * FOUT: www.xrtv.nl/assets/* Omdat zowel de assets als de site zelf draaien onder www.xrtv.nl kunnen deze niet op een apart CDN draaien. * GOED: assets.xrtv.nl/* De site kan nu draaien op www.xrtv.nl, terwijl assets.xrtv.nl verwijst naar het image CDN. ===== Draai databases en andere stateful componenten als service in AWS ===== Het is technisch heel goed mogelijk om binnen Openshift een database pod te draaien. En voor test en acceptatie doeleinden is dat ook prima. Maar voor productieomgevingen raden weaan om dit soort stateful componenten (denk bv ook aan elasticsearch) als managed service binnen AWS af te nemen. De redenen hiervoor zijn: * Backup moet je zelf regelen als je de database in een eigen pod draait * Verticaal schalen (**sterkere** hardware) is lastig in eigen pods. * Horizontaal schalen (**meerrrr** servers) is lastig met databases. ===== Caching ===== Voor een schaalbare website is caching vaak heel belangrijk. Maar in CHP is er niets dat uit zichzelf caching doet. Wij adviseren om altijd [[https://www.ietf.org/rfc/rfc2616.txt|RFC2616]] http caching te gebruiken (dwz: genereren van ''Cache-Control'' en ''Expires'' headers in de applicatie, zodat de webserver kan weten wat en hoelang er gecached kan worden). Maar, ook als de applicatie de juiste headers genereert betekent dat nog niet dat die data gecached wordt. Daar is een webserver voor nodig om dat te doen. Hiervoor zijn 2 mogelijkheden: - gebruik maken van AWS Cloudfront - een eigen (nginx) pod draaien die geconfigureerd is om content te cachen. Voor high-volume websites is Cloudfront een goede keuze. Voor de rest adviseren we om een nginx container te gebruiken. ===== Persistent volumes ===== Persistent volumes zijn bedoeld om state op te slaan die niet zomaar weg mag (vandaar "persistent"). Maar denk vantevoren goed na over wat voor state dat dan kan zijn. Idealiter is er niet zoveel van dat soort state namelijk: * Databases kunnen als AWS service leven. In het geval dat je een eigen database pod draait, //dan// heb je een persistent volume nodig om de state van die database op te slaan. * Static assets (plaatjes e.d.) is een andere vorm van state die je in een persistent volume op zou kunnen willen slaan. Maar, ons advies is dus (zie boven) om dat niet zo te doen en deze assets op het CDN te laten landen. * Allerlei caching zaken (denk bv aan de nginx http cache hierboven) hebben wel storage nodig, maar dat hoeft niet //persistent// te zijn. Het is niet erg als de storage opeens weg is, omdat een cache weer opnieuw opgebouwd kan worden. Caching spullen kunnen daarom beter op zogeheten "ephemeral" storage liggen dan op persistent storage. * Ook allerlei werkruimte op een filesysteem die een applicatie nodig zou kunnen hebben (denk bijvoorbeeld aan een plekje om misschien files te converteren ofzo) kan beter op ephemeral storage dan op persistent storage liggen. Dus er zijn wel use cases voor persistent storage, maar veel andere use cases zijn beter gediend bij andere oplossingen. Als je applicatie //toch// persistent storage nodig heeft, denk dan na over de volgende zaken: * Moet deze storage gedeeld worden tussen verschillende pods? Als dat niet nodig is, dan is het beter om per pod een prive stukje persistent storage aan te vragen (rwo ipv rwx) Dit is omdat row storage efficienter is dan rwx storage. * Hoeveel bestanden gaan erop landen? Bij het starten van een pod worden alle bestanden stuk voor stuk voorzien van de juiste security context. Indien er sprake is van veel (>1000) bestanden is het checken daarvan dermate zwaar dat de pod er erg lang over doet om op te starten //en// dit veroorzaakt een grote load op het achterliggende storage systeem. Concluderend: * persistent volumes alleen gebruiken als het strict noodzakelijk is. * liever eigen storage (rwo) dan gedeelde storage (rwx) * niet geschikt voor duizenden bestanden ===== 1 pod is geen pod ===== Applicaties die draaien in openshift moeten er rekening mee houden dat elke pod die onderdeel maakt van de applicatie op elk moment gestopt kan worden door het systeem en eventueel elders weer opgestart kan worden. Dit is namelijk een gevolg van de automatische schaling (als het druk is worden er pods bijgemaakt, wordt het daarna weer rustiger dan worden deze pods weer gestopt) en de self-healing in het cluster (als een stuk onderliggende hardware een probleem heeft kan het systeem besluiten alle pods die daar draaien te verhuizen naar een andere node. De pod in kwestie zal dan dus gestopt worden en ergens anders weer opgestart worden). Dit betekent dat een HA applicatie niet exclusief kan leunen op het altijd bestaan van 1 pod. Die pod zou namelijk zomaar eventjes weg kunnen zijn. Het meest sprekende voorbeeld zijn applicaties die gebruik maken van redis. Redis is een key-value store. Als er maar 1 redis container draait, dan zal de applicatie waarschijnlijk stuk gaan op het moment dat die container even verhuisd wordt naar een andere node. Het is dus zaak om ervoor te zorgen dat er geen single points of faillure in de applicatie zijn, zoals in het voorbeeld hierboven de enkele redis pod. De oplossing hiervoor is om gebruik te maken van clustering oplossingen. Bijvoorbeeld bij redis is het mogelijk om een dit zodanig te draaien dat er altijd meerdere pods zijn die elkaar onderling in de gaten houden en data onderling kunnen repliceren, zodat als er 1 pod down gaat, de dienst als geheel onverstoord door kan draaien. ===== Versturen van mail ===== Dit kan uitsluitend via [[:chp:handleiding:aws_ses_aanvragen|Simple Email Service]] (SES) ====== Procedureel ====== * [[https://en.wikipedia.org/wiki/DevOps|DevOps]] capability, naast dev ook ops. * [[https://en.wikipedia.org/wiki/CI/CD|CI/CD]] * Applicatiemonitoring en alerting op orde ===== DevOps ===== Taken die traditioneel meer aan de operationele kant zaten, zoals het configureren van een webserver, vallen in een DevOps platform als Openshift opeens onder de verantwoordelijkheid van het team dat de applicatie maakt ("dev") en niet meer onder het team dat het platform als geheel in de lucht houdt ("ops"). Dat betekent dat er in ontwikkelteams meer kennis moet zijn van operationele zaken. Houd daar bij de samenstelling van ontwikkelteams rekening mee. Een taak die hier ook onder valt is het bijhouden van software versies. Als de gebruikte software in een pod verouderd is en mogelijk security problemen heeft, dan is het de verantwoordelijkheid van het ontwikkelteam op deze weer up-to-date te krijgen. ===== CI/CD ===== Wij raden sterk aan om een CI/CD straat in te richten om op deze manier de development en deployment van applicaties gestroomlijnd te hebben. Hierdoor wordt het makkelijker om wijzigingen in de codebase door te voeren en deze door te zetten naar de productie omgevingen. ===== Applicatiemonitoring en alerting op orde ===== Het is mogelijk dat het platform als geheel het prima doet, maar dat applicaties die erin draaien het niet meer doen. Voorbeelden hiervan kunnen zijn dat er wordt geleund op een single instance pod en dat die pod ermee opgehouden is. In zo'n geval werkt het platform prima (je zou tenslotte zo weer een nieuwe pod kunnen starten als je wilt) maar is de applicatie wel down. Omdat het platform het goed doet gaan er bij de platformbeheerders (de medewerkers van team H&S) geen alarmbellen af. Het is dus zaak je eigen alarmbellen in te bouwen die monitoring op applicatieniveau doen. En mocht er een alarmbel afgaan (b.v. buiten kantoortijd) procedures te hebben om ervoor te zorgen dat hier ook opvolging aan wordt gegeven.