cloudNet@ 팀의 가시다 님이 진행하는 쿠버네티스 CI/CD 스터디 7주차 내용입니다.
Vault 개요
1. 정보보안의 3요소 (CIA Triad)
1) 기밀성 (Confidentiality)
- 의미: 허가된 사람(또는 시스템)만 정보에 접근할 수 있어야 합니다.
- 비유: "자물쇠가 채워진 일기장"
- 열쇠를 가진 나만 볼 수 있고, 동생은 볼 수 없어야 합니다.
- Vault에서는?
- Secrets Engine (KV, Transit)을 통해 데이터를 암호화하여 저장합니다. 토큰이 없으면 데이터를 읽을 수 없습니다.
2) 무결성 (Integrity)
- 의미: 정보가 허가 없이 변조되거나 삭제되지 않아야 하며, 변경되었다면 알아챌 수 있어야 합니다.
- 비유: "편지 봉투에 찍힌 밀랍 도장 (Sealing)"
- 도장이 깨져 있다면 누군가 중간에 편지를 뜯어봤거나 내용을 바꿨다는 뜻입니다.
- Vault에서는?
- 저장된 데이터가 임의로 수정되지 않도록 보호합니다.
- Hashing 기능을 통해 데이터 원본이 변하지 않았음을 검증합니다.
3) 가용성 (Availability)
- 의미: 정당한 사용자가 원할 때는 언제든지 정보나 서비스를 이용할 수 있어야 합니다.
- 비유: "24시간 열려 있는 편의점"
- 내가 물건이 필요할 때 문이 잠겨 있거나 정전이 되어 있으면 안 됩니다.
- Vault에서는?
- HA (High Availability) 구성을 통해 서버 한 대가 죽어도 (Down), 대기 중인 다른 서버가 즉시 역할을 이어받아 서비스가 멈추지 않게 합니다.

2. 액세스 제어의 3단계 (AAA) : 인증(Who?), 인가(What?), 감사/계정관리 - Link
보안 시스템이 사용자를 처리하는 과정은 AAA라고 불리는 3단계 흐름을 따릅니다. Vault의 작동 방식 그 자체이기도 합니다.
“엄격한 보안이 걸려있는 '판교 테크 회사'에 출근하는 과정”을 상황 비유와 함께 설명해보겠습니다.
1) 인증 (Authentication) - "Who are you?”
- 설명: 접속하려는 대상이 누구인지 신원을 확인하는 절차입니다.
- 비유: "출입 게이트에 사원증 찍기" 🪪
- "나는 이 회사 직원 김지입니다"라고 증명하는 과정입니다. (ID/PW, 지문, 사원증 등)
- Vault 연계: Auth Methods
- GitHub, AWS IAM, Kubernetes, Userpass 등을 통해 "나 클라이언트야!"라고 증명하면 Vault가 Token을 발급해 줍니다.
2) 인가 (Authorization) - "What can you do?”
- 설명: 인증된 사용자에게 허용된 권한(읽기/쓰기/삭제 등)을 부여하는 절차입니다. → 인증과 혼동하지 않도록 주의!
- 비유: "사원증 색깔에 따른 출입 구역 제한" 🚦
- 일반 사원(홍길동)은 휴게실과 사무실은 갈 수 있지만, **'전산실(Server Room)'**에는 들어갈 수 없습니다. 내가 직원임은 ***증명(인증)***됐지만, 권한(인가)은 없기 때문입니다.
- Vault 연계: Policies (ACL) → AWS IAM, K8s RBAC(SA, Role, Rolebinding)
- "DB 비밀번호는 **읽기(Read)**만 가능하고, **수정(Update)**은 불가능해"라고 정의하는 정책입니다.
3) 감사/계정관리 (Accounting/Auditing) - "What did you do?”
- 설명: 사용자가 수행한 모든 활동(접속 시간, 수행 명령, 접근 데이터 등)을 기록하고 추적하는 것입니다.
- 비유: "CCTV 녹화 및 출입 기록 로그" 📹
- 만약 전산실 서버가 고장 났다면, "오후 2시에 전산실에 누가 들어갔지?"를 확인하기 위해 기록을 돌려보는 것입니다.
- Vault 연계: Audit Devices
- 누가, 언제, 어떤 시크릿을 조회했는지 로그 파일로 남겨서 나중에 사고가 터졌을 때 추적합니다.

