목차
- 1. 왜 AKS에서 Vault on K8s가 필요할까요
- 2. Vault, AKS, Kubernetes Auth를 쉽게 풀어보면
- 3. AKS에서 Vault on K8s 아키텍처를 어떻게 잡으면 좋을까
- 4. 실전 구현: AKS에 Vault 배포하기
- 4-1. 네임스페이스와 Helm 저장소 준비
- 4-2. values.yaml 예시
- 4-3. 배포
- 4-4. 초기화와 언실
- 5. Kubernetes Auth와 시크릿 엔진 구성
- 5-1. KV 시크릿 엔진 활성화
- 5-2. Kubernetes Auth 활성화
- 5-3. 정책 생성
- 5-4. Role 생성
- 6. 애플리케이션 Pod에 시크릿 주입하기
- 7. ⚠️ 운영 중 자주 만나는 문제와 트러블슈팅
- 7-1. Pod는 떴는데 시크릿 파일이 안 생기는 경우
- 7-2. Vault 로그인 또는 Auth 설정이 실패하는 경우
- 7-3. Vault 자체의 고가용성은 올렸는데 운영 절차가 없는 경우
- 8. 검증 방법과 기대 결과
- 9. 정리와 다음 단계
- FAQ: 자주 묻는 질문
- AKS에서 꼭 Vault가 필요할까요?
- Vault on K8s는 운영 난도가 높지 않나요?
- 시크릿은 환경 변수보다 파일 주입이 더 나은가요?
[k8s] AKS에서 Vault on K8s 구축: 보안 강화 및 민감 정보 관리 방안
AKS(Azure Kubernetes Service, 애저 쿠버네티스 서비스)를 운영하다 보면 결국 부딪히는 문제가 하나 있습니다. 바로 시크릿 관리예요. 처음에는 Kubernetes Secret(쿠버네티스 시크릿)만으로도 충분하다고 느끼실 수 있는데, 저도 처음엔 그랬거든요. 그런데 운영 환경이 커지고, 애플리케이션 수가 늘고, 누가 어떤 자격 증명(credential)을 어디서 쓰는지 추적해야 하는 순간이 오면 상황이 달라져요. 그때부터는 “이걸 계속 이렇게 들고 가도 될까?” 싶은 생각이 드더라고요.
그래서 오늘은 Vault on K8s AKS 구성을 어떻게 접근하면 좋을지, 제가 실제로 비슷한 구조를 설계하고 검증할 때 중요하게 봤던 포인트를 중심으로 정리해보려 해요. 핵심은 단순히 HashiCorp Vault(해시코프 볼트)를 올리는 게 아니라, AKS 환경에서 인증(auth), 저장(storage), 정책(policy), 주입(injection) 흐름을 어떻게 안전하게 묶을지하는 거거든요. 특히 민감 정보가 Git, 환경 변수, 컨테이너 이미지 안에 흩어지기 시작한 팀이라면 한 번쯤 진지하게 볼 만한 주제입니다.
AKS 클러스터, Vault 서버, 애플리케이션 Pod, Kubernetes Auth 흐름을 한눈에 보여주는 전체 구조 이미지입니다.
1. 왜 AKS에서 Vault on K8s가 필요할까요
쉽게 말해, Vault는 시크릿을 중앙에서 관리하고 접근을 통제하는 금고 역할을 하는 거예요. Kubernetes Secret도 이름은 시크릿이지만, 그 자체만으로는 운영 통제 수준이 부족하다고 느끼는 경우가 많아요. Base64 인코딩만으로는 보안이 해결되지 않거든요. 물론 etcd 암호화(encryption at rest) 같은 보완책이 있지만, 접근 통제와 감사(audit), 동적 자격 증명(dynamic credentials)까지 생각하면 Vault가 주는 이점이 분명합니다.
- 중앙 집중형 관리: DB 비밀번호, API 토큰, 인증서 등을 한곳에서 관리할 수 있어요.
- 정책 기반 접근 제어: 누가 어떤 경로(path)의 시크릿을 읽을 수 있는지 세밀하게 나눌 수 있습니다.
- 감사 추적: 접근 기록을 남겨서 운영 가시성을 확보하기 좋아요.
- 동적 시크릿 확장 가능성: 정적 비밀번호를 오래 들고 가지 않는 구조로 발전시키기 쉬워요.
여기서 중요한 포인트! AKS에서 Vault를 쓴다고 해서 자동으로 다 안전해지는 건 아니에요. 어디에 저장할지, 어떻게 인증할지, 어떤 네트워크 경계 안에 둘지를 같이 설계해야 의미가 있어요. 저도 처음엔 “Vault만 올리면 끝 아닌가?” 싶었는데, 실제로 해보니까 그다음이 진짜 시작이더라고요.
2. Vault, AKS, Kubernetes Auth를 쉽게 풀어보면
개념을 너무 어렵게 잡으면 오히려 구현이 꼬여요. 쉽게 말하면 흐름은 이렇습니다.
- 애플리케이션 Pod가 AKS 안에서 실행돼요.
- Pod는 자신의 ServiceAccount(서비스 어카운트)를 이용해 Vault에 신원을 증명합니다.
- Vault는 Kubernetes Auth(쿠버네티스 인증)로 이 Pod가 누구인지 확인해요.
- 정책에 맞으면 필요한 시크릿을 내려줍니다.
즉, 애플리케이션 입장에서는 “내가 누구인지 증명하고, 허용된 비밀만 받아간다”는 구조예요. 이 방식의 장점은 시크릿을 애플리케이션 매니페스트에 하드코딩하지 않아도 된다는 거거든요. 운영해보신 분들은 아실 텐데, Secret YAML 파일이 여기저기 복사되기 시작하면 관리가 정말 힘들어져요.
| 항목 | Kubernetes Secret | Vault on K8s |
|---|---|---|
| 저장 위치 | 클러스터 내부 | Vault 백엔드 |
| 접근 제어 | RBAC 중심 | 정책 기반 세분화 가능 |
| 감사 추적 | 제한적 | Audit Device(감사 장치) 활용 가능 |
| 주입 방식 | 환경 변수, 볼륨 | Agent Injector, CSI 등 확장 가능 |
| 운영 복잡도 | 낮음 | 상대적으로 높음 |
결국 선택의 기준은 단순해요. 작고 단순한 환경이면 Kubernetes Secret만으로도 충분합니다. 반대로 권한 분리, 감사, 로테이션, 멀티 서비스 운영이 중요해지면 Vault on K8s AKS 구성이 훨씬 낫습니다.
3. AKS에서 Vault on K8s 아키텍처를 어떻게 잡으면 좋을까
제가 추천하는 기본 방향은 이래요. 과하게 복잡하게 시작하지 말고, 운영상 필요한 최소 안전장치를 먼저 넣는 거예요.
- Vault는 전용 네임스페이스에 배치합니다.
- Integrated Storage Raft(통합 스토리지 래프트)를 사용해 내부 저장소를 구성해요.
- Kubernetes Auth로 애플리케이션 인증을 처리합니다.
- Vault Agent Injector 또는 템플릿 렌더링 방식으로 시크릿을 Pod에 주입해요.
- NetworkPolicy(네트워크 정책)와 Ingress(인그레스, 외부 트래픽 진입점) 또는 내부 LoadBalancer 정책을 명확히 나누어요.
실무에서는 Vault를 외부에 완전히 공개하지 않는 편이 훨씬 나아요. 가능하면 내부 네트워크에서만 접근하게 만들고, 운영자 접근도 제한하는 쪽이 좋거든요. 홈랩에서도 이 부분을 느슨하게 두면 결국 테스트 편의성이 보안 기준을 이겨버리더라고요. 처음엔 편한데 나중에 반드시 정리해야 해요.

