파드에 환경변수를 전달하는 Configmap

Created
April 4, 2022
Created by
D
DaEun Kim
Tags
Kubernetes
Property

컨피그맵(configmap)은 일반적인 설정값을 담아 저장할 수 있는 오브젝트다.

네임스페이스에 속하기 때문에 네임스페이스 별로 컨피그맵이 존재한다.

Configmap 생성하는 방법

  • kubectl create configmap <컨피그맵 이름> -—from-literal key=value
  • kubectl create configmap <컨피그맵 이름> -—from-file key=<파일경로> 또는 <파일경로>
  • kubectl create configmap <컨피그맵 이름> -—from-env-file <env 파일경로>
  • kubectl create configmap <컨피그맵 이름> -—from-literal key=value —dry-run -o yaml

컨피그맵을 파드에서 사용하는 방법

  • 컨피그맵 값을 컨테이너 환경변수로 사용
  • 컨피그맵 값을 파드 내부 파일로 마운트해서 사용

1. —from-literal

컨피그맵은 kubectl 으로 생성할 수 있다. —-from-literal 옵션으로 설정값을 여러 개 정의할 수 있다.

$ kubectl create configmap basic-configmap \
--from-literal ENV=dev \
--from-literal LOG_LEVEL=DEBUG
$ ku get cm
NAME               DATA   AGE
basic-configmap    2      3s
kube-root-ca.crt   1      35s

생성한 컨피그맵은 YAML 형식으로 조회할 수 있다.

$ ku get cm basic-configmap -o yaml
apiVersion: v1
data:
  ENV: dev
  LOG_LEVEL: DEBUG
kind: ConfigMap
metadata:
  creationTimestamp: "2022-04-04T11:57:15Z"
  name: basic-configmap
  namespace: default
  resourceVersion: "4059654"
  uid: 855d8b36-5490-4086-b711-b162e00c0f45

컨피그맵 값을 컨테이너 환경변수로 사용하기

컨피그맵에 저장된 key-value 가 컨테이너의 환경변수 key-value 로 그대로 사용되기 때문에 컨테이너 쉘에서 $ echo LOG_LEVEL 으로 확인 가능하다. 애플리케이션이 시스템 환경변수에서 설정값을 가져오면 이 방법을 사용하면 된다.

1-a. envFrom

apiVersion: v1
kind: Pod
metadata:
  name: env-from-sysvar
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      envFrom:
        - configMapRef:
            name: basic-configmap  # LOG_LEVEL=DEBUG, ENV=dev 
        - configMapRef:
            name: special-configmap  # container=docker

basic-configmap, special-configmap 두 개의 컨피그맵으로부터 key-value 를 가져와 환경변수를 생성하도록 했다.

envFrom 은 하나의 컨피그맵에 다수의 key-value 가 존재하더라도 모두 환경변수로 가져오도록 한다. 따라서 위에서 env-from-sysvar 파드는 LOG_LEVEL, ENV, container 3개 환경변수에 접근할 수 있다.

$ kubectl exec [POD] —- env 명령어로 파드 컨테이너의 환경변수를 조회해본다.

image

KUBERNETES_ 으로 시작하는 환경변수들도 있는데, 이는 쿠버네티스가 자동으로 디폴트 네임스페이스에 존재하는 kubernetes 라는 서비스에 대한 접근 정보를 컨테이너 환경변수로 설정했기 때문이다.

1-b. valueFrom

apiVersion: v1
kind: Pod
metadata:
  name: value-from-sysvar
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      env:
        - name: ENV_KEYNAME_1        # 가져온 값으로 설정될 컨테이너 내 환경변수 이름
          valueFrom:
            configMapKeyRef:
              name: basic-configmap  # 참조할 컨피그맵 이름
              key: LOG_LEVEL         # 가져올 값의 키
        - name: ENV_KEYNAME_2     
          valueFrom:
            configMapKeyRef:
              name: special-configmap
              key: container

valueFrom 을 사용하면 컨피그맵 내에 특정 key-value 를 선택해서 파드에서 사용할 키 이름을 바꿀 수 있다.

image

basic-configmap 에 있는 LOG_LEVEL=DEBUG 키/값의 값이 컨테이너에서는 ENV_KEYNAME_1 이라는 키의 환경변수로 들어갔고, spcial-configmap 에 있는 container=docker 키/값의 값이 ENV_KEYNAME_2 라는 키의 환경변수로 들어갔다.

2. —from-file

컨피그맵 값을 파드 내부 파일로 마운트해서 사용하기

컨피그맵의 키/값을 컨테이너 내에 특정 위치에 파일로 마운트한다.

apiVersion: v1
kind: Pod
metadata:
  name: env-from-volume
spec:
  volumes:
    - name: v-cm-basic           # 컨피그맵 볼륨
      configMap:
        name: basic-configmap    # 키/값을 가져올 컨피그맵 이름
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      volumeMounts:
        - name: v-cm-basic       # volumes 에서 정의한 컨피그맵 볼륨 이름
          mountPath: /etc/config # 마운트 된 컨피그맵 경로

