본문 바로가기
Cloud Native/Kubernetes

4. ConfigMap, Secret - Env, Mount

by jys275 2026. 1. 18.

컨테이너 환경에서 가장 비효율적인 작업은 환경별로 이미지를 따로 만드는 것이다. 이미지는 하나로 유지하되, 그 안에 들어갈 '설정'만 갈아 끼우는 것이 핵심이고, 그게 오늘 다룰 주제인 ConfigMap Secret이다.

 

 


 

 

1. 왜 사용하는가? (Decoupling)

  • 이미지 재사용: 개발(Dev)과 상용(Prod) 환경의 설정(DB 주소, 보안 키 등)이 다르다고 이미지를 두 개 만들지 마라.
  • 설정의 외주화: 환경에 따라 변하는 상수나 보안 정보는 컨테이너 외부(쿠버네티스 오브젝트)에서 관리하고, 실행 시점에 주입한다.

 

 

 

2. ConfigMap vs Secret (용도와 보안)

  • ConfigMap: 일반적인 설정 상수나 설정 파일을 저장한다.
  • Secret: 패스워드, 인증키 등 보안이 필요한 데이터를 담는다.
    • Base64 인코딩: ConfigMap과 다르게 Secret의 데이터는 반드시 Base64로 변환해서 넣어야 한다. (보안용이 아니라 단순히 데이터 형식을 맞추는 규칙일 뿐이다.)
      • 이게 또 파드로 주입이 될 때는 자동으로 디코딩이 돼서 원래 값이 보이게된다.
    • 메모리 저장: 보안을 위해 디스크가 아닌 메모리(Memory)에 저장되며, 크기는 1MB로 제한된다.
      • 아무래도 파일에 저장된 것 보단 메모리에 있는게 보안에 좋기 때문이다.
      • 근데 메모리를 사용하는 만큼 이 Secret을 너무 많이 만들게 되면 시스템 자원에 영향을 끼칠 것이다.

 

 

 

3. 주입 방식에 따른 차이 존재

  • 환경 변수(Env) 방식
    • 파드 생성 시점에 딱 한 번 주입된다.
    • ConfigMap 내용을 바꿔도 이미 실행 중인 파드에는 반영되지 않는다. 파드를 재시작해야만 바뀐 값을 읽어온다.
    • YAML 구성을 보면, 방식은 다르지만 ConfigMap, Secret YAML을 각각 만든 후에, 파드에서 Ref해서 갖고오는 방식이다.
      1. Literal(정수) 방식
        • ConfigMap: name 지정 후, Key-Value 형태로 Literal(상수)를 넣는다.
        • Secret: name 지정 후, Key-Value 형태로 Literal(상수)를 넣는다. 대신 value에는 값을 base64 변환해서 넣는다.
        • Pod: envfrom 속성과 configMapRef, secretRef를 통해 레퍼런스한다
      2. File(파일) 방식
        • 파일을 통으로 담는 형식이다.
        • 즉, 파일 이름(file.txt)이 키가되고, 파일 내용 전체(--from-file=./file.txt)가 값으로 들어간다.
          • 파일 이름 = Key
          • 파일 안의 내용 = Value
        • ConfigMap: 파일을 만드는 것은 콘솔로 kubectl 명령을 실행해야한다. 위의 그림의 경우 cmfile이라는 configmap을 만드는 예시가 있다. 
        • Secret: 대신, Secret을 file로 만들 때는 안의 내용이 file로 만들면서 base64로 알아서 변환이 되기 때문에, 미리 변환을 해두었다면 두번 인코딩이 되는 사태가 일어난다.
        • Pod: env 속성으로 name을 file(방식)로 지정, valueFrom으로 이 file의 값을 가져올 것이고, 만든 파일을 레퍼런스한다.
  • 볼륨 마운트(Volume Mount, File) 방식
    • File 방식에서 ConfigMap이나 Secret 같은 설정 파일에 담는 것까지는 똑같다.
    • 그 설정 파일을 컨테이너 내부 경로에 파일로 연결한다.
      • ConfigMap 내용이 변하면 파드 안의 파일 내용도 실시간으로 변한다. 애플리케이션이 파일 변경을 감시(Watch)한다면 재시작 없이 설정 변경이 가능하다.
      • 즉, 한번 주입하면 끝인 File 방식과 큰 차이가 존재하는 것임.

pod를 describe 명령어로 봤을 때



 

💡 꼬리 질문

Q: Secret은 Base64로 인코딩되어 저장된다고 했다. 그렇다면 인코딩된 문자열을 알면 누구나 내용을 볼 수 있는데, 실무 환경에서 etcd에 저장된 Secret 데이터를 진짜 '암호화'하려면 어떤 설정을 추가해야 할까?

 

 

결론: 'Encryption at Rest' 설정을 통해 etcd 레벨에서 암호화해야 한다.

  1. Base64의 한계: 앞서 말했듯 Base64는 암호화가 아니다. kubectl get secret -o yaml만 쳐도 원문을 다 볼 수 있다.
  2. 실제 암호화 전략:
    • EncryptionConfiguration: 쿠버네티스 API 서버 설정에 EncryptionConfiguration을 적용하면, 데이터가 etcd에 저장되기 직전에 암호화된다.
    • KMS(Key Management Service) 연동: AWS KMS나 HashiCorp Vault 같은 외부 키 관리 솔루션을 연동하여 암호화 키 자체를 안전하게 관리하는 것이 빅테크 기업의 표준 보안 절차다.

 


 

 

 

1. 상수 정의 (Literal)와 환경 변수 주입

