본문 바로가기

Container/Kubernetes

[K8S] ConfigMap

ConfigMap: 컨테이너 구성 정보를 한 곳에 모아서 관리하는, 애플리케이션의 설정 데이터를 외부화하기 위해 사용되는 API 리소스

애플리케이션 코드와 환경별 설정 데이터를 분리할 수 있으며, 설정 변경 시 애플리케이션을 재배포하지 않아도 된다.

  1. 설정 분리: 환경별로 다른 설정 데이터를 외부화하여 ConfigMap에 저장하여 코드와 설정을 분리.
  2. Key-Value 형태
  3. 다양한 데이터 소스 지원: YAML/JSON 파일, 명령어 출력, 문자열 데이터 등.
  4. 동적인 재구성 가능: ConfigMap을 변경하면 애플리케이션이 즉시 새로운 값을 읽도록 구성 가능. (변경 용이성)
  5. 다양한 사용 방법: 환경 변수, 커맨드라인 인수, 볼륨 마운트를 통해 애플리케이션에 설정 데이터 제공
  6. 주의사항
    1. 데이터 크기 제한: ConfigMap의 데이터 크기는 1MB로 제한
    2. ConfigMap은 민감한 데이터를 저장하는 데 적합하지 않으며, 이를 위해 Secret을 사용해야 함
    3. 애플리케이션이 ConfigMap의 변화를 동적으로 감지하도록 설계 필요
    4. ConfigMap이 삭제되면 이를 참조하는 Pod이 예상치 못한 동작을 할 수 있음
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  APP_ENV: production
  APP_DEBUG: "false"

 

  • configMap 생성하기
# kubectl create configmap [이름]
$ kubectl create configmap NAME [--from-file=source] [--from-literal=key1=value1]
# value는 1MiB를 초과할 수는 없다.

$ kubectl create configmap my-config --from-file=config.properties
$ kubectl create configmap webapp-config-map --from-literal=APP_COLOR=darkblue --from-literal=APP_OTHER=disregard
  • configMap 조회
$ kubectl get configmap
NAME               DATA   AGE
db-config          3      5s
kube-root-ca.crt   1      19m
$ kubectl describe configmap db-config
Name:         db-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
DB_HOST:
----
SQL01.example.com

DB_NAME:
----
SQL01

DB_PORT:
----
3306


BinaryData
====

Events:  <none>
  • configMap 수정
# YAML 파일로 내보내기
$ kubectl get configmap my-config -o yaml > my-config.yaml

$ kubectl apply -f my-config.yaml
$ kubectl describe cm webapp-config-map 
Name:         webapp-config-map
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
APP_COLOR:
----
darkblue

APP_OTHER:
----
disregard


BinaryData
====

Events:  <none>

$  kubectl edit pod webapp-color

$ kubectl replace --force -f /tmp/kubectl-edit-3910849657.yaml 
pod "webapp-color" deleted
pod/webapp-color replaced

$ kubectl describe pod webapp-color
... # 변경된 것 확인
  Environment Variables from:
      webapp-config-map  ConfigMap  Optional: false
  • configMap 삭제
$ kubectl delete configmap my-config

ConfigMap과 Secret의 차이점

  ConfigMap Secret
