sterretje-cluster:cluster-hosting_opbouw-omgeving

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sterretje-cluster:cluster-hosting_opbouw-omgeving [2020/05/20 05:30]
sterretje-cluster:cluster-hosting_opbouw-omgeving [2020/09/09 11:26] (current)
Line 1: Line 1:
 +===== Opbouw van de omgevingen =====
 +Het hart van de omgeving is de storage server.
 +Hier ligt alle data van alle andere servers opgeslagen.
 +De lokale disken van de andere servers bevatten alleen het OS.
 +Het voordeel van
 +deze opzet is dat als er een server uit mocht vallen, deze zeer snel te
 +vervangen is door een reserveserver. Omdat er geen data op de uitgevallen
 +server staat, hoeft er geen restore uitgevoerd te worden en kan de
 +reserverserver zeer snel weer online zijn.
 +De storage server zelf is o.a. geselecteerd op z'n betrouwbaarheid,​ zodat
 +de kans dat deze uitvalt zeer gering is.
 +
 +Middels NFS over een prive netwerk is de storage server gekoppeld aan
 +de frontproxy-,​ applicatie- en database servers. Deze servers zijn
 +op hun beurt via een publiek netwerk (en een tussenliggende router)
 +aan het internet verbonden. ​ Op de router gebeurt afscherming,​ zodat
 +alleen http verkeer (webserving) en ssh verkeer (uploaden bestanden)
 +tussen het internet en de servers mogelijk is.
 +Daarnaast vindt op de hosts zelf ook afscherming plaats, zodat er geen
 +ongeoorloofd verkeer tussen verschillende servers in hetzelfde cluster
 +mogelijk is.
 +
 +In onderstaand overzicht zijn 4 servers getekend,
 +in werkelijkheid zijn dit er in het appcluster nu bijna 30. Het geheel van
 +alle servers tezamen vormt het hosting cluster.
 +
 +{{omgeving.gif|upload-,​ proxy,​app,​db- en storageservers}}
 +
 +==== Instanties ====
 +Een belangrijk concept in het cluster is dat van een "​instantie"​.
 +Een instantie is de combinatie van een proces en resources behorende bij
 +zo'n proces (met name storage en een eigen IP adres)
 +Bekendste voorbeeld is een database instantie.
 +Daar heb je dus het database proces en de on-disk data files waar
 +het database proces op werkt.
 +Maar, ook van andere diensten kan je een instantie hebben. Denk aan een
 +webserver instantie. Een proces ("​apache"​) in combinatie met storage
 +(o.a. de documentroot van een website) waar dat proces wat mee doet.
 +
 +Dit concept is zo belangrijk, omdat de individuele nodes (servers) in
 +het cluster "​instantie agnostisch"​ zijn opgezet. Dwz er is geen binding
 +tussen een node en een instantie. Een instantie kan draaien op node
 +A, maar net zo goed op node B. (bedenk dat de storage van een instantie
 +niet op de lokale disken van een node ligt, maar op de gesharede disken
 +van de fileserver)
 +
 +Sterker nog, er kunnen meerdere instanties van hetzelfde type
 +(webservers,​ database servers) draaien op dezelfde node.
 +Bijvoorbeeld,​ in het appcluster hebben we een node aangewezen als plekje
 +waar normaliter alle shared databases moeten draaien. Op dit moment
 +draaien daar 4 database instanties op.
 +Als we hardware zouden hebben met heel veel CPU en geheugen, dan
 +zou niets ons letten om alle instanties van het hele cluster op die ene
 +superkrachtige node te draaien.
 +
 +Dit kan omdat we ervoor zorgen dat een instantie nooit "​unieke"​
 +resources van een node in kan pikken. Bijvoorbeeld:​ apache laten we
 +nooit binden aan het 0.0.0.0 adres, maar alleen maar een een specifiek,
 +bij die instantie behorend ip adres.
 +Net zo voor databases. Die willen vaak graag een socket in /tmp
 +aanmaken. Dat gaat mooi niet door, want zo'n socket kan maar 1x
 +aangemaakt worden. In de start/stop scripts zorgen we er dus voor dat
 +zo'n socket niet in de globale /tmp directory aangemaakt wordt, maar in
 +een directory behorende bij de instantie.
 +
 +Tegelijkertijd hebben we onze eigen versies van de normale start/stop
 +scripts (dwz de scripts die je normaal in /etc/init.d vindt); onze
 +versies doen extra zaken. Waaronder het dynamisch opbrengen van het IP
 +adres behorende bij een instantie, op de node waar je op dat moment de
 +instantie opstart. Bij het afluiten van de instantie wordt het IP adres
 +ook weer verwijderd.
 +
 +De grap nu van die instanties is dat het dus heel makkelijk is om
 +een individuele node even tijdelijk uit de running te halen.
 +Simpel alle instanties die op die node draaien even "​overhupsen"​ naar
 +een andere node. Stoppen aan de ene kant, weer opstarten aan de andere
 +kant en de dienst draait weer verder. Dit kan binnen seconden geregeld
 +zijn.
 +Hiermee is het mogelijk om b.v. nodes voorzien van kernel of OS
 +upgrades, zonder dat de diensten die aan de buitenwereld geleverd worden
 +down gebracht hoeven te worden.
 +
 +==== Naamgeving ====
 +De policy voor naamgeving is als volgt:
 +(ingewikkeld?​ Vertel ons wat u wilt en wij regelen het zonder u te vermoeien
 +met onderstaande details)
 +
 +  * Websites
 + Elke omroep is geheel vrij een naam voor de website te
 +kiezen. Elke applicatie kan onder een andere naam draaien
 +(bv "​www.groente.nl"​ vs "​www.fruit.nl"​),​ een gedeelde naam (bv
 +"​www.plantaardig.nl/​groente vs www.plantaardig.nl/​fruit"​) of onder
 +de default naam "​sites.omroep.nl"​ (bv sites.omroep.nl/​groente)
 +De naam die u kiest, is de naam die in de locatiebalk van de webserver
 +zichbaar is en de naam die extern bekend gemaakt wordt.
 +Alle naamgeving die hieronder nog staat is alleen maar intern, en niet
 +extern zichtbaar.
 +In de testomgeving hebben wij liefst dat applicaties draaien onder
 +"​testsites.omroep.nl/<​applicatie>",​ maar indien gewenst kunnen
 +er ook (lange!) namen als "<​omroep>​-<​applicatie>​test.omroep.nl"​
 +aangemaakt worden (bv degezondeomroep-groentetest.omroep.nl)
 +  * Frontproxies
 + Deze worden genoemd naar de omroep waar ze bij horen,
 +gevolgd door een volgnummer. B.v. ''/​e/​fp/​dgo01''​ zou de 1e frontproxy
 +van "De Gezonde Omroep"​ (DGO) zijn. De shared frontproxy heet <​tt/​shrd01/​
 +De dns naam van een frontproxy wordt "<​omroep>​-sites.omroep.nl"​.
 +(bv "​degezondeomroep-sites.omroep.nl"​). Deze naam wordt iha niet extern
 +genoemd, maar is alleen een "​kapstok"​ om domeinnamen aan op te kunnen
 +hangen, dmv DNS CNAMES. (b.v. www.groente.nl is een CNAME naar
 +degezondeomroep-sites.omroep.nl;​ dmv een virtualhost constructie in de
 +frontproxy zorgen wij er dan voor dat www.groente.nl uitkomt bij de groente
 +applicatie)
 +  * Databases
 + Deze worden ook genoemd naar de omroep waar ze bij horen,
 +gevolgd door een volgnummer. In de naamgeving wordt geen onderscheid tussen
 +de verschillende types database (mysql of postgresql) aangehouden. B.v.
 +''/​e/​db/​dgo01''​ zou de eerste database instance van de gezonde omroep
 +zijn. De shared
 +database instances heten shrd01 (mysql) en shrd02 (postgresql)
 +Binnen de database instances kunnen voor de diverse applicaties diverse
 +databases aangemaakt worden. Als er een applicatie genaamd "​groente"​ zou zijn, zou
 +de database die daarbij hoort "​groentedb"​ heten en de database user die daarbij
 +hoort zou "​groente'​ heten.
 +  * Applicatie Servers
 + Ook deze worden genoemd naar de omroep waar ze bij
 +horen, met een volgnummer. De tiende DGO applicatieserver zou
 +''/​e/​as/​dgo10''​ heten.
 +De naam van applicatieservers wordt generiek gehouden, omdat een
 +applicatieserver geen 1 op 1 relatie met een applicatie heeft.
 +  * Applicaties
 + Voor applicaties wordt bij voorkeur gepoogd om een 1
 +op 1 mapping tussen url en applicatienaam te hebben. Dwz als een
 +website www.groentenenfruit.nl heet, dan is de applicatienaam ook
 +/​e/​ap/​www.groentenenfruit.nl
 +In geval van java hosting wil het nog wel eens voorkomen dat er onder 1
 +url meerdere applicaties hangen (verschillende mountpoints in tomcat)
 +In dat geval wordt gepoogd een min of meer
 +descriptieve naam te gebruiken.
 +Stel dat onder de groentenenfruit site nog een speciale shop module nodig is, dan zou deze op disk /​e/​ap/​groentenenfruitshop kunnen heten en bereikbaar kunnen zind als www.groentenenfruit.nl/​shop.
 +  * Upload Accountnamen
 +De upload accounts worden meestal genoemd naar de organisatie die de
 +uploads wil kunnen doen. Stel dat DGO het maken van z'n Groenten en Fruit
 +site geheeld uit zou besteden aan de "​DeNeefjesCompany Ltd" dan zou het upload
 +account iets als "​neefjes"​ kunnen heten; dit account zou vervolgens
 +schrijfrechten onder onder ''/​e/​ap/​groentenenfruit/​web-app''​ krijgen
 +om daar de applicatie te plaatsen.
 +Als een omroep zelf z'n eigen applicaties plaatst, dan wordt de accountnaam
 +weer iets als "​omroep+volgnummer"​.
 +
 +Webservers leven altijd onder ''/​e/​fp''​.
 +De naam daaronder ziet eruit als ''​xxxx[0-9][a-z]'',​ waarbij
 +de ''​xxxx''​ een tag is om aan te duiden van of voor wie deze
 +instantie is (bv een omroepnaam of een applicatienaam),​ daarna volgt een
 +cijfer, wat een volgnummer is. De N'e instance van klant xxxx.
 +Tenslotte volgt weer een letter om aan te geven dat iets geloadbalanced
 +is. Stel dat foo1 geloadbalanced zou worden over 3 instanties, dan zou
 +je deze onder ''/​e/​fp''​ terugvinden als ''​foo1a'',​
 +''​foo1b''​ en ''​foo1c''​.
 +
 +Vaak zullen de a,b en c instanties onderling veel configuratie delen.
 +Om deze nu niet 3x te dupliceren is deze terug te vinden in een gedeelde
 +directory ''/​e/​fp/​foo1''​ (dwz zonder volgletter).
 +
 +Zowel de static proxies, als de php enabled servers zijn webservers en
 +leven dus beide onder ''/​e/​fp''​. Er is geen onderscheid in
 +naamgeving tussen proxies en php servers. In praktijk betekent dit vaak
 +dat een proxy en php server dezelfde prefix hebben ("​foo"​),​ maar een
 +ander volgnummertje ("​foo1"​ tegenover "​foo2"​).
 +Het kan natuurlijk ook zo zijn dat 1 setje proxies (foo1&​lsqb;​a-z&​rsqb;​)
 +loadbalanced over meerdere setjes php servers (foo2&​lsqb;​a-z&​rsqb;​ voor
 +applicatie X en foo3&​lsqb;​a-z&​rsqb;​ voor applicatie Y).
 +Wij streven ernaar om in het GECOS veld van de password file aan te
 +geven wat een webserver isntantie precies doet.
 +
 +De user waar een webserver onder draait is z'n naam gevolgd door de
 +letters "​fp"​. B.v. ''​foo1afp''​. En het adres waar die aan bindt
 +heeft meestal als DNS naam ''​foo1afp.omroep.nl'',​
 +
 +==== Shared vhost includes ====
 +de configuratie van apache virtual hosts leeft bij ons altijd in losse
 +''​.vhost''​ files, welke door de webserver geinclude worden.
 +In een loadbalanced context moeten zowel de proxies als de php servers
 +weet hebben van de vhosts. Om nu niet alle informatie N maal te
 +dupliceren hebben we vsan elke vhost file slechts een kopie, die door
 +alle (proxies <​em>​en</​em>​ php servers) webserver geinclude wordt.
 +In de vhost file wordt met Define'​s gespeeld om ervoor te zorgen dat
 +elke instantie alleen maar het stukje configuratie krijgt dat voor die
 +instantie van toepassing is.
 +
 +==== Sessies ====
 +Niet alles is rozegeur en maneschijn, nl sessies zijn een probleem.
 +Er is geen garantie dat een sessie altijd bij dezelfde php node terecht
 +komt.
 +Er zijn een aantal oplossingen:​
 +
 +  * route constructies gebruiken
 +We gaan er van uit dat sessie informatie in http cookies gestopt zit.
 +Als de cookies op een zodanige wijze gegenereerd kunnen worden dat het
 +duidelijk is door welke worker node dit gedaan is, dan zit er in de http
 +proxy functionaliteit om op basis van zo'n cookie het request naar de
 +juiste worker door te sturen.
 +Concreet betekent dat dat de cookiename statisch moet zijn (bv
 +PHPSESSIONID) en dat de waarde van de cookie eruit moet zien als
 +''​sessiadata.NODE_ID'',​ waarbij het NODE_ID bepalend is voor naar
 +welke node een request doorgezet moet worden.
 +In een java tomcat context is dit tamelijk eenvoudig te doen door in de
 +tomcat server.xml een jvmRoute op te nemen:
 +<​code>​
 +<Engine name="​Standalone"​ defaultHost="​none"​ jvmRoute="​NODE_x">​
 +</​code>​
 +Dit zorgt ervoor dat er cookies JSESSIONID=sessiedata.NODE_x gezet
 +worden.
 +Vervolgens stellen we op de proxy in:
 +<​code>​
 +ProxyPass / balancer://​cluster/​ stickysession=JSESSIONID
 +<Proxy balancer://​cluster>​
 + BalancerMember http://​node1 route=NODE_1
 + BalancerMember http://​node2 route=NODE_2
 + BalancerMember http://​node3 route=NODE_3
 + ...
 +</​Proxy>​
 +</​code>​
 +En zo weet de proxy dat sessies met NODE_1 doorgestuurd moeten worden naar
 +node1.
 +Het probleem hierbij echter is dat dat bij php niet zo fijn werkt.
 +Er is in php geen makkelijke manier (a la jvmRoute in tomcat) om php duidelijk
 +te maken dat ie z'n sessie namen volgens een bepaalde syntax aan moet
 +maken. Daarom hebben we een speciale truc verzonnen, waardoor door middel van een RewriteRule in de PHP-worker een cookie geset wordt (vaak iets als '​BALANCEID'​),​ wat dan als stickysession gebruikt kan worden. Hierdoor komt uiteindelijk dan alsnog brafa elk request van 1 bezoeker op dezelfde PHP-worker terecht.
 +  * sessies in database opslaan
 +Aangezien de verschillende webserver nodes uiteindelijk weer aan
 +dezelfde database refereren, kan de database goed gebruikt worden om
 +sessie informatie in op te slaan.
 +  * sessies op het filesysteem opslaan
 +Dit zou in theorie kunnen, maar is in praktijk een slecht idee.
 +De gedachte is dat de verschillende php nodes een shared filesysteem
 +hebben. Dus, als node 1 op het filesysteem wat sessie info neerzet, dan
 +kan node 2 dat weer oppikken.
 +Probleem hierbij is dat we NFS gebruiken voor het filesysteem en dat NFS
 +geen cache consistency biedt. Dat betekent dat op het moment dat node 1
 +iets weggeschreven heeft, dit niet meteen op node 2 bekend is.
 +  * sessies in memcache opslaan
 +We bieden inmiddels ook support voor [[http://​www.danga.com/​memcached/​|memcache]],​ een stukje geheugen dat op een eigen intern ip-adresje beschikbaar is voor alle php-workers.
 +
 +
  
  • sterretje-cluster/cluster-hosting_opbouw-omgeving.txt
  • Last modified: 2020/09/09 11:26
  • (external edit)