인프런_대세는 쿠버네티스

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-dev
data:
  SSH: 'false'
  User: dev
  • ConfigMap의 규칙: 데이터는 반드시 String(문자열) 형태여야 한다. true/false 같은 불리언 값도 반드시 따옴표('false')를 붙여야 하며, 이를 어기면 생성 시 에러가 발생한다.
apiVersion: v1
kind: Secret
metadata:
  name: sec-dev
data:
  Key: MTIzNA==
  • Secret의 규칙: Value에 데이터를 직접 넣을 때는 반드시 Base64로 인코딩된 문자열을 넣어야 한다. 그렇지 않으면 인코딩이 필요하다는 에러 메시지를 보게 된다.
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
spec:
  containers:
  - name: container
    image: kubetm/init
    envFrom:
    - configMapRef:
        name: cm-dev
    - secretRef:
        name: sec-dev
  • 주입 확인: 파드 생성 시 envFrom을 통해 한꺼번에 주입할 수 있으며, 컨테이너 내부에서 env 명령어를 쳐보면 Secret에 인코딩해서 넣었던 값이 자동으로 디코딩되어 원문으로 보이는 것을 확인할 수 있다.

 

 

2. 파일 기반 환경 변수 (Env from File)

인프런_대세는 쿠버네티스

echo "Content" >> file-c.txt
kubectl create configmap cm-file --from-file=./file-c.txt

echo "Content" >> file-s.txt
kubectl create secret generic sec-file --from-file=./file-s.txt
  • CLI 생성: 대시보드에서는 파일을 직접 넣는 기능을 지원하지 않으므로 마스터 노드 터미널에서 kubectl create configmap/secret ... --from-file 명령어를 사용한다.
  • 자동 인코딩: 명령어로 Secret을 만들 때는 파일 안의 일반 텍스트가 자동으로 Base64 인코딩되어 올라간다. 이미 인코딩된 파일을 넣으면 두 번 인코딩될 수 있으니 주의해라.
apiVersion: v1
kind: Pod
metadata:
  name: pod-file
spec:
  containers:
  - name: container
    image: kubetm/init
    env:
    - name: file-c
      valueFrom:
        configMapKeyRef:
          name: cm-file
          key: file-c.txt
    - name: file-s
      valueFrom:
        secretKeyRef:
          name: sec-file
          key: file-s.txt
  • 환경 변수 매칭: 파드의 env 설정에서 valueFrom을 사용해 특정 파일 이름(Key)을 환경 변수명과 매칭시켜 주입한다.

 

 

3. 볼륨 마운트 (Volume Mount) 방식

인프런_대세는 쿠버네티스

apiVersion: v1
kind: Pod
metadata:
  name: pod-mount
spec:
  containers:
  - name: container
    image: kubetm/init
    volumeMounts:
    - name: file-volume
      mountPath: /mount
  volumes:
  - name: file-volume
    configMap:
      name: cm-file
  • 연결 방식: 파일을 환경 변수가 아닌 특정 경로(예: /mount)에 실제 파일 형태로 마운트한다.
  • 설정 흐름: 파드 정의서의 volumes 섹션에 ConfigMap 이름을 지정하고, volumeMounts를 통해 컨테이너 내부 경로와 연결한다.

 

 

4. [가장 중요] 값 변경 시의 차이점

  • 환경 변수(Env): ConfigMap의 데이터를 수정해도 이미 실행 중인 파드에는 반영되지 않는다. 파드를 삭제하고 재생성해야만 변경된 값이 적용된다.
  • 볼륨 마운트(Mount): 파드를 재생성하지 않아도 ConfigMap의 변경 사항이 컨테이너 내부의 마운트된 파일에 즉시(또는 짧은 시간 내에) 반영된다. 실시간 설정 변경이 필요한 서비스에 유리하다.

 

 

5. 시스템 제약 사항

  • 용량 제한: 하나의 ConfigMap이나 Secret은 1MB를 초과할 수 없다. 이는 etcd의 개별 데이터 크기 제한(1.5MiB) 때문이다.
  • 보안 특성: Secret은 데이터를 메모리 영역에 올려두고 사용하므로 디스크에 저장되는 ConfigMap보다 보안상 유리하다.

 

 

💡 꼬리 질문

Q: 볼륨 마운트 방식은 실시간 업데이트가 된다고 했는데, 업데이트되는 정확한 시점은 언제이며 이를 결정하는 쿠버네티스 컴포넌트의 설정은 무엇인가?

 

결론: 'Kubelet'의 동기화 주기(Sync Period)에 따라 결정된다.

  1. 동작 원리: 워커 노드에서 실행 중인 kubelet은 주기적으로 API 서버를 확인하며 마운트된 ConfigMap/Secret의 변경 사항을 체크한다.
  2. 업데이트 시점: 변경을 감지하면 kubelet이 로컬의 마운트된 파일을 업데이트한다. 기본적으로 약 1분(60초) 내외의 주기를 가지며, configMapAndSecretChangeDetectionStrategy 설정에 따라 달라질 수 있다.
  3. 주의 사항: 애플리케이션이 실행 시점에 파일을 한 번만 읽고 메모리에 캐싱해 둔다면, 파일 내용이 변해도 앱 내부 로직에는 반영되지 않을 수 있다. 이 경우 앱이 파일 변경을 감시(Watch)하도록 개발해야 한다.

 

 

위 학습용 정리 내용 및 사진 자료는 "인프런_대세는 쿠버네티스(https://inf.run/Lv5RV)" 강의를 소스로 작성하였습니다.