3. 시크릿이란?
1) 시크릿이란? → 대표적인 시크릿 종류종류 설명 및 특징 보안 위험 (노출 시)
| 비밀번호(Password) | 개인 계정, 서버 접근, 설정 파일 내의 일반 텍스트 암호. | 시스템 무단 접근, 데이터 유출, 계정 도용. |
| SSH Key | 서버(VM)에 안전하게 접속하기 위한 암호화된 키 쌍. | 서버 장악, 중요 데이터 탈취, 악성코드 배포. |
| Database Credentials | 데이터베이스에 접속하여 데이터를 읽고 쓰기 위한 사용자 ID 및 암호. | 모든 데이터(고객 정보, 금융 정보 등)의 유출 및 변조. |
2) 서비스 연동 및 자동화 키 종류 설명 및 특징 보안 위험 (노출 시)
| Cloud Credentials | ||
| (AWS Access Key, GCP Service Account Key 등) | 클라우드 환경의 리소스(저장소, VM, 네트워크 등)를 제어하기 위한 접근 키. | 클라우드 자원 무단 사용 및 삭제, 대규모 요금 발생, 클라우드 환경 장악. |
| Token, API Key (GitHub, Slack, OpenAI 등) | 외부 서비스의 기능을 사용하기 위해 발급받는 인증 토큰 또는 키. | 서비스 연한 계정의 권한 도용, 민감 정보(소스코드, 대화 내용) 접근. |
| → Vibe Coding 열풍으로 AI개발을 위한 API Key 관리 중요성 강화 |
3) 보안 통신 및 암호화 자산 종류 설명 및 특징 보안 위험 (노출 시)
| 인증서 (PKI/TLS) | 웹사이트의 신뢰성을 보장하고 통신을 암호화하는 데 사용되는 인증서 및 개인 키. | 중간자 공격(MITM), 웹사이트 위장, 통신 내용 도청, 서비스 신뢰도 하락. |
| 암호화 키 | 데이터베이스 또는 파일 시스템의 데이터를 암호화/복호화하는 데 사용되는 핵심 키. | 암호화된 데이터가 무력화되어 민감 정보 유출. |
Vault를 활용한 시크릿 중앙 관리가 필요한 이유
1. 시크릿 중앙 관리와 Vault의 필요성
IT 인프라와 애플리케이션 아키텍처가 복잡해지면서 기존의 방식으로는 '시크릿'을 안전하게 관리하기 불가능해졌기 때문입니다.
2. IT 아키텍처의 진화와 시크릿 관리의 복잡성
애플리케이션 환경은 지난 수십 년간 엄청난 변화를 겪었습니다. 문제는 아키텍처는 발전했지만 시크릿 관리 방식은 그 속도를 따라가지 못했다는 것입니다.
- 메인프레임 / 모놀리식 시대
- 시크릿 관리: 관리할 시크릿(DB 접속 정보 등)의 수가 적고, 변경이 거의 없었으며, 접근 경로가 명확했습니다. 관리가 비교적 단순했습니다.
- 3-Tier / 클라이언트-서버 시대
- 시크릿 관리: 관리할 컴포넌트가 늘어나면서 시크릿도 분산되기 시작했습니다. (e.g., A서버(WAS)가 DB 시크릿을 가져야 함) 하지만 여전히 인프라는 **정적(Static)**이었고 변경 주기가 길었습니다.
- 현대 클라우드 / MSA / DevOps 시대
- 특징: 수십, 수백 개의 마이크로서비스(MSA), **동적(Dynamic)**으로 생성되고 사라지는 컨테이너, 다양한 클라우드 서비스(AWS, GCP, Azure)와 API의 조합으로 시스템이 구성됩니다.
- 시크릿 관리의 위기:
- 시크릿의 폭증: 각 서비스, 각 컨테이너, 각 API 연동마다 고유한 자격증명(Credential)이 필요합니다. 관리할 시크릿의 수가 기하급수적으로 증가했습니다.
- 동적 환경: VM이나 컨테이너가 수시로 생기고 사라집니다. 이 동적인 환경에 맞춰 시크릿을 안전하게 전달하고 사용 후 즉시 폐기하는 것이 매우 어려워졌습니다.
- 시크릿의 분산: 시크릿이 코드 저장소(Git), 설정 파일(config.yml), 환경 변수, 개발자 PC 등 여러 곳에 하드코딩되거나 방치되기 시작했습니다. → 이를 **'시크릿 스프롤(Secret Sprawl)'이라고 부릅니다. - **What is "secret sprawl" and why is it harmful?, Solutions to secret sprawl: A 4-part framework

- 아키텍처 변화가 가져온 문제점
- 관리 대상 폭증: 메인프레임(소수) → 3-Tier(중간) → MSA(수백 개 이상)로 관리할 시크릿의 수가 폭발적으로 증가.
- 정적 → 동적 환경: 시크릿의 생성/소멸 주기가 인프라의 생명 주기(초/분 단위)와 같아져야 함.
- 시크릿 분산 (Secret Sprawl): 시크릿이 중앙에서 관리되지 않고 여러 곳에 흩어져 보안에 매우 취약해짐.
3. 제로 트러스트(Zero Trust) 보안 모델의 대두
- 과거의 보안 모델과 현대 보안 모델의 비교
과거의 보안 모델은 "성과 해자(Castle and Moat)" 방식이었습니다. 일단 내부망(성)에 들어오면, 내부의 시스템들은 서로를 신뢰했습니다.

하지만 클라우드와 MSA 환경에서는 '내부'와 '외부'의 경계가 모호해졌습니다. 해커가 일단 내부망에 침투하면, 신뢰를 기반으로 다른 시스템에 쉽게 접근(Lateral Movement)할 수 있게 됩니다.

"절대 신뢰하지 말고, 항상 검증하라 (Never Trust, Always Verify)"
이것이 제로 트러스트의 핵심입니다. 네트워크 위치(내부망 여부)를 신뢰의 기준으로 삼지 않고, 모든 접근 요청을 의심하고 검증합니다.

- 시크릿 관점에서의 제로 트러스트
제로 트러스트는 **'사람'**에게만 적용되지 않습니다. **'애플리케이션'**과 **'시스템'**에게도 동일하게 적용되어야 합니다.
- 기존: "저 서비스는 내부망에 있으니깐 DB에 접근해도 돼." (위치 기반 신뢰)
- 제로 트러스트: "저 서비스가 정말 '주문 서비스'가 맞는지 **신원(Identity)**을 확인하고, DB의 '주문 테이블'에만 SELECT할 수 있는 최소한의 권한을 5분 동안만 부여하겠어." (신원 기반 + 최소 권한 + 동적 접근)
요약: 제로 트러스트가 요구하는 것
- 경계 기반 보안의 종말: 내부망이라고 해서 안전하거나 신뢰할 수 없음 → Never Trust, Always Verify
- '사람' 뿐만 아니라 '시스템'의 신원 확인: 모든 사용자(사람)와 머신(애플리케이션, 컨테이너)은 접근 전 반드시 신원을 인증해야 함 → Never Trust, Always Verify
- 최소 권한의 원칙 (Principle of Least Privilege): 인증된 신원이라도, 작업에 필요한 '최소한의 권한'만 '최소한의 시간' 동안 부여받아야 함.
4. 결론: HashiCorp Vault가 필요한 이유
앞서 언급한 두 가지 큰 흐름(복잡한 아키텍처, 제로 트러스트)은 기존의 시크릿 관리 방식으로는 해결할 수 없는 문제들을 야기했습니다.
HashiCorp Vault는 바로 이 문제들을 해결하기 위해 설계된 **'시크릿 중앙 관리 솔루션'**입니다.

- 시크릿 스프롤(분산) 문제 해결 → 시크릿 중앙 저장소
- 모든 시크릿(DB/API 키, 인증서, 토큰 등)을 Vault라는 하나의 안전한 저장소에 암호화하여 중앙 관리합니다. 더 이상 코드나 설정 파일에 시크릿을 하드코딩할 필요가 없습니다.
- 동적 인프라 문제 해결 → 동적 시크릿 (Dynamic Secrets)
- Vault는 요청이 있을 때마다 '실시간으로' 시크릿(e.g., 10분짜리 DB 임시 계정)을 생성하고, 사용이 끝나면 자동으로 폐기합니다. 시크릿의 생명 주기를 관리합니다.
- 제로 트러스트(신원 확인) 문제 해결 → 신원 기반 접근 (Identity-Based Access)
- Vault는 사람(LDAP, Okta 등)뿐만 아니라 머신(Kubernetes, AWS IAM, GCP 등)의 신원을 인증할 수 있습니다. 인증된 신원(Identity)에게만 정책(Policy)에 따라 정확한 시크릿 접근 권한을 부여합니다.
- 감사 및 통제 문제 해결 → 감사 로그 (Audit Logs)
- '누가(어떤 시스템이)', '언제', '어떤 시크릿에' 접근했는지 상세한 로그를 제공하여 강력한 통제와 추적성을 확보합니다.
Vault
1. Vault란? - Docs
- HashiCorp Vault는 신원 기반(identity-based)의 시크릿 및 암호화 관리 시스템입니다.
- 이 시스템은 인증(authentication) 및 인가(authorization) 방법을 통해 암호화 서비스를 제공하여 비밀에 대한 안전하고 감사 가능하며 제한된 접근을 보장합니다.

