본문 바로가기
카테고리 없음

[AEWS] 10주차 - HashiCorp Vault with Kubernetes 개요 및 설치

by james_janghun 2025. 4. 8.

 

이번 스터디에서는 Vault 관련 내용을 학습하여 정리합니다.

 

Vault의 구성 요소 4가지

HashiCorp Vault는 신원 기반의 시크릿 및 암호화 관리 시스템으로 인증 및 인가 방법을 통해 암호화 서비스를 제공하고 Secret에 대한 안전하고 감사 가능하며 제한된 접근을 보장하도록 하는 소프트웨어입니다. 여기서 인증과 인가가 매우 중요합니다.

 

1. 누가 Vault에게 요청하는가?

- Client. 즉 사용자인 시스템, 애플리케이션, 사람 등 다양한 요청자가 Vault에 접속합니다.

 

2. 대상 시스템은 무엇인가?

- 서버, DB, 스토리지, 클라우드 등 다양한 secret 정보들을 획득해야 합니다.

 

3. 획득한 정보를 얼마나 사용할 수 있는가?

- 최소 시간의 원칙이라는 개념에 맞게 필요한 만큼만 사용하고 만료되도록 해야합니다. TTL(Time-To-Live) 특정시간만 사용가능한 매커니즘을 이용하게 됩니다. 영구적으로 사용해서는 안됩니다.

 

4. 라이프 사이클

- 생성되고, 만료 후 삭제되는 등의 라이프 사이클 정책을 따릅니다.

 

대표적인 Vault의 시크릿 종류

  • 비밀번호
  • Cloud Credentials : AWS, GCP, Azure, NCP
  • Database Credentials : MySQL,
  • SSH Key
  • Token, API Key : GitHub, Telegram, Slack, OpenAI, Claude
  • 인증서(PKI, TLS 등)
  • 이 외에 수 많은 기타 Secret

 

Vault 동작방식

Vault는 주로 토큰(Token)을 기반으로 작동하고, 이 토큰은 클라이언트의 정책(Policy)와 연결되어 작동합니다. 각 정책은 경로(path) 기반으로 설정되고, 정책 규칙은 클라이언트가 해당 경로에서 수행할 수 있는 작업과 접근 가능성을 제한합니다.

 

1. Authenticate : 인증 요청을 보냅니다.

2. Validate : 다양한 관련 서비스에서 유효성 검사를 진행합니다.

3. Authorize : 인가를 합니다. 관련된 정책에 허용되어야 합니다.

4. Access : Authorize 된 정책에 따라 access를 진행한다.

 

helm으로 vault 설치하기

https://github.com/hashicorp/vault-helm

 

GitHub - hashicorp/vault-helm: Helm chart to install Vault and other associated components.

Helm chart to install Vault and other associated components. - hashicorp/vault-helm

github.com

 

kubectl create namespace vault
helm repo add hashicorp https://helm.releases.hashicorp.com

# 버전 검색시
helm search repo hashicorp/vault

values.yaml은 다음과 같이 설정합니다.

 

이 때 몇 가지 주의사항입니다.

1. hashicorp/vault는 개인용입니다. 엔터프라이스 모델은 별도로 존재합니다.

2. standalone 기능은 replicas를 기본적으로 하나만 두어 고가용성을 보장하지 않습니다. 테스트 용도로 사용할 때 사용하고, 만약 운영망에서는 standalone을 true로 두어서는 안됩니다.

3. tls_disable 또한 테스트를 위해서 사용합니다.

cat <<EOF > override-values.yaml
global:
  enabled: true
  tlsDisable: true  # Disable TLS for demo purposes

server:
  image:
    repository: "hashicorp/vault"
    tag: "1.19.0"
  standalone:
    enabled: true
    replicas: 1
    config: |
      ui = true

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

      storage "file" {
        path = "/vault/data"
      }

  service:
    enabled: true
    type: NodePort
    port: 8200
    targetPort: 8200
    nodePort: 30000   # 🔥 Kind에서 열어둔 포트 중 하나 사용

injector:
  enabled: true
EOF

 

헬름 설치를 진행합니다.

helm upgrade vault hashicorp/vault -n vault -f override-values.yaml --install

 

