Vault Helm 차트 실행

Vault Helm 차트 실행 (Run Vault with the Helm chart)

쿠버네티스에서 Vault Helm 차트를 실행하는 방법과 dev/standalone/ha/external 모드, 초기화·봉인 해제, 업그레이드를 다룹니다.

출처: 문서

본문

Vault는 쿠버네티스에서 dev, standalone, ha, external의 여러 모드로 동작해요.

중요한 참고: 이 차트는 Helm 2와 호환되지 않아요. 이 차트에는 Helm 3.6 이상을 사용해 주세요.

Helm 차트

Vault Helm 차트는 쿠버네티스에 Vault를 설치·구성하는 권장 방법이에요. Vault 자체를 실행하는 것 외에도, Helm 차트는 HA(고가용성) 배포를 위해 Consul 같은 다른 서비스와 통합하도록 Vault를 설치·구성하는 기본 방법입니다.

Helm 차트가 복잡한 리소스를 자동으로 설정하고 요구사항에 맞는 구성을 노출하지만, Vault를 자동으로 운영하지는 않아요. Vault 클러스터를 모니터링·백업·업그레이드하는 방법은 여전히 직접 배워야 합니다.

보안 경고: 기본적으로 차트는 standalone(단일 서버) 모드로 실행돼요. 이 모드는 단일 Vault 서버와 파일 스토리지 백엔드를 사용합니다. 이는 보안성·복원력이 떨어지는 설치로, 프로덕션 설정에는 적합하지 않아요. 적절히 보안이 설정된 쿠버네티스 클러스터를 사용하고, 사용 가능한 구성 옵션을 배우고, 프로덕션 배포 체크리스트를 읽는 것을 강력히 권장합니다.

방법 (How-To)

Vault 설치

Helm이 머신에 설치·구성되어 있어야 해요. Helm 문서Installation to Minikube via Helm 튜토리얼을 참고하세요.

Helm 차트를 사용하려면 Hashicorp Helm 레포지토리를 추가하고 차트에 접근할 수 있는지 확인해요.

$ helm repo add hashicorp https://helm.releases.hashicorp.com
"hashicorp" has been added to your repositories

$ helm search repo hashicorp/vault
NAME            CHART VERSION   APP VERSION DESCRIPTION
hashicorp/vault 0.34.1          2.0.4       Official HashiCorp Vault Chart

중요해요: Helm 차트는 새 제품이고 활발히 개발 중이에요. 설치나 업그레이드 전에는 항상 --dry-run으로 Helm을 실행해 변경 사항을 확인해 주세요.

helm install로 Vault Helm 차트의 최신 릴리스를 설치해요.

$ helm install vault hashicorp/vault

또는 차트의 특정 버전을 설치할 수도 있어요.

# 사용 가능한 릴리스 나열
$ helm search repo hashicorp/vault -l
NAME            CHART VERSION   APP VERSION DESCRIPTION
hashicorp/vault 0.34.1          2.0.4       Official HashiCorp Vault Chart
hashicorp/vault 0.34.0          2.0.3       Official HashiCorp Vault Chart
hashicorp/vault 0.33.0          2.0.2       Official HashiCorp Vault Chart
hashicorp/vault 0.32.0          1.21.2      Official HashiCorp Vault Chart
hashicorp/vault 0.31.0          1.20.4      Official HashiCorp Vault Chart
hashicorp/vault 0.30.1          1.20.1      Official HashiCorp Vault Chart
hashicorp/vault 0.30.0          1.19.0      Official HashiCorp Vault Chart
hashicorp/vault 0.29.1          1.18.1      Official HashiCorp Vault Chart
hashicorp/vault 0.29.0          1.18.1      Official HashiCorp Vault Chart
hashicorp/vault 0.28.1          1.17.2      Official HashiCorp Vault Chart
...

# 버전 0.34.1 설치
$ helm install vault hashicorp/vault --version 0.34.1

helm install 명령은 기본 구성 값을 인라인으로 또는 파일에 정의해 오버라이드하는 파라미터를 받아들여요.

server.dev.enabled 구성 값 오버라이드:

$ helm install vault hashicorp/vault \
    --set "server.dev.enabled=true"

파일의 모든 구성을 오버라이드:

$ cat override-values.yml
server:
  ha:
    enabled: true
    replicas: 5
##
$ helm install vault hashicorp/vault \
    --values override-values.yml
Dev 모드

Helm 차트는 Vault 서버를 개발 모드로 실행할 수 있어요. 메모리 스토리지 백엔드를 사용하는 단일 Vault 서버를 설치합니다.

Dev 모드: 학습·데모 환경에 이상적이지만, 프로덕션 환경에는 권장되지 않아요.

개발 모드로 최신 Vault Helm 차트 설치하기:

$ helm install vault hashicorp/vault \
    --set "server.dev.enabled=true"
Standalone 모드

Helm 차트는 기본적으로 standalone 모드로 실행돼요. 파일 스토리지 백엔드를 사용하는 단일 Vault 서버를 설치합니다.

standalone 모드로 최신 Vault Helm 차트 설치하기:

$ helm install vault hashicorp/vault
HA 모드

Helm 차트는 고가용성(HA) 모드로 실행할 수 있어요. 기존 Consul 스토리지 백엔드와 함께 3개의 Vault 서버를 설치합니다. Consul은 Consul Helm 차트로 설치하는 것을 권장해요.

HA 모드로 최신 Vault Helm 차트 설치하기:

$ helm install vault hashicorp/vault \
    --set "server.ha.enabled=true"

HA 모드에서 Consul과 Vault를 설정하는 방법은 Installation to Minikube via Helm 튜토리얼을 참고하세요.

쿠버네티스 1.35+의 Vault Enterprise 배포에서는 가용성 영역에 걸쳐 향상된 가용성·내결함성을 위해 redundancy zones을 활성화할 수 있어요.

External 모드

Helm 차트는 external 모드로 실행할 수 있어요. Vault 서버를 설치하지 않고 네트워크로 접근 가능한 Vault 서버가 존재한다고 가정합니다.

external 모드로 최신 Vault Helm 차트 설치하기:

$ helm install vault hashicorp/vault \
    --set "injector.externalVaultAddr=http://external-vault:8200"

쿠버네티스 클러스터 안에서 외부 Vault를 사용하는 방법은 Integrate a Kubernetes Cluster with an External Vault 튜토리얼을 참고하세요.

Vault UI 보기

Vault UI는 활성화되어 있지만 보안상의 이유로 서비스로 노출되지는 않아요. Vault UI는 port-forwarding이나 ui 구성 값으로 노출할 수 있습니다.

port-forwarding으로 Vault UI 노출:

$ kubectl port-forward vault-0 8200:8200
Forwarding from 127.0.0.1:8200 -> 8200
Forwarding from [::1]:8200 -> 8200
##...

Vault 초기화와 봉인 해제

Vault Helm 차트가 standalone이나 ha 모드로 설치된 후에는 Vault 서버 중 하나를 초기화해야 해요. 초기화는 모든 Vault 서버를 봉인 해제하는 데 필요한 자격 증명을 생성합니다.

CLI 초기화와 봉인 해제

현재 네임스페이스의 모든 Vault 파드 보기:

$ kubectl get pods -l app.kubernetes.io/name=vault
NAME                                    READY   STATUS    RESTARTS   AGE
vault-0                                 0/1     Running   0          1m49s
vault-1                                 0/1     Running   0          1m49s
vault-2                                 0/1     Running   0          1m49s

기본 키 공유 수와 기본 키 임계값으로 한 Vault 서버를 초기화:

$ kubectl exec -ti vault-0 -- vault operator init
Unseal Key 1: MBFSDepD9E6whREc6Dj+k3pMaKJ6cCnCUWcySJQymObb
Unseal Key 2: zQj4v22k9ixegS+94HJwmIaWLBL3nZHe1i+b/wHz25fr
Unseal Key 3: 7dbPPeeGGW3SmeBFFo04peCKkXFuuyKc8b2DuntA4VU5
Unseal Key 4: tLt+ME7Z7hYUATfWnuQdfCEgnKA2L173dptAwfmenCdf
Unseal Key 5: vYt9bxLr0+OzJ8m7c7cNMFj7nvdLljj0xWRbpLezFAI9