- **시크릿(Secret)**이란 접근을 철저히 통제하고자 하는 모든 것을 의미하며, 예를 들어 토큰, API 키, 비밀번호, 암호화 키 또는 인증서 등이 이에 해당합니다.
- Vault는 모든 시크릿에 대해 통합된 인터페이스를 제공하면서, 엄격한 접근 제어와 상세한 감사 로그 기록 기능을 제공합니다.
- 외부 서비스용 API 키, 서비스 지향 아키텍처 간 통신을 위한 자격 증명 등은 플랫폼에 따라 누가 어떤 시크릿에 접근했는지를 파악하기 어려울 수 있습니다.
- 여기에 키 롤링(교체), 안전한 저장, 상세한 감사 로그까지 추가하려면 별도의 커스텀 솔루션 없이는 거의 불가능합니다. Vault는 바로 이 지점에서 해결책을 제공합니다.
- Vault는 클라이언트(사용자, 기계, 애플리케이션 등)를 검증하고 인가한 후에만 비밀이나 저장된 민감한 데이터에 접근할 수 있도록 합니다.
2. Vault가 액세스를 제어하는 4가지 핵심 요소

1) 누가 (Who) : 인증 (Authentication)
가장 먼저, 접근하려는 대상이 **'신뢰할 수 있는 주체'**인지 확인합니다.
- 대상: 사람(개발자, 관리자)뿐만 아니라 애플리케이션, 시스템, 머신을 포함합니다.
- 방식: ID/PW, GitHub 토큰, K8s Service Account, AWS IAM 등 다양한 방식을 통해 신원을 검증합니다.
- Vault 역할: "너 누구니?"를 확인하고, 검증된 사용자에게 Vault를 사용할 수 있는 **토큰(Token)**을 발급합니다.
2) 무엇에 (What) : 대상 지정 (Target System)
인증된 사용자가 **'어떤 시스템'**에 접근해야 하는지 명확히 합니다.
- 대상 리소스: Database, Web Server, Object Storage(S3), Cloud Console 등 민감한 자산들.
- 기존의 문제: 각각의 시스템마다 ID/PW가 파편화되어 관리가 어려웠습니다.
- Vault 역할: 다양한 시스템(Secret Engine)에 접근할 수 있는 단일한 게이트웨이(Gateway) 역할을 수행합니다.
3) 얼마 동안 (How Long) : 접근 시간 제어 (TTL)
한번 발급된 권한이 영원히 유효하다면, 유출되었을 때 큰 보안 사고로 이어집니다.
- 핵심 개념: TTL (Time To Live, 유효 기간)
- 동작: "이 DB 접속 권한은 딱 1시간 동안만 유효해"라고 제한을 둡니다.
- Vault 역할: 영구적인 키 대신, 시간이 지나면 자동으로 만료되는 **임시 자격 증명(Lease)**을 발급합니다.
4) 라이프 사이클 (Lifecycle) : 자동화 (Automation)
사람이 수동으로 비밀번호를 만들고, 갱신하고, 폐기하는 것은 비효율적이며 실수할 위험이 큽니다.
- 접근 키 관리: 생성(Create) → 갱신(Renew) → 폐기(Revoke)의 과정을 자동화합니다.
- 동적 시크릿 (Dynamic Secrets): 사용자가 요청할 때 계정을 즉시 생성하고, 사용이 끝나면 즉시 삭제합니다 → Just in Time(JIT)
- Vault 역할: 관리자의 개입 없이 시스템이 알아서 키의 수명주기를 관리하여 운영 부담과 보안 위험을 동시에 줄입니다.
3. Vault의 동작방식? - Docs
Vault는 주로 **토큰(Token)**을 기반으로 작동하며, 이 토큰은 클라이언트의 **정책(Policy)**과 연결되어 있습니다. 각 정책은 경로(path) 기반으로 설정되며, 정책 규칙은 클라이언트가 해당 경로에서 수행할 수 있는 작업과 접근 가능성을 제한합니다. Vault에서는 토큰을 수동으로 생성해 클라이언트에 할당할 수도 있고, 클라이언트가 로그인하여 토큰을 직접 획득할 수도 있습니다.
- 아래 그림은 Vault의 핵심 워크플로우를 보여줍니다.

Vault의 핵심 워크플로우는 다음 네 단계로 구성됩니다:
- 인증 (Authenticate): Vault에서 인증은 클라이언트가 Vault에 자신이 누구인지 증명할 수 있는 정보를 제공하는 과정입니다. 클라이언트가 인증 메서드를 통해 인증되면, 토큰이 생성되고 정책과 연결됩니다.
- 검증 (Validation): Vault는 Github, LDAP, AppRole 등과 같은 신뢰할 수 있는 외부 소스를 통해 클라이언트를 검증합니다.
- 인가 (Authorize): 클라이언트는 Vault의 보안 정책과 비교됩니다. 이 정책은 Vault 토큰을 사용하여 클라이언트가 접근할 수 있는 API 엔드포인트를 정의하는 규칙의 집합입니다. 정책은 Vault 내 특정 경로나 작업에 대한 접근을 허용하거나 거부하는 선언적 방식으로 권한을 제어합니다.
- 접근 (Access): Vault는 클라이언트의 신원에 연관된 정책을 기반으로 토큰을 발급하여 비밀, 키, 암호화 기능 등에 대한 접근을 허용합니다. 클라이언트는 이후 작업에서 해당 Vault 토큰을 사용할 수 있습니다.
4. 호텔 체크인 절차에 비유한 Vault의 동작방식 이해
- 개별 ID 인증/인가를 통해 필요한 자격 증명을 동적을 발급

