Käivitage Kubernetesis Keycloak HA-režiimis

Käivitage Kubernetesis Keycloak HA-režiimis

TL; DR: seal on avatud lähtekoodiga juurdepääsukontrollisüsteemi Keycloaki kirjeldus, siseseadme analüüs, konfiguratsiooni üksikasjad.

Sissejuhatus ja peamised ideed

Selles artiklis näeme peamisi ideid, mida Kubernetese peal Keycloaki klastri juurutamisel meeles pidada.

Kui soovite Keycloaki kohta rohkem teada saada, vaadake artikli lõpus olevaid linke. Selleks, et praktikasse süveneda, saab õppida meie hoidla mooduliga, mis rakendab selle artikli peamisi ideid (käivitusjuhend on olemas, selles artiklis on ülevaade seadmest ja sätetest, u. tõlkija).

Keycloak on keeruline süsteem, mis on kirjutatud Java keeles ja ehitatud rakendusserveri peale. Metsik kärbes. Lühidalt öeldes on see autoriseerimisraamistik, mis annab rakenduse kasutajatele liitmise ja SSO (ühekordse sisselogimise) võimaluse.

Kutsume teid lugema ametlikku veebisait või Vikipeedia üksikasjaliku mõistmise jaoks.

Käivitage Keycloak

Keycloak vajab käitamiseks kahte püsivat andmeallikat.

  • Andmebaas, mida kasutatakse püsivate andmete, näiteks kasutajate teabe salvestamiseks
  • Datagridi vahemälu, mida kasutatakse andmete vahemällu salvestamiseks andmebaasist, samuti mõne lühiajalise ja sageli muudetava metaandmete, näiteks kasutajaseansside salvestamiseks. Välja antud Infinispan, mis on tavaliselt andmebaasist oluliselt kiirem. Kuid igal juhul on Infinispanisse salvestatud andmed lühiajalised – ja neid pole vaja klastri taaskäivitamisel kuhugi salvestada.

Keycloak töötab neljas erinevas režiimis:

  • tavaline - üks ja ainus protsess, mis on konfigureeritud faili kaudu standalone.xml
  • tavaline klaster (kõrgesti saadaolev valik) – kõik protsessid peavad kasutama sama konfiguratsiooni, mis tuleb käsitsi sünkroonida. Seadistused salvestatakse faili standalone-ha.xml, lisaks peate tegema jagatud juurdepääsu andmebaasile ja koormuse tasakaalustajale.
  • Domeeniklaster - klastri käivitamine tavarežiimis muutub klastri kasvades kiiresti rutiinseks ja igavaks ülesandeks, kuna iga kord, kui muudate konfiguratsiooni, peate tegema kõik muudatused klastri igas sõlmes. Domeeni töörežiim lahendab selle probleemi, seadistades mõne jagatud salvestusruumi ja avaldades konfiguratsiooni. Need sätted salvestatakse faili domeen.xml
  • Replikatsioon andmekeskuste vahel - kui soovite käivitada Keycloaki mitme andmekeskuse klastris, enamasti erinevates geograafilistes asukohtades. Selle valiku korral on igal andmekeskusel oma Keycloaki serverite klaster.

Käesolevas artiklis vaatleme lähemalt teist võimalust, s.o. tavaline klaster, samuti veidi puudutage andmekeskuste vahelise replikatsiooni teemat, kuna neid kahte võimalust on mõistlik Kubernetesis käivitada. Õnneks pole Kubernetesil probleeme mitme kausta (Keycloaki sõlmede) sätete sünkroonimisega, nii et domeeni klaster seda teha ei saa liiga raske.

Pange tähele ka seda, et sõna klaster Kuni artikli lõpuni kehtib see ainult koos töötavate Keycloaki sõlmede rühma kohta, pole vaja viidata Kubernetese klastrile.

Tavaline Keycloak Cluster