Vault 전용 네임스페이스, Raft 스토리지, Agent Injector, 애플리케이션 네임스페이스 분리를 보여주는 구성 이미지입니다.
4. 실전 구현: AKS에 Vault 배포하기
이제 실제 흐름으로 가봅시다. 여기서는 Helm(헬름)을 이용해 Vault를 AKS에 배포하는 예시를 기준으로 설명할게요. 세부 값은 환경마다 다르니, 그대로 복붙보다 구조를 이해하고 적용하시는 게 훨씬 중요합니다.
4-1. 네임스페이스와 Helm 저장소 준비
kubectl create namespace vault
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
여기까지는 크게 어렵지 않아요. 문제는 그다음 values 설정이에요. 처음엔 기본값으로 올리고 싶어지는데, 운영 목적이라면 최소한 스토리지와 UI, Injector 여부는 같이 잡아주는 게 좋습니다.
4-2. values.yaml 예시
server:
enabled: true
ha:
enabled: true
replicas: 3
raft:
enabled: true
dataStorage:
enabled: true
size: 10Gi
service:
enabled: true
type: ClusterIP
ingress:
enabled: false
resources: {}
ui:
enabled: true
injector:
enabled: true
여기서는 HA(고가용성)와 Raft storage를 켰어요. Vault on K8s는 단일 인스턴스로도 테스트는 되지만, 실제 운영 관점에서는 장애 대응을 생각하지 않을 수가 없거든요. 물론 노드 수, 디스크 크기, 서비스 타입은 환경에 맞춰 조정해야 합니다.
4-3. 배포
helm install vault hashicorp/vault \
--namespace vault \
--values values.yaml
배포 후에는 Pod 상태부터 확인하세요.
kubectl get pods -n vault
kubectl get svc -n vault
이 시점에서 Pod가 뜬다고 끝이 아니에요. Vault는 초기화(initialization)와 언실(unseal) 과정을 거쳐야 하거든요. 이 부분에서 처음 삽질 많이 합니다 ㅎㅎ
4-4. 초기화와 언실
kubectl exec -it -n vault vault-0 -- vault operator init
이 명령을 실행하면 unseal key와 initial root token이 출력돼요. 이 정보는 정말 민감하니까요, 테스트 환경이라고 터미널 히스토리에 남기고 방치하면 나중에 곤란해져요. 저도 예전에 PoC 환경이라고 가볍게 봤다가 정리하느라 번거로웠던 적이 있어요.
이후 각 Pod에 대해 언실을 진행합니다.
kubectl exec -it -n vault vault-0 -- vault operator unseal
kubectl exec -it -n vault vault-1 -- vault operator unseal
kubectl exec -it -n vault vault-2 -- vault operator unseal
로그인도 해두세요.
kubectl exec -it -n vault vault-0 -- vault login
5. Kubernetes Auth와 시크릿 엔진 구성
이제부터가 진짜 핵심이에요. Vault 서버를 띄우는 건 절반이고, AKS 워크로드가 안전하게 시크릿을 받아가게 만드는 과정이 나머지 절반입니다.
5-1. KV 시크릿 엔진 활성화
kubectl exec -it -n vault vault-0 -- vault secrets enable -path=secret kv-v2
kubectl exec -it -n vault vault-0 -- vault kv put secret/app/config username="demo-user" password="demo-pass"
여기서는 예시로 KV v2(Key-Value Version 2) 엔진을 사용했어요. 정적 시크릿 관리의 기본 출발점으로 가장 무난하거든요.
5-2. Kubernetes Auth 활성화
kubectl exec -it -n vault vault-0 -- vault auth enable kubernetes
그다음 Kubernetes API와 통신할 수 있도록 설정해야 합니다. 실제 값은 클러스터 환경에 맞게 확인이 필요해요.
kubectl exec -it -n vault vault-0 -- sh
vault write auth/kubernetes/config \
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"
환경에 따라 서비스 계정 토큰과 CA 인증서 경로까지 함께 지정하는 구성이 필요할 수 있어요. 이 부분은 클러스터 설정과 배포 방식에 따라 달라지니, 반드시 현재 환경 기준으로 검증해야 합니다.
5-3. 정책 생성
kubectl exec -it -n vault vault-0 -- sh -c 'cat > /tmp/app-policy.hcl <<EOF
path "secret/data/app/config" {
capabilities = ["read"]
}
EOF
vault policy write app-policy /tmp/app-policy.hcl'
정책은 정말 최소 권한(least privilege)으로 가야 해요. “일단 다 읽게 해두고 나중에 줄이자”는 접근이 제일 위험하거든요. 운영에 들어가면 나중은 잘 안 와요.
5-4. Role 생성
kubectl exec -it -n vault vault-0 -- vault write auth/kubernetes/role/app-role \
bound_service_account_names=app-sa \
bound_service_account_namespaces=default \
policies=app-policy \
ttl=1h
이렇게 하면 default 네임스페이스의 app-sa 서비스 계정을 사용하는 Pod만 해당 정책으로 인증받을 수 있어요. namespace와 service account를 분리해두면 실수 범위를 줄이기 좋거든요.