containers[].volumeMounts[].mountPath 위치에 각 키/값이 키 이름으로 된 파일로 마운트 된 것을 확인할 수 있다.

image

위 방법으로 nginx.conf, mysql.cnf 과 같은 파일을 통째로 컨피그맵에 저장한 뒤 볼륨 파드 내부에 제공할 수 있다. --from-file 옵션을 사용하면 컨피그맵 값을 파일로 생성할 수 있다. 키 이름은 디폴트로 파일 이름으로 만들어진다.

$ ku create configmap index-file --from-file index.html
image

키 이름을 직접 지정하고 싶으면 아래와 같이 한다. (custom-key 라는 키로 컨피그맵 생성)

$ ku create configmap index-file --from-file custom-key=index.html

nginx.conf.template 파일을 컨피그맵으로 만들어서 nginx 파드에 마운트하기

nginx.conf.template 파일을 아래와 같이 만들었다.

ubuntu@ip-10-220-12-225:~/k8s-practice$ cat nginx.conf.template
user nginx;
worker_processes auto;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

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

    error_log  /var/log/nginx/error.log warn;
    access_log /var/log/nginx/access.log main;

    server {
        listen 80 default_server;
        location / {
            proxy_pass http://${APP_ADDRESS};
        }
    }
}

템플릿 파일로 nginx-configmap 이라는 이름의 컨피그맵을 생성한다. (키 이름을 따로 지정하지 않았으므로 파일이름이 키 이름이 된다.)

ubuntu@ip-10-220-12-225:~/k8s-practice$ ku create configmap nginx-configmap --from-file nginx.conf.template
configmap/nginx-configmap created
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku describe cm nginx-configmap
Name:         nginx-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf.template:
----
user nginx;
worker_processes auto;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

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

    error_log  /var/log/nginx/error.log warn;
    access_log /var/log/nginx/access.log main;

    server {
        listen 80 default_server;
        location / {
            proxy_pass http://${APP_ADDRESS};
        }
    }
}



BinaryData
====

Events:  <none>

위에서 만든 컨피그맵을 볼륨에 마운트하는 파드를 생성한다.

apiVersion: v1
kind: Pod
metadata:
  name: conf-from-file
spec:
  volumes:
    - name: nginx-conf-vol        # 컨피그맵 볼륨
      configMap:
        name: nginx-configmap     # 파드 볼륨에 마운트 시킬 nginx 컨피그맵
  containers:
    - name: my-container
      image: nginx:latest
      volumeMounts:
        - name: nginx-conf-vol                       # 위에서 정의한 볼륨 이름
          mountPath: /etc/nginx/nginx.conf.template  # 컨피그맵을 마운트 시킬 경로
          subPath: nginx.conf.template               # 이미지 빌드할 때 이미 생성된 디렉토리 (/etc/nginx) 에 단일 파일을 마운트하려면 subPath 를 설정한다.

conf-from-file 이라는 파드 내부에 /etc/nginx/nginx.conf.template 위치에 템플릿 파일이 마운트 된 것을 확인할 수 있다.

한 가지 주의할 점: 컨피그맵을 subPath 볼륨 마운트로 사용하는 컨테이너는 컨피그맵 업데이트를 수신하지 않는다.

image

3. —from-env-file

—-from-env-file 옵션으로 여러 개의 키/값 형태의 내용으로 구성된 설정 파일을 한꺼번에 컨피그맵으로 가져올 수 있다.

ubuntu@ip-10-220-12-225:~/k8s-practice$ cat multiple.env
KEY1=VALUE1
KEY2=VALUE2
KEY3=VALUE3
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku create cm mutiple-key-value-configmap --from-env-file multiple.env
configmap/mutiple-key-value-configmap created
image

4. —from-<env-file/file/literal> —dry-run -o yaml

컨피그맵을 반드시 명령어를 통해 생성해야 하는 것은 아니다. —dry-run-o yaml 옵션을 사용하면 YAML 파일로 뽑을 수 있다.

참고로 apply, create 같은 명령어에 —dry-run=client 옵션을 주면 리소스는 생성하지 않으면서 실행 가능 여부를 확인할 수 있다.

ubuntu@ip-10-220-12-225:~/k8s-practice$ ku create configmap cm-to-file --from-literal KEY1=VALUE1 --dry-run=client -o yaml > configmap.yaml
ubuntu@ip-10-220-12-225:~/k8s-practice$ cat configmap.yaml
apiVersion: v1
data:
  KEY1: VALUE1
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: cm-to-file
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku apply -f configmap.yaml
configmap/cm-to-file created
ubuntu@ip-10-220-12-225:~/k8s-practice$ ku describe cm cm-to-file
Name:         cm-to-file
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
KEY1:
----
VALUE1

BinaryData
====

Events:  <none>

참고자료