멀티 계정 쿠버네티스, External Secrets Operator로 비밀 확산 해결
Posted on June 9, 2026
by Viktoria Bisova, DevOps Engineer, Itigix
이 글에서 강조된 CNCF 프로젝트
Kubernetes에서 인프라 프로비저닝은 점점 자동화되고 있지만, 환경이 커질수록 비밀 관리가 여전히 큰 과제로 남아 있습니다. 조직에서는 보안을 강화하고 영향을 최소화하기 위해 개발, 스테이징, 프로덕션 워크로드를 클러스터, 네임스페이스 또는 클라우드 계정 별로 분리하는 경우가 많습니다. 이러한 격리는 유익하지만, 반복되는 운영 문제를 야기합니다: 공유 자격 증명을 어떻게 일관되게 배포하고 회전시켜야 할까요? 저희 팀은 최근 AWS EKS에서 실행되는 고객을 위한 확장 가능한 환경을 설계하면서 이 문제에 직면했습니다.
우리가 해결하려는 문제는 AWS에만 국한된 것이 아니라 클라우드 인프라 전반에 해당합니다. Azure, Google Cloud, 멀티‑클라우드, 온‑프레미스 인프라, 혹은 KIND·Minikube와 같은 로컬 개발 환경 자동화에서도 동일한 고통을 겪습니다: 격리된 경계 사이에서 비밀을 원활하게 복제하는 것이 핵심 과제입니다. 각 환경(Dev, Staging, Prod)은 고유한 계정, 네임스페이스 또는 클러스터에 존재합니다. 이러한 분리는 보안과 영향 범위 감소에 탁월하지만, 운영 복잡성을 크게 증가시킵니다. 격리된 환경들 사이에서 공유 비밀을 수동 복사 없이 어떻게 동기화할 수 있을까요?
이 글에서는 External Secrets Operator (ESO)와 Bitwarden Secrets Manager를 활용해 멀티‑계정 비밀 동기화 문제를 해결한 방법을 설명합니다.
도전 과제: 격리된 환경 간 공유 비밀 관리
고객은 서드파티 통합에 크게 의존하는 두 개의 애플리케이션을 운영하고 있습니다. 새로운 환경을 프로비저닝하기 위한 자동화를 설계하던 중 다음과 같은 장애물에 부딪혔습니다:
- 공유 자격 증명: 비프로덕션 환경에서는 애플리케이션이 서드파티 도구용 “sandbox” 자격 증명을 동일하게 사용합니다.
- 분산된 저장소: 각 EKS 클러스터가 별도의 AWS 계정에 존재합니다. 계정당 AWS Secrets Manager를 사용하면 서드파티 API 키가 회전될 때마다 모든 AWS 계정에 수동으로 업데이트해야 했습니다.
중앙 집중식 관리: 공유 자격 증명의 단일 진실 소스를 원했으며, 비밀 회전이 한 곳에서 이루어지고 자동으로 모든 소비 환경에 전파되길 바랐습니다. 핵심 요구사항은 비밀 저장소와 비밀 소비를 분리하는 것이었습니다.
해결책: External Secrets Operator를 다리 역할로 활용
우리는 External Secrets Operator(ESO)를 선택했습니다. ESO는 외부 비밀 관리 시스템에서 Kubernetes Secret API로 비밀을 동기화하는 Kubernetes‑네이티브 조정 모델을 제공합니다. 이를 통해 애플리케이션은 표준 Kubernetes Secret을 그대로 사용하면서, 진실 소스는 클러스터 외부에 유지됩니다.
백엔드 저장소로는 Bitwarden Secrets Manager를 선택했습니다. 이유는 실용적이었습니다. 고객이 이미 조직 전체에서 Bitwarden 비밀번호 관리자를 사용하고 있었기 때문에, 동일한 솔루션을 활용해 조직 차원의 접근 제어를 한 곳에서 관리하기 쉬웠습니다.
ESO의 강점 중 하나는 공급자에 구애받지 않는 설계입니다. 운영자는 HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager, Bitwarden Secrets Manager 등 다양한 비밀 백엔드를 지원합니다. 이번 구현에서는 고객의 기존 자격 증명 관리 관행에 맞춰 Bitwarden을 선택했지만, 공급자와 관계없이 패턴은 동일합니다: 비밀을 중앙에 저장하고, ESO가 모든 계정의 클러스터에 Kubernetes Secret으로 동기화합니다.

아키텍처 작동 방식
전체적인 흐름은 세 가지 구성 요소로 이루어집니다:
- 진실 소스로 작동하는 중앙 비밀 관리 시스템.
- 각 Kubernetes 클러스터 내에서 실행되는 External Secrets Operator.
- 애플리케이션이 소비하도록 ESO가 생성·관리하는 Kubernetes Secret.
ExternalSecret 리소스가 생성되면, ESO는 외부 공급자에서 참조된 비밀을 가져와 해당 Kubernetes Secret을 생성하거나 업데이트합니다. 조정 루프는 설정된 새로 고침 간격에 따라 지속적으로 업데이트를 확인하고 동기화합니다.
이 접근 방식은 비밀 저장소와 비밀 소비를 분리하면서도, 애플리케이션이 기존 Kubernetes‑네이티브 메커니즘을 그대로 사용할 수 있게 합니다.
구현
아래는 Kubernetes 환경에 이를 설정하는 단계별 가이드입니다. 모든 리소스를 Terraform으로 자동화했지만, 여기서는 이해를 돕기 위해 직접 실행 가능한 명령어를 보여줍니다. 자동화 코드는 GitHub 저장소를 참고하세요.
전제 조건
- Kubernetes 클러스터(EKS, AKS, GKE 등).
- 로컬에
kubectl및helm설치. - 지원되는 비밀 관리 공급자에 대한 접근 권한. 이 예제는 Bitwarden Secrets Manager를 사용하지만, External Secrets Operator가 지원하는 다른 공급자에도 동일한 흐름을 적용할 수 있습니다.
Step 1: ESO와 Bitwarden SDK 간 통신 보안 확보
ESO와 Bitwarden SDK 간 통신은 HTTPS를 통해 안전하게 이루어져야 합니다.
- 클러스터 내에서 TLS 인증서를 동적으로 관리하기 위해 먼저 Cert Manager를 설치했습니다.
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
- Self‑Signed ClusterIssuer 생성:
cat <<EOF > cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
EOF
kubectl apply -f cluster-issuer.yaml
참고: 접근 토큰에 쓰기 권한을 부여할 수도 있습니다. ESO PushSecret API를 사용해 Bitwarden에 비밀을 생성하도록 External Secrets Operator를 구성할 수 있습니다.
Step 4: ClusterSecretStore 생성
ESO에서 SecretStore는 공급자와 통신하는 방법을 정의합니다. 우리는 전역 범위인 ClusterSecretStore를 선택해 어느 네임스페이스에서든 중앙 스토어를 재인증 없이 참조할 수 있게 했습니다.
cat <<EOF > cluster-secretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: bitwarden-global-store
spec:
provider:
bitwarden:
server: "https://api.bitwarden.com"
tokenSecretRef:
name: bitwarden-token
key: token
EOF
kubectl apply -f cluster-secretstore.yaml
Step 5: 동기화 (ExternalSecret) 정의
마지막으로 ExternalSecret을 생성했습니다. 이 리소스는 운영자에게 “Bitwarden에서 stripe-api-key라는 비밀을 가져와 payment-creds라는 Kubernetes Secret을 만들라”는 지시를 내립니다.
cat <<EOF | kub