Highly available Vault Enterprise cluster with integrated storage (Raft)
Important Note: This chart is not compatible with Helm 2. Please use Helm 3.6+ with this chart.
Deploy with integrated storage
Step 1: Deploy the cluster
Enable integrated storage using the
server.ha.raft.enabledvalue. You need to configure the pods to use the internal service provided by the Helm chart so they can communicate directly:$ helm install vault hashicorp/vault \ --set='server.image.repository=hashicorp/vault-enterprise' \ --set='server.image.tag=2.0.2-ent' \ --set='server.ha.enabled=true' \ --set='server.ha.raft.enabled=true'Initialize the
vault-0pod:$ kubectl exec -ti vault-0 -- vault operator initUnseal the
vault-0pod:$ kubectl exec -ti vault-0 -- vault operator unsealJoin the remaining pods to the Raft cluster. For example, to join
vault-1to the cluster:$ kubectl exec -ti vault-1 -- vault operator raft join http://vault-0.vault-internal:8200Unseal the remaining pods to the Raft cluster. For example, to unseal
vault-1to the cluster:$ kubectl exec -ti vault-1 -- vault operator unseal
Step 2: Verify deployment
You can verify that the Raft cluster was initialized successfully by connecting to the pod and listing active peers.
Login using the
roottoken on thevault-0pod:$ kubectl exec -ti vault-0 -- vault loginList all the raft peers:
$ kubectl exec -ti vault-0 -- vault operator raft list-peers Node Address State Voter ---- ------- ----- ----- a1799962-8711-7f28-23f0-cea05c8a527d vault-0.vault-internal:8201 leader true e6876c97-aaaa-a92e-b99a-0aafab105745 vault-1.vault-internal:8201 follower true 4b5d7383-ff31-44df-e008-6a606828823b vault-2.vault-internal:8201 follower true
Set up redundancy zones
Enterprise
Appropriate Vault Enterprise license required
For Vault Enterprise deployments on Kubernetes 1.35+, you can enable redundancy zones for improved availability and fault tolerance across availability zones.
Requirements
- Kubernetes 1.35 or later
- Nodes labeled with
topology.kubernetes.io/zone - Vault Enterprise license
Option 1: Configure Vault with server flags
You can provide explicit server flags during the Helm install:
$ helm install vault hashicorp/vault \
--set='server.image.repository=hashicorp/vault-enterprise' \
--set='server.image.tag=2.0.2-ent' \
--set='server.ha.enabled=true' \
--set='server.ha.replicas=6' \
--set='server.ha.raft.enabled=true' \
--set='server.ha.raft.redundancyZones.enabled=true' \
--set-string='server.ha.raft.config=
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "raft" {
path = "/vault/data"
autopilot_redundancy_zone = "VAULT_REDUNDANCY_ZONE"
}
service_registration "kubernetes" {}' \
--set='server.topologySpreadConstraints[0].maxSkew=1' \
--set='server.topologySpreadConstraints[0].topologyKey=topology.kubernetes.io/zone' \
--set='server.topologySpreadConstraints[0].whenUnsatisfiable=DoNotSchedule'
Option 2: Configure Vault with a values file
Create a YAML values file:
# values.yaml server: image: repository: hashicorp/vault-enterprise tag: 2.0.2-ent ha: enabled: true replicas: 6 # 2 voting nodes per zone across 3 zones raft: enabled: true redundancyZones: enabled: true config: | ui = true listener "tcp" { tls_disable = 1 address = "[::]:8200" cluster_address = "[::]:8201" } storage "raft" { path = "/vault/data" autopilot_redundancy_zone = "VAULT_REDUNDANCY_ZONE" } service_registration "kubernetes" {} topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule
Reference the values file during Helm install:
$ helm install vault hashicorp/vault -f values.yaml
Initialize and verify redundancy configuration
To verify the install and redundancy zones configuration, you must initialize and unseal Vault.
Initialize Vault to generate the unseal keys:
$ kubectl exec -ti vault-0 -- vault operator initUnseal the first pod:
$ kubectl exec -ti vault-0 -- vault operator unsealJoin and unseal the remaining pods to the cluster:
$ for i in {1..5}; do kubectl exec -ti vault-$i -- vault operator raft join http://vault-0.vault-internal:8200 kubectl exec -ti vault-$i -- vault operator unseal doneCheck the pod zone distribution:
$ kubectl get pods -l app.kubernetes.io/name=vault \ -o custom-columns=NAME:.metadata.name,ZONE:.metadata.labels.'topology\.kubernetes\.io/zone'Verify the raft peers:
$ kubectl exec -ti vault-0 -- vault operator raft list-peersCheck Autopilot state (shows voting/non-voting status per zone)
$ kubectl exec -ti vault-0 -- vault operator raft autopilot state
For more details, refer to the full redundancy zones documentation.