쿠버네티스 마스터 — ConfigMap·Secret

2026-05-03확률과 통계 마스터 노트

쿠버네티스 마스터 노트 시리즈 5편. ConfigMap이 12-Factor의 'config in environment'를 K8s에 적용한 방식, Secret이 base64만 인코딩이고 암호화 X인 진실, Pod에 주입하는 4가지 방법(env·envFrom·volume·subPath), 운영 환경에서 Secret 평문 위험과 Sealed Secrets·External Secrets·Vault 통합 패턴까지.

이 글은 쿠버네티스 마스터 노트 시리즈의 다섯 번째 편입니다. 4편(Services)까지 Pod 외부 접근이었다면, 이번엔 Pod 안 설정·민감 정보 — ConfigMap과 Secret.

코드 안 비밀번호 박는 건 안티패턴. 환경 변수로? 어디서 관리? K8s가 그 답 — ConfigMap·Secret. 다만 Secret은 암호화 X 함정이 있습니다.

처음 ConfigMap·Secret이 어렵게 느껴지는 이유

처음 이 단원이 어렵게 느껴지는 이유는 두 가지예요. 첫째, 둘이 어떻게 다른지 막연합니다. 같은 키-값인데 왜 두 종류? 둘째, Pod에 주입하는 방법이 4가지 — env·envFrom·volume·subPath 헷갈립니다.

해결법은 한 가지예요. "ConfigMap = 일반 / Secret = 민감" 한 줄. 이름만 다르고 동작은 거의 같음. 다만 Secret은 평문 base64일 뿐 암호화 X — 이 함정만 인식하면 운영 안전.

12-Factor App — Config in Environment

환경별 다른 값 (DB 호스트·API 키·로그 레벨) →
코드에 박지 말고 → 환경 변수 또는 외부 설정으로

K8s에서 = ConfigMap (일반) + Secret (민감).

ConfigMap — 일반 설정

생성 방법 4종

# 1. CLI로 직접
kubectl create configmap app-config \
  --from-literal=DB_HOST=postgres \
  --from-literal=LOG_LEVEL=info

# 2. 파일에서
kubectl create configmap app-config \
  --from-file=config.properties

# 3. 디렉토리 전체
kubectl create configmap app-config \
  --from-file=./config-dir/

# 4. YAML
kubectl apply -f configmap.yaml

YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: "postgres"
  DB_PORT: "5432"
  LOG_LEVEL: "info"
  config.properties: |
    server.port=8080
    spring.profiles.active=production

Pod에 주입 4종

1. 단일 환경 변수 (env.valueFrom)

spec:
  containers:
    - name: app
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DB_HOST

2. 모든 키를 환경 변수로 (envFrom)

spec:
  containers:
    - name: app
      envFrom:
        - configMapRef:
            name: app-config

ConfigMap의 모든 키-값이 환경 변수로 주입.

3. Volume Mount (파일)

spec:
  containers:
    - name: app
      volumeMounts:
        - name: config
          mountPath: /etc/config
  volumes:
    - name: config
      configMap:
        name: app-config

/etc/config/DB_HOST, /etc/config/config.properties 등 파일로.

4. SubPath (특정 파일만)

volumeMounts:
  - name: config
    mountPath: /etc/myapp/config.properties
    subPath: config.properties

특정 파일 하나만 마운트. 디렉토리 덮어쓰기 회피.

여기서 정말 중요한 시험 함정 — ConfigMap 변경 시 Pod 자동 갱신:

  • env / envFrom = 자동 갱신 X (Pod 재시작 필요)
  • Volume Mount = 자동 갱신 O (수십 초 후)

설정 변경이 잦으면 Volume 권장. 단 메모리에서 갱신은 앱 코드 책임.

Secret — 민감 정보

# CLI
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=s3cr3t

# YAML
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=          # base64
  password: czNjcjN0

Secret 타입

Type 용도
Opaque 일반 (기본)
kubernetes.io/dockerconfigjson Docker registry
kubernetes.io/tls TLS 인증서
kubernetes.io/service-account-token ServiceAccount

TLS Secret

kubectl create secret tls my-tls \
  --cert=cert.pem \
  --key=key.pem

Ingress 등에서 사용.

Pod 주입 — ConfigMap과 동일

env:
  - name: DB_PASS
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password

envFrom:
  - secretRef:
      name: db-secret

volumeMounts:
  - name: secret
    mountPath: /etc/secret
volumes:
  - name: secret
    secret:
      secretName: db-secret

Secret의 결정적 함정 — 암호화 X

> kubectl get secret db-secret -o yaml
data:
  password: czNjcjN0     # base64

