hashicorp vault в режиме HA с integrated storage(raft)

Thank you for reading this post, don't forget to subscribe!

1.Общее по hashicorp vault
2.Установка keepalived
3.Установка hashicorp vault
3.1Создание клю­чей
3.2.Конфигурация vault
3.3.Добавление сер­ти­фи­ка­тов в доверенные
4.Создание мето­да аутен­ти­фи­ка­ции user/password
4.1Создание admin policy для user
4.2.Добавление group с admin правами
4.3.Добавление допол­ни­тель­но­го поль­зо­ва­те­ля в группу
4.4 Настро­им все те же досту­пы но с помо­щью команд
5.Аутентификация через gitlab
6. Auto unseal hashicorp vault
6.1 уста­нов­ка minikub
6.2 под­го­тов­ка хра­ни­ли­ща для PV (nfs)
6.3 уста­нов­ка vault в minikub
6.4 auto unseal vault с помо­щью дру­го­го vault
7.Бэкап данных(backup raft)
8. Настрой­ка LDAP — freeipa
9. Добав­ля­ем сек­ре­ты из vault в POD (vault уста­нов­лен в k8s)
9.1 secrets-store-csi-driver
9.2 Vault Secrets Operator (наи­бо­лее опти­маль­ный вари­ант для использования)
9.2.1 При­мер с под­ки­ды­ва­ни­ем сек­ре­та в deployment
9.2.2 Вклю­че­ние Vault Secrets Operator reloader

10.SSH аутен­ти­фи­ка­ция через vault
10.1 SSH аутен­ти­фи­ка­ция через vault OTP (вре­мен­ный пароль)
10.2 SSH аутен­ти­фи­ка­ция через vault SSH (certificate authority)

 

Vault поз­во­ля­ет хра­нить сек­ре­ты, токе­ны, паро­ли, сер­ти­фи­ка­ты и т.п., предо­став­ляя к ним огра­ни­чен­ный и без­опас­ный доступ. Есте­ствен­но, внут­ри Vault все хра­нит­ся в зашиф­ро­ван­ном виде.
Под катом про­це­ду­ра инстал­ля­ция и запуск Vault на трех узлах в отка­зо­устой­чи­вом режиме.

В про­стом вари­ан­те Vault состо­ит из неко­то­ро­го коли­че­ства вза­и­мо­свя­зан­ных меж­ду собой сер­ве­ров, один из кото­рых рабо­та­ет в режи­ме active, а осталь­ные в режи­ме standby.

HA, либо High Availability поз­во­ля­ет выдер­жать поте­рю одно­го или несколь­ких узлов (в зави­си­мо­сти от кофи­гу­ра­ции), сохра­нив при этом доступ к дан­ным. Не со все­ми бэк­эн­да­ми, исполь­зу­е­мы­ми для хра­не­ния, воз­мож­но исполь­зо­вать HA механизм.

Для хра­не­ния дан­ных Vault может исполь­зо­вать боль­шое коли­че­ство бэк­эн­дов.

Пол­но­стью под­дер­жи­ва­е­мые HC бэк­эн­ды (не все, но основные):
Filesystem – назва­ние гово­рит само за себя. Хра­ним дан­ные на локаль­ной фай­ло­вой систе­ме, там же, где и уста­нов­лен Vault. Не под­хо­дит для HA конфигурации;

Consul – Так же явля­ет­ся раз­ра­бот­кой HashiCorp. Исполь­зо­ва­ние в каче­стве бэк­эн­да поз­во­ля­ет реа­ли­зо­вать Vault HA. Одна­ко, дан­ный вари­ант потре­бу­ет раз­вер­ты­ва­ния допол­ни­тель­ных машин и орга­ни­за­ции отдель­но­го кла­сте­ра Consul (ну либо все в одном, но я не люби­тель такого);

Integrated Storage (Raft) – дан­ные Vault так же хра­нят­ся на фай­ло­вой систе­ме, но при этом реп­ли­ци­ру­ют­ся на дру­гие узлы кла­сте­ра, поз­во­ляя им оста­вать­ся доступ­ны­ми даже в слу­чае выхо­да из строя одно­го из узлов. Дан­ный вари­ант под­дер­жи­ва­ет функ­ци­о­нал HA.

Мой выбор в дан­ном слу­чае – Integrated Storage.

Итак, нач­нем с под­го­тов­ки машин. В моем слу­чае это три маши­ны (мини­маль­ное коли­че­ство для кворума) 

добав­ля­ем в hosts на все тачки

cat /etc/hosts

192.168.1.171 vault1 vault1.test.local
192.168.1.172 vault2 vault2.test.local
192.168.1.173 vault3 vault3.test.local
192.168.1.174 vault.test.local

айпиш­ник 192.168.1.174 - виртуальный

ста­вим на все тачки:

yum install -y yum-utils wget curl
yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

и отклю­ча­ем SELINUX на ВСЕХ тачках

cat /etc/selinux/config

sed -i 's|SELINUX=enforcing|SELINUX=disabled|g' /etc/selinux/config

ребу­та­ем­ся.

теперь поставим keepalived ОБЯЗАТЕЛЬНО 2 версии

на каж­дую ноду ставим:

wget http://www.nosuchhost.net/~cheese/fedora/packages/epel-7/x86_64/cheese-release-7-1.noarch.rpm
rpm -Uvh cheese-release*rpm
yum install keepalived -y

systemctl enable keepalived

если есть firewall то добав­ля­ем в раз­ре­шён­ные про­то­кол vrrp

firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
firewall-cmd --reload

mkdir /usr/libexec/keepalived/

chmod +x /usr/libexec/keepalived/vault-health

mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.old

cat /etc/keepalived/keepalived.conf

groupadd -r keepalived_script
useradd -r -s /sbin/nologin -g keepalived_script -M keepalived_script
systemctl enable --now keepalived.service

Далее ставим vault

yum -y install vault

про­ве­ря­ем:

Откры­ва­ем необ­хо­ди­мые для рабо­ты Vault порты:

Далее необ­хо­ди­мо обза­ве­стись сер­ти­фи­ка­та­ми. Если тако­вые отсут­ству­ют – выпу­стить свои, само­под­пи­сан­ные. Все опе­ра­ции я выпол­няю с пер­вой ноды.

Спер­ва выпу­стим свой CA сер­ти­фи­кат, а затем с его помо­щью под­пи­шем сер­ти­фи­ка­ты для всех узлов кластера:

Теперь под­го­то­вим кон­фи­гу­ра­ци­он­ные фай­лы, содер­жа­щие Subject Alternate Name (SAN) для каж­до­го из узлов. Важ­но, что­бы в SAN был кор­рект­ней хост­нейм и IP каж­до­го узла:

Теперь для каж­до­го из узлов сфор­ми­ру­ем CSR файл:

И выпу­стим сер­ти­фи­ка­ты на осно­ва­нии запросов:


вывод следующий:

Ско­пи­ру­ем сер­ти­фи­ка­ты и клю­чи на узлы B и C:

На каж­дом из узлов уста­но­вим соот­вет­ству­ю­щие пра­ва для досту­па к фай­лам сер­ти­фи­ка­тов и ключам:

Теперь, когда для каж­дой из нод гото­вы сертификаты.

 

Перей­дем к кон­фи­гу­ра­ции Vault.
Отре­дак­ти­ру­ем кон­фи­гу­ра­ци­он­ный файл vault для пер­вой ноды:

вто­рая нода:

cp /etc/vault.d/vault.hcl /etc/vault.d/vault.hcl.backup

[root@vault2 ~]# cat /etc/vault.d/vault.hcl

тре­тья нода:

cp /etc/vault.d/vault.hcl /etc/vault.d/vault.hcl.backup

[root@vault3 ~]# cat /etc/vault.d/vault.hcl

Обра­ти­те вни­ма­ние как меня­ют­ся поля с адре­са­ми, сер­ти­фи­ка­та­ми, а так­же node_id.

api_addr – адрес и порт, на кото­ром будет досту­пен API сервер;
cluster_addr – адрес и порт по кото­ро­му будут вза­и­мо­дей­ство­вать кла­стер­ные сервисы;
disable_mlock – реко­мен­ду­е­мый пара­метр при исполь­зо­ва­нии Integrated Storage;
ui – вклю­че­ние досту­па к веб-интер­фей­су Vault;
в сек­ции listener ука­зы­ва­ют­ся сер­ти­фи­ка­ты, кото­рые будут исполь­зо­ва­ны при сете­вом вза­и­мо­дей­ствии. У каж­дой ноды они свои, за исклю­че­ни­ем CA, дан­ный сер­ти­фи­кат оди­на­ко­вый для всех.

Сек­цию storage сто­ит так же рассмотреть:
path = “/opt/vault/data” – дирек­то­рия, где будут хра­нить­ся дан­ные Vault;
node_id = “vault-a.vmik.lab” – id, с кото­рым нода будет участ­во­вать в кла­сте­ре. У каж­дой ноды он дол­жен отличаться;
Далее идут несколь­ко сек­ций retry_join, с пере­чис­ле­ни­ем всех узлов кла­сте­ра. Посколь­ку допод­лин­но неиз­вест­но, какой из узлов будет актив­ным при запус­ке служб Vault, будет про­из­ве­де­на попыт­ка под­клю­че­ния к каж­до­му из узлов.
Здесь же ука­зы­ва­ют­ся адре­са узлов – leader_api_addrleader_tls_servername – хост­нейм сер­ве­ра, кото­рый дол­жен сов­па­дать с тем, что про­пи­са­но в сер­ти­фи­ка­те дан­но­го сер­ве­ра. Так же ука­зы­ва­ют­ся сер­ти­фи­ка­ты, кото­ры­ми кли­ент будет под­клю­чать­ся к лиде­ру (у каж­дой из нод свои сер­ти­фи­ка­ты, кото­рые мы созда­ва­ли ранее).

Теперь, когда кон­фи­гу­ра­ци­он­ные фай­лы гото­вы, воз­вра­ща­ем­ся на пер­вый узел. Добав­ля­ем Vault в авто­за­груз­ку и авто­ма­ти­че­ски его запускаем:

Про­ве­рим ста­тус Vault, пред­ва­ри­тель­но отме­нив про­вер­ку сер­ти­фи­ка­тов, выста­вив зна­че­ние спе­ци­аль­ной переменной:

Как мож­но заме­тить на теку­щий момент Vault не ини­ци­а­ли­зи­ро­ван (Initialized false), а так­же запе­ча­тан (Sealed true).

При­ме­ча­ние: доба­вив наш CA файл, сге­не­ри­ро­ван­ный ранее, в спи­сок дове­рен­ных сер­ти­фи­ка­тов, при­бе­гать к отмене про­вер­ки сер­ти­фи­ка­тов будет необязательно.

Ини­ци­а­ли­зи­ру­ем Vault:

vault operator init

Vault выдаст 5 клю­чей, кото­рые необ­хо­ди­мо исполь­зо­вать при «рас­пе­чат­ке». Как ска­за­но выше, после каж­дой оста­нов­ки либо пере­за­пус­ка, Vault будет вновь нахо­дить­ся в запе­ча­тан­ном состо­я­нии и для откры­тия нуж­но будет исполь­зо­вать любые три из пяти предо­став­лен­ных клю­чей. Терять эти клю­чи не стоит!
Так же нам предо­став­ля­ет­ся Root Token для досту­па к Vault с мак­си­маль­ны­ми правами.

Рас­пе­ча­та­ем Vault. Опе­ра­цию vault operator unseal нуж­но будет про­ве­сти 3 раза. Каж­дый раз с раз­ным ключом:

На дан­ном эта­пе мы настро­и­ли одну ноду Vault, а так­же ини­ци­а­ли­зи­ро­ва­ли и рас­пе­ча­та­ли ее. Теперь под­клю­чим в кла­стер две дру­гих ноды.
Ранее мы уже под­го­то­ви­ли и раз­ме­сти­ли кон­фи­гу­ра­ци­он­ные фай­лы на нодах B и C.
Под­клю­ча­ем­ся к ноде B, запус­ка­ем Vault:

systemctl enable --now vault
systemctl status vault

Теперь, в отли­чии от пер­вой ноды, ини­ци­а­ли­зи­ро­вать Vault боль­ше не нуж­но, но новая нода все еще в запе­ча­тан­ном состо­я­нии. Рас­пе­ча­та­ем ноду B:

После рас­пе­чат­ки нода будет под­клю­че­на к кла­сте­ру. Мож­но обра­тить вни­ма­ние, что новая нода нахо­дит­ся в режи­ме standby, так же мож­но опре­де­лить теку­щий адрес актив­ной ноды. Это нода A.