- 사람 또는 애플리케이션(시스템)에 최적화된 인증방식 → 모든 인증의 목적은 “토큰(Token)”을 획득하기 위한 행위임
| 사람 (Human) | 애플리케이션/시스템 (Machine) |
| LDAP/AD | AWS |
| Okta | Azure |
| OIDC | Google Cloud |
| SAML | JWT |
| GitHub | Kubernetes |
| Cloud IAM | RADIUS |
| Username & Password | TLS Certificates |
| AppRole | |
| Cloud Foundry |
- Vault의 인증 및 권한 부여
- Vault는 사용자 인증이 아닌 권한 부여를 제공
- 실제 인증 프로세스는 관리하지 않음
- 다양한 인증 방법 권장
- 사람: LDAP, OIDC, SAML 등의 외부 IDP 활용
- 애플리케이션/시스템:
- AWS IAM, EC2 등
- Token/AppRole/Kuberntes/TLS 등
- 보안 및 신뢰성 확보
- 다양한 유형에 적합한 인증 방법을 사용
5. Vault Identity & Authentication
- Vault는 다양한 IdPs(Identity Providers)와 통합하여 사용자의 인증 요청을 검증
- 자격 증명에 대한 검증(Validation)
- 사전 정의된 정책(Policy)과 연결된 Token을 생성하여 제공
- Vault에 액세스 할 수 있는 Vault Token을 사용자(클라이언트)에게 반환
→ Vault Token은 인증된 사용자(클라이언트)에게 할당된 액세스 대상 및 기능(Engine)에 Vault 정책과 연결

- 사용자 인증/인가를 위해 외부 IDP를 연동하고, 엔티티를 기준으로 인증 방법/정책/엔진 접근을 관리

- Authentiction을 위한 절차

그림: HashiCorp Korea 내부자료(사용시 출처반드시 표기)
실습 환경 구성 - Kubernetes에 Vault 설치 - Docs1 | Docs2 | Docs3 |
1. Kind K8s 배포
# kind k8s 배포
kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000 # Vault UI
hostPort: 30000
- containerPort: 30001 # Jenkins UI
hostPort: 30001
- containerPort: 30002 # DB 배포(PostgreSQL 또는 MySQL)
hostPort: 30002
- containerPort: 30003 # # Sample App
hostPort: 30003
EOF
Vault on Kubernets 설치
1. 학습목표
- 실습용 K8s 환경(KinD)에 Vault를 Helm으로 설치
- 설치된 Vault 서버에 접속하고 UI/CLI로 기본 기능을 확인
- Vault의 동작 방식과 구조의 이해
- 초기화 및 Root Key 관리방안(이론 소개만)
2. 실습 환경 구성 - Dev Mode 설치
- In-Memory Storage: 데이터를 메모리에 저장하므로 재시작 시 데이터가 초기화됩니다.
- Auto Unseal: 자동으로 봉인이 해제된 상태로 시작됩니다.
- Root Token: 초기 루트 토큰이 지정된 값(여기서는 root)으로 고정됩니다.
1) Helm을 사용한 Vault 배포
- 네임스페이스 생성 및 Helm Repo 추가
# Create a Kubernetes namespace.
kubectl create namespace vault
# View all resources in a namespace.
kubectl get all --namespace vault
# Setup Helm repo
helm repo add hashicorp https://helm.releases.hashicorp.com
# Check that you have access to the chart.
helm search repo hashicorp/vault
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/vault 0.31.0 1.20.4 Official HashiCorp Vault Chart
hashicorp/vault-secrets-gateway 0.0.2 0.1.0 A Helm chart for Kubernetes
hashicorp/vault-secrets-operator 1.0.1 1.0.1 Official Vault Secrets Operator Chart
# vault-values-dev.yaml 생성
cat <<EOF > vault-values-dev.yaml
global:
enabled: true
tlsDisable: true
injector:
enabled: true
# Sidecar Injection을 위해 필요한 설정
server:
dev:
enabled: true
devRootToken: "root" # 학습 편의를 위해 Root Token을 'root'로 고정
# 데이터 영구 저장이 필요 없으므로 비활성화 (Dev모드는 메모리 사용)
dataStorage:
enabled: false
# UI 활성화 및 NodePort 노출
service:
type: "NodePort"
nodePort: 30000
ui:
enabled: true
EOF
# Helm Install 실행
helm upgrade vault hashicorp/vault -n vault -f vault-values-dev.yaml --install
# 네임스페이스 변경 : vault
kubens vault
Context "kind-myk8s" modified.
Active namespace is "vault".
# 배포확인
k get pods,svc,pvc
NAME READY STATUS RESTARTS AGE
pod/vault-0 0/1 ContainerCreating 0 9s
pod/vault-agent-injector-556c5dd8fb-7w7mh 0/1 ContainerCreating 0 9s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/vault ClusterIP 10.96.236.165 <none> 8200/TCP,8201/TCP 9s
service/vault-agent-injector-svc ClusterIP 10.96.235.29 <none> 443/TCP 9s
service/vault-internal ClusterIP None <none> 8200/TCP,8201/TCP 9s

2) Vault 초기화 및 잠금해제
kubectl exec -ti vault-0 -- vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.20.4
Build Date 2025-09-23T13:22:38Z
Storage Type inmem
Cluster Name vault-cluster-4336e9b4
Cluster ID c45bb2d0-69c4-03d7-909f-f0f4bd7d61fc
HA Enabled false
- SSS(Shamir Secret Sharing) 방식이란?
- 암호학자 아디 샤미르(Adi Shamir)의 이름에서 따온 이 시크릿 공유 알고리즘은 개인이 특정 시크릿 정보를 보유하지 않고 결합 될 때에야 암호화 된 루트 키를 해제할 수 있는 단일 키로 조합되는 방식이다.
- 이 알고리즘은 N개의 Unseal Key를 생성(Key Shares)하고, 그 중 M개의 Key를 제공(Key Threshold)하면 이를 토대로 Root Key를 획득 및 Unseal을 수행한다. → Key Shares 5개, Threshold: 3개를 설정하면 과반수 이상 참여했으므로 Root Key 제공



