[MacOS 환경 #24] 쿠버네티스 ConfigMap

도람·2025년 11월 27일
post-thumbnail

ConfigMap 이란?

쿠버네티스 공식 문서에서는 ConfigMap 을 이렇게 정의한다.

“기밀이 아닌 설정 데이터를 key-value 형태로 저장하는 API 오브젝트이며,
파드에서 환경변수, 커맨드 인자, 볼륨 파일로 소비할 수 있다.”

한 마디로,
이미지 안에 두기 애매한 설정값들을 따로 뽑아놓은 설정 저장소라고 보면 된다.

  • 리소스 타입: ConfigMap (네임스페이스 단위)

  • 저장 형태: data(문자열), binaryData(바이너리)

  • 파드에서 쓰는 방법

    • 환경 변수 (envFrom, configMapKeyRef)
    • 컨테이너 command/args 에 끼워 넣기
    • 파일(볼륨)로 마운트해서 읽기

왜 ConfigMap 을 쓸까?

솔직히 그냥 파드 YAML 에 환경변수 몇 개 박아 넣거나
이미지 안 설정파일 한 줄 고쳐도 돌아가긴 하는데 왜 굳이 ConfigMap을 쓰지 라는 의문이 들었었다.

그래서 찾아보니 다음과 같은 결론이 나왔다.

그래도 굳이 ConfigMap 을 쓰는 이유는
“코드/이미지랑 설정을 분리해서 운영을 편하게 만들기 위해서”이다.

대표적인 상황 몇 가지를 생각해보면 된다.


1. 이미지 다시 빌드하지 않고 설정만 바꾸고 싶을 때

예를 들어 애플리케이션이 이런 값들을 가진다고 해보자.

  • DB 접속 주소 (DB_HOST)
  • 외부 API URL (PAY_API_URL)
  • 로그 레벨 (LOG_LEVEL)

이걸 이미지 안 설정파일에 넣어두면:

  • DB 주소가 바뀌거나
  • 로그 레벨만 잠깐 DEBUG 로 올리고 싶어도
    → 이미지를 다시 빌드해서 배포해야 한다.

ConfigMap 을 쓰면:

  • 이미지는 그대로 두고
  • sleepy-config 같은 ConfigMap 값만 수정하고
  • Deployment 를 롤링 재시작만 하면 된다.

즉, “설정 변경 = YAML 수정 + 재시작” 으로 끝난다.
운영 입장에서 훨씬 효율적인 방법인 것이다.


2. 같은 코드로 dev / stage / prod 를 나눠 돌릴 때

코드는 똑같은데, 환경만 다를 수 있다.

  • dev

    • DB: mysql-dev.svc.cluster.local
    • 로그 레벨: DEBUG
  • prod

    • DB: mysql-prod.svc.cluster.local
    • 로그 레벨: INFO

이걸 ConfigMap 두 개로 나누면 된다.

  • sleepy-config-dev
  • sleepy-config-prod

Deployment YAML 은 똑같이 두고,
각 네임스페이스에서 참조하는 ConfigMap 이름만 바꾸면 된다.

envFrom:
- configMapRef:
    name: sleepy-config   # dev, prod 에서 각자 다른 ConfigMap 으로 매핑

이렇게 하면

  • 코드/이미지는 재사용
  • 환경마다 ConfigMap 만 다르게

이라서 멀티 환경 운영이 쉬워지는 것이다.


3. 여러 파드가 같은 설정을 공유해야 할 때

예를 들어

여러 worker 파드가 같은

  • Redis 주소
  • 공통 feature flag
  • 공통 timeout 값

을 써야 하는 상황이라고 가정한다,
각 파드 YAML 안에 똑같은 값들을 복붙해두면:
값 하나 바꿀 때 모든 Deployment 를 찾아서 수정해야 된다.

이럴 경우 실수가 나기 딱 좋다.
코딩이라고 생각하면 어떤 상황인지 이해가 쉽게 될 것이다.
함수마다 똑같은 지역변수에 int var= 10;을 하여 계속 바꾸는 것보다 , 글로벌 변수 하나를 선언해서
가져다 쓰는 느낌인 것이다.

아무튼,

ConfigMap 을 쓰면:

  • app-common-config 하나만 고치면
  • 그걸 참조하는 모든 파드가 같이 설정이 바뀐다.

즉, 공통 설정을 중앙집중식으로 관리하는 느낌이다.


실습


1. ConfigMap 생성

먼저 모든 실습에서 같이 쓸 ConfigMap 을 하나 만든다.

파일명: ConfigMap-sleepy-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: sleepy-config
data:
  STATUS: "WAKE UP"
  NOTE: "TestBed Configuration"

적용&확인 명령어

kubectl apply -f ConfigMap-sleepy-config.yaml
kubectl get configmap sleepy-config -o yaml


data 아래에 STATUS, NOTE 두 개의 key 가 있는 아주 단순한 ConfigMap이 생성 된 것을 확인할 수 있다.


이것은 describe를 사용하여 확인한 결과이다.


2. envFrom – 전체 키를 환경변수로 주입

첫 번째 패턴은 ConfigMap 의 모든 key 를 그대로 환경변수로 뿌려주는 방식이다.
공식 문서에서도 envFrom.configMapRef 로 예시를 보여준다.

파일명: deploy-configMapRef.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-configmapref
  labels:
    app: deploy-configmapref
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy-configmapref
  template:
    metadata:
      labels:
        app: deploy-configmapref
    spec:
      containers:
      - name: sleepy
        image: sysnet4admin/sleepy
        command: ["/bin/sh", "-c"]
        args:
        - |
          echo "sleepy $STATUS"
          echo "NOTE: $NOTE"
          sleep 3600
        envFrom:
        - configMapRef:
            name: sleepy-config   # 아까 만든 ConfigMap 전체를 환경변수로

적용&확인 명령어

kubectl apply -f deploy-configMapRef.yaml

# 파드 이름 확인
kubectl get pods -l app=deploy-configmapref

# 파드 안에서 환경변수 확인
kubectl exec -it deploy-configmapref-78858d77c5-4d6sq -- sh
env | grep -E 'STATUS|NOTE'


echo "sleepy $STATUS"
echo "NOTE: $NOTE"
에서 wake up과 TestBed Configuration가 잘 매핑되는 것을 확인할 수 있다.


3. configMapKeyRef – 특정 키만 골라서 환경변수로

두 번째 패턴은 ConfigMap 의 일부 key 만 골라서 다른 이름의 환경변수로 매핑하는 방식이다.
공식 문서에서도 env[].valueFrom.configMapKeyRef 예시로 설명한다.

파일명: deploy-configMapKeyRef.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-configmapkeyref
  labels:
    app: deploy-configmapkeyref
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy-configmapkeyref
  template:
    metadata:
      labels:
        app: deploy-configmapkeyref
    spec:
      containers:
      - name: sleepy
        image: sysnet4admin/sleepy
        command: ["/bin/sh", "-c"]
        args:
        - |
          echo "APP_STATUS = $APP_STATUS"
          sleep 3600
        env:
        - name: APP_STATUS
          valueFrom:
            configMapKeyRef:
              name: sleepy-config   # ConfigMap 이름
              key: STATUS           # 그 중 STATUS 키만 가져오기

포인트
  • envFrom 이 아니라 env 배열을 사용한다.
  • APP_STATUS 환경변수 하나를 만들고
    그 값은 sleepy-config 의 STATUS key 값으로 채워진다.
  • NOTE 같은 나머지 key 는 이 컨테이너 환경변수에 들어오지 않는다.

배포&적용 명령어

kubectl apply -f deploy-configMapKeyRef.yaml

kubectl get pods -l app=deploy-configmapkeyref
kubectl logs -l app=deploy-configmapkeyref

APP_STATUS = WAKE UP라고 뜨는 것을 확인하여
매핑이 잘된 것을 확인할 수 있다.


4. volume + configMap – 파일로 마운트해서 읽기

세 번째 패턴은 ConfigMap 을 볼륨으로 마운트해서 파일처럼 읽는 방식이다.
공식 문서의 “Using ConfigMaps as files from a Pod” 에 해당한다.

파일명: deploy-vol-configMap.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-vol-configmap
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy-vol-configmap
  template:
    metadata:
      labels:
        app: deploy-vol-configmap
    spec:
      containers:
      - name: sleepy
        image: sysnet4admin/sleepy
        command: ["/bin/sh", "-c"]
        args:
        - |
          echo "===== file list ====="
          ls -R /etc/sleepy.d
          echo ""
          echo "===== file contents ====="
          echo "NOTE:   $(cat /etc/sleepy.d/NOTE)"
          echo "STATUS: $(cat /etc/sleepy.d/STATUS)"
          sleep 3600
        volumeMounts:
        - name: appconfigvol
          mountPath: /etc/sleepy.d
      volumes:
      - name: appconfigvol
        configMap:
          name: sleepy-config
  • volumes[].configMap.name: sleepy-config
    → 이 ConfigMap 을 볼륨으로 선언한다.

  • volumeMounts[].mountPath: /etc/sleepy.d
    → 이 경로 아래에 STATUS, NOTE 파일이 생성된다.

  • 각 파일 내용은 ConfigMap 의 value 와 동일하다.


배포 & 테스트 명령어

kubectl apply -f deploy-vol-configMap.yaml
kubectl get pods -l app=deploy-vol-configmap
kubectl logs -l app=deploy-vol-configmap

이렇게 볼륨 마운트가 잘 되어 로그가 출력이 되는 것을 확인할 수 있다.


5. ConfigMap 값 변경

공식 문서 기준으로:

  • 볼륨으로 마운트한 ConfigMap
    → kubelet 이 주기적으로 새 값을 가져와서 파일이 자동으로 갱신된다.

  • 환경변수로 주입한 ConfigMap (env, envFrom)
    → 파드가 처음 생성될 때만 값이 들어가고,
    ConfigMap 을 바꿔도 이미 떠 있는 파드에는 자동 반영되지 않는다
    (파드 재시작/롤링업데이트 필요).

그래서

  1. sleepy-config 의 STATUS 값을 "SLEEP AGAIN" 으로 바꾸고
  2. Deployment 를 rollout restart 해서 새 파드를 뜨게 한 뒤
  3. 다시 로그를 보면 값이 바뀐 것을 확인할 수 있다.
# ConfigMap 수정 (파일 수정 후 다시 apply)
kubectl apply -f ConfigMap-sleepy-config-chg.yaml

# 디플로이먼트 롤링 재시작
kubectl rollout restart deployment/deploy-configmapref

kubectl logs -l app=deploy-configmapref
# -> sleepy SLEEP AGAIN

세 가지 패턴 한 번에 정리

패턴어떻게 주입?YAML 키워드컨테이너 안에서 모습
envFrom 전체 주입ConfigMap 의 모든 key 를 환경변수로 사용envFrom.configMapRefSTATUS, NOTE 등 key 이름 그대로 환경변수 생성
특정 key 만 주입필요한 값만 골라서 다른 이름의 env 로 사용env[].valueFrom.configMapKeyRefAPP_STATUS 같은 이름으로 원하는 key 만 매핑
파일로 마운트설정파일처럼 읽고 싶을 때volumes[].configMap + volumeMounts[]/etc/sleepy.d/STATUS, /etc/sleepy.d/NOTE 같은 파일로 생성

짧게 정리하자면 각 상황에 맞춰 사용하면 된다.

  • “환경변수로 쓰고 싶다” → envFrom 또는 configMapKeyRef
  • “파일로 읽고 싶다” → configMap 볼륨 마운트
  • “값 바꿨을 때 자동 갱신되길 원한다”

    • 볼륨 마운트 → 자동 갱신 (약간의 지연 있음)
    • env → 파드 재시작 필요

참고자료:
[Kubernetes 공식 문서 – ConfigMaps]
https://kubernetes.io/ko/docs/concepts/configuration/configmap/

profile
정도를 걷는 엔지니어

0개의 댓글