ConfigMap 한 줄 요약
ConfigMap은 "쿠버네티스 클러스 안에 설정값을 저장해두고 Pod에서 꺼내 쓰게 해주는 리소스"이다.
ConfigMap을 쓰는 이유
1) 이미지와 설정을 분리
컨테이너 이미지는 바꾸지 않고, 설정만 바꿔서 다른 환경에 배포할 수 있다.
- 이미지: myap:1.0 (고정)
- 설정: APP_MODE=dev / APP_MODE=prod (환경별 ConfigMap)
2) YAML로 관리 가능 (GitOps / 추적 / 롤백에 유리)
ConfigMap은 Kubernetes 오브젝트라스 kubectl apply 로 배포하고 변경 이력을 남기기 쉽다.
3) Pod에 주입 방식을 표준화
앱에서 설정을 읽는 방식(환경변수/파일)에 맞춰 ConfigMap을 깔끔하게 연결할 수 있다.
ConfigMap은 "로컬 파일"이 아니라 "클러스터 리소스"
많이 헷갈리는 지점:
- 로컬에 있는 건 ConfigMap YAML 파일(설계도)일 뿐이고,
- kubectl apply 하면 실제 ConfigMap은 클러스터(etcd)에 저장된다.
- Pod가 뜰 때, 노드의 kubelet이 클러스터에 저장된 ConfigMap 내용을 가져와서 Pod에 주입한다.
ConfigMap 생성 방법
방법 A) YAML로 생성
apiVersion: v1
kind: ConfigMap
metadata:
name: app-cm
data:
APP_MODE: "prod"
LOG_LEVEL: "info"
적용:
kubectl apply -f app-cm.yaml
kubectl get cm app-cm -o yaml
방법 B) 명령어로 생성
kubectl create configmap app-cm \
--from-literal=APP_MODE=prod \
--from-literal=LOG_LEVEL=info
Pod에 ConfigMap 주입하는 2가지 방식(핵심)
ConfigMap을 컨테이너에 넣는 방법은 큰 갈래로 2개이다.
- Env(환경변수)로 주입
- Volume(파일)로 주입
1) Env(환경변수)로 주입
특정 key만 주입: env + configMapKeyRef
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: c
image: busybox:1.36
command: ["sh","-c","sleep 3600"]
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-cm
key: APP_MODE
확인:
kubectl exec env-pod -- sh -c 'echo $APP_MODE'
전체 key를 통째로 주입: envFrom + configMapRef
envFrom:
- configMapRef:
name: app-cm
Env 방식 특징 (중요)
- Pod가 시작될 때 환경변수가 결정됨
- ConfigMap을 수정해도 이미 떠 있는 Pod의 env는 자동 갱신되지 않음
- 따라서 변경을 반영하려면 보통 Pod 재시작 / Deployment 롤아웃이 필요
결론: Env 주입은 "간단하지만 변경 반영엔 재배포가 필요하다"가 핵심.
2) Volume(파일)로 주입
Volume 방식은 항상 2개가 한 세트이다.
- spec.volumes: "어떤 ConfigMap을 볼륨으로 쓸지(출저)"
- containers[].volumeMounts: "컨테이너 안 어디에 붙일지(마운트 위치)"
예시: /etc/config에 마운트
apiVersion: v1
kind: Pod
metadata:
name: vol-pod
spec:
containers:
- name: c
image: busybox:1.36
command: ["sh","-c","sleep 3600"]
volumeMounts:
- name: cm-vol
mountPath: /etc/config
volumes:
- name: cm-vol
configMap:
name: app-cm
확인:
kubectl exec vol-pod -- sh -c 'ls -l /etc/config && cat /etc/config/APP_MODE'
"mountPath에 폴더를 내가 안만들었는데? → 정상
- /etc/config는 컨테이너 이미지에 원래 없어도 됨
- kubelet이 마운트 포인트로 자동 재생성해준다.
Volume 방식 특징 (중요)
- ConfigMap의 key가 파일명, value가 파일내용으로 보인다.
- /etc/config/APP_MODE 파일 내용 = prod
- ConfigMap 수정 시, 환경에 따라 마운트된 파일이 갱신될 수 있음
- 다만 앱이 파일을 다시 읽는 구조여야 실제 동작이 반영된다.
변경 반영(재배포/롤아웃) 포인트 정리
1) Env 주입이면: 대부분 롤아웃 필요
- ConfigMap 수정 → 기존 Pod의 env는 그대로
- 새 Pod를 만들거나 Deployment를 롤아웃해야 새 env가 들어감
2) Volume 주입이면: 파일은 바뀔 수 있으나 "앱이 읽어야" 적용
- 파일 내용이 바뀌어도 앱이 재로딩하지 않으면 동작은 그대로일 수 있음
- "확실하게 반영"이 요구되면 롤아웃을 쓰는게 안정적
3) subPath는 함정
- ConfigMap을 Volume으로 마운트하면서 subPath로 단일 파일만 꽂으면,
ConfigMap 변경이 파일에 반영되지 않은 경우가 많다. - 시험/실무에서 "왜 안 바뀌지?"의 대표 원인.
subPath는 볼륨(Volume)을 통째로 마운트하지 않고, 그 안의 "일부분(특정 파일/디렉터리)"만 골라서 컨테이너 경로에 마운트할 때 쓰는 옵션이다.
1. subPath 한 줄 정의
볼륨의 하위 경로(sub-path)를 지정해서 한 파일만 또는 한 폴더만 컨테이너에 "꽂는" 기능
2. 왜 필요한가? (쓰는 이유)
볼륨을 /etc/config 같은 디렉터리에 통째로 마운트하면,
- 그 디렉터리에 원래 있던 파일들이 가려질 수 있음 (마운트가 덮어씀)
그래서 "디렉터리 전체를 덮지 말고, 특정 파일만 딱 끼워 넣고 싶다" 할 때 subPath를 씀.
예를 들면:
- /etc/nginx/nginx.conf 파일 하나만 ConfigMap으로 교체하고 싶다
- 앱이 /app/config.yaml 파일 하나만 필요하다
이런 케이스
3. 기본 (통째 마운트) vs subPath(부분 마운트)
A. 통째 마운트(정석)
volumeMounts:
- name: cm-vol
mountPath: /etc/config
결과:
- /etc/config/APP_MODE
- /etc/config/LOG_LEVEL
처럼 키들이 파일로 쫙 생김
B. subPath로 "파일 하나만" 마운트
volumeMounts:
- name: cm-vol
mountPath: /etc/config/APP_MODE
subPath: APP_MODE
의미:
- cm-vol 안에 있는 APP_MODE 라는 "파일"만 골라서
- 컨테이너의 /etc/config/APP_MODE 경로에 꽂아라
4. ConfigMap/Secret에서 subPath가 "함정"인 이유
ConfigMap/Secret 볼륨은 보통 내용 변경 시 파일이 업데이트될 수 있는데,
subPath로 마운트하면 많은 경우 변경이 자동 반영되지 않는다.
왜 그럴까?
- 통째 마운트는 kubelet이 "볼륨 디렉터리"를 개신해주기 쉬움
- subPath는 "그 시점의 특정 파일을 고정해서 꽂아두는 느낌"이라
업데이트 추적/반영이 안되는 케이스가 흔함
결과적으로
- ConfigMap/Secret 수정해도,
- Pod안 subPath로 꽂힌 파일은 안 바뀔 수 있음
- 그래서 "설정 변경 자동 반영"이 목표라면 subPath를 피하거나, 롤아웃으로 해결하는 쪽이 안전
실습 시 자주 쓰는 확인 방법
ConfigMap 확인
kubectl get cm app-cm -o yaml
Pod에 주입되었는지 확인 (Env)
kubectl exec env-pod -- sh -c 'env | grep APP_MODE'
Pod에 주입되었는지 확인 (Volume)
kubectl exec vol-pod -- sh -c 'ls -l /etc/config && cat /etc/config/APP_MODE'
'CKA' 카테고리의 다른 글
| [k8s] 스케줄링 기본기: nodeSelector / nodeAffinity / podAntiAffinity로 Pod 배치 제어하기 (실습 포함) (0) | 2026.02.22 |
|---|---|
| [k8s] Secret 정리 (ConfigMap 차이) (0) | 2026.02.20 |
| [k8s] kubectl 자동완성(Tab completion) 설정하기 : zsh에서 kubectl completion 켜는 방법 (0) | 2026.02.16 |
| [k8s] namespace 구분 (0) | 2026.02.15 |
| [k8s] 컨텍스트(context)에 대해 알아보자 (0) | 2026.02.15 |