Featured image of post Установка HashiCorp Vault в Kubernetes

Установка HashiCorp Vault в Kubernetes

Онлайн и оффлайн установка Vault в кубернетес

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

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 .

Создаём файл с переменными:

1
nano values.yaml

И добавляем конфигурацию для автоматического присоединения нод и количество реплик 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)

Перейти в домашнюю директорию текущего пользователя:

1
cd ~

Упаковываем 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 готов для дальнейшей настройки и эксплуатации

Информацию можно использовать в свободном доступе, с указанием ссылки на сайт
Telegram GitHub YouTube