Keycloaki selles režiimis käitamiseks vajate:

  • välise jagatud andmebaasi seadistamine
  • paigaldage koormuse tasakaalustaja
  • omama sisevõrku IP multicasti toega

Me ei analüüsi välise andmebaasi konfiguratsiooni, kuna see ei ole selle artikli eesmärk. Oletame, et kuskil on töötav andmebaas – ja meil on sellega ühenduspunkt. Lisame need andmed lihtsalt keskkonnamuutujatesse.

Et paremini mõista, kuidas Keycloak tõrkesiirdeklastris (HA) töötab, on oluline teada, kui palju see kõik sõltub Wildfly klastrite loomise võimalustest.

Wildfly kasutab mitmeid alamsüsteeme, mõnda neist kasutatakse koormuse tasakaalustajana, mõnda kasutatakse tõrkevahetuseks. Koormuse tasakaalustaja tagab rakenduse saadavuse, kui klastri sõlm on ülekoormatud, ja tõrkesiirde tagab rakenduse saadavuse isegi siis, kui mõni klastri sõlm ebaõnnestub. Mõned neist alamsüsteemidest on järgmised:

  • mod_cluster: töötab koos Apache'iga HTTP koormuse tasakaalustajana, sõltub hosti vaiketuvastuse jaoks TCP multisaatest. Saab asendada välise tasakaalustajaga.

  • infinispan: hajutatud vahemälu, kasutades transpordikihina JGroupsi kanaleid. Valikuliselt saab see kasutada HotRodi protokolli, et suhelda välise Infinispani klastriga, et sünkroonida vahemälu sisu.

  • jgroups: pakub tuge JGroupsi kanalitel põhinevate kõrgetasemeliste teenuste jaoks rühmade ühendamiseks. Nimega torud võimaldavad klastris olevaid rakendusjuhte ühendada rühmadesse, nii et ühendusel on sellised omadused nagu töökindlus, korrapärasus ja tõrketundlikkus.

koormuse tasakaalustaja

Kui installite Kubernetese klastris tasakaalustaja sisendkontrollerina, on oluline meeles pidada järgmist.

Keycloaki töö tähendab, et HTTP kaudu autentimisserveriga ühenduse loova kliendi kaugaadress on klientarvuti tegelik IP-aadress. Tasakaalustaja ja sisendseaded peaksid HTTP-päised õigesti määrama X-Forwarded-For и X-Forwarded-Protoja säilitage algne pealkiri HOST. Uusim versioon ingress-nginx (> 0.22.0) keelab selle vaikimisi

Lipu aktiveerimine proxy-address-forwarding keskkonnamuutuja määramisega PROXY_ADDRESS_FORWARDING в true annab Keycloakile arusaamise, et see töötab puhverserveri taga.

Samuti peate lubama kleepuvad seansid sissetungimisel. Keycloak kasutab Infinispani hajutatud vahemälu praeguse autentimisseansi ja kasutajaseansiga seotud andmete salvestamiseks. Vahemälu on vaikimisi ühe omanikuga, teisisõnu, konkreetne seanss on salvestatud mõnda klastri sõlme ja teised sõlmed peavad seda kaughaldusega taotlema, kui neil on vaja sellele seansile juurdepääsu.

Täpsemalt, vastupidiselt dokumentatsioonile, ei toiminud küpsisenimega seansi lisamine meie jaoks AUTH_SESSION_ID. Keycloak on ümbersuunamise tsükliga, seega soovitame valida kleepuva seansi jaoks teise küpsisefaili nime.

Keycloak lisab ka esimesena vastanud hosti nime AUTH_SESSION_IDja kuna iga sõlm väga kättesaadavas versioonis kasutab sama andmebaasi, siis igaüks neist peab olema eraldiseisev ja kordumatu sõlme ID tehingute haldamiseks. Soovitav on sisse panna JAVA_OPTS parameetrid jboss.node.name и jboss.tx.node.id iga sõlme jaoks ainulaadne – näiteks saate määrata podi nime. Kui paned podi nime, ärge unustage jbossi muutujate 23 tähemärgi piirangut, seega on parem kasutada StatefulSet, mitte juurutamist.

Veel üks reha – kui pod kustutatakse või taaskäivitatakse, läheb selle vahemälu kaotsi. Seda silmas pidades tasub kõigi vahemälude vahemälu omanike arvuks seada vähemalt kaks, nii et vahemälust tuleb koopia. Lahendus on jooksmine Wildfly stsenaarium podi käivitamisel asetage see kataloogi /opt/jboss/startup-scripts konteineris:

Skripti sisu

embed-server --server-config=standalone-ha.xml --std-out=echo
batch

echo * Setting CACHE_OWNERS to "${env.CACHE_OWNERS}" in all cache-containers

/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=owners, value=${env.CACHE_OWNERS:1})

run-batch
stop-embedded-server

seejärel määrake keskkonnamuutuja väärtus CACHE_OWNERS nõutavale.

Privaatvõrk IP multicasti toega

Kui kasutate oma CNI-na Weaveneti, töötab multisaade kohe – ja teie Keycloaki sõlmed näevad üksteist kohe, kui need tööle hakkavad.

Kui teie Kubernetese klastris pole IP-i multisaadete tuge, saate konfigureerida JGroupsid töötama sõlmede leidmiseks teiste protokollidega.

Esimene võimalus on kasutada KUBE_DNSmis kasutab headless service Keycloaki sõlmede leidmiseks edastage JGroupsile lihtsalt selle teenuse nimi, mida sõlmede leidmiseks kasutatakse.

Teine võimalus on kasutada meetodit KUBE_PING, mis töötab API-ga sõlmede leidmiseks (peate konfigureerima serviceAccount õigustega list и getja seejärel konfigureerige kaustad sellega töötama serviceAccount).

Kuidas sõlmedest JGroupsi otsitakse, konfigureeritakse keskkonnamuutujate määramisega JGROUPS_DISCOVERY_PROTOCOL и JGROUPS_DISCOVERY_PROPERTIES. Jaoks KUBE_PING kaunad tuleb valida küsides namespace и labels.

️ Kui kasutate multiedastust ja käitate samas Kubernetese klastris kahte või enamat Keycloaki klastrit (oletame nimeruumis production, teine ​​- staging) – ühe Keycloaki klastri sõlmed saavad liituda teise klastriga. Muutujate määramisel kasutage iga klastri jaoks unikaalset multisaateaadressijboss.default.multicast.address и jboss.modcluster.multicast.address в JAVA_OPTS.

Replikatsioon andmekeskuste vahel

Käivitage Kubernetesis Keycloak HA-režiimis

Link

Keycloak kasutab mitut eraldi Infinispani vahemäluklastrit iga andmekeskuse jaoks, mis majutab Keycloaki sõlmedest koosnevaid Keycloack-klastreid. Kuid samal ajal pole Keycloaki sõlmede vahel erinevates andmekeskustes vahet.

Keycloak-sõlmed kasutavad andmekeskuste vaheliseks suhtlemiseks välist Java Data Gridit (Infinispani serverid). Side toimib vastavalt protokollile Infinispan HotRod.

Infinispani vahemälud peavad olema atribuudiga konfigureeritud remoteStore, et andmeid saaks salvestada kaugseadmesse (teisse andmekeskusesse, u. tõlkija) vahemälud. JDG serverite hulgas on eraldi infinispan klastrid, nii et andmed salvestatakse JDG1-sse kohapeal site1 kopeeritakse kohapeal JDG2-sse site2.

Lõpuks teavitab vastuvõttev JDG-server oma klastri Keycloak-servereid kliendiühenduste kaudu, mis on HotRod-protokolli funktsioon. Võtmekatte sõlmed sisse lülitatud site2 värskendage oma Infinispani vahemälu ja konkreetne kasutajaseanss muutub Keycloaki sõlmedes kättesaadavaks site2.