> echo "czNjcjN0" | base64 -d
s3cr3t                   # 평문 노출!

여기서 정말 중요한 시험 함정 — K8s Secret은 base64 인코딩만, 암호화 X. etcd에 그대로 저장. RBAC 권한 있는 사람은 즉시 평문 조회 가능. 운영 환경엔 추가 보호 필수.

운영 Secret 관리 패턴

1. EncryptionConfiguration — etcd 암호화

# /etc/kubernetes/encryption.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources: [secrets]
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

API Server가 etcd 쓰기 전 암호화. 기본 활성 X — 명시 설정.

2. Sealed Secrets

# 클라이언트 도구
kubeseal < secret.yaml > sealed-secret.yaml

# 결과 — 클러스터 안 전용 키로 암호화된 SealedSecret 객체
# Git에 커밋해도 안전

GitOps 환경 표준. Bitnami가 만듦.

3. External Secrets Operator

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-secret
spec:
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: db-secret
  data:
    - secretKey: password
      remoteRef:
        key: secret/data/db
        property: password

Vault·AWS Secrets Manager·GCP Secret Manager 등 외부 시스템에서 자동 동기화.

4. CSI Secret Store Driver

Pod 시작 시 외부 시스템에서 직접 마운트. K8s Secret 객체 거치지 않음.

여기서 정말 중요한 시험 함정 — 운영 Secret 관리 = 외부 도구 거의 필수:

  • 작은 환경 = Sealed Secrets
  • 엔터프라이즈 = External Secrets + Vault
  • 클라우드 네이티브 = 클라우드 Secret Manager

ConfigMap vs Secret — 결정 기준

데이터 선택
DB 호스트·포트 ConfigMap
로그 레벨·기능 플래그 ConfigMap
일반 설정 파일 ConfigMap
DB 비밀번호·API 키 Secret
TLS 인증서·키 Secret (tls 타입)
OAuth 토큰 Secret

동시 사용

spec:
  containers:
    - name: app
      envFrom:
        - configMapRef:
            name: app-config        # 일반
        - secretRef:
            name: db-secret         # 민감

환경별 분리

configmap-dev.yaml
configmap-staging.yaml
configmap-prod.yaml

Helm·Kustomize로 환경별 관리 (9편).

또는 namespace로 분리:

ns: dev
  ConfigMap app-config (개발 값)
ns: prod
  ConfigMap app-config (운영 값)

ConfigMap 크기 제한

여기서 시험 함정이 하나 있어요. ConfigMap·Secret 한 객체 ≤ 1MB. etcd 한계. 큰 설정 파일은 분리 또는 외부 저장소.

ConfigMap 자동 갱신

Volume mount 시 자동 갱신:

1. ConfigMap 수정 (kubectl apply)
2. ~수십 초 후 Pod 안 파일 자동 갱신
3. 앱이 파일 변경 감지·재로드 (앱 코드 책임)

여기서 시험 함정이 하나 있어요. 앱이 파일 watch 안 하면 갱신 무용. Spring Boot Refresh Scope 또는 inotify 같은 메커니즘 필요.

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 5편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.

  • ConfigMap = 일반 설정 / Secret = 민감 정보
  • 동작 거의 같음, 이름만 다름
  • ConfigMap 생성 — --from-literal / --from-file / 디렉토리 / YAML
  • Pod 주입 4종 — env (단일) / envFrom (전체) / Volume / subPath
  • env / envFrom = 자동 갱신 X (Pod 재시작)
  • Volume Mount = 자동 갱신 O (수십 초)
  • 앱이 파일 watch 안 하면 무용
  • Secret = base64만, 암호화 X (가장 큰 함정)
  • etcd에 평문 저장
  • 운영 환경 = 추가 보호 필수
  • Secret 타입 — Opaque / dockerconfigjson / tls / service-account-token
  • EncryptionConfiguration = etcd 암호화 (기본 비활성)
  • Sealed Secrets = GitOps 환경 표준 (Bitnami)
  • External Secrets Operator = Vault·AWS Secrets Manager 동기화
  • CSI Secret Store Driver = Pod 직접 마운트
  • 운영 — Sealed Secrets / External Secrets+Vault / 클라우드 SM
  • ConfigMap·Secret ≤ 1MB (etcd 한계)
  • 환경별 분리 — Helm·Kustomize 또는 namespace

시리즈 다른 편

공식 문서: Kubernetes ConfigMap / Secret 에서 더 깊이.

다음 글(6편)에서는 Storage — Volume·PV·PVC·StorageClass·CSI까지 풀어 갑니다.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!