3) CLI 설정
- MacOS
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
Token (will be hidden): root # Dev 모드로 설치시 설정한 Root Token
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token root
token_accessor euQQ1Uf8L2zDZioBqmgx7Go0
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
- WSL 2 Ubuntu
# 1) 필수 패키지 설치
sudo apt-get update
sudo apt-get install -y gpg curl lsb-release
# 2) HashiCorp 공식 APT Repository 등록
# HashiCorp GPG Key 등록
curl -fsSL https://apt.releases.hashicorp.com/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
# HashiCorp Repo 추가
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/hashicorp.list
# 3) Vault 설치
sudo apt-get update
sudo apt-get install -y vault
# 4) 설치 확인
vault --version
# 5) Vault 주소 설정 (NodePort 30000 사용)
export VAULT_ADDR='http://localhost:30000'
# export VAULT_ADDR='http://<WINDOWS_HOST_IP>:30000'
# 6) Vault 상태 확인
vault status
# 7) Root Token으로 로그인
vault login

4. UI 접속확인
open http://localhost:30000


5. KV 시크릿 엔진 활성화 및 샘플 구성 → 정적 시크릿(Static Secret)
- Vault KV version 2 엔진을 활성화하고 샘플 데이터를 저장합니다.
- Version1 : KV 버전관리 불가 / Version2 : KV 버전관리 가능 [Docs]
- KV 엔진 활성화 및 샘플 데이터 추가
# 활성화된 시크렛 엔진 목록 조회
vault secrets list
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_92a571f7 per-token private secret storage
identity/ identity identity_464bc39a identity store
secret/ kv kv_737df813 key/value secret storage
sys/ system system_699be8c4 system endpoints used for control, policy and debugging
# KV v2 형태로 엔진 활성화하기 위한 명령은 다음과 같지만 Dev 모드에서 활성화 되어있음.
# vault secrets enable -path=secret kv-v2
# 샘플 시크릿 저장 (경로: secret/sampleapp/config)
vault kv put secret/sampleapp/config \
username="demo" \
password="p@ssw0rd"
# 입력된 데이터 확인
vault kv get secret/sampleapp/config

- Vault UI : [Secrets Engine] 탭에 접속 후 [sampleapp - config] 접속하여 실제 저장된 Key / Value 확인
- username : demo
- password : p@ssw0rd

- 경로를 확인하는 명령 가이드 - Link

curl -s --header "X-Vault-Token: root" \
--request GET http://127.0.0.1:30000/v1/secret/data/sampleapp/config | jq

Vault Agent와 Sidecar 패턴
1. 왜 Vault Agent가 필요한가?
- Vault를 도입하면 개발자들이 가장 먼저 부딪히는 문제가 있다. 바로 “애플리케이션에서 Vault를 어떻게 연동할 것인가?” 이다.
- 개발자가 Vault SDK를 직접 사용하면 “비즈니스 로직 외에 보안 인프라 로직”까지 모두 구현해야 하므로 부담이 크고 언어마다 구현 방식이 달라진다.
- Vault Agent는 이 문제를 사이드카(Sidecar) 기반 표준 패턴으로 깔끔하게 해결해준다.
1) 기존 방식: 애플리케이션에서 Vault를 직접 호출하는 Direct Integration
- SDK로 직접 연동하면 다음 모든 로직을 개발자가 직접 구현해야 한다.
- Auth Method 구현
- Kubernetes, AWS, AppRole 등 다양한 인증 방식을 직접 구현
- JWT 생성/서명 검증 등 앱 언어별로 다르게 처리해야 함
- Token 관리 로직
- 발급된 토큰의 TTL 확인
- 만료되기 전에 자동 갱신(Renewal)
- 갱신 실패 시 재로그인 방식 처리
- 인증을 편하게 하기 위해 영구 토큰 사용한다면? → 보안 구멍 발생!
- 에러 처리 및 재시도 로직
- Vault 장애·네트워크 지연 발생 시 재시도
- 백오프 전략 구현
- Vault Unseal 시점 대기 처리
- Secret JSON Parsing & 파일 반영
- Vault 응답(JSON)을 파싱해 애플리케이션 환경 변수나 파일에 반영
- 시크릿 Rotation 시 재반영(reload) 로직 필요
2) 해결책: Vault Agent (Sidecar 패턴)
Agent가 (대신)인증 → 토큰 발급/갱신 → 시크릿 렌더링 → 파일 생성(+ 명령 실행)까지 자동으로 처리한다. 앱은 “파일만 읽으면” 됨.
Vault Agent는 클라이언트 호스트(혹은 컨테이너)에서 동작하며 다음 기능을 제공한다.
- 자동 로그인(Auto-Auth)
- AWS/Kubernetes/AppRole 등 어떤 인증 방식이든 Agent가 대신 Vault 로그인 수행
- 앱은 “어떻게 로그인하는지” 몰라도 됨
- 토큰 자동 갱신(Lifecycle Management)
- Token TTL 체크 → 자동 Renew
- 만료되기 전에 자동 연장
- 갱신 실패 시 재로그인까지 자동 처리
- 템플릿 렌더링(Consul Template 내장)
- Vault에서 가져온 시크릿을 config.json, .env, tls.crt, application.properties 등 앱이 기대하는 형태의 파일로 자동 생성
- Secret이 rotate되면 파일도 자동으로 업데이트
- Simplified Consumption
- 앱은 “Vault 모른다”
- 그냥 /app/config/config.json 같은 파일만 읽으면 됨
→ “결과적으로 개발자는 Vault API를 호출할 필요가 없어지고, 보안·토큰·시크릿 갱신 문제는 전부 플랫폼 표준으로 해결된다.”
3) Vault Agent가 내부적으로 동작하는 과정의 이해