Samuti on võimalik, et mõnda vahemälu ei varundata ja nad keelduvad täielikult Infinispani serveri kaudu andmete kirjutamisest. Selleks peate seade eemaldama remote-store konkreetne Infinispani vahemälu (failis standalone-ha.xml), mille järel mõned konkreetsed replicated-cache pole enam vaja ka Infinispani serveri poolel.

Vahemälu seadistamine

Keycloakis on kahte tüüpi vahemälu:

  • Kohalik. See asub aluse kõrval, selle eesmärk on vähendada andmebaasi koormust ja vähendada vastuse latentsust. Seda tüüpi vahemälu salvestab valdkonna, kliendid, rollid ja kasutaja metaandmed. Seda tüüpi vahemälu ei kopeerita isegi siis, kui see vahemälu on osa Keycloaki klastrist. Kui mõni vahemälu kirje muutub, saadetakse klastri ülejäänud serveritele muudatusteade, misjärel kirje vahemälust välja jäetakse. vaata kirjeldust work allpool, et näha protseduuri üksikasjalikumat kirjeldust.

  • Kopeeritav. Töötleb kasutajaseansse, võrguühenduseta märke ja jälgib sisselogimistõrkeid, et tuvastada paroolide andmepüügikatseid ja muid ründeid. Nendesse vahemäludesse salvestatud andmed on ajutised, salvestatud ainult RAM-i, kuid neid saab kopeerida kogu klastris.

Infinispani vahemälud

Seansid - Keycloaki kontseptsioon, eraldi vahemälud, mida nimetatakse authenticationSessions, kasutatakse konkreetsete kasutajate andmete salvestamiseks. Nendest vahemäludest päringuid vajavad tavaliselt brauser ja Keycloaki serverid, mitte rakendused. Siin avaldubki sõltuvus kleepuvatest seanssidest ja selliseid vahemälu ise ei pea kordama, isegi Active-Active režiimi puhul.

Tegevusmärgid. Teine kontseptsioon, mida tavaliselt kasutatakse erinevate stsenaariumide jaoks, kui kasutaja peab näiteks midagi asünkroonselt posti teel tegema. Näiteks protseduuri ajal forget password vahemälu actionTokens kasutatakse seotud märkide metaandmete jälgimiseks – näiteks luba on juba kasutatud ja seda ei saa uuesti aktiveerida. Seda tüüpi vahemälu tuleks tavaliselt andmekeskuste vahel kopeerida.

Vahemällu salvestamine ja salvestatud andmete aegumine töötab andmebaasi koormuse eemaldamiseks. See vahemällu salvestamine parandab jõudlust, kuid lisab ilmse probleemi. Kui üks Keycloaki server andmeid uuendab, tuleb sellest teavitada ka ülejäänud servereid, et nad saaksid oma vahemälu uuendada. Keycloak kasutab kohalikke vahemälu realms, users и authorization andmete vahemällu salvestamiseks andmebaasist.

Samuti on eraldi vahemälu work, mida korratakse kõigis andmekeskustes. See ise ei salvesta andmebaasist mingeid andmeid, vaid on mõeldud andmekeskuste vahelistele klastri sõlmedele andmete vananemise sõnumite saatmiseks. Teisisõnu, niipea kui andmeid värskendatakse, saadab Keycloaki sõlm teate teistele andmekeskuse sõlmedele ja ka muude andmekeskuste sõlmedele. Sellise teate saamisel tühjendab iga sõlm vastavad andmed oma kohalikes vahemäludes.