ServiceAccount, Vault Role, Policy, Secret Path가 어떻게 연결되는지 보여주는 인증 및 권한 흐름 이미지입니다.
6. 애플리케이션 Pod에 시크릿 주입하기
실제로 써보니까 운영팀과 개발팀 모두 만족도가 올라가는 구간이 바로 여기였어요. 개발자는 애플리케이션에서 민감 정보를 직접 들고 다니지 않아도 되고, 운영자는 중앙 통제가 가능해지거든요.
Vault Agent Injector를 사용하는 예시는 아래처럼 가져갈 수 있습니다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-role"
vault.hashicorp.com/agent-inject-secret-config.txt: "secret/data/app/config"
vault.hashicorp.com/agent-inject-template-config.txt: |
{{- with secret "secret/data/app/config" -}}
username={{ .Data.data.username }}
password={{ .Data.data.password }}
{{- end }}
spec:
serviceAccountName: app-sa
containers:
- name: app
image: nginx
volumeMounts: []
이 예시는 Pod 안에 파일 형태로 시크릿을 렌더링하는 방식이에요. 환경 변수 주입만 고집하기보다, 파일 기반 주입을 먼저 고려해보세요. 이유는 단순해요. 환경 변수는 프로세스 정보나 디버깅 과정에서 노출 범위를 관리하기 까다로울 수 있거든요.
배포 후에는 Pod 내부에서 실제로 파일이 생성됐는지 확인하세요.
kubectl apply -f app.yaml
kubectl get pods
kubectl exec -it deploy/demo-app -- cat /vault/secrets/config.txt
7. ⚠️ 운영 중 자주 만나는 문제와 트러블슈팅
여기서는 제가 꼭 강조하고 싶은 실전 포인트를 적어볼게요. 문서대로만 하면 바로 될 것 같지만, 실제 AKS에서 붙일 때 자주 막히는 지점이 몇 군데 있어요.
7-1. Pod는 떴는데 시크릿 파일이 안 생기는 경우
- ServiceAccount 이름과 Vault Role의 bound_service_account_names가 일치하는지 확인하세요.
- 네임스페이스가 Role 설정과 같은지 봐요.
- Pod annotation 오타가 없는지 확인해요.
- Injector Pod 로그를 확인합니다.
kubectl logs -n vault deploy/vault-agent-injector
이거 진짜 자주 나와요. 저도 처음엔 Vault 정책 문제인 줄 알았는데, 알고 보니 annotation 키 오타였던 적이 있었어요. 허무하죠. 근데 이런 게 제일 오래 갑니다.
7-2. Vault 로그인 또는 Auth 설정이 실패하는 경우
- Kubernetes API 접근 경로가 맞는지 봐요.
- Vault 서버가 클러스터 내부 DNS와 API 서버에 접근 가능한지 확인하세요.
- 서비스 계정 토큰과 CA 인증서 전달이 필요한 구성인지 점검해요.
AKS는 관리형 Kubernetes라서 제어 플레인 세부 구현을 직접 만지지는 않지만, 그렇다고 인증 흐름이 자동으로 다 맞아떨어지지는 않아요. 특히 네트워크 제한이나 정책이 들어가면 더 꼼꼼히 봐야 합니다.
7-3. Vault 자체의 고가용성은 올렸는데 운영 절차가 없는 경우
이 부분도 많이 놓쳐요. HA로 배포했다고 해서 운영이 끝난 게 아니거든요.
- 언실 절차를 누가 어떻게 수행할지
- 루트 토큰 보관 정책을 어떻게 할지
- 백업과 복구 테스트를 할지
- 감사 로그 보존을 어디까지 할지
보안 시스템은 설치보다 운영 절차가 훨씬 중요해요. 이건 정말 해보면 바로 체감됩니다.
8. 검증 방법과 기대 결과
구축이 끝났다면 그냥 “접속된다” 수준에서 멈추면 아쉬워요. 최소한 아래 항목은 꼭 검증해보세요.
- 권한이 있는 Pod만 시크릿을 읽을 수 있는지 확인하세요.
- 다른 ServiceAccount를 쓰는 Pod는 접근이 거부되는지 확인합니다.
- Vault 정책 변경 시 반영 범위를 확인해요.
- Pod 재기동 시 시크릿 주입이 일관되게 되는지 확인하세요.
- 감사 로그와 서버 로그에서 접근 기록을 추적할 수 있는지 봐요.
예를 들어 권한 없는 Pod를 하나 띄워서 동일 경로를 읽어보는 식으로 검증할 수 있어요. 이런 부정 테스트(negative test)를 같이 해봐야 진짜 구성이 맞는지 보여요.
kubectl run test-deny --rm -it --image=busybox --restart=Never -- sh
운영 결과 관점에서 기대할 수 있는 건 명확합니다.
- 애플리케이션 매니페스트에 민감 정보가 직접 들어가지 않아요.
- 시크릿 접근 경로가 정책으로 정리돼요.
- 누가 무엇을 읽는지 추적성이 좋아져요.
- 향후 동적 시크릿이나 인증서 자동화로 확장하기 쉬워져요.
특히 팀 규모가 커질수록 이점이 커져요. 처음엔 조금 번거롭지만, 나중에는 “왜 더 빨리 안 했지?” 싶을 때가 와요. 실제로 써보니까 시크릿이 여기저기 흩어져 있던 상태보다 운영 피로도가 훨씬 낮아지더라고요.

