Application Lifecycle Management - Secret

2025. 12. 30. 13:50·CKA

웹 애플리케이션이 데이터베이스에 연결할 때는 보통 다음 정보가 필요합니다.

  • DB Host
  • DB Username
  • DB Password

강의 예시처럼 MySQL에 붙는 간단한 Python 웹앱이 있고, 코드에 호스트/유저/비밀번호가 하드코딩되어 있다면 동작은 하겠지만 운영 관점에서는 좋지 않습니다. 값 변경이 어렵고, 무엇보다 비밀번호가 코드/이미지/레포에 남는 보안 사고로 이어지기 쉽습니다.

이전 글에서 ConfigMap으로 구성 데이터를 분리할 수 있다고 했지만, ConfigMap은 일반 텍스트로 저장되므로 비밀번호 저장처로 적합하지 않습니다. 그래서 등장하는 것이 Secret입니다.


1) Secret이 필요한 이유: ConfigMap은 평문, Secret은 민감 정보용

ConfigMap

  • 일반 구성 데이터(예: APP_COLOR, LOG_LEVEL, DB_HOST, DB_USER)
  • 기본적으로 평문 저장(보안 목적 아님)

Secret

  • 비밀번호/토큰/키 같은 민감 정보
  • ConfigMap과 비슷하게 “키-값”을 저장하지만
  • 값은 보통 Base64 인코딩된 형태로 저장됩니다.

중요한 주의: Base64는 “암호화(encryption)”가 아니라 “인코딩(encoding)”입니다. 즉, 그대로 디코딩하면 원문이 나옵니다. Secret은 “평문 ConfigMap에 비해 의도/표준이 맞는 저장소”이지만, 보안은 RBAC, etcd 암호화, 외부 Secret 관리(Vault/Cloud KMS) 등과 함께 설계해야 합니다.


2) Secret 작업도 ConfigMap처럼 2단계

  1. Secret 생성
  2. Pod(또는 Deployment 등)에 주입

3) Secret 생성 방법 2가지: 명령형 vs 선언형

Secret도 ConfigMap과 동일하게 명령형(Imperative), 선언형(Declarative) 두 방식이 있습니다.


3-1) 명령형: kubectl create secret generic + --from-literal

강의의 흐름 그대로, 커맨드에서 키-값을 직접 넣어 Secret을 만들 수 있습니다.

kubectl create secret generic app-secret \
  --from-literal=DB_HOST=mysql \
  --from-literal=DB_USER=root \
  --from-literal=DB_PASSWORD=passw0rd
  • generic: 일반적인 Key-Value Secret
  • 리터럴이 많아지면 커맨드가 길어지고 관리가 어려워질 수 있습니다.

3-2) 명령형: --from-file로 파일 기반 입력

비밀 데이터가 파일로 있을 때는 파일을 그대로 Secret에 담을 수 있습니다.

kubectl create secret generic app-secret \
  --from-file=./db_password.txt
  • 기본적으로 키 이름은 파일명
  • 파일 내용이 Secret 값이 됩니다.

3-3) 선언형: Secret YAML로 생성 (Base64 인코딩 필요)

ConfigMap처럼 YAML로 Secret을 만들 수도 있습니다. 다만 Secret의 data에는 Base64로 인코딩된 값을 넣어야 합니다.

예: 평문이 mysql이라면 Base64로 변환해야 합니다.

(1) Base64 인코딩

echo -n 'mysql' | base64
echo -n 'root' | base64
echo -n 'passw0rd' | base64

-n을 붙여야 줄바꿈 문자(\n)가 같이 인코딩되는 실수를 피할 수 있습니다.

(2) Secret YAML 예시

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_HOST: bXlzcWw=
  DB_USER: cm9vdA==
  DB_PASSWORD: cGFzc3cwcmQ=

적용:

kubectl apply -f secret.yaml

4) Secret 조회/확인: 값은 기본적으로 숨겨진다

목록 조회

kubectl get secrets

클러스터에는 쿠버네티스가 내부적으로 사용하는 Secret도 존재할 수 있습니다.

상세 조회(값은 숨김)

kubectl describe secret app-secret
  • 키 목록은 보이지만 값은 노출되지 않습니다.

YAML로 보기(인코딩 값은 보임)

kubectl get secret app-secret -o yaml
  • Base64 인코딩된 값이 보입니다.

디코딩(원문 확인)

echo 'bXlzcWw=' | base64 --decode

또는 kubectl로 바로 뽑아서 디코딩(실전에서 자주 씀):