Kasutajaseansid. Vahemälud nimedega sessions, clientSessions, offlineSessions и offlineClientSessions, kopeeritakse tavaliselt andmekeskuste vahel ja neid kasutatakse andmete salvestamiseks kasutaja seansside kohta, mis on aktiivsed, kui kasutaja on brauseris aktiivne. Need vahemälud töötavad rakendusega, mis käsitleb lõppkasutajate HTTP-päringuid, nii et need on seotud kleepuvate seanssidega ja neid tuleb andmekeskuste vahel kopeerida.

toore jõu kaitse. Vahemälu loginFailures kasutatakse sisselogimisvea andmete jälgimiseks, näiteks mitu korda kasutaja sisestas vale parooli. Selle vahemälu replikatsiooni otsustab administraator. Kuid täpse arvutuse jaoks tasub aktiveerida andmekeskuste vaheline replikatsioon. Kuid teisest küljest, kui te neid andmeid ei kopeeri, saate jõudlust parandada ja kui see küsimus tekib, ei pruugi replikatsioon olla aktiveeritud.

Infinispani klastri kasutuselevõtul peate seadete faili lisama vahemälu määratlused.

<replicated-cache-configuration name="keycloak-sessions" mode="ASYNC" start="EAGER" batching="false">
</replicated-cache-configuration>

<replicated-cache name="work" configuration="keycloak-sessions" />
<replicated-cache name="sessions" configuration="keycloak-sessions" />
<replicated-cache name="offlineSessions" configuration="keycloak-sessions" />
<replicated-cache name="actionTokens" configuration="keycloak-sessions" />
<replicated-cache name="loginFailures" configuration="keycloak-sessions" />
<replicated-cache name="clientSessions" configuration="keycloak-sessions" />
<replicated-cache name="offlineClientSessions" configuration="keycloak-sessions" />

Enne Keycloaki klastri käivitamist peate konfigureerima ja käivitama Infinispani klastri

Siis peate seadistama remoteStore Keycloaki vahemälu jaoks. Selleks piisab skriptist, mida tehakse sarnaselt eelmisega, mida kasutatakse muutuja seadistamiseks CACHE_OWNERS, peate selle faili salvestama ja kataloogi panema /opt/jboss/startup-scripts:

Skripti sisu

embed-server --server-config=standalone-ha.xml --std-out=echo
batch

echo *** Update infinispan subsystem ***
/subsystem=infinispan/cache-container=keycloak:write-attribute(name=module, value=org.keycloak.keycloak-model-infinispan)

echo ** Add remote socket binding to infinispan server **
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-cache:add(host=${remote.cache.host:localhost}, port=${remote.cache.port:11222})

echo ** Update replicated-cache work element **
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=work, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)

/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache sessions element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=sessions, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache offlineSessions element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=offlineSessions, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache clientSessions element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=clientSessions, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache offlineClientSessions element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=offlineClientSessions, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache loginFailures element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    remote-servers=["remote-cache"], 
    cache=loginFailures, 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache actionTokens element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=remote:add( 
    passivation=false, 
    fetch-state=false, 
    purge=false, 
    preload=false, 
    shared=true, 
    cache=actionTokens, 
    remote-servers=["remote-cache"], 
    properties={ 
        rawValues=true, 
        marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, 
        protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} 
    } 
)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:write-attribute(name=statistics-enabled,value=true)

echo ** Update distributed-cache authenticationSessions element **
/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:write-attribute(name=statistics-enabled,value=true)

echo *** Update undertow subsystem ***
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)

run-batch
stop-embedded-server

Ärge unustage installida JAVA_OPTS Keycloaki sõlmede HotRodi töötamiseks: remote.cache.host, remote.cache.port ja teenuse nimi jboss.site.name.

Lingid ja lisadokumentatsioon

Artikli tõlkisid ja koostasid Habrile töötajad Slurmi koolituskeskus — intensiivkursused, videokursused ja ettevõtte koolitused praktikutelt (Kubernetes, DevOps, Docker, Ansible, Ceph, SRE)

Allikas: www.habr.com

Lisa kommentaar