Kubernetes: Config & Storage API 3 - ConfigMap

JIWON·2025년 7월 9일

Kubernetes

목록 보기
24/32
post-thumbnail

쿠버네티스에서 애플리케이션의 설정 데이터를 코드와 분리하여 관리하는 것은 매우 중요하다. ConfigMap은 이러한 요구사항을 충족시켜주는 핵심 리소스로, 설정 정보를 유연하게 관리하고 주입할 수 있도록 돕는다.

1. ConfigMap

ConfigMap은 설정 정보 등을 Key-Value 형태로 저장할 수 있는 쿠버네티스 API 리소스이다.

Pod의 설정은 애플리케이션 코드에 하드코딩하기보다 외부로 분리하는 것이 좋다. ConfigMap을 사용하면 Pod의 재배포 없이 설정을 변경하고, 다양한 환경(개발, 테스트, 운영)에 맞는 설정을 손쉽게 적용할 수 있다.

주로 일반 텍스트 기반의 설정 데이터를 다루며, nginx.confhttpd.conf 같은 설정 파일 전체를 저장하는 용도로도 사용 가능하다.

📌 Secret과 ConfigMap의 차이점

ConfigMap은 일반적인 설정 정보, 구성 파일 등 민감하지 않은 데이터를 저장하는 데 사용한다. 데이터는 Base64로 인코딩되지 않고 평문으로 저장된다.
반면, Secret은 API 키, DB 패스워드, TLS 인증서와 같이 민감한 데이터를 저장하기 위해 사용하며, 데이터는 기본적으로 Base64로 인코딩되어 저장된다.


2. ConfigMap 생성

ConfigMap은 Secret 리소스의 Generic 타입과 거의 동일한 방법으로 생성할 수 있다. 주로 세 가지 방법을 사용한다.

  • --from-file: 파일로부터 값을 참조하여 생성한다.

  • --from-literal: 커맨드라인에서 직접 Key-Value 값을 전달하여 생성한다.

  • -f: YAML 형식의 매니페스트 파일을 작성하여 생성한다.

1) 파일에서 값 참조하여 생성 (--from-file)

설정 파일 전체를 ConfigMap 데이터로 저장하는 가장 일반적인 방법이다.

먼저, 예시로 사용할 nginx.conf 파일을 준비한다.