Под­клю­чим­ся к ноде C и выпол­ним ана­ло­гич­ные действия:

 

Теперь мы успеш­но сфор­ми­ро­ва­ли кла­стер из трех нод. Вер­нем­ся на первую и про­ве­рим состо­я­ние кластера.

Для нача­ла авто­ри­зу­ем­ся с токе­ном, кото­рый был полу­чен ранее:

И про­ве­рим ста­тус хранилища:

По ста­ту­су вид­но 3 сер­ве­ра, один из кото­рых в ста­ту­се лиде­ра, а два дру­гих – ведомые.

Попро­бу­ем доба­вить новый сек­рет в хра­ни­ли­ще. Для это­го исполь­зу­ем меха­низм kv (key-value):

И поме­стим сек­рет под име­нем db:

Посмот­рим спи­сок всех сек­ре­тов в нашем KV хра­ни­ли­ще test-secrets:

А так­же зна­че­ние сек­ре­та db:

Про­ве­рим рабо­то­спо­соб­ность меха­низ­ма HA. Отклю­чим ноду A:

[root@vault1 tls]# poweroff

Под­клю­чим­ся к ноде B и про­ве­рим статус:

HA Mode изме­не­но со standby на active. Запро­сим спи­сок узлов raft:

но сна­ча­ла пере­да­дим в пере­мен­ные окру­же­ния наш токен руто­вый, мы его полу­чи­ли когда ини­ци­и­ро­ва­ли кластер:

Лидер так же был пере­не­сен на ноду B. В завер­ше­нии запро­сим ранее создан­ный секрет:

Vault про­дол­жа­ет функ­ци­о­ни­ро­вать при поте­ре одной актив­ной ноды. Отклю­чим ноду B. Теперь из трех узлов досту­пен толь­ко один. Про­ве­рим работоспособность:

[root@vault2 ~]# poweroff

Ста­тус Vault с ноды C:

Актив­ная нода не изме­ни­лась. Нода C все так же в режи­ме standby. Ана­ло­гич­но, не удаст­ся запро­сить и сек­рет, посколь­ку запрос пере­на­прав­ля­ет­ся на ранее актив­ную ноду (B):

Запу­стим обрат­но ноду A. После запус­ка, как и ожи­да­ет­ся, нода A нахо­дит­ся в ста­ту­се sealed:

Рас­пе­ча­та­ем:

про­ве­рим:

Рабо­та кла­сте­ра вос­ста­нов­ле­на. Нода С теперь актив­ная. Доступ к сек­ре­там так же восстановлен:

Запу­стим обрат­но выклю­чен­ную ноду B и рас­пе­ча­та­ем. На этом рабо­та по настрой­ке кла­сте­ра Vault закончена.

Нерас­смот­рен­ным остал­ся один вопрос – как под­клю­чать­ся внеш­ним кли­ен­там? Под­клю­че­ние к любой из standby нод пере­на­пра­вит запрос на active ноду, поэто­му знать теку­щий адрес актив­ной ноды не обязательно.
Одна­ко, кли­ент может не знать все адре­са Vault и в слу­чае отклю­че­ния извест­ной ноды, доступ кли­ен­та к Vault может прекратиться.

Наи­бо­лее при­ем­ле­мые на мой взгляд решения:
1. Внеш­ний балан­си­ров­щик нагруз­ки меж­ду узла­ми Vault с зара­нее извест­ным и посто­ян­ным адре­сом. HAProxy, либо nginx;
2. Общий IP-адрес меж­ду узла­ми кла­сте­ра Vault, напри­мер, на осно­ве keepalived.

 

Доба­вим сер­ти­фи­ка­ты в дове­рен­ные, что­бы каж­дый раз не заки­ды­вать в пере­мен­ные окружения 

export VAULT_SKIP_VERIFY="true"

для это­го на каж­дой из нод выполним:

 

Подключимся к кластеру:

https://vault.test.local:8200/

аутен­ти­фи­ци­ру­ем­ся с помо­щью root token

Initial Root Token: hvs.yInppPkxqfAcVcODMVlvLjN3

видим создан­ный нами ранее секрет

теперь созда­дим метод аутен­ти­фи­ка­ции по user/password

созда­дим теперь пользователя

