이 가이드는 macOS 환경에서 Kind (Kubernetes in Docker) 클러스터에 HashiCorp Vault를 배포하는 방법을 단계별로 설명합니다.
# Homebrew 설치 (이미 설치되어 있다면 생략)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Docker Desktop 설치
brew install --cask docker
# Kind 설치
brew install kind
# kubectl 설치
brew install kubectl
# Helm 설치
brew install helm
# jq 설치 (JSON 파싱용)
brew install jq
Docker Desktop을 실행하고 Docker daemon이 시작될 때까지 기다립니다.
# Docker 상태 확인
docker ps
cat <<EOF > kind-vault-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: vault-demo
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 8200
protocol: TCP
- containerPort: 30001
hostPort: 8201
protocol: TCP
EOF
설정 설명:
extraPortMappings: Vault UI(8200) 및 API(8201) 포트를 로컬에서 접근 가능하도록 매핑kind create cluster --config kind-vault-cluster.yaml
kubectl cluster-info
kubectl get nodes
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
examples/vault-values.yaml 파일을 생성합니다 (이미 제공된 경우 사용):
# Vault 서버 설정
server:
# 개발 모드로 실행 (운영 환경에서는 사용하지 마세요)
dev:
enabled: false
# Standalone 모드로 실행
standalone:
enabled: true
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "file" {
path = "/vault/data"
}
# NodePort 서비스로 외부 접근 허용
service:
type: NodePort
nodePort: 30000
# 데이터 영구 저장
dataStorage:
enabled: true
size: 10Gi
# 리소스 제한
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
# Vault UI 활성화
ui:
enabled: true
serviceType: NodePort
serviceNodePort: 30000
# Injector (사이드카 방식, VSO 사용 시 불필요할 수 있음)
injector:
enabled: true
# vault namespace 생성
kubectl create namespace vault
# Helm으로 Vault 설치
helm install vault hashicorp/vault \
--namespace vault \
--values examples/vault-values.yaml
# Pod 상태 확인
kubectl get pods -n vault -w
kubectl exec -n vault -it vault-0 -- sh
# Vault 초기화 (5개의 키 조각, 3개로 unsealing)
vault operator init \
-key-shares=5 \
-key-threshold=3 \
-format=json > /tmp/vault-init.json
# 출력 확인
cat /tmp/vault-init.json
중요: 출력된 Unseal Keys와 Root Token을 안전한 곳에 저장하세요!
# 다른 터미널에서 실행
kubectl cp vault/vault-0:/tmp/vault-init.json ./vault-init.json
# Unseal Keys 추출
cat vault-init.json | jq -r '.unseal_keys_b64[]'
# Root Token 추출
cat vault-init.json | jq -r '.root_token'
# Vault Pod 내에서 실행
# Unseal Key 3개를 순서대로 입력
vault operator unseal <KEY_1>
vault operator unseal <KEY_2>
vault operator unseal <KEY_3>
# Unseal 상태 확인
vault status
출력 예시:
Sealed false
vault login <ROOT_TOKEN>
Kubernetes Pod가 Vault에 인증할 수 있도록 설정합니다.
# Vault Pod 내에서 실행
vault auth enable kubernetes
# Kubernetes API 서버 정보 설정
vault write auth/kubernetes/config \
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"
# myapp-policy 생성
vault policy write myapp-policy - <<EOF
path "secret/data/myapp/*" {
capabilities = ["read", "list"]
}
EOF
vault write auth/kubernetes/role/myapp-role \
bound_service_account_names=myapp-sa \
bound_service_account_namespaces=default \
policies=myapp-policy \
ttl=24h
설명:
bound_service_account_names: 허용할 ServiceAccount 이름bound_service_account_namespaces: 허용할 Namespacepolicies: 이 Role에 연결할 정책ttl: 토큰 유효 기간vault secrets enable -version=2 -path=secret kv
vault kv put secret/myapp/database \
username="dbuser" \
password="dbpassword" \
host="postgres.default.svc.cluster.local" \
port="5432"
# Secret 읽기 (vault read 사용 권장)
vault read secret/data/myapp/database
# 또는 vault kv get 사용 (UI 권한 필요)
# vault kv get secret/myapp/database
# 로컬 터미널에서 실행
export VAULT_ADDR='http://localhost:8200'
export VAULT_TOKEN='<ROOT_TOKEN>'
# Vault 상태 확인
vault status
브라우저에서 http://localhost:8200을 엽니다.
# 로컬 터미널에서 실행
kubectl create serviceaccount myapp-sa
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: vault-test
spec:
serviceAccountName: myapp-sa
containers:
- name: vault-client
image: hashicorp/vault:latest
command: ['sh', '-c', 'sleep 3600']
env:
- name: VAULT_ADDR
value: "http://vault.vault.svc.cluster.local:8200"
kubectl apply -f test-pod.yaml
# Pod가 실행될 때까지 대기
kubectl wait --for=condition=ready pod/vault-test --timeout=60s
# Pod에 접속
kubectl exec -it vault-test -- sh
# ServiceAccount 토큰 가져오기
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
# Vault에 로그인
VAULT_TOKEN=$(vault write -field=token auth/kubernetes/login \
role=myapp-role \
jwt=$KUBE_TOKEN)
export VAULT_TOKEN
# Secret 읽기 - vault read 명령어 사용
vault read secret/data/myapp/database
성공 시 출력:
====== Data ======
Key Value
--- -----
host postgres.default.svc.cluster.local
password dbpassword
port 5432
username dbuser
[!WARNING] 이 가이드의 설정은 학습 및 개발 목적입니다. 운영 환경에서는 다음을 고려해야 합니다:
# HA 모드 설정 예시
server:
ha:
enabled: true
replicas: 3
standalone:
enabled: false
# AWS KMS를 사용한 Auto-Unseal 예시
server:
extraEnvironmentVars:
VAULT_SEAL_TYPE: awskms
VAULT_AWSKMS_SEAL_KEY_ID: "your-kms-key-id"
listener "tcp" {
tls_disable = 0
tls_cert_file = "/vault/tls/tls.crt"
tls_key_file = "/vault/tls/tls.key"
}
운영 환경에서는 Consul, etcd, 또는 클라우드 스토리지를 사용하세요:
storage "consul" {
address = "consul.service.consul:8500"
path = "vault/"
}
vault audit enable file file_path=/vault/logs/audit.log
# Pod 로그 확인
kubectl logs -n vault vault-0
# Pod 상세 정보 확인
kubectl describe pod -n vault vault-0
# Vault 상태 확인
kubectl exec -n vault vault-0 -- vault status
# 수동으로 Unseal
kubectl exec -n vault vault-0 -- vault operator unseal <KEY>
# Vault에서 Kubernetes 인증 설정 확인
kubectl exec -n vault vault-0 -- vault read auth/kubernetes/config
# ServiceAccount 확인
kubectl get serviceaccount myapp-sa
kubectl describe serviceaccount myapp-sa
Vault가 성공적으로 배포되었습니다! 다음 문서로 진행하세요: