Vault это менеджер секретов. Для его деплоя в кластер kubernetes можно использовать следующую конфигурацию:
deployment.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vault
namespace: vault
labels:
app: vault
spec:
serviceName: "vault-headless"
replicas: 3
selector:
matchLabels:
app: vault
template:
metadata:
labels:
app: vault
spec:
serviceAccountName: vault
securityContext:
runAsUser: 100
runAsGroup: 1000
fsGroup: 1000
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- vault
topologyKey: "kubernetes.io/hostname"
containers:
- name: vault
image: hashicorp/vault:1.20.0
command: ["vault"]
args:
- "server"
- "-config=/vault/config/vault.hcl"
ports:
- containerPort: 8200
name: http
- containerPort: 8201
name: cluster
env:
- name: VAULT_K8S_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: VAULT_K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: VAULT_ADDR
value: "http://127.0.0.1:8200"
- name: VAULT_API_ADDR
value: "http://$(VAULT_K8S_POD_NAME).vault-headless.vault.svc.cluster.local:8200"
- name: VAULT_CLUSTER_ADDR
value: "http://$(VAULT_K8S_POD_NAME).vault-headless.vault.svc.cluster.local:8201"
- name: SKIP_SETCAP
value: "true"
securityContext:
capabilities:
add:
- IPC_LOCK
volumeMounts:
- name: config
mountPath: /vault/config/vault.hcl
subPath: vault.hcl
- name: data
mountPath: /vault/data
volumes:
- name: config
configMap:
name: vault-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: ssd-pool
resources:
requests:
storage: 10Gi
rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault
namespace: vault
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: vault
name: vault-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints"]
verbs: ["get", "list", "watch", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vault-rolebinding
namespace: vault
subjects:
- kind: ServiceAccount
name: vault
namespace: vault
roleRef:
kind: Role
name: vault-role
apiGroup: rbac.authorization.k8s.io
vault-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: vault-config
namespace: vault
data:
vault.hcl: |
ui = true
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
cluster_address = "0.0.0.0:8201"
}
storage "raft" {
path = "/vault/data"
}
service_registration "kubernetes" {}
service.yaml
apiVersion: v1
kind: Service
metadata:
name: vault-headless
namespace: vault
spec:
clusterIP: None
ports:
- port: 8200
targetPort: 8200
name: http
- port: 8201
targetPort: 8201
name: cluster
selector:
app: vault
---
apiVersion: v1
kind: Service
metadata:
name: vault-ui
namespace: vault
spec:
ports:
- port: 8200
targetPort: 8200
name: http
selector:
app: vault
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- vault-config.yaml
- service.yaml
- rbac.yaml
- deployment.yaml
- ingress.yaml
После деплоя заходим в контейнер k exec -it vault-0 -n vault -- /bin/sh и получаем init ключи командой vault operator init. Получим ключики (их сохраняем), и root token (он используется для входа в UI).
После получения ключиков (в дефолте 5 штук) мы должны сделать им unseal. Пишем vault operator unseal КЛЮЧ и получаем статус:
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 5
Threshold 3
Unseal Progress 1/3
Unseal Nonce aa650d18-a52e-caf4-8352-7574a452f3f3
Version 1.20.0
Build Date 2025-06-23T10:21:30Z
Storage Type raft
Removed From Cluster false
HA Enabled true
После ввода трех ключей получаем следующее:
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.20.0
Build Date 2025-06-23T10:21:30Z
Storage Type raft
Cluster Name vault-cluster-92af0e3b
Cluster ID 2a7080ff-79e2-5ade-fe2f-7681e01734e9
Removed From Cluster false
HA Enabled true
HA Cluster https://vault-0.vault.svc.cluster.local:8201
HA Mode active
Active Since 2025-09-27T21:02:05.080432894Z
Raft Committed Index 37
Raft Applied Index 37
Далее смотрим пиры, для этого экспортируем в env рут токен: export VAULT_TOKEN="s.XXXXXXXXXXXXXXXX" и смотрим пиры vault operator raft list-peers
Далее подключим другие ноды. Заходим на под vault-1 и пишем vault operator raft join http://vault-0.vault-headless.vault.svc.cluster.local:8200, после чего делаем unseal трех ключей командой vault operator unseal КЛЮЧ. После трех введенных ключей проверяем статус: vault operator status и статус пиров raft:
/ $ vault operator raft list-peers
Node Address State Voter
---- ------- ----- -----
838f1dc3-ba4c-fb93-0938-afdd8c0776ab vault-0.vault-headless.vault.svc.cluster.local:8201 leader true
bbbe7964-44b5-238c-d39f-3acf7234c727 vault-1.vault-headless.vault.svc.cluster.local:8201 follower true
2b5c2f4e-6304-d93c-5647-985a53e66c16 vault-2.vault-headless.vault.svc.cluster.local:8201 follower true
В итоге мы должны получить три raft пира, со статусом Voter: "true"