kubectl get secret app-secret -o jsonpath='{.data.DB_PASSWORD}' | base64 --decode
echo

5) Pod에 Secret 주입하기: 환경 변수로 쓰기

이제 2단계(주입)입니다. 강의처럼 “파드 정의 파일에 env를 추가하고, 각 env 항목이 secret의 키를 참조”하면 됩니다.

5-1) 단일 키를 환경 변수로 주입: secretKeyRef

apiVersion: v1
kind: Pod
metadata:
  name: webapp-with-secret
spec:
  containers:
    - name: webapp
      image: my-python-webapp:1.0
      env:
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: DB_HOST
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: DB_USER
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: DB_PASSWORD

이렇게 하면 애플리케이션에서 DB_HOST, DB_USER, DB_PASSWORD 환경 변수를 읽어 DB 연결에 사용할 수 있습니다.


6) Pod에 Secret 주입하기: 다른 2가지 방식도 있다

강의에서 마지막에 언급한 것처럼 Secret 주입은 환경 변수 외에도 가능합니다.

6-1) Secret 전체를 한 번에 환경 변수로 주입: envFrom

envFrom:
  - secretRef:
      name: app-secret
  • Secret의 모든 키가 환경 변수로 들어갑니다.
  • 키 충돌/예상치 못한 주입을 피하려면 팀 규칙을 두는 게 좋습니다.

6-2) Secret을 볼륨으로 마운트: “키마다 파일 생성”

Secret을 볼륨으로 마운트하면, Secret의 각 키가 파일이 됩니다.

apiVersion: v1
kind: Pod
metadata:
  name: webapp-secret-volume
spec:
  containers:
    - name: webapp
      image: my-python-webapp:1.0
      volumeMounts:
        - name: secret-vol
          mountPath: /etc/secret
          readOnly: true
  volumes:
    - name: secret-vol
      secret:
        secretName: app-secret

결과:

  • /etc/secret/DB_HOST
  • /etc/secret/DB_USER
  • /etc/secret/DB_PASSWORD

처럼 파일이 생성되고, 예를 들어 DB_PASSWORD 파일 내용이 실제 비밀번호가 됩니다.


7) 핵심 정리

  • 코드에 비밀번호를 하드코딩하는 것은 운영/보안적으로 위험
  • ConfigMap은 평문 구성 데이터에 적합(비밀번호에는 부적절)
  • Secret은 민감 정보를 저장/주입하기 위한 오브젝트(값은 Base64 형태로 저장)
  • Secret 작업은 2단계:
    1. 생성(create/apply)
    2. Pod에 주입(env / envFrom / volume)
  • 볼륨 마운트 시 Secret의 각 키는 “파일”이 된다

 

**Base64로 인코딩하는거면 사실상 디코딩이 쉬우니 ConfigMap과 별 다를 것 아닌것 아닌가?

-> Secret을 읽을 수 있다면 사실상 맞지만 일반적으로 대부분의 유저에게 Secret에 대해 접근 권한을 주지 않는 등으로 별도 관리하여 보안성을 높혀줌

 

Practice Test: https://uklabs.kodekloud.com/topic/practice-test-secrets-2/

'CKA' 카테고리의 다른 글

Application Lifecycle Management - 멀티 컨테이터 파드  (1) 2025.12.30
Application Lifecycle Management - etcd에 저장되는 secret 암호화하기  (0) 2025.12.30
Application Lifecycle Management - ConfigMap  (0) 2025.12.30
Application Lifecycle Management - Docker CMD/Entrypoint와 쿠버네티스  (0) 2025.12.30
Application Lifecycle Management - 배포전략  (0) 2025.12.30
'CKA' 카테고리의 다른 글
  • Application Lifecycle Management - 멀티 컨테이터 파드
  • Application Lifecycle Management - etcd에 저장되는 secret 암호화하기
  • Application Lifecycle Management - ConfigMap
  • Application Lifecycle Management - Docker CMD/Entrypoint와 쿠버네티스
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (119)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      hibernate5module
      조회 성능 최적화
      jpq
      고급
      WAS
      reentarantlock
      jdk 동적 프록시
      typequery
      버퍼
      @args
      자바
      김영한
      Thread
      단방향 맵핑
      양방향 맵핑
      프록시 팩토리
      @discriminatorvalue
      cglib
      빈 후처리기
      @discriminatorcolumn
      페치 조인
      gesingleresult
      log trace
      Target
      스레드
      requset scope
      JPQL
      락
      프록시
      @within
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Application Lifecycle Management - Secret
    상단으로

    티스토리툴바