- Vault에 인증 요청 (Authenticate with Vault)
- Vault Agent가 설정된 Auto-Auth 방식을 사용해 Vault에 인증을 시작한다. (Kubernetes, AWS, AppRole 등)
- 애플리케이션은 Vault와 직접 통신하지 않는다.
- 애플리케이션 신원 검증 (Verify the identity of the application)
- Vault는 신뢰할 수 있는 플랫폼을 통해 애플리케이션이 실제로 인증된 워크로드인지 확인한다.
- 예: Kubernetes ServiceAccount JWT 검증 / AWS IAM Role 검증 / GCP Metadata 검증
- VM 환경에서는 Kubernetes나 Cloud Identity처럼 “플랫폼이 제공하는 ID”가 없기 때문에, Vault는 AppRole, TLS Certificates, OIDC 같은 “대체 신원 검증 방식”을 사용
- Vault는 신뢰할 수 있는 플랫폼을 통해 애플리케이션이 실제로 인증된 워크로드인지 확인한다.
- 신원 확인 완료 (Verified)
- Vault가 애플리케이션의 신원을 검증하면 해당 워크로드에 어떤 Role과 Policy를 적용할지 결정한다.
- 클라이언트 토큰 발급 (Return a client token)
- Vault는 Agent에게 애플리케이션 전용 클라이언트 토큰을 반환한다.
- 이 토큰에는 애플리케이션이 접근할 수 있는 권한이 Policy 기반으로 포함되어 있다.
- 토큰 저장 (Store the token in a sink)
- Vault Agent는 발급받은 토큰을 로컬 Sink에 저장한다. (이 토큰은 이후 시크릿 조회·토큰 갱신에 사용)
- (참고) Sink는 tmpfs(메모리 기반 파일 시스템)으로 관리하는 것이 안전 → auto-auth 사용시 Sink설정 필수
- 시크릿 조회 및 템플릿 렌더링 (Read secrets to render the template file)
- 애플리케이션은 Vault를 직접 호출하지 않고 Agent가 생성한 파일만 읽어서 실행한다.
- 로그인, 토큰 갱신, 에러 처리, JSON 파싱, secret rotation 같은 작업은 모두 Agent가 담당한다.
- 애플리케이션이 렌더링된 파일 사용 (App uses the rendered output file)
- 애플리케이션은 Vault를 직접 호출하지 않고 Agent가 생성한 파일만 읽어서 실행한다.
- 로그인, 토큰 갱신, 에러 처리, JSON 파싱, secret rotation 같은 작업은 모두 Agent가 담당한다.
2. Vault Agent injector - 공식문서
- Vault Agent Injector는 Kubernetes Pod 내부에 Vault Agent를 자동으로 주입해주는 기능입니다.
- 애플리케이션이 Vault로부터 자동으로 비밀 정보를 받아올 수 있습니다.
- 사용하기 전에 다음과 같은 사전 준비가 필요합니다.
1) Vault가 설치되어 있고, Kubernetes와 통합되어 있어야 합니다.
- Vault가 실행 중이어야 하며, Kubernetes 클러스터에 접근 가능해야 합니다. → K8s 안/팎 모두 가능하지만 통신이 가능해야 합니다.
- Vault는 Kubernetes 인증 방식을 설정해야 하며, 이를 통해 서비스 어카운트 기반으로 토큰을 발급받을 수 있습니다.
2) Vault Agent Injector가 클러스터에 배포되어 있어야 합니다.
- Injector는 Kubernetes에 배포되는 별도의 구성 요소입니다.
- 일반적으로 Helm Chart를 통해 배포하며, Pod에 Vault Agent가 자동으로 주입되려면 이 컴포넌트가 필요합니다.
3) Kubernetes 인증 방식이 활성화되어야 합니다.
- Vault에서 Kubernetes Auth Method를 활성화하고 구성해야 합니다.
- 이 설정을 통해 특정 서비스 어카운트에 Vault 접근 권한을 부여할 수 있습니다.
4) 정책과 역할이 정의되어 있어야 합니다.
- Vault에 접근할 수 있도록 적절한 Policy와 Role을 설정해야 합니다.
- 예를 들어, 특정 서비스 어카운트가 특정 경로의 시크릿에만 접근하도록 제한할 수 있습니다.
5) 애플리케이션 Pod에 주입할 주석(annotation)을 추가해야 합니다.
- Vault Agent Injector는 특정 주석이 있는 Pod에만 Vault Agent를 주입합니다.
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "example-role"
3. Vault Kubernetes Sidecar 아키텍처 및 워크플로우





4. 실습
1) Vault AppRole 방식 인증 구성 - AppRole 인증이란?
- 인증 구성 및 정책 적용
# 1. AppRole 인증 방식 활성화
vault auth list
vault auth enable approle || echo "AppRole already enabled"
vault auth list
# 2. 정책 생성
vault policy write sampleapp-policy - <<EOF
path "secret/data/sampleapp/*" {
capabilities = ["read"]
}
EOF
# 3. AppRole Role 생성 - 앞서 생성한 정책(sampleapp-policy) 연결
vault write auth/approle/role/sampleapp-role \
token_policies="sampleapp-policy" \
secret_id_ttl="1h" \
token_ttl="1h" \
token_max_ttl="4h"
# 4. Role ID 및 Secret ID 추출 및 저장
ROLE_ID=$(vault read -field=role_id auth/approle/role/sampleapp-role/role-id)
SECRET_ID=$(vault write -f -field=secret_id auth/approle/role/sampleapp-role/secret-id)
echo "ROLE_ID: $ROLE_ID"
echo "SECRET_ID: $SECRET_ID"
# 5. 파일로 저장
mkdir -p approle-creds
echo "$ROLE_ID" > approle-creds/role_id.txt
echo "$SECRET_ID" > approle-creds/secret_id.txt
# 6. Kubernetes Secret으로 저장 (Agent 인증시 AppRole Role ID, Secret ID 사용)
kubectl create secret generic vault-approle -n vault \
--from-literal=role_id="${ROLE_ID}" \
--from-literal=secret_id="${SECRET_ID}" \
--save-config \
--dry-run=client -o yaml | kubectl apply -f -

