Что такое Vault и зачем он нужен написал в своём ТГ канале
Присоединяйся

HashiCorp рекомендует Helm chart как основной способ установки Vault в Kubernetes.
Требования:
- Готовый Kubernetes-кластер (или K3S)
- Ingress NGINX
- StorageClass для PVC, например longhorn
- Приватный репозиторий Harbor
- helm, nerdctl/docker
План:
- Подготовить chart и образы Vault
- Залить chart и образы в Harbor
- Установить Vault HA через Helm
- vault operator init
- Unseal vault-0, vault-1, vault-2
Данный гайд - это часть общего взимодействия.
Vault из этого мануала может быть установлен и сконфигурирован как отдельно или совместно с общим планом.

Шаг 1. Онлайн установка
Так как репозитории и сайт HashiCorp для РФ закрыт используем Git.
1
2
| git clone https://github.com/hashicorp/vault-helm.git
cd vault-helm
|
Упаковываем Helm чарт и устанавливаем
1
2
| helm dependency update
helm package .
|
Создаём файл с переменными:
И добавляем конфигурацию для автоматического присоединения нод и количество реплик 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| server:
ha:
enabled: true
replicas: 3
raft:
enabled: true
config: |
ui = true
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = 1
}
storage "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "http://vault-0.vault-internal:8200"
}
}
service_registration "kubernetes" {}
|
Устанавливаем:
1
| helm install vault ./vault-*.tgz -n vault -f values.yaml
|
Готово. Переходи к шагу 5
Шаг 2. Оффлайн установка
Подготовка пакетов и образов
На компе/сервере с инетом скачиваем пакеты и чарт.
1
2
| git clone https://github.com/hashicorp/vault-helm.git
cd vault-helm
|
Достаём список необходимых образов:
1
2
| helm template vault ./vault -f values.yaml > rendered.yaml
grep -oE 'image:\s*"?[^"]+' rendered.yaml | sed -E 's/^image:\s*"?//; s/"$//' | sort -u > vault-images.txt
|
Скачиваем образы:
1
2
3
| while read -r img; do
docker pull "$img"
done < vault-images.txt
|
Сохраняем в архив:
1
| docker save -o vault-images.tar $(cat vault-images.txt)
|
Перейти в домашнюю директорию текущего пользователя:
Упаковываем HELM чарт:
1
| tar -cvf vault-chart.tgz vault-chart
|
Переносим в закрытый контур vault-chart.tgz
Перенос в закрытый контур
Распаковываем архив:
1
| tar -xvf vault-0.32.0.tgz
|
Загружаем образы в репозиторий Harbor. Внутри создан публичный проект с именем platform куда будут складываться образы.