зай­дём под этим поль­зо­ва­те­лем и про­ве­рим что нам доступно:

как видим недо­ста­точ­но доступов.

 

теперь создадим admin policy пример возьмём отсюда:

https://learn.hashicorp.com/tutorials/vault/policies

 

policy созда­ли, теперь нуж­но создать Entities (сущ­но­сти)

логи­ним­ся под нашим поль­зо­ва­те­лем и про­ве­рям какие теперь есть доступы:

как видим теперь мы видим все наши сек­ре­ты воз­мож­ность созда­вать новые policy тоже появи­лась, попро­бу­ем создать новый секрет:

как видим сек­рет создался.

====================================================

Создание группы с админскими правами

созда­ём сущ­ность Entities и alias для неё. alias дол­жен сов­па­дать с име­нем наше­го пользователя

"entity" - это абстракт­ное пред­став­ле­ние чело­ве­ка или сер­ви­са, кото­рый вза­и­мо­дей­ству­ет с сер­ве­ром Vault. Entity может быть свя­зан с одним или несколь­ки­ми мето­да­ми аутен­ти­фи­ка­ции, таки­ми как userpass, ldap или github, и к нему мож­но при­кре­пить поли­ти­ки для управ­ле­ния досту­пом к ресур­сам в Vault.

При исполь­зо­ва­нии мето­да аутен­ти­фи­ка­ции userpass в Vault для каж­до­го поль­зо­ва­те­ля, заре­ги­стри­ро­ван­но­го с этим мето­дом, созда­ет­ся entity. Entity хра­нит инфор­ма­цию о поль­зо­ва­те­ле, такую как имя поль­зо­ва­те­ля, пароль и любые поли­ти­ки, свя­зан­ные с ним. При вхо­де поль­зо­ва­те­ля с помо­щью userpass Vault исполь­зу­ет инфор­ма­цию, хра­ня­щу­ю­ся в entity, что­бы аутен­ти­фи­ци­ро­вать поль­зо­ва­те­ля и опре­де­лить, к каким ресур­сам у него есть доступ.

 

отме­тим что в дан­ном слу­чае мы НЕ ПРИВЯЗЫВАЕМ policy

теперь созда­ём alias

теперь созда­ём группу(в теку­щем при­ме­ре internal):

и уже тут цеп­ля­ем нашу policy

про­ве­ря­ем нашу группу:

id в members группы:

это id Entities

захо­дим под нашим поль­зо­ва­те­лем mid и про­ве­ря­ем что всё ок и досту­пов на добав­ле­ние сек­ре­тов хватает:

создадим ещё пользователя и добавим в ту же группу:

теперь доба­вим его в нашу груп­пу, для это­го созда­ём Entities

добав­ля­ем теперь в группу:

отме­чу что все эти дей­ствия я выпол­нял уже под поль­зо­ва­те­лем MID а не root

всё, мож­но теперь логи­нить­ся под этим пользователем(mid2).

 

Повторим те же действия, но с помощью команд:

  1. Созда­дим userpass - доступ по логи­ну и паролю:

  2. Созда­ём policy с досту­па admin

  3. Созда­ём поль­зо­ва­те­ля mid с авто­ри­за­ци­ей по логи­ну и паролю:

  4. созда­ём entity для поль­зо­ва­те­ля mid

    результат:

    если забы­ли id его мож­но посмот­реть вот так:

    результат:

    ещё нам нуж­на будет пере­мен­ная mount_accessor
    что­бы уви­деть mount_accessor выпол­ним команду:

    всё, мы полу­чи­ли зна­че­ние для mount_accessor и canonical_id теперь мож­но выпол­нять коман­ду на созда­ние alias для entity:

    результат:

    если забы­ли id то его мож­но посмот­реть вот так(тут будут все ключи):

    полу­чить инфор­ма­цию по нему мож­но так:

     
  5. Созда­дим теперь group к кото­рой будет при­со­еди­не­на policy и Member Entity IDs, коман­да выгля­дит вот так:

    вот результат:

     
  6. Доба­вим ново­го поль­зо­ва­те­ля в эту же груп­пу admins:

    обра­ти­те вни­ма­ние что при добав­ле­нии к груп­пе id entity ново­го поль­зо­ва­те­ля нуж­но пере­чис­лять их все.

    что­бы гля­нуть какие уже id есть в груп­пе admins можем исполь­зо­вать команду:

    vault read identity/group/name/admins | grep member_entity_ids