2) Vault Agent Sidecar 연동
- Vault Agent는 vault-agent-config.hcl 설정을 통해 연결할 Vault의 정보와, Template 구성, 렌더링 주기, 참조할 Vault KV 위치정보 등을 정의한다.
1. Vault Agent 설정 파일 작성 및 생성 (vault-agent-config.hcl) - HCL(HashiCorp Configuration Language)
cat <<EOF | kubectl create configmap vault-agent-config -n vault --from-file=agent-config.hcl=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -
vault {
address = "http://vault.vault.svc:8200"
}
auto_auth {
method "approle" {
config = {
role_id_file_path = "/etc/vault/approle/role_id"
secret_id_file_path = "/etc/vault/approle/secret_id"
remove_secret_id_file_after_reading = false
}
}
sink "file" {
config = {
path = "/etc/vault-agent-token/token"
}
}
}
template_config {
static_secret_render_interval = "20s"
}
template {
destination = "/etc/secrets/index.html"
contents = <<EOH
<html>
<body>
<p>username: {{ with secret "secret/data/sampleapp/config" }}{{ .Data.data.username }}{{ end }}</p>
<p>password: {{ with secret "secret/data/sampleapp/config" }}{{ .Data.data.password }}{{ end }}</p>
</body>
</html>
EOH
}
EOF
2. 샘플 애플리케이션 + Sidecar 배포 (수동방식)
- Nginx + Vault Agent 생성
kubectl apply -n vault -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-vault-demo
spec:
replicas: 1
selector:
matchLabels:
app: nginx-vault-demo
template:
metadata:
labels:
app: nginx-vault-demo
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
- name: vault-agent-sidecar
image: hashicorp/vault:latest
args:
- "agent"
- "-config=/etc/vault/agent-config.hcl"
volumeMounts:
- name: vault-agent-config
mountPath: /etc/vault
- name: vault-approle
mountPath: /etc/vault/approle
- name: vault-token
mountPath: /etc/vault-agent-token
- name: html-volume
mountPath: /etc/secrets
volumes:
- name: vault-agent-config
configMap:
name: vault-agent-config
- name: vault-approle
secret:
secretName: vault-approle
- name: vault-token
emptyDir: {}
- name: html-volume
emptyDir: {}
EOF
3. SVC 생성
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx-vault-demo
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30001 # Kind에서 설정한 Port
EOF
4. 생성된 컨테이너 확인
# 파드 내에 사이드카 컨테이너 추가되어 2/2 확인
kubectl get pod -l app=nginx-vault-demo
NAME READY STATUS RESTARTS AGE
nginx-vault-demo-7776649597-tcnxd 2/2 Running 0 5m32s
kubectl describe pod -l app=nginx-vault-demo
...
Containers:
nginx:
Container ID: containerd://c160c2268ce6d7602b718336b9036ae89646b5fdb7ebf310bed3dcf497b8675e
Image: nginx:latest
...
vault-agent-sidecar:
Container ID: containerd://6d7e37e8925e681d163b06ae7d18f5d3a236164a60ebf422abd4229a2e337e4e
Image: hashicorp/vault:latest
Image ID: docker.io/hashicorp/vault@sha256:ee674e47dcf85849aadf255b5341f76c0e1a474bc5fa9be9cdfff2a2edf9a628
Port: <none>
Host Port: <none>
Args:
agent
-config=/etc/vault/agent-config.hcl
...
# mutating admission
# Kubernetes Admission Controller 중 MutatingWebhook 목록 조회
kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io
NAME WEBHOOKS AGE
vault-agent-injector-cfg 1 3h10m
# vault agent 확인
kubectl exec -it -n vault deploy/nginx-vault-demo -c vault-agent-sidecar -- vault agent -h
...
Usage: vault agent [options]
This command starts a Vault Agent that can perform automatic authentication
in certain environments.
Start an agent with a configuration file:
$ vault agent -config=/etc/vault/config.hcl
# 마운트된 파일들 확인
kubectl exec -it -n vault deploy/nginx-vault-demo -c vault-agent-sidecar -- cat /etc/vault/agent-config.hcl
kubectl exec -it -n vault deploy/nginx-vault-demo -c vault-agent-sidecar -- ls -l /etc/vault/approle
kubectl exec -it -n vault deploy/nginx-vault-demo -c vault-agent-sidecar -- cat /etc/vault/approle/role_id
kubectl exec -it -n vault deploy/nginx-vault-demo -c vault-agent-sidecar -- cat /etc/vault/approle/secret_id
# 렌더링 완료된 최종 index.html 확인
kubectl exec -it -n vault deploy/nginx-vault-demo -c nginx -- ls -l /usr/share/nginx/html
total 4
-rw-r--r-- 1 100 1000 94 Nov 22 07:59 index.html
# nginx 웹 페이지에 Vault 시크릿이 반영되었는지 확인
kubectl exec -it -n vault deploy/nginx-vault-demo -c nginx -- cat /usr/share/nginx/html/index.html