Initial Root Token: s.zJNwZlRrqISjyBHFMiEca6GF
##...

출력에 생성된 키 공유와 초기 루트 키가 표시됩니다.

키 임계값에 도달할 때까지 키 공유로 Vault 서버를 봉인 해제:

## 첫 번째 vault 서버를 키 임계값에 도달할 때까지 봉인 해제
$ kubectl exec -ti vault-0 -- vault operator unseal # ... Unseal Key 1
$ kubectl exec -ti vault-0 -- vault operator unseal # ... Unseal Key 2
$ kubectl exec -ti vault-0 -- vault operator unseal # ... Unseal Key 3

모든 Vault 서버 파드에 대해 봉인 해제 과정을 반복해요. 모든 Vault 서버 파드가 봉인 해제되면 READY 1/1을 보고합니다.

$ kubectl get pods -l app.kubernetes.io/name=vault
NAME                                    READY   STATUS    RESTARTS   AGE
vault-0                                 1/1     Running   0          1m49s
vault-1                                 1/1     Running   0          1m49s
vault-2                                 1/1     Running   0          1m49s
Google KMS 자동 봉인 해제

Helm 차트는 Google KMS for Auto Unseal과 함께 실행할 수 있어요. 이를 통해 Vault 서버 파드가 재스케줄링되면 자동으로 봉인 해제됩니다.

Vault Helm은 credentials.json에 저장된 Google Cloud KMS 자격 증명을 요구하며, 각 Vault 서버 파드에 시크릿으로 마운트해야 합니다.

먼저 쿠버네티스에서 시크릿을 만들어요.

kubectl create secret generic kms-creds --from-file=credentials.json

Vault Helm은 이것을 /vault/userconfig/kms-creds/credentials.json에 마운트합니다.

Google KMS를 사용하는 Vault Helm 구성 예제:

global:
  enabled: true

server:
  extraEnvironmentVars:
    GOOGLE_REGION: global
    GOOGLE_PROJECT: <PROJECT>
    GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/kms-creds/credentials.json

  volumes:
    - name: userconfig-kms-creds
      secret:
        defaultMode: 420
        secretName: kms-creds

  volumeMounts:
    - mountPath: /vault/userconfig/kms-creds
      name: userconfig-kms-creds
      readOnly: true

  ha:
    enabled: true
    replicas: 3

    config: |
      ui = true

      listener "tcp" {
        tls_disable = 1
        address = "[::]:8200"
        cluster_address = "[::]:8201"
      }

      seal "gcpckms" {
        project     = "<PROJECT>"
        region      = "global"
        key_ring    = "<KEY_RING>"
        crypto_key  = "<CRYPTO_KEY>"
      }

      storage "consul" {
        path = "vault"
        address = "HOST_IP:8500"
      }
Amazon KMS 자동 봉인 해제

Helm 차트는 AWS KMS for Auto Unseal과 함께 실행할 수 있어요. 이를 통해 Vault 서버 파드가 재스케줄링되면 자동으로 봉인 해제됩니다.

Vault Helm은 각 Vault 서버 파드에 정의된 환경 변수로 저장된 AWS 자격 증명을 요구합니다.

먼저 KMS 액세스 키/시크릿으로 시크릿을 만들어요.

$ kubectl create secret generic kms-creds \
    --from-literal=AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID?}" \
    --from-literal=AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY?}"

AWS KMS를 사용하는 Vault Helm 구성 예제:

global:
  enabled: true