vi /etc/nginx/nginx.conf
vim /etc/nginx/nginx.conf
nano /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    include /etc/nginx/conf.d/*.conf
}

이제 nginx.conf 파일을 사용하여 sample-configmap이라는 이름의 ConfigMap을 생성한다. Key는 파일명인 nginx.conf가 되고, Value는 파일의 내용 전체가 된다.

kubectl create configmap sample-configmap --from-file=nginx.conf

생성된 ConfigMap은 getdescribe 명령어로 확인할 수 있다.

# YAML 형식으로 상세 정보 확인
kubectl get configmap sample-configmap -o yaml

# JSON 형식으로 상세 정보 확인
kubectl get configmap sample-configmap -o json

# 리소스의 요약 정보 확인
kubectl describe configmap sample-configmap

get -o json 명령의 결과는 아래와 같다. data 필드에 nginx.conf라는 키와 파일 내용이 값으로 저장된 것을 볼 수 있다.

{
    "apiVersion": "v1",
    "data": {
        "nginx.conf": "vi /etc/nginx/nginx.conf\nvim /etc/nginx/nginx.conf\nnano /etc/nginx/nginx.conf\n\nuser  nginx;\nworker_processes  1;\n\nerror_log  /var/log/nginx/error.log warn;\n\npid        /var/run/nginx.pid;\n\n\nevents {\n    worker_connections  1024;\n}\n\n\nhttp {\n    include       /etc/nginx/mime.types;\n    \n    default_type  application/octet-stream;\n\n    log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\n                      '$status $body_bytes_sent \"$http_referer\" '\n                      '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n    access_log  /var/log/nginx/access.log  main;\n\n    sendfile        on;\n    #tcp_nopush     on;\n\n    keepalive_timeout  65;\n\n    #gzip  on;\n    \n    include /etc/nginx/conf.d/*.conf\n}\n"
    },
    "kind": "ConfigMap",
    "metadata": {
        "creationTimestamp": "2025-07-09T06:31:18Z",
        "name": "sample-configmap",
        "namespace": "default",
        "resourceVersion": "182200",
        "uid": "79425d5c-4b3f-4aa6-b9de-5d406df92d71"
    }
}

2) 리터럴(값을 직접 입력)로 생성 (--from-literal)

간단한 Key-Value 쌍의 설정 데이터는 --from-literal 옵션을 사용하여 커맨드라인에서 직접 생성할 수 있다.

kubectl create configmap --save-config web-config \
--from-literal=connection.max=100 \
--from-literal=connection.min=10

--save-config 옵션은 kubectl apply와 같은 선언적 명령어로 리소스를 관리할 수 있도록 kubectl.kubernetes.io/last-applied-configuration 어노테이션을 추가하는 역할을 한다. (참고: 현재 예제에서는 create와 함께 사용되었으나, 주로 apply와 함께 사용된다.)

생성된 web-config ConfigMap을 확인한다.

kubectl get configmap web-config -o yaml

data 필드에 connection.maxconnection.min 키와 해당 값이 문자열 형태로 저장된 것을 확인할 수 있다.

apiVersion: v1
data:
  connection.max: "100"
  connection.min: "10"
kind: ConfigMap

3) 매니페스트 파일을 이용한 생성 (-f)

IaC(Infrastructure as Code) 관점에서 가장 권장되는 방식으로, YAML 파일에 리소스의 상태를 선언적으로 정의하여 생성한다. 이 방식은 설정 내용을 명확하게 문서화하고 버전 관리를 용이하게 한다.

아래와 같이 sample-configmap.yaml 파일을 작성한다. data 필드에 단일 값, 여러 줄로 된 설정 파일(| 사용), 셸 스크립트 등 다양한 형식의 데이터를 Key-Value 형태로 정의할 수 있다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-configmap
data:
  thread: "16"
  connection.max: "100"
  connection.min: "10"
  sample.properties: |
    property.1=value-1
    property.2=value-2
    property.3=value-3
  nginx.conf: |
    user nginx;
    worker_processes auto;
    pid /run/nginx.pid;
  test.sh: |
    #! /bin/bash
    echo "Hello Kubernetes"
    sleep infinity

작성한 매니페스트 파일을 kubectl apply 명령어로 클러스터에 적용한다.

kubectl apply -f sample-configmap.yaml

생성된 ConfigMap은 describe 명령어로 확인할 수 있다.

kubectl describe configmap sample-configmap

이렇게 생성된 ConfigMap들은 이제 Pod에서 환경 변수로 참조하거나, 볼륨으로 마운트하여 파일처럼 사용하는 단계를 거쳐 애플리케이션에 실제 설정 값을 전달하게 된다.


3. ConfigMap 사용

생성된 ConfigMap의 데이터는 Pod 내부에서 사용할 수 있도록 전달되어야 한다. 주요 방법은 두 가지가 있다.

  • 환경 변수로 전달: ConfigMap의 데이터를 컨테이너의 환경 변수로 주입한다.

  • 볼륨으로 마운트: ConfigMap의 데이터를 파일 형태로 컨테이너의 특정 경로에 마운트한다.

각 방법은 ConfigMap의 특정 키만을 선택적으로 전달하거나, 전체 키-값 쌍을 한 번에 전달할 수 있다.

1) 환경 변수로 전달

특정 키(Key)만 환경 변수로 전달
spec.containers[].env 필드 아래에 valueFrom.configMapKeyRef 를 사용하여 ConfigMap의 특정 키 값을 컨테이너의 환경 변수로 주입한다.

먼저, 이전에 생성한 sample-configmapconnection.max 키 값을 CONNECTION_MAX 라는 환경 변수로 사용하는 Pod 매니페스트를 작성한다.

# sample-configmap-single-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-single-env
spec:
  containers:
  - name: configmap-container
    image: nginx:1.27.0
    env:
    - name: CONNECTION_MAX  # 컨테이너 내에서 사용할 환경 변수 이름
      valueFrom:
        configMapKeyRef:
          name: sample-configmap  # 사용할 ConfigMap 이름
          key: connection.max      # 사용할 ConfigMap의 키

Pod을 생성하고, exec 명령어로 컨테이너 내부의 환경 변수를 확인한다.

# Pod 생성
kubectl apply -f sample-configmap-single-env.yaml

# 컨테이너 내부 환경 변수 확인
kubectl exec -it sample-configmap-single-env -- env

아래 출력 결과에서 CONNECTION_MAX=100 이 성공적으로 주입된 것을 확인할 수 있다.

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=sample-configmap-single-env
NGINX_VERSION=1.27.0
...
CONNECTION_MAX=100         # ConfigMap의 값이 환경 변수로 주입됨
KUBERNETES_SERVICE_PORT_HTTPS=443
...
HOME=/root

ConfigMap 전체 데이터를 환경 변수로 전달
spec.containers[].envFrom 필드와 configMapRef를 사용하면 ConfigMap에 있는 모든 키-값 쌍을 컨테이너의 환경 변수로 한 번에 주입할 수 있다. 이때 각 키가 환경 변수의 이름이 된다.

# sample-configmap-multi-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-multi-env
spec:
  containers:
  - name: configmap-container
    image: nginx:1.27.0
    envFrom:
    - configMapRef:
        name: sample-configmap # 사용할 ConfigMap 이름

Pod을 생성하고 환경 변수를 확인한다.

# Pod 생성
kubectl apply -f sample-configmap-multi-env.yaml

# 컨테이너 내부 환경 변수 확인
kubectl exec -it sample-configmap-multi-env -- env

sample-configmap 에 정의된 thread , connection.max , nginx.conf 등의 모든 키가 환경 변수로 설정된 것을 볼 수 있다.

...
nginx.conf=user nginx;
worker_processes auto;
pid /run/nginx.pid;

sample.properties=property.1=value-1
property.2=value-2
property.3=value-3

test.sh=#! /bin/bash
echo "Hello Kubernetes"
sleep infinity

thread=16
connection.max=100
connection.min=10
...

📌 환경 변수 사용 시 주의사항

  • 환경 변수로 사용할 데이터의 키(Key)에는 .이나 -가 포함되지 않도록 하는 것을 권장한다. 대부분의 셸에서 이러한 특수 문자를 변수명으로 사용할 수 없어 참조가 어렵기 때문이다.

  • 값(Value)에 YAML의 멀티라인 문법을 위한 :| 등이 포함된 경우, 환경 변수로 주입될 때 의도치 않은 줄 바꿈이나 문자로 처리될 수 있어 사용에 주의가 필요하다.

따라서 환경 변수로 ConfigMap을 사용할 때는 단순한 문자열 형태의 Key-Value 쌍을 사용하는 것이 가장 안정적이다.

2) 볼륨으로 마운트

nginx.conf와 같은 설정 파일이나 여러 줄로 구성된 스크립트는 환경 변수보다 파일 형태로 전달하는 것이 더 적합하다. 이때 ConfigMap을 볼륨으로 마운트하는 방식을 사용한다.

특정 키(Key)만 파일로 마운트
spec.volumesconfigMap을 정의하고, items 필드를 이용해 원하는 키만 특정 파일 이름으로 지정하여 마운트할 수 있다.

아래 예제는 sample-configmap 에 있는 nginx.conf 키의 데이터를 가져와 컨테이너 내부의 /config/production.conf 파일로 저장한다.

# sample-configmap-single-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-single-volume
spec:
  containers:
  - name: configmap-container
    image: nginx:1.27.0
    volumeMounts:
    - name: config-volume      # 마운트할 볼륨의 이름
      mountPath: /config        # 컨테이너 내부에 마운트할 경로
  volumes:
  - name: config-volume        # 볼륨의 이름 (volumeMounts의 name과 일치)
    configMap:
      name: sample-configmap  # 사용할 ConfigMap의 이름
      items:
      - key: nginx.conf       # 마운트할 데이터의 키
        path: production.conf # 마운트될 파일의 이름

Pod을 생성하고, 마운트된 파일의 내용을 확인한다.

# 리소스 생성
kubectl apply -f sample-configmap-single-volume.yaml

# 마운트된 파일 내용 확인
kubectl exec -it sample-configmap-single-volume -- cat /config/production.conf

ConfigMap 전체 데이터를 파일로 마운트

items 필드를 생략하면 ConfigMap에 있는 모든 키-값 쌍이 각각의 파일로 마운트된다. 이때 파일명은 ConfigMap의 키 이름과 동일하게 생성된다.

# sample-configmap-multi-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-multi-volume
spec:
  containers:
  - name: configmap-container
    image: nginx:1.27.0
    volumeMounts:
    - name: config-volume
      mountPath: /config
  volumes:
  - name: config-volume
    configMap:
      name: sample-configmap # `items` 없이 ConfigMap 전체를 지정

Pod을 생성하고 마운트된 디렉터리의 파일 목록을 확인한다.

# 리소스 생성
kubectl apply -f sample-configmap-multi-volume.yaml

# 마운트된 디렉터리 확인
kubectl exec -it sample-configmap-multi-volume -- ls /config

실행 결과, sample-configmap의 키였던 connection.max, connection.min, nginx.conf, sample.properties, test.sh, thread가 모두 파일 이름으로 생성된 것을 볼 수 있다.

[🚀] 자동 업데이트 기능

ConfigMap을 볼륨으로 마운트하는 방식의 가장 큰 장점 중 하나는 자동 업데이트이다.
원본 ConfigMap 리소스의 내용이 변경되면, 쿠버네티스는 기본적으로 약 60초 이내에 마운트된 파일의 내용을 자동으로 갱신한다. 이 기능 덕분에 Pod을 재시작하지 않고도 애플리케이션의 설정을 동적으로 변경할 수 있다.


동적 시크릿 업데이트

  • 볼륨 마운트를 사용한 시크릿에서는 일정기간마다(kubelet 의 Sync Loop 타이밍) kube apiserver로 변경을 확인하고 변경이 있을 경우 파일을 교체한다

  • Secret 생성을 위한 yaml 파일 작성

sample-db-auth.yaml

apiVersion: v1
kind: Secret
metadata:
  name: sample-db-auth
type: Opaque
stringData:
  username: admin
  password: rootpassword
kubectl apply -f sample-db-auth.yaml
kubectl get secret -o yaml
  • Secret을 파일로 저장해서 사용하기위한 리소스 파일을 생성
    sample-secret-multi-volume.yaml
# sample-secret-multi-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-secret-multi-volume
spec:
  containers:
  - name: secret-container
    image: nginx:1.16
    volumeMounts:
    - name: config-volume
      mountPath: /config
  volumes:
  - name: config-volume
    secret:
      secretName: sample-db-auth 

리소스 확인

kubectl apply -f sample-secret-multi-volume.yaml

kubectl exec -it sample-secret-multi-volume -- ls /config
> password  username

 kubectl exec -it sample-secret-multi-volume -- cat /config/username
> admin
 
kubectl exec -it sample-secret-multi-volume -- cat /config/password
> rootpassword

시크릿이 저장된 매니페스트 파일을 수정하고 다시 적용

# sample-db-auth.yaml
...
stringData:
  username: user00        # 변경
  password: rootpassword
kubectl apply -f sample-db-auth.yaml

1분 정도 후에 파드를 다시 확인(기본적으로 파드는 볼륨 마운트가 되어 있는 경우 그 내용을 1분마다 확인해서 변경된 내용이 있으면 다시 적용한다.)

kubectl exec -it sample-secret-multi-volume -- cat /config/username
> user00

0개의 댓글