- 자동 주입이 작동했다면 vault.hashicorp.com/* annotation들이 있어야 합니다.

5. 실제 배포된 화면 확인

6. KV 값 변경 후 확인



# 업데이트된 index.html 확인
kubectl exec -it -n vault deploy/nginx-vault-demo -c nginx -- ls -l /usr/share/nginx/html
kubectl exec -it -n vault deploy/nginx-vault-demo -c nginx -- cat /usr/share/nginx/html/index.html

7. configMap 과 Secret syncFrequency 확인 - kubelet Blog
- Mounted ConfigMaps(Secret) are updated automatically

# [터미널1]
kubectl proxy
# [터미널2
docker ps
export NODE=myk8s-control-plane
docker exec -it $NODE cat /etc/kubelet
##
curl -s -X GET http://127.0.0.1:8001/api/v1/nodes/$NODE/proxy/configz | jq .
curl -s -X GET http://127.0.0.1:8001/api/v1/nodes/$NODE/proxy/configz | jq . | egrep 'configMap|syncFrequency'
"syncFrequency": "1m0s",
"configMapAndSecretChangeDetectionStrategy": "Watch",
# Kubelet이 1분마다 Pod 상태를 동기화 및 ConfigMap/Secret 변경사항 체크 주기
# Watch 모드: 실시간으로 변경사항 감지

8. Annotation을 활용한 Vault Sidecar Injection - Docs
- Vault의 Kubernetes 인증 활성화 및 구성
# Kubernetes Auth Method 활성화
vault auth enable kubernetes
vault auth list
# Kubernetes Auth Config 설정 (최신 방식)
# Service Account관련 Secrets을 자동으로 생성하려면? - Helm Chart Values
TOKEN=$(kubectl create token vault -n vault)
CA_CERT=$(kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode)
vault write auth/kubernetes/config \
token_reviewer_jwt="$TOKEN" \
kubernetes_host="https://kubernetes.default.svc.cluster.local" \
kubernetes_ca_cert="$CA_CERT" \
issuer="https://kubernetes.default.svc.cluster.local" \
disable_iss_validation=false
# (앞선 과정에서 만들었으므로 생략가능) 필요한 Policy 작성
vault policy write sampleapp-policy - <<EOF
path "secret/data/sampleapp/*" {
capabilities = ["read"]
}
EOF
# Role 생성 (Injector가 로그인할 수 있도록)
vault write auth/kubernetes/role/sampleapp-role \
bound_service_account_names="vault-ui-sa" \
bound_service_account_namespaces="vault" \
policies="sampleapp-policy" \
ttl="24h" \
audience="https://kubernetes.default.svc.cluster.local"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault-ui-sa
namespace: vault
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault-injected-ui
namespace: vault
spec:
replicas: 1
selector:
matchLabels:
app: vault-injected-ui
template:
metadata:
labels:
app: vault-injected-ui
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "sampleapp-role"
vault.hashicorp.com/agent-inject-secret-config.json: "secret/data/sampleapp/config"
vault.hashicorp.com/agent-inject-template-config.json: |
{{- with secret "secret/data/sampleapp/config" -}}
{
"username": "{{ .Data.data.username }}",
"password": "{{ .Data.data.password }}"
}
{{- end }}
vault.hashicorp.com/agent-inject-output-path: "/vault/secrets"
spec:
serviceAccountName: vault-ui-sa
containers:
- name: app
image: python:3.10
ports:
- containerPort: 5000
command: ["sh", "-c"]
args:
- |
pip install flask && cat <<PYEOF > /app.py
import json, time
from flask import Flask, render_template_string
app = Flask(__name__)
while True:
try:
with open("/vault/secrets/config.json") as f:
secret = json.load(f)
break
except:
time.sleep(1)
@app.route("/")
def index():
return render_template_string("<h2>🔐 Vault Injected UI</h2><p>👤 사용자: {{username}}</p><p>🔑 비밀번호: {{password}}</p>", **secret)
app.run(host="0.0.0.0", port=5000)
PYEOF
python /app.py
---
apiVersion: v1
kind: Service
metadata:
name: vault-injected-ui
namespace: vault
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30002
selector:
app: vault-injected-ui
EOF
9. init 컨테이너에서 service account token 에 정보 확인
# 단, init 과정 완료 시에는 해당 컨테이너가 종료되니, 파드 기동 후에는 아래 app 컨테이너로 확인 할 것
kubectl exec -n vault -it deploy/vault-injected-ui -c vault-agent-init -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d '.' -f2 | base64 -d| jq
kubectl exec -n vault -it deploy/vault-injected-ui -c app -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d '.' -f2 | base64 -d| jq
{
"aud": [
"https://kubernetes.default.svc.cluster.local"
],
"exp": 1795337098,
"iat": 1763801098,
"iss": "https://kubernetes.default.svc.cluster.local",
"jti": "19b49152-71d9-4858-bdf4-fee3f18200ca",
"kubernetes.io": {
"namespace": "vault",
"node": {
"name": "myk8s-control-plane",
"uid": "8651b768-a9fa-40bf-9113-2d65db1e9477"
},
"pod": {
"name": "vault-injected-ui-77fb865789-pmc57",
"uid": "5a484d8e-adab-4765-afaf-c5dfc7c1a710"
},
"serviceaccount": {
"name": "vault-ui-sa",
"uid": "bb514801-5f50-4295-81ec-390dbffead75"
},
"warnafter": 1763804705
},
"nbf": 1763801098,
"sub": "system:serviceaccount:vault:vault-ui-sa"
}
10. 정상적으로 Secret 생성되었는지 확인
- http://localhost:30002 접속 후 확인

POD=$(kubectl get pod -n vault -l app=vault-injected-ui -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n vault $POD -- cat /vault/secrets/config.json

11. 리소스 삭제
# 실습시 생성한 리소스 삭제
kubectl delete deployment/nginx-vault-demo \
deployment/vault-injected-ui \
service/nginx-service \
service/vault-injected-ui \
sa/vault-ui-sa \
secret/vault-approle -n vault
# 삭제확인
kubectl get deploy,svc,sa,secret -n vault
Vault Proxy
1. Vault Proxy란?
Vault Proxy는 애플리케이션이 Vault와 통합하는 초기 진입 장벽을 낮추고, 더 확장 가능하고 단순한 방식을 제공하기 위해 만들어졌습니다. Vault Proxy는 Vault의 API 프록시 역할을 하며, 클라이언트가 자동 인증된 토큰을 사용하도록 허용하거나 강제할 수 있습니다.
Vault Proxy는 클라이언트 데몬으로 다음과 같은 기능을 제공합니다:
- Auto-Auth: Vault에 자동으로 인증하고, 로컬에서 가져온 동적 비밀의 토큰 갱신 프로세스를 관리합니다.
- API Proxy: Vault의 API에 대한 프록시 역할을 하며, Auto-Auth 토큰을 선택적으로 또는 강제로 사용하게 할 수 있습니다.
- 캐싱(Caching): 새로 생성된 토큰이나 이 토큰으로부터 생성된 리스 비밀(leased secrets)에 대한 응답을 클라이언트 측에서 캐싱할 수 있도록 합니다. 또한, 에이전트는 캐시된 토큰과 리스의 갱신도 관리합니다.
2. Vault Agent vs Vault Proxy - Docs
- Vault Agent: Client Side 초점. 애플리케이션에 필요한 파일(Config) 생성 및 토큰 관리.

- Vault Proxy: Network Side 초점. Vault API 호출 시 중계(Gateway) 역할 및 캐싱 수행.

| 기능 (Capability) | Vault | AgentVault | Proxy설명 |
| Auto-Auth (자동 인증) |
✅ | ✅ | AWS, K8s, AppRole 등의 방식으로 자동 로그인을 수행하고 토큰을 획득/갱신하는 기능. |
| Caching (캐싱) |
✅ | ✅ | 자주 요청되는 시크릿(Token, Lease)을 메모리에 저장하여 Vault 서버 부하를 줄이고 응답 속도를 높이는 기능. |
| Templating (템플릿 렌더링) |
✅ (핵심) | ❌ | 가져온 시크릿을 database.yaml 같은 실제 설정 파일로 만들어주는 기능. (Agent의 가장 큰 존재 이유) |
| API Proxy (API 중계) |
⚠️ (Deprecated) |
✅ (핵심) | 앱이 HTTP 요청을 보내면, 이를 받아서 Vault 서버로 전달하는 기능. (Agent의 Proxy 기능은 Proxy 모드로 이관됨) |
| Windows Service (윈도우 서비스) |
✅ | ❌ | Windows 환경에서 백그라운드 서비스로 실행 가능 여부. |
| Process Supervisor (프로세스 관리) |
✅ | ❌ | 시크릿 값이 변경(Rotation)되었을 때, 애플리케이션을 재시작(Restart)하거나 시그널(HUP)을 보내는 기능. |
'Kubernetes' 카테고리의 다른 글
| AEWS 4기 | 1주차 #2 EKS Cluster Endpoint Access (0) | 2026.03.17 |
|---|---|
| AEWS 4기 | 1주차 #1 EKS 구성 방식 및 실습 환경 (1) | 2026.03.16 |
| Kubernetes CI/CD Study 1기 | 6주차 ArgoCD 3/3 (0) | 2025.11.21 |
| Kubernetes CI/CD Study 1기 | 5주차 ArgoCD 2/3 (0) | 2025.11.10 |
| Kubernetes CI/CD Study 1기 | 4주차 ArgoCD 1/3 (0) | 2025.11.08 |