이렇게 pvc까지 설치되는 것을 확인할 수 있습니다.

처음 기동시 vault가 제대로 실행되지 않을 수 있습니다.

내부 로그에서 not initialized 에러가 발생할 텐데 이는 정상입니다. 아직 init을 안했기 때문입니다.

 

Vault 초기화 및 잠금해제

# Vault Status 명령으로 Sealed 상태확인
kubectl exec -n vault -it vault-0 -- vault status

 

현재는 initialized가 false이고 sealed가 true것을 확인할 수 있습니다.

 

unseal 방법

이제 vault pod 내부에 들어가서 다음 명령어로 unseal을 진행해보겠습니다.

 

vault init

아주 정통적인 방법은 init 명령어를 직접 수행하는 것입니다. 다음과 같이 나오는 unseal key 5개와 token 정보를 복사해 둡니다.

vault operator init

 

이제 나온 5개의 키를 다음 unseal 명령어를 입력한 후 하나 씩 넣는 방식을 총 3번 수행해서 

vault operator unseal

 

예를 들어 이렇게 한 번 수행하게 되면 임계치(Threshold) 3번 중 1번이 unseal 된 상황을 확인할 수 있습니다.

 

Sealed를 false로 만듭니다.

 

로그를 확인해 보면 unseal과 함께 vault가 정상적으로 띄워진 것을 확인할 수 있습니다.

(참고) init-unseal.sh를 사용해 vault unseal 자동화하기

해당 스크립트를 통해 자동화 하는 방법도 있다. init 명령어를 수행할 때 키 수를 1개로 줄이고 바로 unseal 해버리는 방법이다. 테스트할 때는 이 스크립트로 바로 unseal 해도 좋지만 일반적으로 정통적인 init을 사용하는게 더 올바르다고 생각한다.

cat <<EOF > init-unseal.sh
#!/bin/bash

# Vault Pod 이름
VAULT_POD="vault-0"

# Vault 명령 실행
VAULT_CMD="kubectl exec -ti \$VAULT_POD -- vault"

# 출력 저장 파일
VAULT_KEYS_FILE="./vault-keys.txt"
UNSEAL_KEY_FILE="./vault-unseal-key.txt"
ROOT_TOKEN_FILE="./vault-root-token.txt"

# Vault 초기화 (Unseal Key 1개만 생성되도록 설정)
\$VAULT_CMD operator init -key-shares=1 -key-threshold=1 | sed \$'s/\\x1b\\[[0-9;]*m//g' | tr -d '\r' > "\$VAULT_KEYS_FILE"

# Unseal Key / Root Token 추출
grep 'Unseal Key 1:' "\$VAULT_KEYS_FILE" | awk -F': ' '{print \$2}' > "\$UNSEAL_KEY_FILE"
grep 'Initial Root Token:' "\$VAULT_KEYS_FILE" | awk -F': ' '{print \$2}' > "\$ROOT_TOKEN_FILE"

# Unseal 수행
UNSEAL_KEY=\$(cat "\$UNSEAL_KEY_FILE")
\$VAULT_CMD operator unseal "\$UNSEAL_KEY"

# 결과 출력
echo "[🔓] Vault Unsealed!"
echo "[🔐] Root Token: \$(cat \$ROOT_TOKEN_FILE)"
EOF

# 실행 권한 부여
chmod +x init-unseal.sh

# 실행
./init-unseal.sh

 

 

 

(참고) Vault 삭제시

vault를 삭제하고 다시 사용할 때는 반드시 pvc까지 지워야 합니다. 사용한 unseal 키 등이 pv에 남아있기때문입니다.

 

(참고) Vault UI에서도 unseal 가능

콘솔 내부에서도 다음과 같이 unseal이 가능하도록 제공하고 있습니다.

 

(참고) Vault에서 unseal은 샤미르 비밀 분산(Shamir’s Secret Sharing, SSS) 알고리즘을 사용합니다.

샤미르 비밀 분산(SSS)은 비밀 정보를 여러 조각(shares)으로 나누어 보관하고, 특정 개수 이상의 조각이 모여야만 원래 비밀을 복원할 수 있도록 하는 알고리즘입니다.