1
2
3
4
5
6
7
8
9
10
| docker load -i vault-images.tar
export HARBOR="harbor.domain.local"
export PROJECT="platform"
while read -r img; do
new="${HARBOR}/${PROJECT}/${img}"
docker tag "${img}" "$new"
docker push "$new"
done < vault-images.txt
|
Далее удаляем мусор из директории:
1
| rm vault-*/rendered.yaml
|
Упаковываем архив:
1
| helm package ./vault-* -d .
|
нужно загрузить чарт в репозиторий.
1
| helm push vault-*.tgz oci://${HARBOR}/helm
|
Шаг 3. Подготовка к установке в закрытом контуре
Сикреты для pull из Harbor
Если репозиторий Harbor приватный нужно создать в кубернетес сикрет с помощью которого он будет авторизовываться.
Сначала робота нужно создать в Harbor и дать ему права на репозиторий, потом добавить логин и пароль здесь
1
2
3
4
5
| kubectl -n vault create secret docker-registry harbor-secret \
--docker-server=harbor.domain.local \
--docker-username='robot$auth-robot' \
--docker-password='REPLACE_ME' \
--docker-email=robot@myemail.com
|
Файл values.yaml для Vault
1
| Создаём файл vault-values.yaml:
|
Внутри указываем количество реплик и репозиторий Harbor с образами. Также в качестве storage у меня Longhorn:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| global:
imagePullSecrets:
- name: harbor-secret
tlsDisable: true
server:
image:
repository: harbor.domain.local/platform/hashicorp/vault
standalone:
enabled: false
ha:
enabled: true
replicas: 3
raft:
enabled: true
config: |
ui = true
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = 1
}
storage "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "http://vault-0.vault-internal:8200"
}
}
service_registration "kubernetes" {}
dataStorage:
enabled: true
storageClass: longhorn
size: 7Gi
auditStorage:
enabled: true
storageClass: longhorn
size: 5Gi
ui:
enabled: true
serviceType: ClusterIP
ingress:
enabled: true
ingressClassName: nginx
hosts:
- host: vault.k8s.domain.local
tls: []
injector:
enabled: true
image:
repository: harbor.domain.local/platform/hashicorp/vault-k8s
agentImage:
repository: harbor.domain.local/platform/hashicorp/vault
|
Шаг 4. Установка Vault в Kubernetes
После того как образы лежат в репозитории, в Longhorn достаточно свободного места под 3 реплики, запускаем установку:
1
2
3
4
| helm install vault oci://harbor.domain.local/helm/vault \
-n vault \
--create-namespace \
-f vault-values.yaml
|
Проверяем, чтобы поды поднялись:
1
| kubectl get pods -n vault
|
Шаг 5. Инициализация и сборка HA Raft-кластера Vault
Инициализация кластера
Прежде чем использовать кластер его нужно инициализировать. Получить 5 ключей для разблокировки и root-ключ для управления
1
| kubectl -n vault exec -it vault-0 -- vault operator init -format=json > init-vault.json
|
Полученный файл init-vault.json содержит:
1
2
| unseal keys
root token
|
Его нужно сохранить вне кластера в защищённом месте. При перезапуске подов всегда будет нужны данные ключи.
ЕСЛИ ФАЙЛ ИЛИ КЛЮЧИ УТЕРЯНЫ, ТО ДОСТУП К КЛАСТЕРУ НЕ ВОССТАНОВИТЬ
Вскрываем первый узел
Нужно ввести 3 разных unseal key:
1
2
3
| kubectl -n vault exec -it vault-0 -- vault operator unseal
kubectl -n vault exec -it vault-0 -- vault operator unseal
kubectl -n vault exec -it vault-0 -- vault operator unseal
|
Другие узлы должны присоединиться сами, потому что мы указали это в конфиге, но на всякий случай команды для добавления:
1
2
| kubectl -n vault exec -it vault-1 -- sh -lc 'vault operator raft join http://vault-0.vault-internal:8200'
kubectl -n vault exec -it vault-2 -- sh -lc 'vault operator raft join http://vault-0.vault-internal:8200'
|
После join распечатываем каждый узел тремя ключами:
1
2
3
| kubectl -n vault exec -it vault-1 -- vault operator unseal
kubectl -n vault exec -it vault-1 -- vault operator unseal
kubectl -n vault exec -it vault-1 -- vault operator unseal
|
И последнюю ноду:
1
2
3
| kubectl -n vault exec -it vault-2 -- vault operator unseal
kubectl -n vault exec -it vault-2 -- vault operator unseal
kubectl -n vault exec -it vault-2 -- vault operator unseal
|
Проверка:
1
2
3
4
| kubectl get pods -n vault
kubectl -n vault exec -it vault-0 -- vault status
kubectl -n vault exec -it vault-1 -- vault status
kubectl -n vault exec -it vault-2 -- vault status
|
Ожидаем примерно такое:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.21.2
Build Date 2026-01-06T08:33:05Z
Storage Type raft
Cluster Name vault-cluster-164c11b7
Removed From Cluster false
HA Enabled true
HA Cluster https://vault-1.vault-internal:8201
HA Mode standby
Raft Committed Index 475
Raft Applied Index 475
|
Кластер Vault готов для дальнейшей настройки и эксплуатации