Clustering¶
Bemærk
Denne funktion er i øjeblikket en teknisk forhåndsvisning med følgende midlertidige begrænsninger:
Hvis en klynge går tabt (quorum går tabt), er den eneste måde at genoprette på fabriksnulstilling + gendannelse. Sørg for at tage backup ofte. Fremtidige udgivelser vil indeholde metoder til at gendanne data på disken.
Aktiv/passiv opsætning til understøttelse af to-node-klynger, enten ved at bruge etcd Learner eller Mirror, er endnu ikke tilgængelig.
Systemtid mellem noder skal indtil videre synkroniseres manuelt. En fremtidig udgave vil indeholde automatisk synkronisering af uret.
NetHSM 4.0 og fremefter understøtter klyngedannelse for at synkronisere data direkte mellem flere NetHSM’er. Dette understøtter høj frekvens af nøglegenerationer, realiserer høj tilgængelighed og belastningsbalancering. En NetHSM-klynge er baseret på etcd, som bruger Raft-konsensusalgoritmen til stærk konsistens. Det sikrer, at data (f.eks. nøgler) til enhver tid er korrekte i alle NetHSM’er.
Før du opsætter en NetHSM-klynge, skal du gøre dig bekendt med denne teknologi og dens begrænsninger for at undgå utilsigtede udfald og datatab. Ud over dette dokument kan du også se etcd’s dokumentation.
Operational Redundancy¶
Vi vil kalde »node« en NetHSM, der forventes at være en del af en klynge. En klynge af N noder vil fortsætte med at fungere, så længe mindst (N/2)+1 noder er sunde og kan nås. Den minimale mængde af sunde, tilgængelige noder kaldes quorum.
Det indebærer følgende scenarier.
Et knudepunkt går ned, og quorum er stadig nået¶
I en klynge med tre noder vil de to andre noder fortsætte med at arbejde og betjene anmodninger, hvis en node fejler (går ned eller bliver utilgængelig på grund af netværksforhold).
Hvis den fejlslagne node stadig er sund (f.eks. hvis det bare var et netværksproblem), vil den være ubrugelig, mens den er isoleret (ikke engang skrivebeskyttet).
Men hvis noden kommer sig, synkroniseres den igen med resten af klyngen og bliver funktionsdygtig igen uden at miste data.
Hvis den aldrig kommer sig, skal den fjernes fra klyngen (se næste afsnit), fabriksnulstilles og gennemgå join-processen igen fra bunden.
En netværksopdeling sker, og quorum er stadig nået¶
Dette er blot en generalisering af det foregående scenarie. I en klynge med 5 noder, hvor f.eks. 3 noder befinder sig på en fysisk placering A og 2 noder på en anden placering B, vil et netværksproblem, der isolerer A og B, betyde følgende:
De 3 noder på placering A opfylder quorum (3 i dette tilfælde), så de fortsætter med at fungere.
De 2 noder på placering B er ikke opfylder quorum (stadig 3), så de holder op med at fungere (selv skrivebeskyttet).
Hvis netværksproblemet er løst, vil de 2 noder rent faktisk slutte sig til de 3 andre.
Beslutningsdygtigheden er varigt tabt¶
En fejl, der får alle delmængder af klyngen til at miste quorum, gør, at klyngen og dens data går helt tabt, medmindre fejlen løses. I så fald skal noderne nulstilles fra fabrikken, og en backup skal gendannes.
Det kan f.eks. ske, hvis en enkelt node fejler i en klynge med 2 noder (hvor quorum er 2). I denne situation kan den fejlslagne node ikke fjernes fra klyngen bagefter, fordi den resterende sunde node allerede er ude af drift, da den har mistet quorum.
Derfor anbefales det altid at have et ulige antal noder i en klynge og at tage backup ofte.
For at gøre det klart, så er det ikke et problem, at midlertidigt mister beslutningsdygtighed (f.eks. hvis du genstarter alle noder i en klynge sammen, eller en midlertidig netværksfejl isolerer noder): Når nok noder er forbundet igen (uden at skulle tilsluttes manuelt) til at nå beslutningsdygtighed, vil klyngen genoptage sin normale drift. Kun permanente fejl som f.eks. netværkspartitioner, fejlkonfigurationer i netværket, autentificeringsproblemer eller hardwarefejl kræver manuel handling.
For mere information, se etcd’s OFTE STILLEDE SPØRGSMÅL.
2-node klynge¶
En aktiv/passiv klynge med to noder er ikke understøttet endnu og vil blive tilføjet i en fremtidig version. Vi anbefaler at introducere en 3. node, enten en 3. NetHSM eller et etcd-»vidne«, som kan betjenes på en hvilken som helst vært. Se næste afsnit »Vidne«.
Vidne¶
Klyngens natur med etcd gør den mere pålidelig, jo flere noder der er i klyngen. Som forklaret i afsnittet Operational Redundancy bør klynger ideelt set have mindst 3 noder for at have plads til at fejle, da en klynge med 2 noder vil fejle helt, hvis kun den ene fejler.
Men funktionen er designet sådan, at du ikke behøver at tilføje en fuld, ægte NetHSM-enhed til din klynge for at nå et stabilt antal noder. I stedet kan du selv implementere og tilføje en »vidne«-node. En sådan node er bare en instans af etcd, der kører på en maskine efter eget valg (eller i en container) og er forbundet til klyngen. Den vil blive genkendt som en normal node af de rigtige enheder i klyngen og modtage alle data og opdateringer fra enhederne (men du vil selvfølgelig ikke kunne udføre nogen HSM-operationer med den - den gemmer kun data).
Security Considerations¶
Vidnenoden (eller enhver med adgang til den) har direkte adgang til storage backend for alle noder i klyngen (f.eks. kan du dumpe alle poster og tilhørende værdier med etcdctl get "/" "0").
Men med undtagelse af config-versionen (/config/version, som altid skal være »1«) er alle værdier krypterede (med enten en enhedsnøgle for nodespecifikke værdier eller domænenøgler for andre), hvilket sikrer fortroligheden af følsomme data.
Bemærk dog, at en ondsindet node kan:
skrive skrald som værdi for en hvilken som helst post i lageret, hvilket vil få noder til at fejle i dekrypteringen (hvilket kan føre til nedbrud for nogle systemposter).
listepostnavne som brugere, navneområder og nøgler, som du måske betragter som følsomme.
Creating a Cluster¶
Enhver klynge starter oprindeligt med en enkelt node. Nye noder vil slutte sig til klyngen en efter en.
Preparing Nodes¶
Netværkstrafikken mellem noderne er krypteret og autentificeret ved hjælp af deres TLS-certifikat.
Alle noder, der forventes at være en del af den samme klynge, skal først installere en fælles Certificate Authority (CA), der gør det muligt for dem at verificere, at andre noder er legitime.
I det følgende antager vi, at alle knudepunkter er nyetablerede og i drift.
Networking¶
Nodes must first be reconfigured with their expected final network configuration using the /config/network endpoint (refer to the API documentation).
Oprettelse og installation af en CA¶
Brugere bør oprette en CA på deres egen måde og i henhold til deres egne operationelle begrænsninger og sørge for, at den mindst tillader brug af nøglen keyCertSign.
En minimal CA kan f.eks. oprettes med openssl:
$ openssl genrsa -out CA.key 2048 # create a key
$ openssl req -x509 -new -nodes -key CA.key -sha256 -days 1825 -out CA.pem -addext keyUsage=critical,keyCertSign
Denne CA skal nu installeres på hver node.
To do this, first generate a Certificate Signing Request (CSR) from the node with the /config/tls/csr.pem endpoint (refer to the API documentation).
Bemærk
For at kunne godkende noder korrekt forventer klyngens backend (etcd), at hver node har et certifikat med et korrekt udfyldt SAN-felt (Subject Alt Names). Især skal noder, der kun forventes at kunne nås via deres IP, have et korrekt IP-SAN i deres certifikat. Der kan anmodes om IP-SAN’er til CSR’en ved at sætte »IP:« foran navnene, som i openssl:
"subjectAltNames": [ "normalname.org", "IP:192.168.1.1" ]
Med den opnåede CSR (lad os kalde den nethsm.csr) kan vi derefter generere et certifikat til den, som er klar til at blive installeret. For eksempel med openssl:
$ openssl x509 -req -days 1825 -in nethsm.csr -CA CA.pem -copy_extensions copy \
-CAkey CA.key -out new_cert.pem -set_serial 01 -sha256
Then install the obtained new_cert.pem with the /config/tls/cert.pem endpoint (refer to the API documentation).
Endelig kan CA (CA.pem) nu installeres med /config/tls/cluster-ca.pem endpoint (se API-dokumentation). Dette er kun muligt, når det installerede TLS-certifikat er underskrevet af det. Ellers vil operationen blive afvist.
Bemærk
Denne proces skal gentages for hver node.
Ur-synkronisering¶
Sørg for, at alle noder har fået en nøjagtig systemtid. Hvis ikke, skal du justere deres ure med /config/time endpoint.
Adding a New Node¶
Tilføjelse af en node til en klynge sker i to trin:
registrer tilføjelsen til klyngen (gennem et hvilket som helst af dens medlemmer)
Fortæl den nye node, at den skal deltage
Configure a Backup Passphrase¶
Sørg først for, at der er konfigureret en backup-passphrase på den node, der skal bruges til at registrere en ny snedker (se API-dokumentationen for slutpunktet /config/backup-passphrase).
Registrering af et nyt knudepunkt¶
Advarsel
Registrering af en node introducerer straks en ny node i klyngen og ændrer quorumtærsklen, selv om noden faktisk ikke har sluttet sig til endnu. Dette kan gøre de eksisterende noder ubrugelige, indtil den nye node rent faktisk er kommet til. Se API-dokumentation og afsnittet Operational Redundancy i dette dokument.
Hav IP-adressen på den node, der skal deltage, ved hånden. Den fulde URL (også kaldet peer URL i etcd terminologi) for denne node vil være https://<IP_of_node>:2380 (f.eks. https://192.168.1.1:2380). Porten skal være 2380, så sørg for, at en eventuel firewall mellem noderne tillader TCP-trafik på den port.
Du kan dobbelttjekke, at URL’en er korrekt, ved at kalde GET /cluster/members på den node, der forventes at deltage. Dette bør kun vise ét medlem: sig selv.
Registrer derefter den forventede URL på en eksisterende node i klyngen (hvis du ikke har en klynge endnu, skal du gøre det på den NetHSM, der skal fungere som den første node i klyngen). Dette gøres ved hjælp af POST /cluster/members endpoint (se API-dokumentation), hvor du sender en JSON body, der indeholder URL’en.
Hvis det lykkes, returneres en JSON-krop af formularen:
{
"members": [
{
"name": "",
"urls": [
"https://172.22.1.3:2380"
]
},
{
"name": "9ZVNM2MNWP",
"urls": [
"https://172.22.1.2:2380"
]
}
],
"joinerKit": "eyJiYWNrdXBfc2FsdCI6IkVlUzNPOEhHSEc5NnlNRktrdG1NZmc9PSIsInVubG9ja19zYWx0IjoiU3phMkEvYW13NlhxVWsrdHZMMmFubm5SZFlWd2ZQUjdpZ3IxK1RSdTdVaU14dmh3d0x2NWIvYVNkY2c9IiwibG9ja2VkX2RvbWFpbl9rZXkiOiIyMnNGVlkyelhQUVZ6S1pQenI3MmkwTk1WM3lmQ2k5dGwzeDhUbGtuOXM0WjFOd3JoZkRQTFZIVHp1WVl0YkQxaVZCMlovV3JHUHJlMXlwN0t4U0w4WkxjY2ZUTmUzcFg0WXE4YXNlY0wwREhXNGlIaXlPMlZnPT0ifQ=="
}
som indeholder de oplysninger, der er nødvendige for, at den nye node kan slutte sig til klyngen. Den indeholder især en liste over alle medlemmer af klyngen (hvor medlemmet med et tomt navn er den nye deltager). Den indeholder også domænenøglen, der er krypteret med både oplåsnings- og backup-passphrase - så der skal være konfigureret en backup-passphrase før.
Gem det svar til næste trin.
Faktisk tilslutning til klyngen¶
Tag svaret fra det sidste trin og tilføj et backupPassphrase-felt, der indeholder backup-passphrasen for den node, hvor den nye deltager blev registreret, og send disse data til et kald til POST /cluster/join (se API-dokumentation) på den node, der forventes at deltage.
Forudsat at både klyngen og noden kan nå hinanden, vil dette gennemføre den faktiske tilslutning og slette dataene på den nye deltager for i stedet at synkronisere dens tilstand med klyngens.
Afhængigt af netværks- og klyngeforholdene kan denne operation tage et par dusin sekunder. Hvis operationen mislykkes med det samme (f.eks. hvis klyngen ikke kan nås, eller hvis autentificeringen mislykkes), bliver denne nodes tilstand ikke slettet, og tilslutningen bliver gjort om. Men så snart en første tilslutning er vellykket, er denne operation endelig og kan kun annulleres ved en fabriksnulstilling.
Hvis denne tilslutning er vellykket, ender noden i tilstanden Locked og skal låses op med oplåsningspasfrasen for den node, der blev brugt til registrering. Bagefter kan oplåsningspasfrasen ændres (oplåsningspasfraser forbliver nodespecifikke og deles ikke på tværs af noder).
Bemærk
Selv efter at joinen er lykkedes, hvis klyngens database er stor, eller hvis klyngen har travlt, kan det tage noget tid for den nye joiner at synkronisere sin tilstand fuldt ud. I løbet af den tid kan alle noder (herunder især den nye joiner) være mindre responsive eller ikke responsive. Især den nye snedker kan i starten returnere fejl, når man f.eks. forsøger at låse den op. I så fald skal du give det lidt tid og prøve igen.
Adding a Witness Node¶
Prepare a Witness¶
Du skal bruge et miljø med etcd v3.6 tilgængelig, med en IPv4-adresse (mindst), der kan nås af de andre medlemmer af din klynge. TCP-trafik til og fra port 2380 skal være tilladt.
Opret en tom mappe, hvor etcd skal gemme sine data, og skriv dens sti ned (vi bruger /var/etcd/data). Sørg for, at den bruger, der skal starte processen, har tilladelse til at læse og skrive til mappen.
Overfør CA-certifikatet, der bruges til at autentificere noder i klyngen, til maskinen. Du burde have oprettet et i afsnittet Oprettelse og installation af en CA. Vi gemmer det i /var/etcd/CA.pem.
Derefter skal du oprette et certifikat til vidnet og underskrive det med CA’en, så det kan kommunikere med sine kolleger. Dette kan f.eks. gøres via openssl:
# Create a key
$ openssl genrsa -out witness.key 2048
# Create a CSR with a SAN that corresponds to the witness's IP or hostname
$ openssl req -new -sha256 -key own.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=witness" \
-addext "subjectAltName=IP:172.22.1.3" --out witness.csr
# Sign it
$ openssl x509 -req -days 1825 -in witness.csr -CA CA.pem -copy_extensions copy \
-CAkey CA.key -out witness.pem -set_serial 01 -sha256
Gem også de resulterende witness.key og witness.pem i /var/etcd.
Register Witness to Cluster¶
Følg de normale instruktioner fra afsnittet Registering a New Node for at signalere til den eksisterende klynge, at der er tilføjet et nyt medlem med de(n) angivne URL(er).
Skriv svaret fra klyngen ned: Det bør indeholde en liste over klyngemedlemmer og et joiner-kit (du får ikke brug for denne del).
Configure etcd¶
I modsætning til NetHSM’er, som automatisk vælger et nodenavn til sig selv (ved hjælp af enhedens ID), skal du vælge et navn til hvert vidne, du tilføjer, og sørge for, at navnene er unikke. Vi bruger »witness1« i de følgende eksempler.
Med NetHSM’s svar på registrering af vidnet skal du udarbejde variabler af formularen:
export ETCD_NAME="witness1"
export ETCD_DATA_DIR="/var/etcd/data"
export ETCD_INITIAL_CLUSTER="peer1=url1,peer1=url2,peer2=url1,peer2=url2,..."
export ETCD_INITIAL_ADVERTISE_PEER_URLS="my_url1,my_url2,..."
Hvis vi antager, at svaret fra NetHSM er gemt i en response.json fil, kan du generere disse to sidste variabler automatisk med følgende jq udtryk:
export ETCD_INITIAL_CLUSTER=$(jq --raw-output '[.members[] | ["\(if .name == "" then "witness1" else .name end)=\(.urls[])"]] | flatten | join(",")' < response.json)
export ETCD_INITIAL_ADVERTISE_PEER_URLS=$(jq --raw-output '.members[] | select(.name=="") | .urls | join(",")' < response.json)
For eksempel med det eksempel på svar, der findes i afsnittet Registrering af et nyt knudepunkt, vil du få:
ETCD_NAME="witness1"
ETCD_DATA_DIR="/var/etcd/data"
ETCD_INITIAL_CLUSTER="witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.1.3:2380"
Til sidst skal du oprette en etcd.conf.yml-fil ved at bruge den skabelonfil, der findes i docs/etcd_witness.conf.template:
$ envsubst < NETHSM_ROOT/docs/etcd_witness.conf.template > /var/etcd/witness.conf.yml
$ cat witness.conf.yml
Det burde give dig en fil med formularen:
name: witness1
data-dir: /var/etcd/data
log-level: warn
log-format: console
listen-peer-urls: https://0.0.0.0:2380
listen-client-urls: http://localhost:2379
initial-advertise-peer-urls: https://172.22.1.3:2380
advertise-client-urls: http://localhost:2379
initial-cluster: witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380
initial-cluster-state: 'existing'
peer-transport-security:
cert-file: witness.pem
key-file: witness.key
client-cert-auth: true
trusted-ca-file: CA.pem
skip-client-san-verification: true
Start etcd¶
Start etcd på din foretrukne måde (manuelt, systemd service, container osv.), og peg på den konfigurationsfil, der blev oprettet i det foregående trin:
$ cd /var/etcd
$ etcd --config-file witness.conf.yml
Du skulle gerne se den starte, slutte sig til klyngen og indhente data. Efter et stykke tid bør du kunne tjekke, at den er sund og rask med klienten etcdctl:
etcdctl get /config/version
Denne nøgle skal eksistere og indeholde »1«.
Sørg for, at denne proces bliver ved med at køre, da den nu er et rigtigt medlem af din klynge. Hvis du skal afvikle den, skal du først fjerne den korrekt fra klyngen (se det dedikerede afsnit). Hvis dens tilgængelige IP ændres, skal du opdatere dens URL fra klyngen.
Operating a Cluster¶
Sikkerhedskopiering og gendannelse¶
Backup-operationen fungerer på samme måde som uden en klynge og kan rekvireres fra enhver node i klyngen. Den vil sikkerhedskopiere data for hele klyngen, inklusive nodespecifikke felter (selvom disse vil blive ignoreret, medmindre sikkerhedskopien gendannes på en ikke-provisioneret node).
En backup, der er lavet på en klynge, kan gendannes på den samme klynge, selv om nogle noder er blevet tilføjet eller fjernet siden. Sådanne gendannelser på operationelle klynger vil ikke påvirke konfigurationsværdier (kun nøgler, brugere, navneområder), ligesom enhver anden delvis gendannelse.
Gendannelse af en sikkerhedskopi på en ikke-provisioneret node vil gendanne de nodespecifikke felter (som netværkskonfiguration, certifikater osv.) på den node, der blev brugt til at oprette sikkerhedskopien.
Gendannelse af en stor backup kan overbelaste klyngen i nogen tid, mens den node, der foretager gendannelsen, videresender ændringer til de andre.
Denne handling forbliver kompatibel med sikkerhedskopier, der er lavet på tidligere versioner af NetHSM.
Bemærk
Hvis man på en node A gendanner en backup, der er lavet på en anden node Z med en anden domænenøgle, vil A’s domænenøgle blive omskrevet korrekt som før. Men hvis A var i en klynge med node B, vil B blive ubrugelig, da Z’s domænenøgle ikke vil blive gendannet på B.
Med andre ord skal du kun udføre en gendannelse i en klynge med sikkerhedskopier, der er lavet i samme klynge (selvom der igen kan være fjernet eller tilføjet noder siden). Hvis du vil gendanne en fremmed sikkerhedskopi på en node, skal du først fjerne den sikkert fra dens klynge, derefter fabriksindstille den og gendanne sikkerhedskopien.
Fjernelse af et knudepunkt på en ren måde¶
Så længe en del af klyngen stadig er beslutningsdygtig, kan ethvert af dens medlemmer bruges til at fjerne en anden node fra klyngen, uanset om denne node allerede er utilgængelig eller forventes at blive det.
Du skal først kende ID’et på den node, du vil fjerne, ved at liste alle noder via GET /cluster/members og lede efter den rigtige.
Derefter kan den fjernes ved at kalde DELETE /cluster/members/<id>. Hvis den pågældende node stadig var sund, vil dette isolere den fra resten af klyngen og gøre den ubrugelig.
Software Updates in Clusters¶
Fremtidige opdateringer vil blive markeret som »klyngesikker« (det burde være de fleste) eller »klyngeusikker«.
Klyngesikre opdateringer kan anvendes på noder, der er en del af en klynge, uden at fjerne dem fra klyngen først. Men som med alle andre operationer skal du sørge for at gøre det på én node ad gangen og i en klynge, hvor det at fjerne en node ikke går under quorum (f.eks. hvis opdateringen mislykkes).
Klynge-usikre opdateringer skal anvendes på isolerede noder. Du skal afmontere klyngen (fjerne noder en efter en), fabriksnulstille alle noder undtagen én, anvende opdateringen på alle noder og derefter få alle nulstillede noder til at slutte sig til den resterende node.
Sørg for at tage backup før sådanne operationer.
Rekonfigurering af en eksisterende klynge¶
Changing the Cluster CA¶
En eksisterende klynge (med to eller flere noder) kan ikke ændre sin klynge-CA, mens den er i drift. Hvis du har brug for at ændre certifikatet, skal du vælge en node, fjerne alle andre noder, opdatere CA’et og derefter få de andre medlemmer til at tilslutte sig igen.
Changing the Network Configuration of Nodes¶
Hvis man ændrer en nodes netværkskonfiguration (f.eks. ændrer dens IP), informeres de andre noder automatisk om opdateringen. Du bør dog sikre dig, at du kun udfører sådanne opdateringer på en enkelt node ad gangen og i en klynge, hvor tabet af den pågældende node ikke vil medføre tab af quorum.