주요 목적 애플리케이션 설정 데이터 저장 민감한 데이터(비밀번호, 인증 키 등) 저장
데이터 형식 일반 텍스트 Base64로 인코딩된 데이터
보안 일반 텍스트로 저장 Kubernetes Secret으로 보호
암호화 필요성 선택적 민감 데이터로 암호화 권장
# 실제 nginx의 구성파일
[master ~/configMap/config.dir]$ls -al
total 12
drwxr-xr-x 2 soyun3963 soyun3963 4096 Mar  7 15:11 .
drwxr-xr-x 4 soyun3963 soyun3963 4096 Mar  7 15:11 ..
-rw-r--r-- 1 soyun3963 soyun3963  218 Mar  7 15:11 nginx-config.conf
[master ~/configMap/config.dir]$cat nginx-config.conf 
server {
    listen   80;
    server_name  www.example.com;

    gzip on;
    gzip_types text/plain application/xml;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

[master ~/configMap]$kubectl create configmap soyun-config --from-literal=INTERVAL=2 --from-literal=OPTION=boy --from-file=config.dir/
configmap/soyun-config created
[master ~/configMap]$kubectl get configmap soyun-config
NAME           DATA   AGE
soyun-config   3      19s
[master ~/configMap]$kubectl describe configmap soyun-config
Name:         soyun-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
INTERVAL:
----
2
OPTION:
----
boy
nginx-config.conf:
----
server {
    listen   80;
    server_name  www.example.com;

    gzip on;
    gzip_types text/plain application/xml;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}


BinaryData
====

Events:  <none>

# edit 명령 통해 수정 가능
[master ~/configMap]$kubectl edit configmaps soyun-config

 

# ConfigMap의 일부분 적용하기

  • 생성한 ConfigMap의 Key를 Pod의 컨테이너에 적용
# rig
# 실행할 때마다 랜덤한 fakeID를 생성해줌 (별도 설치 필요)
[master ~/configMap]$sudo apt-get install -y rig
[master ~/configMap]$sudo apt-get install -y boxes
[master ~/configMap]$rig | boxes
/************************/
/* Freeman Lyons        */
/* 688 Genesse Blvd     */
/* Vancouver, WA  98661 */
/* (206) xxx-xxxx       */
/************************/
[master ~/configMap]$rig | boxes -d boy
        .-"""-.
       / .===. \
       \/ 6 6 \/
       ( \___/ )
  _ooo__\_____/______
 /                   \
| Georgia Snyder      |
| 404 Lemoyer Blvd    |
| Kinston, NC  28501  |
| (919) xxx-xxxx      |
 \_______________ooo_/
        |  |  |
        |_ | _|
        |  |  |
        |__|__|
        /-'Y'-\
       (__/ \__)
[master ~/configMap]$rig | boxes -d stone
+---------------------+
| Oliver Newton       |
| 812 Midland St      |
| Richmond, VA  23232 |
| (804) xxx-xxxx      |
+---------------------+
[master ~/configMap]$rig | boxes
/************************/
/* Freeman Lyons        */
/* 688 Genesse Blvd     */
/* Vancouver, WA  98661 */
/* (206) xxx-xxxx       */
/************************/
[master ~/configMap]$rig | boxes -d boy
        .-"""-.
       / .===. \
       \/ 6 6 \/
       ( \___/ )
  _ooo__\_____/______
 /                   \
| Georgia Snyder      |
| 404 Lemoyer Blvd    |
| Kinston, NC  28501  |
| (919) xxx-xxxx      |
 \_______________ooo_/
        |  |  |
        |_ | _|
        |  |  |
        |__|__|
        /-'Y'-\
       (__/ \__)
[master ~/configMap]$rig | boxes -d stone
+---------------------+
| Oliver Newton       |
| 812 Midland St      |
| Richmond, VA  23232 |
| (804) xxx-xxxx      |
+---------------------+

 

[master ~/configMap/build]$cat Dockerfile 
FROM ubuntu:18.04
RUN apt-get update ; apt-get -y install rig boxes
ENV INTERVAL 5
ENV OPTION stone
ADD genid.sh /bin/genid.sh
RUN chmod +x /bin/genid.sh
ENTRYPOINT ["/bin/genid.sh"]

[master ~/configMap/build]$cat genid.sh 
#!/bin/bash
mkdir -p /webdata
while true
do
  /usr/bin/rig | /usr/bin/boxes -d $OPTION  > /webdata/index.html
  sleep $INTERVAL
done

[master ~/configMap]$cat genid.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: genid-stone
spec:
  containers:
  - image: smlinux/genid:env
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: soyun-config
          key: INTERVAL 
    name: fakeid
    volumeMounts:
    - name: html
      mountPath: /webdata
  - image: nginx:1.14
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
  volumes:
  - name: html
    emptyDir: {}

[master ~/configMap]$kubectl apply -f genid.yaml 
pod/genid-stone configured

[master ~/configMap]$kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
genid-stone   2/2     Running   0          91s   10.36.0.1   node2.example.com   <none>           <none>

[master ~/configMap]$ curl 10.36.0.1
+-----------------------+
| Melva Moreno          |
| 603 North Hampton St  |
| Burlington, NC  27215 |
| (919) xxx-xxxx        |
+-----------------------+
[master ~/configMap]$ curl 10.36.0.1 # 값 2초마다 바뀌는 것 확인가능
+---------------------+
| Milo Bailey         |
| 422 Cedarwood Ln    |
| Richmond, VA  23232 |
| (804) xxx-xxxx      |
+---------------------+

 

  • 환경변수로 설정데이터 전달
    • ConfigMap의 전체 key를 Pod의 컨테이너에 적용
envFrom:
- configMapRef:
     name: ttabae-config
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      env:
        - name: APP_ENV
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: APP_ENV  # ConfigMap의 APP_ENV 키 값을 환경 변수로 전달
[master ~/configMap]$cat genid-whole.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: genid-boy
spec:
  containers:
  - image: smlinux/genid:env
    envFrom:
    - configMapRef:
        name: soyun-config
    name: fakeid
    volumeMounts:
    - name: html
      mountPath: /webdata
  - image: nginx:1.14
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
  volumes:
  - name: html
    emptyDir: {}
    
[master ~/configMap]$kubectl create -f genid-whole.yaml 
pod/genid-boy created
[master ~/configMap]$kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
genid-boy   2/2     Running   0          57s   10.44.0.1   node1.example.com   <none>           <none>

[master ~/configMap]$kubectl exec genid-boy -- env
Defaulted container "fakeid" out of: fakeid, web-server
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=genid-boy
INTERVAL=2
OPTION=boy
nginx-config.conf=server {
    listen   80;
    server_name  www.example.com;

    gzip on;
    gzip_types text/plain application/xml;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
HOME=/root

[master ~/configMap]$curl 10.44.0.1 #  boy가 적용된 값 확인
          .-"""-.
         / .===. \
         \/ 6 6 \/
         ( \___/ )
  ___ooo__\_____/________
 /                       \
| Danial Wilkins          |
| 102 Pleasant View Dr    |
| Indianapolis, IN  46206 |
| (317) xxx-xxxx          |
 \_________________ooo___/
          |  |  |
          |_ | _|
          |  |  |
          |__|__|
          /-'Y'-\
         (__/ \__)

 

# ConfigMap을 볼륨으로 적용하기

- 생성한 ConfigMap의 key를 pod의 컨테이너에 볼륨 마운트하기

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: my-config
[master ~/configMap]$cat genid-volume.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: genid-volume
spec:
  containers:
  - image: smlinux/genid:env
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: soyun-config
          key: INTERVAL
    name: fakeid-generator
    volumeMounts:
    - name: html
      mountPath: /webdata
  - image: nginx:1.14
    name: web-server
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: soyun-config
      items:
      - key: nginx-config.conf
        path: nginx-config.conf
        
[master ~/configMap]$kubectl create -f genid-volume.yaml
pod/genid-volume created

 # 실제 마운트된 상태 확인
[master ~/configMap]$kubectl exec -it genid-volume -c web-server -- /bin/bash
root@genid-volume:/# cd /etc/enginx/conf.d/
root@genid-volume:/etc/nginx/conf.d# ls -l
total 0
lrwxrwxrwx 1 root root 24 Mar 24 14:38 nginx-config.conf -> ..data/nginx-config.conf
# nginx-config.conf 파일 존재하는 것 확인
# symbolic link로 volume mount되어있음.
반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] TLS  (0) 2025.01.10
[K8S] Encrypting Secret Data at Rest  (0) 2025.01.08
[K8S] Rollout  (0) 2025.01.08
[K8S] Static Pods  (0) 2025.01.07
[K8S] Endpoints  (0) 2025.01.02