Vault KV v1 vs v2 — 경로 차이
쿠버네티스에 올린 앱들이 쓰는 DB 비밀번호나 API 키는 Vault 에 모아 뒀습니다. Vault 는 저장소를 엔진 단위로 마운트해서 쓰고, 그냥 키와 값을 넣어 두는 용도면 KV Secret Engine 을 씁니다.
vault secrets enable -path=secret kv
이렇게 경로를 정해 켜 두면 그 아래에 secret/myapp/db 같은 식으로 쌓입니다. 여기서 버전을 안
적으면 v1 으로 켜지는 게 기본입니다.
엔진은 경로마다 따로 켜니 한 Vault 안에 여러 개가 공존할 수 있고, 처음 만든 경로와 나중에 추가한 경로가 서로 다른 설정으로 떠 있기도 합니다.
이 KV 엔진에는 v1 과 v2 가 있고, 이름만 보면 그냥 버전을 올린 것 같지만 경로 구조가 아예 달라서 서로 호환되지 않습니다.
v1과 v2의 차이
| 구분 | KV v1 | KV v2 |
|---|---|---|
| 버전 히스토리 | 없음 | 있음 (기본 10개 보관, 조정 가능) |
| 경로 | secret/foo |
secret/data/foo(데이터), secret/metadata/foo(메타데이터) |
| 삭제 | 즉시 삭제 | soft delete (destroy 로 영구 삭제) |
| CAS | 없음 | Check-And-Set (동시 쓰기 방지) |
v2 는 버전 관리와 soft delete 를 지원해서 실수로 지운 시크릿을 되살리거나 이전 버전으로 돌아갈 수 있지만, 대신 경로 구조가 바뀝니다.
경로에 끼어드는 /data/
가장 헷갈리는 게 이 경로고, v2 는 데이터와 메타데이터를 분리하느라 실제 HTTP 경로에 /data/ 가
끼어듭니다.
# KV v1
GET /v1/secret/foo
# KV v2 — 내부적으로 /data/ 삽입
GET /v1/secret/data/foo
vault kv get secret/foo 로 CLI 를 쓰면 v1 이든 v2 든 알아서 처리해 줍니다. 문제는 REST API 를
직접 호출하거나 다른 도구에서 경로를 명시할 때. 이때는 /data/ 를 직접 신경 써야 했습니다.
v1 경로에 v2로 접근하면 404
Vault Secrets Operator 는 Vault 에 들어 있는 값을 읽어다 쿠버네티스 Secret 으로 만들어 주는
오퍼레이터인데, 이렇게 엔진 타입을 직접 적는 도구에서 사고가 납니다. VaultStaticSecret 에
type: kv-v2 라고 적어 놓고 정작 그 경로가 v1 으로 마운트돼 있으면, 도구는 v2 방식대로
/data/ 를 붙여 조회하다 404 를 받습니다.
시크릿이 분명히 있는데 “not found” 가 나오면 값이 없는 게 아닙니다. 엔진 버전이 안 맞아서 엉뚱한 경로를 보고 있는 겁니다.
버전이 섞인 환경이면 어느 마운트가 어느 버전인지 정리해 두는 편이 안전합니다. 같은 secret/
아래처럼 보여도 마운트마다 다를 수 있어서, 경로만 보고는 구분이 안 됩니다.
마운트 버전은 이걸로 확인합니다.
vault secrets list -detailed
# Options 칼럼의 version 이 1인지 2인지 본다
시크릿을 못 찾는다는 에러가 나면 값을 찾아 헤매기 전에 이걸로 그 경로의 버전부터 확인하고, 도구 설정의 타입을 거기 맞춥니다. 값이 없어서 나는 404 와 경로가 틀려서 나는 404 는 메시지가 똑같으니까.
댓글 0