애플리케이션 Pod 내부 시크릿 파일 생성, 정책 기반 접근 허용/거부 검증 결과를 보여주는 이미지입니다.
9. 정리와 다음 단계
Vault on K8s AKS 구성의 핵심은 단순해요. Vault를 설치하는 것이 목적이 아니라, AKS에서 민감 정보를 안전하게 배포하고 통제하는 체계를 만드는 게 진짜 목표거든요. 처음엔 Kubernetes Secret만으로 충분해 보일 수 있어요. 저도 그렇게 시작했었는데, 서비스가 늘고 권한 관리가 복잡해지니까 한계가 분명히 보이더라고요.
오늘 정리한 흐름을 다시 압축하면 이렇습니다.
- Vault를 AKS에 전용 네임스페이스로 배치해요.
- Raft 기반 저장소와 HA 구성을 검토해요.
- Kubernetes Auth로 Pod 신원을 검증합니다.
- 정책 기반으로 필요한 시크릿만 주입해요.
- 운영 절차와 감사 체계를 같이 설계하세요.
혹시 지금 HashiCorp Vault 도입을 고민 중이세요? 그렇다면 처음부터 모든 기능을 한 번에 붙이기보다, KV 시크릿 엔진 + Kubernetes Auth + 최소 정책부터 시작해보는 걸 추천해요. 그게 훨씬 덜 꼬여요. 드디어 됐다! 싶은 순간이 분명 옵니다.
다음 글에서는 AKS에서 Vault와 외부 비밀 저장소를 어떻게 연계해서 운영 부담을 줄일지, 또는 Vault Agent Injector와 CSI 방식의 차이를 어떻게 판단하면 좋을지 이어서 다뤄볼 예정이에요. 이전 글에서 Kubernetes 기본 보안 설정을 정리했다면 그 내용과 함께 보셔도 흐름이 잘 맞을 거예요.
FAQ: 자주 묻는 질문
AKS에서 꼭 Vault가 필요할까요?
작고 단순한 환경이라면 꼭 그렇지는 않아요. 다만 시크릿 관리 범위가 넓어지고 감사와 권한 분리가 중요해지면 검토 가치가 크답니다.
Vault on K8s는 운영 난도가 높지 않나요?
맞습니다. Kubernetes Secret보다 복잡해요. 대신 통제력과 확장성이 좋아져요. 그래서 작은 범위로 시작하는 게 중요합니다.
시크릿은 환경 변수보다 파일 주입이 더 나은가요?
상황에 따라 다르지만, 운영 노출 범위를 생각하면 파일 기반 주입이 더 다루기 편한 경우가 많아요.

도입 전 분산된 시크릿 관리와 도입 후 중앙 통제 구조를 비교하는 요약 인포그래픽입니다.
![[k8s] AKS에서 Vault on K8s 구축: 보안 강화 및 민감 정보 관리 방안](https://blog.pswq.net/wp-content/uploads/2026/07/aks-vault-on-k8s-setup-security-enhancement-and-sensitive-data-management-thumbnail.jpg)