Аутентификация через gitlab

офф инструк­ция:

https://docs.gitlab.com/ee/integration/vault.html

идём в наш гитлаб:

добав­ля­ем:
http://localhost:8250/oidc/callback
http://127.0.0.1:8200/ui/vault/auth/oidc/oidc/callback

Application ID a4b9c2ce0b1a62d4e448450bdb4e458a123a6806549bb660e8179bf70ac13259

Secret 69fa2b783fc889b77cdfdfe20de999585d68183bcdd8341692b421e0dbacc598

пере­хо­дим в кон­соль, логи­ним­ся в vault

[root@vault3 ~]# vault login
Token (will be hidden):

токен копи­ру­ем отсюда:

vault auth enable oidc

теперь нуж­но пере­дать application ID и secret сге­не­ри­ро­ван­ный в GitLab

при­мер:

а вот то что я вставляю:

теперь надо запи­сать роль

а вот что я буду вставлять:

резуль­тат такой:

всё мож­но захо­дить через гитлаб

6. Auto unseal hashicorp vault

идея в сле­ду­ю­щем, у нас есть 2 кла­сте­ра hashicorp vault кото­рые будут делать auto unseal друг дру­га. один кла­стер у нас на отдель­ных тач­ках а вто­рой будет внут­ри k8s. Для про­сто­ты при­ме­ра поста­вим minikub

6.1 установка minikub

отклю­ча­ем selinux

[root@minikub ~]# cat /etc/selinux/config | grep -v ^#
SELINUX=disabled

ребу­та­ем сервер.

ста­вим докер:

vi /etc/yum.repos.d/docker.repo

yum -y install docker-ce

systemctl start docker

systemctl enable docker

ста­вим Conntrack - он явля­ет­ся частью плат­фор­мы Netlifier. тре­бу­ет­ся для рабо­ты слож­ной сети Kubernetes, посколь­ку узлы долж­ны отсле­жи­вать соеди­не­ния меж­ду тыся­ча­ми моду­лей и сервисов.

yum -y install conntrack

chmod +x kubectl

mv kubectl /usr/local/bin/

chmod +x minikube-linux-amd64

mv minikube-linux-amd64 /usr/local/bin/minikube

minikube start

если при запус­ке мы полу­ча­ем сле­ду­ю­щую ошибку:

мож­но запу­стить с фла­гом --force - если рабо­та­е­те из под root
minikube start --force

если хоти­те рабо­тать из под поль­зо­ва­те­ля то нуж­но доба­вить прав:

[root@minikub ~]# adduser mid
[root@minikub ~]# usermod -aG docker mid
[root@minikub ~]# su - mid
[mid@minikub ~]$ minikube start

вклю­ча­ем ingress для minikube

[root@minikub ~]# minikube addons enable ingress

и вклю­чим авто­до­пол­не­ние для kubectl

[root@minikub ~]# yum install bash-completion -y

[root@minikub ~]# echo 'source <(kubectl completion bash)' >>~/.bashrc

 

6.2 подготовка хранилища для PV (nfs)

в каче­стве хра­ни­ли­ща pv будем исполь­зо­вать nfs сервер.

192.168.1.176

настра­и­ва­ем его:

yum install nfs-utils -y

systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap

созда­дим раз­дел (мож­но и не созда­вать а выбрать удоб­ную для вас дирек­то­рию, я захо­тел сде­лать отдель­ный раздел)

lvcreate -L 5G -n nfs centos
mkfs.ext4 -L nfs /dev/centos/nfs
mkdir /nfs
mount /dev/centos/nfs /nfs/
vi /etc/fstab

добав­ля­ем пра­ва на запись:

[root@nfs ~]# chmod 777 /nfs

на кли­ент (minikub) тоже ста­вим nfs-client

yum install nfs-utils -y

systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap

теперь настра­и­ва­ем про­ви­жи­нер (provisioner)

cat rbac.yaml

cat nfs_class.yaml

cat nfs_provision.yaml

при­ме­ня­ем:

kubectl apply -f rbac.yaml
kubectl apply -f nfs_class.yaml
kubectl apply -f nfs_provision.yaml

теперь можем про­ве­рить созда­ёт­ся ли PV

cat test-claim.yaml

kubectl apply -f test-claim.yaml

про­ве­ря­ем:

как видим всё ок.
про­ве­ря­ем на nfs шаре:

всё ок.

 

6.3 установка vault в minikub

ста­вить будем в namespace vault

[root@minikub ~]# kubectl create ns vault

будем исполь­зо­вать уже гото­вые helm чар­ты для vault

для нача­ла уста­но­вим helm:

https://github.com/helm/helm/releases/tag/v3.10.3

[root@minikub ~]# wget https://get.helm.sh/helm-v3.10.3-linux-amd64.tar.gz

[root@minikub ~]# tar -zxvf helm-v3.10.3-linux-amd64.tar.gz

[root@minikub ~]# mv linux-amd64/helm /usr/local/bin/helm

Возь­мём офф чарт:

https://github.com/hashicorp/vault-helm

[root@minikub ~]# git clone https://github.com/hashicorp/vault-helm.git

попра­вим values вклю­чим raft (мож­но оста­вить по умол­ча­нию consul мож­но вооб­ще в базу дан­ных postgres всё отправить)

[root@minikub ~]# vim vault-helm/values-my.yaml

что­бы запу­стить на minikub нуж­но выклю­чить affinity

 

а вот такой вид будет при обыч­ном запус­ке в кластере:

как видим раз­ни­ца толь­ко в
affinity: {}

ста­вим сам vault:
[root@minikub ~]# helm upgrade --install vault -n vault ./vault-helm/ -f ./vault-helm/values-my.yaml

теперь нам нуж­но поста­вить Secrets store CSI driver

он потре­бу­ет­ся для под­клю­че­ния сикре­тов из vault в init контейнеры.

теперь нуж­но ини­ци­а­ли­зи­ро­вать vault

Полу­чи­ли ключ для unseal.

далее нам пона­до­бит­ся ути­ли­та jq поста­вим её:

yum install epel-release -y
yum install jq -y

cat cluster-keys.json | jq -r ".unseal_keys_b64[]"

далее рас­пе­ча­ты­ва­ем наше хра­ни­ли­ще командой:

kubectl -n vault exec vault-0 -- vault operator unseal

клю­чи выше.
Если лень вво­дить рука­ми то мож­но исполь­зо­вать цикл:

резуль­тат будет такой:

далее нуж­но собрать raft в кластер:

и рас­пе­ча­ты­ва­ем vault-1 vault-2

 

6.4 auto unseal vault с помощью другого vault

и так мы выпол­ни­ли все пред­ва­ри­тель­ные шаги:
сей­час у нас на 3х отдель­ных тач­ках рас­по­ло­жен vault и в minikub рас­по­ло­жен дру­гой vault, теперь настро­ем их auto unseal.

будет исполь­зо­вать метод Transit Auto Unseal

[root@vault1 ~]# vault login

тут я вби­вал рут токен полу­чен­ный при ини­ци­а­ли­за­ции хранилища

[root@vault1 ~]# vault secrets enable transit
Success! Enabled the transit secrets engine at: transit/

После вклю­че­ния тран­зи­та я запи­шу ключ по это­му пути:

[root@vault1 ~]# vault write -f transit/keys/vault-unseal-key
Success! Data written to: transit/keys/vault-unseal-key

[root@vault1 ~]# vault list transit/keys

Теперь я создам policy и токен с при­креп­лен­ной к нему  поли­ти­кой. Я буду исполь­зо­вать этот токен в кон­фи­гу­ра­ции вто­ро­го сер­ве­ра для Auto Unseal.

[root@vault1 ~]# cat transit-policy.yaml

[root@vault1 ~]# vault policy write unseal-policy transit-policy.yaml
Success! Uploaded policy: unseal-policy

[root@vault1 ~]# vault token create -policy=unseal-policy

Теперь на вто­ром Vault(в minikube) я добав­лю раз­дел с кон­фи­гу­ра­ци­ей для авто­ма­ти­че­ско­го вскры­тия Transit.

Для это­го пра­вим кон­фиг (values) vault-helm/values-my.yaml  и добав­ля­ем вот такой код:

весь values будет вот в таком виде:

cat vault-helm/values-my.yaml