server:
  extraSecretEnvironmentVars:
    - envName: AWS_ACCESS_KEY_ID
      secretName: kms-creds
      secretKey: AWS_ACCESS_KEY_ID
    - envName: AWS_SECRET_ACCESS_KEY
      secretName: kms-creds
      secretKey: AWS_SECRET_ACCESS_KEY

  ha:
    enabled: true
    config: |
      ui = true

      listener "tcp" {
        tls_disable = 1
        address = "[::]:8200"
        cluster_address = "[::]:8201"
      }

      seal "awskms" {
        region     = "KMS_REGION_HERE"
        kms_key_id = "KMS_KEY_ID_HERE"
      }

      storage "consul" {
        address = "HOST_IP:8500"
        path = "vault/"
      }

프로브 (Probes)

프로브는 쿠버네티스에서 실패 감지, 재스케줄링, 파드 사용에 필수적이에요. Helm 차트는 다양한 사용 사례에 맞게 커스터마이즈할 수 있는 구성 가능한 readiness·liveness 프로브를 제공합니다.

Vault의 /sys/health` 엔드포인트는 상태 확인의 동작을 바꾸도록 커스터마이즈할 수 있어요. 예를 들어 다음 프로브로 Vault 파드가 아직 초기화·봉인되지 않았어도 준비된 것으로 표시하도록 Vault readiness 프로브를 바꿀 수 있습니다.

server:
  readinessProbe:
    enabled: true
    path: '/v1/sys/health?standbyok=true&sealedcode=204&uninitcode=204'

이 커스터마이즈된 프로브를 사용하면, 파드가 준비된 후 postStart 스크립트가 추가 설정을 위해 자동으로 실행될 수 있어요.

쿠버네티스에서 Vault 업그레이드

쿠버네티스에서 Vault를 업그레이드하려면 일반적으로 Vault를 업그레이드하는 것과 같은 패턴을 따르되, Helm 차트로 Vault 서버 StatefulSet을 업데이트할 수 있어요. 이 섹션을 읽기 전에 일반 Vault 업그레이드를 이해하는 것이 중요합니다.

Vault StatefulSet은 OnDelete 업데이트 전략을 사용합니다. standby가 active primary보다 먼저 업데이트되어야 하므로 RollingUpdate 대신 OnDelete를 사용하는 것이 중요해요. 더 오래된 Vault 버전으로의 장애 조치는 항상 피해야 합니다.

중요한 참고: 업그레이드 전에 항상 데이터를 백업하세요! Vault는 데이터 스토어에 대한 하위 호환성을 보장하지 않아요. 새로 설치된 Vault 바이너리를 이전 버전으로 단순히 교체하는 것은 Vault를 깔끔하게 다운그레이드하지 못할 수 있는데, 업그레이드가 데이터 구조에 변경을 수행해 다운그레이드와 호환되지 않게 만들 수 있기 때문입니다. 이전 Vault 버전으로 롤백해야 한다면 데이터 스토어도 함께 롤백해야 해요.

Vault 서버 업그레이드

중요한 참고: Helm은 기본으로 레포지토리에서 찾은 최신 차트를 설치해요. 업그레이드 시에는 차트 버전을 지정하는 것이 권장됩니다.

업그레이드를 시작하려면 server.image 값을 원하는 Vault 버전으로 values yaml 파일이나 명령줄에서 설정해요. 예시 목적상 아래 예제는 vault:123.456을 사용합니다.

server:
  image:
    repository: 'vault'
    tag: '123.456'

다음으로 Helm 버전을 나열하고 설치할 원하는 버전을 선택해요.

$ helm search repo hashicorp/vault
NAME            CHART VERSION   APP VERSION DESCRIPTION
hashicorp/vault 0.34.1          2.0.4       Official HashiCorp Vault Chart

다음으로 --dry-run으로 먼저 업그레이드를 테스트해 쿠버네티스 클러스터에 보내지는 변경을 확인해요.

$ helm upgrade vault hashicorp/vault --version=0.34.1 \
    --set='server.image.repository=vault' \
    --set='server.image.tag=123.456' \
    --dry-run

이것은 변경을 일으키지 않아야 합니다(리소스는 업데이트되지만). 모든 것이 안정적이면 helm upgrade를 실행할 수 있어요.

helm upgrade 명령은 Vault 서버의 StatefulSet 템플릿을 업데이트해야 하지만, 파드는 삭제되지 않아요. 업그레이드하려면 파드를 수동으로 삭제해야 합니다. 파드를 삭제해도 영속 데이터는 삭제되지 않아요.

Vault가 ha 모드로 배포되지 않았다면 단일 Vault 서버는 다음을 실행해 삭제할 수 있어요.

$ kubectl delete pod <POD_NAME>

Vault를 고가용성(ha) 모드로 배포했다면, active 파드를 업그레이드하기 전에 standby 파드를 먼저 업그레이드해야 해요.

  1. standby 파드를 삭제하기 전에 vault operator raft remove-peer <server_id>로 associated 노드를 raft에서 제거해요.
  2. vault operator raft list-peers로 Vault가 Raft에서 노드를 성공적으로 제거했는지 확인해요.
  3. 제거를 확인한 뒤 파드를 삭제해요.

불필요한 리더 선출을 피하려면 노드를 삭제하세요. 먼저 클러스터에서 노드를 제거하지 않고 파드를 제거하면 Raft가 클러스터에 있는 노드의 정확한 수를 알지 못할 수 있어요. 올바른 노드 수를 모르면 리더 선출이 트리거되어 불필요한 다운타임이 생길 수 있습니다.

Vault는(서버 구성에서 활성화되면) K8s 서비스 디스커버리를 내장하고 있으며, 파드의 라벨을 현재 리더 상태로 자동 변경합니다. 이 라벨로 파드를 필터링할 수 있어요.

예를 들어 Vault standby인 모든 파드를 선택하려면:

$ kubectl get pods -l vault-active=false

active Vault 파드를 선택하려면:

$ kubectl get pods -l vault-active=true

다음으로 active primary가 아닌 모든 파드를 순차적으로 삭제해 쿼럼이 항상 유지되게 해요.

$ kubectl delete pod <POD_NAME>

자동 봉인 해제를 사용하지 않는다면, 새로 스케줄링된 Vault standby 파드를 봉인 해제해야 해요.

$ kubectl exec -ti <POD_NAME> -- vault operator unseal

마지막으로 standby 노드가 업데이트되고 봉인 해제되면 active primary를 삭제해요.

$ kubectl delete pod <POD_NAME>

standby 노드와 마찬가지로 이전 primary도 봉인 해제해야 해요.

$ kubectl exec -ti <POD_NAME> -- vault operator unseal

몇 분 후 Vault 클러스터가 새 active primary를 선출해야 해요. 이제 Vault 클러스터가 업그레이드됐어요!

민감한 Vault 구성 보호

Vault Helm은 설치 중 Vault 구성 파일을 렌더링하고 그 파일을 쿠버네티스 configmap에 저장합니다. 일부 구성은 구성 파일에 민감한 데이터를 포함해야 하는데, 쿠버네티스에 만들어지면 저장 시 암호화되지 않아요.

다음 예제는 쿠버네티스 시크릿을 사용해 저장 시 평문으로 나타나는 것을 방지하도록 민감한 구성을 보호하기 위해 Vault Helm에 추가 구성 파일을 추가하는 방법을 보여줘요.

먼저 Vault가 시작 시 로드하는 민감한 설정을 가진 부분 Vault 구성을 만들어요.

$ cat <<EOF >config.hcl
storage "mysql" {
username = "user1234"
password = "secret123!"
database = "vault"
}
EOF

다음으로 이 부분 구성을 담은 쿠버네티스 시크릿을 만들어요.

$ kubectl create secret generic vault-storage-config \
    --from-file=config.hcl

마지막으로 이 시크릿을 추가 볼륨으로 마운트하고 Vault 시작 명령에 추가 -config 플래그를 더해요.

$ helm install vault hashicorp/vault \
  --set='server.volumes[0].name=userconfig-vault-storage-config' \
  --set='server.volumes[0].secret.defaultMode=420' \
  --set='server.volumes[0].secret.secretName=vault-storage-config' \
  --set='server.volumeMounts[0].mountPath=/vault/userconfig/vault-storage-config' \
  --set='server.volumeMounts[0].name=userconfig-vault-storage-config' \
  --set='server.volumeMounts[0].readOnly=true' \
  --set='server.extraArgs=-config=/vault/userconfig/vault-storage-config/config.hcl'

아키텍처 (Architecture)

Vault를 쿠버네티스에서 실행할 때도 다른 곳에서 실행할 때와 같은 일반 아키텍처로 실행하는 것을 권장합니다. 쿠버네티스가 Vault 클러스터 운영을 쉽게 해 주는 몇 가지 이점이 있으며, 아래에서 이를 문서화합니다. 쿠버네티스에서 Vault를 실행하더라도 표준 production deployment 튜토리얼은 여전히 중요한 읽을거리입니다.

프로덕션 배포 체크리스트

  • End-to-End TLS — Vault는 프로덕션에서 항상 TLS와 함께 사용해야 해요. Vault 앞에 중간 로드밸런서나 리버스 프록시를 둔다면 TLS를 종료해서는 안 됩니다. 이렇게 하면 트래픽이 Vault까지 전송 중 항상 암호화되고 중간 계층이 도입하는 위험을 최소화합니다. Vault Helm을 TLS로 구성하는 예는 공식 문서를 참고하세요.
  • Single Tenancy — Vault는 머신에서 실행되는 유일한 메인 프로세스여야 해요. 이는 같은 머신에서 실행되는 다른 프로세스가 손상되어 Vault와 상호작용할 위험을 줄입니다. Vault Helm의 affinity 설정으로 이 작업을 수행할 수 있어요. affinity 규칙으로 Vault Helm을 구성하는 예는 공식 문서를 참고하세요.
  • Auditing 활성화 — Vault는 여러 감사 백엔드를 지원합니다. 감사 활성화는 Vault가 수행한 모든 작업의 이력과, 오용·침해 시 포렌식 추적을 제공합니다. 감사 로그는 민감한 데이터를 안전하게 해시하지만, 의도치 않은 공개를 막기 위해 접근은 여전히 제한해야 해요. Vault Helm은 감사 로그를 저장하는 영속 볼륨을 프로비저닝하는 구성 가능한 auditStorage 옵션을 포함합니다. 감사 사용을 위해 Vault Helm을 구성하는 예는 공식 문서를 참고하세요.
  • Immutable Upgrades — Vault는 영속성에 외부 스토리지 백엔드에 의존하며, 이 분리 덕분에 Vault를 실행하는 서버를 불변(immutable)하게 관리할 수 있어요. 새 버전으로 업그레이드할 때 업그레이드된 Vault 버전의 새 서버를 온라인 상태로 만듭니다. 이들은 같은 공유 스토리지 백엔드에 연결되어 봉인 해제됩니다. 그런 다음 오래된 서버를 파괴합니다. 이는 원격 접근과 보안 허점을 도입할 수 있는 업그레이드 오케스트레이션의 필요성을 줄여 줍니다. 쿠버네티스에서 Vault를 업그레이드하는 지침은 upgrade 섹션을 참고하세요.
  • 자주 업그레이드 — Vault는 활발히 개발되며, 보안 수정과 키 길이나 cipher suite 같은 기본 설정 변경을 통합하려면 자주 업데이트하는 것이 중요합니다. 업데이트를 위해 Vault 메일링 리스트와 GitHub CHANGELOG를 구독하세요.
  • Storage 접근 제한 — Vault는 어떤 스토리지 백엔드를 사용하든 모든 저장 데이터를 암호화합니다. 데이터가 암호화되어 있지만, 임의로 제어할 수 있는 공격자는 키를 수정·삭제해 데이터 손상이나 손실을 일으킬 수 있어요. 무단 접근이나 작업을 피하려면 스토리지 백엔드에 대한 접근을 Vault로만 제한해야 합니다.

더 알아보기 (Learn more)