# 2026년 Kubernetes 시크릿 관리 완벽 가이드: External Secrets, Vault, 면접 대비 > Kubernetes 시크릿 관리의 모든 것을 다룹니다. External Secrets Operator, HashiCorp Vault 연동, 프로덕션 환경 모범 사례, 기술 면접 빈출 질문까지 상세히 설명합니다. - Published: 2026-09-02 - Updated: 2026-09-02 - Author: Anthony Fillion-Maillet - Tags: kubernetes, secrets, vault, devops, security - Reading time: 12 min --- Kubernetes 시크릿 관리는 컨테이너 오케스트레이션에서 가장 중요한 보안 과제 중 하나입니다. 네이티브 Kubernetes Secret은 민감한 데이터를 base64 인코딩으로 저장하지만, 기본적으로 저장 시 암호화를 제공하지 않습니다. 이러한 취약점은 DevOps 채용 면접에서 자주 다뤄지는 보안 위험을 야기합니다. > **면접 즉답 포인트** > > Kubernetes 시크릿 보안에 대해 질문받을 때: 네이티브 Secret은 base64 인코딩이며 암호화가 아닙니다. 프로덕션 환경에서는 HashiCorp Vault 또는 AWS Secrets Manager와 같은 외부 시크릿 관리자가 필요하며, External Secrets Operator(ESO)를 통해 동기화합니다. 이러한 분리를 통해 시크릿이 Git 저장소에 존재하지 않도록 보장합니다. ## 네이티브 Kubernetes Secret의 한계 내장 Secret 리소스는 etcd에 base64 인코딩으로 데이터를 저장합니다. 이 인코딩은 단일 명령으로 복원할 수 있습니다: ```bash # decoding-secret.sh # Kubernetes 시크릿 값을 즉시 디코딩 kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d ``` base64는 암호화가 아닙니다. 클러스터 접근 권한이 있는 사람이라면 누구나 시크릿 값을 읽을 수 있습니다. [Kubernetes 문서](https://kubernetes.io/docs/concepts/configuration/secret/)에서는 Secret이 "기본적으로 암호화되지 않는다"고 명시하며, 저장 시 암호화를 활성화할 것을 권장합니다. 프로덕션 배포에 영향을 미치는 세 가지 주요 제한 사항이 있습니다: 1. **감사 추적 부재**: 네이티브 Secret은 누가 언제 어떤 값에 접근했는지에 대한 로그를 제공하지 않습니다 2. **로테이션 메커니즘 부재**: 시크릿 변경에는 수동 개입과 Pod 재시작이 필요합니다 3. **GitOps 비호환성**: 암호화된 시크릿을 Git에 저장해도 암호화 키 관리 문제가 남습니다 ## External Secrets Operator 아키텍처 External Secrets Operator(ESO)는 Kubernetes와 외부 시크릿 관리 시스템을 연결합니다. 2023년 CNCF Sandbox 프로젝트로 출시되어 2026년에 v0.10에 도달했습니다. ESO는 AWS Secrets Manager, HashiCorp Vault, Google Secret Manager, Azure Key Vault 및 15개 이상의 백엔드를 지원합니다. 아키텍처는 세 가지 커스텀 리소스로 구성됩니다: ```yaml # secret-store.yaml # ClusterSecretStore는 Vault로의 연결을 정의 apiVersion: external-secrets.io/v1beta1 kind: ClusterSecretStore metadata: name: vault-backend spec: provider: vault: server: "https://vault.internal:8200" path: "secret" version: "v2" auth: kubernetes: mountPath: "kubernetes" role: "external-secrets" serviceAccountRef: name: "external-secrets" namespace: "external-secrets" ``` 이 ClusterSecretStore는 Kubernetes 서비스 계정 토큰을 사용하여 Vault에서 인증하도록 ESO를 구성합니다. `kubernetes` 인증 방식은 클러스터의 TokenReview API에 대해 서비스 계정 JWT를 검증합니다. ```yaml # external-secret.yaml # ExternalSecret은 실제 시크릿 데이터를 가져와 동기화 apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: database-credentials namespace: production spec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: db-secret creationPolicy: Owner data: - secretKey: username remoteRef: key: secret/data/production/database property: username - secretKey: password remoteRef: key: secret/data/production/database property: password ``` ESO는 1시간마다 Vault를 폴링하고(`refreshInterval: 1h`), Kubernetes Secret을 자동으로 업데이트합니다. `creationPolicy: Owner`는 ExternalSecret이 삭제될 때 Secret도 삭제되도록 보장합니다. ## HashiCorp Vault 연동 패턴 Vault는 동적 시크릿, 자동 로테이션, 포괄적인 감사 로깅을 제공합니다. [Vault Kubernetes 인증 문서](https://developer.hashicorp.com/vault/docs/auth/kubernetes)에 설명된 Kubernetes 인증 방식을 통해 장기 자격 증명을 배포하지 않고도 Pod가 인증할 수 있습니다. Vault 인증 설정에는 세 가지 단계가 필요합니다: ```bash # vault-k8s-auth.sh # Vault에서 Kubernetes 인증 방식 활성화 vault auth enable kubernetes # Kubernetes API에 대해 토큰을 검증하도록 Vault 구성 vault write auth/kubernetes/config \ kubernetes_host="https://kubernetes.default.svc:443" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt # 서비스 계정을 정책에 바인딩하는 역할 생성 vault write auth/kubernetes/role/external-secrets \ bound_service_account_names=external-secrets \ bound_service_account_namespaces=external-secrets \ policies=readonly-secrets \ ttl=1h ``` 이 구성은 `external-secrets` 서비스 계정을 Vault 정책에 바인딩합니다. TTL은 토큰 유효 기간을 제한하여 재인증을 강제하고, 손상된 토큰의 영향 범위를 줄입니다. 프로덕션 배포에서는 최소 권한 원칙을 따르는 정책이 필요합니다: ```hcl # readonly-secrets.hcl # 특정 경로에 대한 읽기 전용 접근을 부여하는 Vault 정책 path "secret/data/production/*" { capabilities = ["read"] } path "secret/metadata/production/*" { capabilities = ["list"] } ``` 이 정책은 프로덕션 시크릿 경로에 대한 읽기 접근만 부여합니다. 다른 환경을 관리하는 팀은 해당 경로 제한이 있는 별도의 정책을 받습니다. ## 다운타임 없는 시크릿 로테이션 자동 로테이션은 시크릿이 노후화된 공격 벡터가 되는 것을 방지합니다. ESO는 Kubernetes 측을 처리하지만, 애플리케이션은 재시작 없이 시크릿을 다시 로드해야 합니다. 제로 다운타임 로테이션을 위한 두 가지 접근 방식이 있습니다: **파일 감시를 통한 볼륨 마운트 시크릿:** ```yaml # deployment-volume-secrets.yaml # 자동으로 업데이트되는 파일로 시크릿 마운트 apiVersion: apps/v1 kind: Deployment metadata: name: api-server spec: template: spec: containers: - name: api image: api:v2.1.0 volumeMounts: - name: secrets mountPath: /etc/secrets readOnly: true volumes: - name: secrets secret: secretName: db-secret ``` Kubernetes는 kubelet 동기화 기간 내(기본 1분)에 마운트된 시크릿 파일을 업데이트합니다. 애플리케이션은 각 데이터베이스 연결 시 `/etc/secrets/password`에서 자격 증명을 읽어 재시작 없이 새 값을 가져옵니다. **환경 변수 시크릿을 위한 Reloader:** 환경 변수를 사용하는 애플리케이션에는 Pod 재시작이 필요합니다. [Stakater Reloader](https://github.com/stakater/Reloader)가 이를 자동화합니다: ```yaml # deployment-with-reloader.yaml # 어노테이션이 시크릿 변경 시 롤링 재시작을 트리거 apiVersion: apps/v1 kind: Deployment metadata: name: api-server annotations: reloader.stakater.com/auto: "true" spec: template: spec: containers: - name: api envFrom: - secretRef: name: db-secret ``` Reloader는 Secret 업데이트를 감시하고 롤링 재시작을 수행하여 로테이션 중 가용성을 유지합니다. ## Kubernetes 시크릿 면접 질문 DevOps 면접에서는 시크릿 관리에 대한 이해를 일관되게 테스트합니다. 이러한 질문은 주니어부터 시니어 레벨까지 출제됩니다: **Q: Kubernetes Secret이 사용하는 인코딩은 무엇이며, 왜 보안에 불충분합니까?** Secret은 base64 인코딩을 사용하는데, 이는 가역 변환이지 암호화가 아닙니다. Secret에 대한 `get` 권한이 있는 모든 사용자가 값을 디코딩할 수 있습니다. 보안을 위해서는 저장 시 암호화(etcd 암호화 활성화)와 RBAC 권한 제한이 필요합니다. 더 깊은 Kubernetes 개념에 대해서는 [Kubernetes 면접 기초](/technologies/devops/interview-questions/kubernetes-basics)를 참조하십시오. **Q: GitOps를 사용할 때 시크릿이 Git 저장소에 나타나지 않도록 하려면 어떻게 해야 합니까?** External Secrets Operator는 값 자체가 아닌 시크릿에 대한 참조만 Git에 저장합니다. ExternalSecret 매니페스트에는 Vault 또는 AWS Secrets Manager의 시크릿 경로가 포함되어 있으며, 실제 시크릿은 저장소에 절대 접촉하지 않습니다. Bitnami의 Sealed Secrets는 비대칭 암호화를 사용하는 대안적 접근 방식을 제공합니다. **Q: SecretStore와 ClusterSecretStore의 차이점을 설명하십시오.** SecretStore는 네임스페이스 범위입니다: 동일한 네임스페이스의 ExternalSecrets가 이를 참조할 수 있습니다. ClusterSecretStore는 클러스터 전체 범위입니다: 모든 네임스페이스에서 참조할 수 있습니다. 여러 팀이 단일 Vault 인스턴스를 공유할 때는 ClusterSecretStore를 사용하고, 각 네임스페이스가 격리된 시크릿 백엔드를 가질 때는 SecretStore를 사용합니다. **Q: 배포 후 Pod가 시크릿에 접근할 수 없습니다. 어떻게 트러블슈팅하시겠습니까?** ExternalSecret 상태부터 시작합니다: ```bash # troubleshoot-secrets.sh # ExternalSecret 동기화 상태 및 조건 확인 kubectl get externalsecret database-credentials -o yaml # Secret이 생성되었는지 확인 kubectl get secret db-secret -o yaml # 인증 오류에 대해 ESO 컨트롤러 로그 확인 kubectl logs -n external-secrets deployment/external-secrets ``` 일반적인 실패 원인으로는 만료된 Vault 토큰, 잘못된 시크릿 경로, ClusterSecretStore의 RBAC 구성 오류가 있습니다. **Q: 프로덕션 환경에서 데이터베이스 자격 증명의 시크릿 로테이션을 어떻게 처리하시겠습니까?** Vault의 데이터베이스 시크릿 엔진은 동적이고 수명이 짧은 자격 증명을 생성합니다. 자격 증명 TTL보다 짧은 `refreshInterval`로 ESO를 구성합니다. 로테이션이 필요한 정적 자격 증명의 경우, Vault의 로테이션 API와 Reloader를 결합하여 업데이트 후 Pod를 재시작합니다. 애플리케이션은 로테이션 기간 동안 연결 실패를 우아하게 처리해야 합니다. ## AWS Secrets Manager와 ESO AWS Secrets Manager 연동에는 서비스 계정용 IAM 역할(IRSA)이 필요합니다. 이 패턴은 정적 자격 증명을 완전히 제거합니다: ```yaml # aws-secret-store.yaml # IRSA를 사용한 AWS Secrets Manager용 ClusterSecretStore apiVersion: external-secrets.io/v1beta1 kind: ClusterSecretStore metadata: name: aws-secrets spec: provider: aws: service: SecretsManager region: ap-northeast-2 auth: jwt: serviceAccountRef: name: external-secrets-sa namespace: external-secrets ``` 서비스 계정 어노테이션이 IAM 역할에 연결됩니다: ```yaml # service-account-irsa.yaml # IAM 역할 어노테이션이 있는 서비스 계정 apiVersion: v1 kind: ServiceAccount metadata: name: external-secrets-sa namespace: external-secrets annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/external-secrets ``` AWS는 Lambda 함수를 사용하여 Secrets Manager에서 생성된 시크릿을 자동으로 로테이션합니다. ESO의 리프레시 간격과 결합하면, 구성된 폴링 기간 내에 시크릿이 Kubernetes로 전파됩니다. ## 멀티 클러스터 시크릿 동기화 여러 클러스터를 운영하는 조직에는 일관된 시크릿 배포가 필요합니다. 이 요구 사항을 해결하는 두 가지 패턴이 있습니다: **ClusterSecretStore를 사용한 허브 앤 스포크:** 모든 클러스터가 중앙 Vault 인스턴스에 연결됩니다. 각 클러스터의 ESO 설치가 동일한 시크릿을 참조하고, Vault가 네임스페이스 기반 정책을 통해 접근 제어를 처리합니다. **Vault Enterprise를 통한 복제:** Vault Enterprise는 리전 간 성능 복제를 지원합니다. 각 클러스터가 로컬 Vault 복제본에 연결하여 일관성을 유지하면서 지연 시간을 줄입니다. [Vault 복제 문서](https://developer.hashicorp.com/vault/docs/enterprise/replication)에서 재해 복구 및 성능 복제 모드를 다룹니다. ArgoCD를 사용하는 팀의 경우, [GitOps 배포 패턴](/blog/devops/argocd-gitops-kubernetes-continuous-deployment-interview-questions) 문서에서 여러 클러스터에 ExternalSecrets를 배포하는 ApplicationSets를 설명합니다. ## 시크릿 접근을 위한 RBAC 강화 기본 클러스터 역할은 과도한 시크릿 접근을 부여합니다. 최소한의 역할을 생성하여 RBAC를 강화합니다: ```yaml # restricted-role.yaml # 특정 네임스페이스에서만 시크릿 접근을 허용하는 역할 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: secret-reader namespace: production rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get"] resourceNames: ["db-secret", "api-key"] ``` `resourceNames` 필드는 명시적으로 나열된 시크릿에 대한 접근을 제한합니다. 이 필드가 없으면 역할은 네임스페이스의 모든 시크릿에 대한 접근을 부여합니다. ## 결론 Kubernetes 시크릿 관리는 base64 인코딩의 한계를 이해하는 것에서 시작합니다. 프로덕션 환경에서는 External Secrets Operator를 통한 HashiCorp Vault 또는 AWS Secrets Manager와 같은 외부 시크릿 관리자가 필요합니다. 핵심 사항은 다음과 같습니다: 네이티브 Secret은 암호화를 제공하지 않습니다, ESO는 외부 백엔드와의 동기화를 자동화합니다, Vault는 동적 시크릿과 감사 로깅을 제공합니다, 그리고 RBAC는 최소 권한 원칙에 따라 강화해야 합니다. 이러한 개념은 DevOps 면접에서 정기적으로 테스트되며, 클라우드 네이티브 환경에서 시크릿 관리의 모범 사례를 형성합니다. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ko/blog/devops/kubernetes-secrets-management-2026-external-secrets-vault-interview