Secret in Kubernetes

Kubernetes 환경에서는 Secret을 코드, 저장소에 포함되는 설정 파일, ConfigMap에 직접 저장하지 말고 Secret 리소스 또는 외부 Secret 연동을 통해 주입해야 합니다.

이런 경우에 참고

  • Kubernetes 배포 서비스에서 코드 또는 설정 파일에 Secret이 있는 경우
  • ConfigMap에 비밀번호, API Key, 토큰을 넣어둔 경우
  • Deployment에서 하드코딩된 환경 변수를 사용 중인 경우

권장 방식

  • Secret 리소스 또는 External Secrets Operator 같은 외부 연동 방식을 사용합니다.
  • Pod에는 env.valueFrom.secretKeyRef 또는 volume mount로 주입합니다.
  • Secret 원문을 Helm values, ConfigMap, Deployment manifest에 직접 적지 않습니다.
  • Secret을 사용하더라도 Base64 인코딩만으로 보호되는 것은 아니므로, 가능하면 클러스터의 etcd encryption at rest 설정도 함께 확인합니다.

예시

변경 전

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          env:
            - name: API_KEY
              value: "sk-prod-123456"

변경 후

Secret 주입 부분만 보여 주는 발췌입니다. Deployment의 선택자와 Pod 라벨 등은 별도로 구성하세요. ${REAL_SECRET_VALUE}는 배포 도구가 안전하게 공급할 값의 자리표시자이며, Kubernetes가 환경 변수로 자동 치환하지 않습니다.

yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
stringData:
  API_KEY: ${REAL_SECRET_VALUE}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:latest
          env:
            - name: API_KEY
              valueFrom:
                secretKeyRef:
                  name: app-secret
                  key: API_KEY

담당자 조치 절차

  1. Deployment, Helm chart, values 파일, ConfigMap에서 실제 Secret 값을 제거합니다.
  2. Kubernetes Secret 또는 외부 Secret 연동 리소스를 생성합니다.
  3. 애플리케이션은 secretKeyRef 또는 secret volume을 통해 값을 받도록 변경합니다.
  4. 기존 Secret 값이 노출되었다면 즉시 회전합니다.
  5. kubectl describe, 로그 출력, 디버그 스크립트에서 Secret이 노출되지 않는지 확인합니다.

담당자에게 안내할 문구 예시

  • "하드코딩된 Secret은 Deployment나 ConfigMap에서 제거하고 Kubernetes Secret으로 이전하세요."
  • "Pod에는 secretKeyRef 또는 secret volume으로 주입하고, Secret 값 자체를 매니페스트에 직접 적지 마세요."
  • "이미 노출된 값은 Secret 리소스로 옮기기 전에 먼저 폐기 및 재발급해야 합니다."

추가 확인 사항

  • ConfigMap에 Secret이 잘못 저장되어 있지 않은가
  • Helm values.yaml에 실제 운영값이 들어가 있지 않은가
  • Secret을 Base64 인코딩만 하고 보호되었다고 오해하고 있지 않은가
  • 클러스터에서 Secret에 대한 encryption at rest가 활성화되어 있는가