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

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

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

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

💡 꼬리 질문
Q: Secret은 Base64로 인코딩되어 저장된다고 했다. 그렇다면 인코딩된 문자열을 알면 누구나 내용을 볼 수 있는데, 실무 환경에서 etcd에 저장된 Secret 데이터를 진짜 '암호화'하려면 어떤 설정을 추가해야 할까?
결론: 'Encryption at Rest' 설정을 통해 etcd 레벨에서 암호화해야 한다.
- Base64의 한계: 앞서 말했듯 Base64는 암호화가 아니다. kubectl get secret -o yaml만 쳐도 원문을 다 볼 수 있다.
- 실제 암호화 전략:
- 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)에 따라 결정된다.
- 동작 원리: 워커 노드에서 실행 중인 kubelet은 주기적으로 API 서버를 확인하며 마운트된 ConfigMap/Secret의 변경 사항을 체크한다.
- 업데이트 시점: 변경을 감지하면 kubelet이 로컬의 마운트된 파일을 업데이트한다. 기본적으로 약 1분(60초) 내외의 주기를 가지며, configMapAndSecretChangeDetectionStrategy 설정에 따라 달라질 수 있다.
- 주의 사항: 애플리케이션이 실행 시점에 파일을 한 번만 읽고 메모리에 캐싱해 둔다면, 파일 내용이 변해도 앱 내부 로직에는 반영되지 않을 수 있다. 이 경우 앱이 파일 변경을 감시(Watch)하도록 개발해야 한다.
위 학습용 정리 내용 및 사진 자료는 "인프런_대세는 쿠버네티스(https://inf.run/Lv5RV)" 강의를 소스로 작성하였습니다.
'Cloud Native > Kubernetes' 카테고리의 다른 글
| 6. ReplicaSet - Template, Replicas, Selector (0) | 2026.01.22 |
|---|---|
| 5. Namespace, ResourceQuota, LimitRange (0) | 2026.01.18 |
| 3. Volume - emptyDir, hostPath, PV/PVC (0) | 2026.01.16 |
| 2. Service - ClusterIP, NodePort, LoadBalancer (0) | 2026.01.16 |
| 1. Pod - Container, Label, NodeSchedule (1) | 2026.01.15 |