Clustering¶
Note
Понастоящем тази функция е техническа предварителна версия със следните временни ограничения:
Ако клъстерът е изгубен (кворумът е изгубен), единственият начин за възстановяване е фабрично нулиране + възстановяване. Уверете се, че често правите резервно копие. Бъдещите версии ще включват средства за възстановяване на данни от диска.
Все още не е налична активна/пасивна настройка за поддръжка на клъстери с два възела чрез използване на etcd Learner или Mirror.
Засега системното време между възлите трябва да се синхронизира ръчно. Бъдеща версия ще включва автоматично синхронизиране на часовника.
NetHSM от версия 4.0 нататък поддържа клъстериране за директно синхронизиране на данни между няколко NetHSM. Това поддържа висока честота на генериране на ключове, реализира висока наличност и балансиране на натоварването. Клъстерът на NetHSM се основава на etcd, който използва консенсусния алгоритъм Raft за силна съгласуваност. Това гарантира, че данните (напр. ключовете) са верни във всички NetHSM по всяко време.
Преди да настроите клъстер NetHSM, се запознайте с тази технология и нейните ограничения, за да избегнете случайно прекъсване и загуба на данни. В допълнение към този документ може да направите справка и с документацията на etcd.
Operational Redundancy¶
Ще наричаме „възел“ NetHSM, който се очаква да бъде част от клъстер. Един клъстер от N възли ще продължи да работи, докато поне (N/2)+1 възли са здрави и достъпни. Този минимален брой здрави и достижими възли се нарича кворум.
Това предполага следните сценарии.
Един възел не работи, а кворумът все още е достигнат¶
В клъстер с три възела, ако един възел се повреди (срине се или стане недостъпен поради мрежови условия), другите два възела ще продължат да работят и да обслужват заявки.
Ако повреденият възел все още е здрав (например става дума за мрежов проблем), той няма да може да работи, докато е изолиран (дори само за четене).
Ако обаче възелът се възстанови, той чисто се ресинхронизира с останалата част от клъстера и отново става работоспособен, без да губи данни.
Ако не се възстанови, трябва да се отстрани от клъстера (вж. следващия раздел), да се възстанови фабричната му настройка и да се премине отново през процеса на присъединяване отначало.
Настъпва разделяне на мрежата и кворумът все още е достигнат¶
Това е просто обобщение на предишния сценарий. В клъстер с 5 възела, където например 3 възела са на едно физическо място А и 2 възела са на друго място В, мрежовият проблем, изолиращ А и В, би означавал следното:
Трите възела в местоположение А отговарят на кворума (3 в този случай), така че продължават да работят.
Двата възела в местоположение B не отговарят на кворума (все още 3), така че те ще спрат да работят (дори само за четене).
Ако проблемът с мрежата е решен, двата възела ще се присъединят обратно към останалите три.
Кворумът е трайно загубен¶
При повреда, в резултат на която всички подмножества на клъстера загубят кворум, клъстерът и неговите данни ще бъдат напълно загубени, освен ако повредата не бъде отстранена. В този случай възлите трябва да бъдат фабрично нулирани и да бъде възстановено резервно копие.
Това може да се случи например при отказ на един възел в клъстер с два възела (където кворумът е 2). В тази ситуация отказалият възел не може да бъде отстранен от клъстера, тъй като останалият здрав възел вече не работи, тъй като е загубил кворум.
Ето защо се препоръчва винаги да имате нечетен брой възли в клъстера и често да правите резервни копия.
За да сме наясно, временно загубата на кворум (например ако рестартирате всички възли на клъстера заедно или временна повреда в мрежата изолира възлите) не е проблем: след като достатъчно възли се свържат отново (без да се налага ръчно повторно свързване), за да достигнат кворум, клъстерът ще възобнови нормалната си работа. Само при постоянни повреди, като например мрежови раздели, неправилна конфигурация на мрежата, проблеми с удостоверяването или хардуерни повреди, се изисква ръчно действие.
За повече информация вижте ЧЕСТО ЗАДАВАНИ ВЪПРОСИ на etcd.
Клъстер с 2 възела¶
Активен/пасивен клъстер с два възела все още не се поддържа и ще бъде добавен в бъдеща версия. Препоръчваме въвеждането на трети възел, или трети NetHSM, или „свидетел“ на etcd, който може да се използва на всеки хост. Вижте следващия раздел „Свидетел“.
Свидетел¶
Естеството на клъстерирането с etcd го прави толкова по-надеждно, колкото повече възли има в клъстера. Както е обяснено в раздела `Operational Redundancy (Оперативно резервиране) `_, в идеалния случай клъстерите трябва да имат поне 3 възела, за да има място за отказ, тъй като клъстер с 2 възела ще се провали изцяло, ако само единият се откаже.
Въпреки това дизайнът на функцията е такъв, че не е необходимо да добавяте пълно, истинско устройство NetHSM към вашия клъстер, за да достигнете стабилен брой възли. Вместо това можете сами да разгърнете и добавите възел „свидетел“. Такъв възел е просто инстанция на etcd, работеща на избрана от вас машина (или в контейнер) и свързана с клъстера. Той ще бъде разпознат като нормален възел от реалните устройства в клъстера и ще получава всички данни и актуализации от устройствата (но, разбира се, няма да можете да извършвате никакви HSM операции с него - той само съхранява данни).
Security Considerations¶
Свидетелският възел (или всеки, който има достъп до него) има директен достъп до бекенда за съхранение на всички възли в клъстера (например можете да изведете всички записи и съответните стойности с etcdctl get "/" "0").
Въпреки това, с изключение на версията на конфигурацията (/config/version, която винаги трябва да бъде „1“), стриктно всички стойности са криптирани (или с ключ на устройството за стойности, специфични за възел, или с ключове на домейна за други), което гарантира поверителността на чувствителните данни.
Имайте предвид обаче, че злонамерен възел може да:
да запишете боклук като стойност за всеки запис в хранилището, което ще доведе до неуспешно декриптиране от възлите (което може да доведе до сривове за някои системни записи).
списък с имена на записи, като например потребители, пространства от имена и ключове, които може да считате за чувствителни.
Creating a Cluster¶
Първоначално всеки клъстер ще започне от един възел. Нови възли се присъединяват към клъстера един по един.
Preparing Nodes¶
Мрежовият трафик между възлите се криптира и удостоверява с помощта на техния TLS сертификат.
Всички възли, които се очаква да бъдат част от един и същ клъстер, трябва първо да инсталират общ удостоверяващ орган (CA), който ще им позволи да проверяват дали другите възли са легитимни.
По-долу приемаме, че всички възли са прясно осигурени и функционират.
Networking¶
Nodes must first be reconfigured with their expected final network configuration using the /config/network endpoint (refer to the API documentation).
Създаване и инсталиране на CA¶
Потребителите трябва да създадат УО със собствени средства и в съответствие със собствените си оперативни ограничения, като се уверят, че той позволява поне използването на keyCertSign ключ.
Например минимален CA може да бъде създаден с 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
Сега този CA трябва да бъде инсталиран на всеки възел.
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).
Note
За правилното удостоверяване на възлите бекендът за клъстериране (etcd) очаква всеки възел да има сертификат с правилно попълнено поле Subject Alt Names (SAN). По-специално, възлите, до които се очаква да бъдат достигнати само чрез техния IP, трябва да имат правилно попълнен IP SAN в сертификата си. IP SAN могат да бъдат поискани за CSR чрез поставяне на префикс „IP:“ към имената, както в openssl:
"subjectAltNames": [ "normalname.org", "IP:192.168.1.1" ]
Като имаме получения CSR (нека го наречем nethsm.csr), можем да генерираме сертификат за него, готов за инсталиране. Например с 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).
И накрая, CA (CA.pem) вече може да се инсталира с крайната точка /config/tls/cluster-ca.pem (вижте документацията на API). Това е възможно само след като инсталираният TLS сертификат е подписан от него. В противен случай операцията ще бъде отхвърлена.
Note
Този процес трябва да се повтори за всеки възел.
Синхронизация на часовника¶
Уверете се, че всеки възел е снабден с точно системно време. Ако това не е така, настройте часовниците им с помощта на крайната точка /config/time.
Adding a New Node¶
Добавянето на възел към клъстер се извършва в две стъпки:
регистриране на допълнението към клъстера (чрез някой от членовете му).
съобщаване на новия възел да се присъедини
Configure a Backup Passphrase¶
Първо се уверете, че е конфигурирана резервна парола на възела, който ще се използва за регистриране на нов присъединител (вижте документацията на API на крайната точка /config/backup-passphrase).
Регистриране на нов възел¶
Warning
Регистрирането на възел незабавно въвежда нов възел в клъстера, като променя прага на кворума, дори ако възелът всъщност все още не се е присъединил. Това може да направи съществуващите възли неработоспособни, докато новият възел не се присъедини. Обърнете се към документацията на API и към раздела Operational Redundancy на този документ.
Имайте под ръка IP адреса на възела, който ще се присъедини. Пълният URL адрес (наричан също peer URL адрес в терминологията etcd) на този възел ще бъде https://<IP_of_node>:2380 (например https://192.168.1.1:2380). Портът трябва да бъде 2380, така че се уверете, че всяка защитна стена между възлите ще позволява TCP трафик на този порт.
Можете да проверите два пъти дали URL адресът е правилен, като извикате GET /cluster/members на възела, към който се очаква да се присъедините. Това трябва да изведе само един член: самия него.
След това регистрирайте този очакван URL адрес във всеки съществуващ възел на клъстера (ако все още нямате клъстер, направете това в NetHSM, който ще служи като начален възел на клъстера). Това се прави с помощта на крайната точка POST /cluster/members (вижте документацията на API), като ѝ предадете JSON тяло, съдържащо URL адреса.
При успех се връща JSON тяло на формуляра:
{
"members": [
{
"name": "",
"urls": [
"https://172.22.1.3:2380"
]
},
{
"name": "9ZVNM2MNWP",
"urls": [
"https://172.22.1.2:2380"
]
}
],
"joinerKit": "eyJiYWNrdXBfc2FsdCI6IkVlUzNPOEhHSEc5NnlNRktrdG1NZmc9PSIsInVubG9ja19zYWx0IjoiU3phMkEvYW13NlhxVWsrdHZMMmFubm5SZFlWd2ZQUjdpZ3IxK1RSdTdVaU14dmh3d0x2NWIvYVNkY2c9IiwibG9ja2VkX2RvbWFpbl9rZXkiOiIyMnNGVlkyelhQUVZ6S1pQenI3MmkwTk1WM3lmQ2k5dGwzeDhUbGtuOXM0WjFOd3JoZkRQTFZIVHp1WVl0YkQxaVZCMlovV3JHUHJlMXlwN0t4U0w4WkxjY2ZUTmUzcFg0WXE4YXNlY0wwREhXNGlIaXlPMlZnPT0ifQ=="
}
която съдържа необходимата информация за присъединяването на новия възел към клъстера. По-специално, в него се изброяват всички членове на клъстера (където членът с празно име е новият присъединяващ се). Той съдържа и ключа на домейна, криптиран с паролата за отключване и паролата за резервно копие - така че преди това трябва да е била конфигурирана парола за резервно копие.
Запазете този отговор за следващата стъпка.
Действително присъединяване към клъстера¶
Вземете отговора от последната стъпка и добавете към него поле backupPassphrase, съдържащо резервната парола на възела, на който е регистриран новият присъединяващ се, и предайте тези данни на извикване на POST /cluster/join (вижте документацията на API) на възела, към който се очаква да се присъедини.
Ако приемем, че и клъстерът, и възелът могат да се свържат помежду си, ще се осъществи действителното присъединяване, като се изтрият данните на новия присъединяващ се, за да се синхронизира състоянието му с това на клъстера.
В зависимост от условията на мрежата и клъстера тази операция може да отнеме няколко десетки секунди. Ако тази операция се провали веднага (например клъстерът не е бил достъпен или удостоверяването е било неуспешно), състоянието на този възел няма да бъде изтрито и присъединяването ще бъде върнато. Въпреки това, веднага щом първото присъединяване е успешно, тази операция е окончателна и може да бъде върната само чрез възстановяване на фабричните настройки.
Ако това присъединяване е успешно, възелът ще се окаже в състояние Locked и трябва да бъде отключен с паролата за отключване на възела, която е използвана за регистрация. След това паролата за отключване може да бъде променена (паролите за отключване остават специфични за всеки възел и не се споделят между възлите).
Note
Дори след успешното присъединяване, ако базата данни на клъстера е голяма или ако клъстерът е зает, може да отнеме известно време на новия участник да синхронизира напълно състоянието си. През това време всички възли (включително и новият участник) може да реагират по-слабо или да не реагират. По-специално новият присъединител може първоначално да връща грешки при опит за отключване например. В такъв случай дайте му известно време и опитайте отново.
Adding a Witness Node¶
Prepare a Witness¶
Ще ви е необходима среда с налична версия etcd v3.6, с IPv4 адрес (поне), който да е достъпен за другите членове на вашия клъстер. Трябва да бъде разрешен TCP трафикът към и от порт 2380.
Създайте празна директория, в която etcd ще съхранява данните си, и запишете пътя до нея (ние ще използваме /var/etcd/data). Уверете се, че потребителят, който ще стартира процеса, има право да чете и записва в директорията.
Прехвърлете на машината сертификата на CA, който се използва за удостоверяване на възлите в клъстера. Трябва да сте създали такъв сертификат в раздела Creating and Installing a CA (Създаване и инсталиране на удостоверяващ орган). Ще го съхраняваме в /var/etcd/CA.pem.
След това ще трябва да създадете сертификат за свидетеля и да го подпишете с удостоверяващия орган, за да може той да комуникира със своите колеги. Това може да се направи например чрез 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
Съхранявайте получените witness.key и witness.pem и в /var/etcd.
Register Witness to Cluster¶
Следвайте обичайните инструкции от раздела Registering a New Node (Регистрация на нов възел), за да сигнализирате на съществуващия клъстер за добавянето на нов член със зададения(ите) URL адрес(и).
Запишете отговора от клъстера: той трябва да съдържа списък на членовете на клъстера и комплект за присъединяване (тази част няма да ви е необходима).
Configure etcd¶
За разлика от NetHSM, които автоматично избират име на възел за себе си (като използват идентификатора на устройството), трябва да изберете име за всеки добавен свидетел, като се уверите, че имената са уникални. В следващите примери ще използваме „свидетел1“.
С отговора на NetHSM за регистриране на свидетеля подгответе променливи на формуляра:
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,..."
Ако приемем, че отговорът на NetHSM се съхранява във файл response.json, можете да генерирате последните две променливи автоматично със следните изрази jq:
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)
Например с примерния отговор, предоставен в раздела Регистриране на нов възел, ще получите:
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"
Накрая създайте файл etcd.conf.yml, като използвате файла-шаблон, предоставен в docs/etcd_witness.conf.template:
$ envsubst < NETHSM_ROOT/docs/etcd_witness.conf.template > /var/etcd/witness.conf.yml
$ cat witness.conf.yml
Това ще ви даде файл с формата:
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¶
Стартирайте etcd по предпочитания от вас начин (ръчно, systemd услуга, контейнер и т.н.), като го насочите към конфигурационния файл, създаден в предишната стъпка:
$ cd /var/etcd
$ etcd --config-file witness.conf.yml
Трябва да видите, че той започва да работи, присъединява се към клъстера и наваксва с данните. След известно време трябва да можете да проверите дали той е здрав с помощта на клиента etcdctl:
etcdctl get /config/version
Този ключ трябва да съществува и да съдържа „1“.
Уверете се, че този процес продължава да работи, тъй като сега той е пълноправен член на вашия клъстер. Ако трябва да го изведете от експлоатация, първо го премахнете правилно от клъстера (вижте специалния раздел). Ако достижимият му IP адрес се промени, актуализирайте URL адреса му от клъстера.
Operating a Cluster¶
Архивиране и възстановяване¶
Операцията за архивиране работи по същия начин, както без клъстер, и може да бъде заявена от всеки възел на клъстера. Тя ще архивира данните за целия клъстер, включително полетата, специфични за възела (въпреки че те ще бъдат пренебрегнати, освен ако не възстановите резервното копие на невъведен възел).
Резервно копие, направено на клъстер, може да бъде възстановено на същия клъстер, дори ако някои възли са били добавени или премахнати след това. Такива възстановявания, извършени на оперативни клъстери, няма да засегнат стойностите на конфигурацията (само ключове, потребители, пространства от имена), както всяко друго частично възстановяване.
Възстановяването на резервно копие на възел, който не е предоставен, ще възстанови специфичните за възела полета (като мрежова конфигурация, сертификати и др.) на възела, който е използван за създаване на резервното копие.
Възстановяването на голямо резервно копие може да претовари клъстера за известно време, докато възелът, който прилага възстановяването, препраща промените към останалите.
Тази операция остава съвместима с резервни копия, направени с предишни версии на NetHSM.
Note
Възстановяването във възел A на резервно копие, направено в друг възел Z с различен ключ на домейна, ще презапише правилно ключа на домейна на A, както преди. Ако обаче A е бил в клъстер с възел B, B ще стане неработещ, тъй като ключът на домейна Z няма да бъде възстановен на B.
С други думи, възстановявайте само в клъстер, чиито резервни копия са направени в същия клъстер (въпреки че оттогава възлите може да са били премахнати или добавени). Ако искате да възстановите чуждо резервно копие на даден възел, първо го премахнете безопасно от неговия клъстер, след това го нулирайте фабрично и възстановете резервното копие.
Чисто премахване на възел¶
Докато част от клъстера все още отговаря на кворума, всеки от неговите членове може да бъде използван за отстраняване на друг възел от клъстера, независимо дали този възел вече е недостъпен, или се очаква да бъде.
Първо трябва да знаете идентификатора на възела, който искате да премахнете, като направите списък на всички възли чрез GET /cluster/members и потърсите правилния.
След това тя може да бъде премахната чрез извикване на DELETE /cluster/members/<id>. Ако въпросният възел все още е бил здрав, това ще го изолира от останалата част на клъстера и ще го направи неработещ.
Software Updates in Clusters¶
Бъдещите актуализации ще бъдат маркирани като „безопасни за клъстера“ (това трябва да е мнозинството) или „опасни за клъстера“.
Актуализациите, защитени от клъстери, могат да бъдат прилагани към възли, които са част от клъстер, без те да бъдат премахвани от клъстера. Въпреки това, както при всички операции, трябва да се уверите, че това се прави на един възел в даден момент и в клъстер, в който премахването на възел не води до намаляване на кворума (напр. ако актуализацията се провали).
Актуализациите, които не са безопасни за клъстера, трябва да се прилагат към изолирани възли. Трябва да разглобите клъстера (като премахвате възлите един по един), да възстановите фабричните настройки на всички възли с изключение на един, да приложите актуализацията на всеки възел, след което да накарате всички възли да се присъединят към останалия възел.
Не забравяйте да направите резервно копие преди такива операции.
Преконфигуриране на съществуващ клъстер¶
Changing the Cluster CA¶
Съществуващ клъстер (с два или повече възела) не може да промени своя CA на клъстера по време на работа. Ако трябва да промените този сертификат: изберете възел, премахнете всички останали възли, актуализирайте CA, след което накарайте останалите членове да се присъединят отново.
Changing the Network Configuration of Nodes¶
Промяната на мрежовата конфигурация на даден възел (например промяна на неговия IP адрес) автоматично информира останалите възли за актуализацията. Трябва обаче да се уверите, че извършвате такива актуализации само на един възел в даден момент и в клъстер, в който загубата на този възел няма да доведе до загуба на кворум.