핵심 아이디어:
• 비밀 분할: 비밀(예: 금고 비밀번호)을 여러 개의 ‘share’로 나눕니다. 각 share 자체로는 비밀에 대한 어떤 정보도 주지 않습니다.
• threshold 설정: 비밀을 복원하는 데 필요한 최소 share 개수(threshold)를 설정합니다.
• 비밀 복원: threshold 이상의 share가 모이면 Lagrange interpolation을 사용하여 원래 비밀을 복원합니다. threshold 미만의 share로는 비밀을 알아낼 수 없습니다.

 

예시: 금고 비밀번호를 6개의 share로 나누고 threshold를 3으로 설정한 경우:

• 6명에게 share를 나누어 줍니다.

• 금고를 열려면 최소 3명 이상의 share가 필요합니다.

• 2명 이하의 share로는 금고 비밀번호를 알아낼 수 없습니다.

 

장점:

• 보안성: threshold 미만의 share로는 비밀을 복원할 수 없으므로 안전합니다.

• 유연성: share 개수를 동적으로 추가하거나 삭제할 수 있습니다.

• 확장성: 비밀을 바꾸지 않고도 보안 수준을 높일 수 있습니다.

 

단점:

• 단일 실패 지점: 비밀을 share로 분할하거나 share를 합쳐 비밀을 복원할 때, 비밀이 한 곳에 모이는 지점이 공격에 취약할 수 있습니다. • 검증 불가능: share가 정확한지 검증하는 과정이 없습니다.

 

내용을 읽어보면 영화 등에서 보물을 보관할 때 쓰는 알고리즘이랑 비슷한 양상의 느낌으로 보입니다.

 

UI 접속

vault에서는 다음과 같이 매니지 콘솔을 제공하고 있습니다. 30000번으로 ui에 접속해서 unseal key 혹은 root token을 사용해서 접속하면됩니다. 30000번은 당연히 커스텀 포트이므로 얼마든지 수정할 수 있습니다.

 

 

여기에 Initial Root Token 정보를 입력해서 sign in을 합니다. 바로 다음과 같이 접속이 가능합니다.

 

 

Mac에서 Vault CLI 운영

운영자의 컴퓨터에서 vault cli를 사용하기 위해서 다음과 같이 설치 및 설정합니다.

brew tap hashicorp/tap
brew install hashicorp/tap/vault
vault --version  # 설치 확인

# NodePort로 공개한 30000 Port로 설정
export VAULT_ADDR='http://localhost:30000'

# vault 상태확인
vault status

# Root Token으로 로그인
vault login

 

연결 후 vault status를 입력하면 다음과 같이 연결된 것을 확인해볼 수 있습니다.

vault login도 진행해봅니다.

Static Secret 구성하기

static Secret은 KV 시크릿 엔진을 활성화하여 사용할 수 있습니다. 이때 KV는 Key, Value를 의미합니다.

Vault에서는 KV 시크릿 엔진이 Version 1과 Version 2로 나뉘는데 둘의 차이는 버전관리가 가능한 유무로 Version 2를 사용하겠습니다.

Vault KV version1 Vault KV version2
KV 버전관리 불가 KV 버전관리 가능

 

Step 1. KV 엔진 활성화 및 샘플 데이터 추가

먼저 엔진을 활성화해야합니다.

# KV v2 형태로 엔진 활성화
vault secrets enable -path=secret kv-v2

다음과 같이 샘플데이터를 추가해보겠습니다.

# 샘플 시크릿 저장
vault kv put secret/sampleapp/config \
  username="demo" \
  password="p@ssw0rd"

 

샘플데이터를 다음과 같이 확인해봅니다.

위치와 메타데이터 등이 공유됩니다.

# 입력된 데이터 확인
vault kv get secret/sampleapp/config

 

참고로 vault 콘솔에서도 해당 경로로 가면 확인이 가능합니다.

 

만약 경로를 확인하면 다음과 같이 확인할 수 있습니다.

 

 

 

실제로 해당 cli를 사용해서 조회가 가능한지도 확인해봅시다. 잘되는 것을 확인할 수 있습니다.

 

 

이상으로 vault의 개념과 설치 그리고 KV 시크릿을 생성하는 것 까지 학습하였습니다.