쿠버네티스 교육

12. Kube 교육 - ConfigMap

Jerry_이정훈 2021. 6. 4. 16:38
728x90

실습

  • Application 설정 파일(nginx.conf) ConfigMap 사용
    : ConfigMap subpath 이용 
  • NGINX 설정 파일 변경 후 POD 적용

Why ConfigMap?

Kube 환경에서 Application 설정 파일(nginx.conf)을 별도로 관리하지 않고 이미지 안에 같이 저장하면 향후 관리가 어렵습니다. 설정 파일 내용을 확인하기 위하여 POD 접속해야 하고 설정 파일만 변경 하려면 이미지를 다시 말고 재배포 해야 하는 등 부가적인 작업이 필요 합니다.

 

설정 파일을 ConfigMap(설정 내역 정도로 번역)으로 관리하면 별도의 Kube Object가 되어 조회(k describe cm)가 용이하고 변경 시 이미지를 다시 배포하는 것이 아니라 ConfigMap(CM이라고도 합니다.)만 수정하고 기존 실행 중인 POD를 내렸다 올리면 변경 사항이 Application에 반영이 되어 관리가 용이 합니다. 

그럼 실습으로 알아 보겠습니다.

 

NGINX Helm 설치

NGINX 설치는 기존과 동일하여 자세한 설명은 생략하겠습니다. (ConfigMap만 참조하시려면 아래 NGINX 설치 부문은 생략하셔도 됩니다.)

[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ helm pull bitnami/nginx

[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ ls -lrt
total 56
drwxr-xr-x 5 spkr spkr  4096 Feb 24 09:29 nginx
-rw-r--r-- 1 spkr spkr 34379 May 28 08:46 nginx-8.9.1.tgz

[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ tar xvfz nginx-8.9.1.tgz 
nginx/Chart.yaml
nginx/Chart.lock
(이하 생략)


[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ ls -lrt
total 60
drwxr-xr-x 5 spkr spkr  4096 Feb 24 09:29 nginx-7.1.5
-rw-r--r-- 1 spkr spkr 34379 May 28 08:46 nginx-8.9.1.tgz
drwxr-xr-x 5 spkr spkr  4096 May 28 08:47 nginx

[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ mv nginx nginx-8.9.1
[spkr@erdia22 41.NGINX (dzbumin:prometheus)]$ cd nginx-8.9.1/

[spkr@erdia22 nginx-8.9.1 (dzbumin:prometheus)]$ ls -lrt
total 92
-rw-r--r-- 1 spkr spkr 22324 May 23 17:56 values.yaml
(생략)


[spkr@erdia22 nginx-8.9.1 (dzbumin:prometheus)]$ cp values.yaml my-values.yml

NGINX Helm Chart는 크게 변경할 부문이 없어서 values.yml default로 사용하셔도 되는데 상황에 따라 몇가지 사항만 변경해 주시면 됩니다. 

values.yml 전체 파일은 아래 gist 파일로 공유해 드립니다.

https://gist.github.com/junghoon2/20d70ab17c564a26aeee945735d3628a

 

nginx-helm-values.yml

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

그럼, 설치를 시작합니다.

[spkr@erdia22 nginx-8.9.1 (spkn02:nginx)]$ helm install nginx -f my-values.yml .
NAME: nginx
LAST DEPLOYED: Fri May 28 08:55:02 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **

NGINX can be accessed through the following DNS name from within your cluster:

    nginx.nginx.svc.cluster.local (port 80)

To access NGINX from outside the cluster, follow the steps below:

1. Get the NGINX URL by running these commands:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace nginx -w nginx'

    export SERVICE_PORT=$(kubectl get --namespace nginx -o jsonpath="{.spec.ports[0].port}" services nginx)
    export SERVICE_IP=$(kubectl get svc --namespace nginx nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo "http://${SERVICE_IP}:${SERVICE_PORT}"

(에러가 발생하지 않으면 정상적으로 POD 확인이 가능합니다.)

C[spkr@erdia22 ~ (spkn01:nginx)]$ kgp
NAME                                READY   STATUS        RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
nginx-88d877b47-bkmzz               2/2     Running       0          84s   10.233.92.46    node3   <none>           <none>
nginx-88d877b47-qgfmc               2/2     Running       0          84s   10.233.92.45    node3   <none>           <none>
nginx-88d877b47-zzh2p               2/2     Running       0          84s   10.233.90.190   node1   <none>           <none>

ConfigMap 수정

NGINX Application 중 nginx.conf 설정 파일만 분리하여 ConfigMap으로 별도 관리하겠습니다.

(불편하게 Bitnami NGINX Helm Chart는 nginx.conf 파일이 기본 설정에서는 ConfigMap으로 분리되지 않았습니다. 하지만, Redis, MySQL 등 다른 Application Helm Chart는 기본으로 설정 파일을 ConfigMap으로 분리되어 있는 경우가 많습니다. )

 

먼저, bitnami nginx application의 nginx.conf를 로컬 PC로 CP 합니다. (컨테이너 안의 특정 파일을 로컬 PC로 copy 시 kubectl cp 명령어 사용 합니다.) 

[spkr@erdia22 nginx-8.9.1 (k3s:nginx)]$ kgp
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE                    NOMINATED NODE   READINESS GATES
svclb-nginx-bthv2        0/2     Pending   0          99s   <none>        <none>                  <none>           <none>
nginx-65947c668c-pfq62   2/2     Running   1          99s   10.42.0.137   localhost.localdomain   <none>           <none>
nginx-65947c668c-bwjdd   2/2     Running   1          99s   10.42.0.136   localhost.localdomain   <none>           <none>

NGINX POD로 접속합니다.
[spkr@erdia22 nginx-8.9.1 (k3s:nginx)]$ k exec -it nginx-65947c668c-pfq62 -- bash
Defaulting container name to nginx.
Use 'kubectl describe pod/nginx-65947c668c-pfq62 -n nginx' to see all of the containers in this pod.

BITNAMI NGINX 이미지의 NGINX.CONF 파일 위치는 /opt/bitnami/nginx/conf 입니다.
I have no name!@nginx-65947c668c-pfq62:/$ cd /opt/bitnami/nginx/conf/
I have no name!@nginx-65947c668c-pfq62:/opt/bitnami/nginx/conf$
I have no name!@nginx-65947c668c-pfq62:/opt/bitnami/nginx/conf$ ls
bitnami       fastcgi.conf.default  fastcgi_params.default  koi-win     mime.types.default  nginx.conf.default  scgi_params.default  uwsgi_params          win-utf
fastcgi.conf  fastcgi_params        koi-utf                 mime.types  nginx.conf          scgi_params         server_blocks        uwsgi_params.default

nginx.conf 파일 위치를 확인하고 kubectl cp 명령어로 로컬 PC로 복사 합니다.
[spkr@erdia22 ~ (spkn01:nginx)]$ k cp nginx-88d877b47-bkmzz:/opt/bitnami/nginx/conf/nginx.conf nginx.conf
Defaulting container name to nginx.
tar: Removing leading `/' from member names

해당 nginx.conf 기준으로 ConfigMap 파일을 만듭니다. 아래 CM YAML에 nginx.conf 파일 본문을 그대로 붙여넣기 합니다. 이 때 VSCode 들여쓰기 단축키 ctrl + ] 사용 하시면 작업 시간이 줄어 듭니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf-cm
  namespace: nginx
data:
  nginx.conf: |
    # Based on https://www.nginx.com/resources/wiki/start/topics/examples/full/#nginx-conf
    # user              www www;  ## Default: nobody

    worker_processes  auto;
    error_log         "/opt/bitnami/nginx/logs/error.log";
    pid               "/opt/bitnami/nginx/tmp/nginx.pid";

    events {
        worker_connections  2048;
    }

    http {
        include       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    "/opt/bitnami/nginx/logs/access.log";
        add_header    X-Frame-Options SAMEORIGIN;

        client_body_temp_path  "/opt/bitnami/nginx/tmp/client_body" 1 2;
        proxy_temp_path        "/opt/bitnami/nginx/tmp/proxy" 1 2;
        fastcgi_temp_path      "/opt/bitnami/nginx/tmp/fastcgi" 1 2;
        scgi_temp_path         "/opt/bitnami/nginx/tmp/scgi" 1 2;
        uwsgi_temp_path        "/opt/bitnami/nginx/tmp/uwsgi" 1 2;

        sendfile           on;
        tcp_nopush         on;
        tcp_nodelay        off;
        gzip               on;
        gzip_http_version  1.0;
        gzip_comp_level    2;
        gzip_proxied       any;
        gzip_types         text/plain text/css application/javascript text/xml application/xml+rss;
        keepalive_timeout  65;
        ssl_protocols      TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers        HIGH:!aNULL:!MD5;
        client_max_body_size 80M;
        server_tokens off;

        include  "/opt/bitnami/nginx/conf/server_blocks/*.conf";

        # HTTP Server
        server {
            # Port to listen on, can also be set in IP:PORT format
            listen  8080;

            include  "/opt/bitnami/nginx/conf/bitnami/*.conf";

            location /status {
                stub_status on;
                access_log   off;
                allow 127.0.0.1;
                deny all;
            }
        }
    }

편의상 예제 파일로 worker_connections Parameter만 1024 -> 2048로 변경 하였습니다. 

 

ConfigMap Object 생성합니다. 

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k apply -f nginx-nginxconf-cm.yml 
configmap/nginx-conf-cm created
[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k get cm
NAME                 DATA   AGE
nginx-conf-cm        1      2s
nginx-server-block   1      17h

ConfigMap이 정상적으로 생성되었으니 다음으로 해당 CM을 Deployment YAML 파일에 추가 합니다. Deployment YAML 파일 수정이 필요하니 현재 실행 내역을 YAML File로 export 합니다. 

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k get deploy nginx -o yaml |k neat > nginx-deploy.yml

nginx-deploy.yml 파일을 수정합니다. 

(생략)
        volumeMounts:
        - mountPath: /opt/bitnami/nginx/conf/server_blocks
          name: nginx-server-block-paths
        - mountPath: /opt/bitnami/nginx/conf/nginx.conf
          name: nginx-cm
          subPath: nginx.conf

(생략)
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: server-blocks-paths.conf
            path: server-blocks-paths.conf
          name: nginx-server-block
        name: nginx-server-block-paths
      - configMap:
          name: nginx-conf-cm # ConfigMap 이름
        name: nginx-cm # volumeMounts 참조 이름

전체 파일은 아래 링크에서 확인 가능합니다.

https://gist.github.com/junghoon2/460027d1ffdc2d523f21a0586885c444

 

nginx-cm-deploy.yml

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

Deployment YAML 파일 중간 부문의 volumeMounts 와 가장 아래 부문 volumes에 위 내역을 추가합니다. ConfigMap은 volumeMounts (.spec.containers[].volumeMounts[]) 와  volumes(.spec.volumes[].configMap.name) 부문에 추가합니다.

 

volumeMounts.mountPath 부문에 POD 내 디렉토리 경로를 지정하고 subPath에 해당 파일 이름을 한번 더 명시합니다. (하나의 configMap object에 여러 설정 file을 사용하기 위해서 subPath 사용합니다.)

 

변경된 nginx-deploy.yml 파일을 적용(apply -f)하면 기존 pod들이 terminating 되고 새로운 pod가 생성됩니다. 

[spkr@erdia22 nginx-8.9.1 (k3s:nginx)]$ k apply -f nginx-deploy.yml 
Warning: resource deployments/nginx is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
deployment.apps/nginx configured

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ kgpw
NAME                     READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
(생략)
nginx-88d877b47-qgfmc    2/2     Terminating   0          18h   10.233.92.45    node3   <none>           <none>
nginx-76fd89b497-pj6c7   0/2     Pending       0          0s    <none>          <none>   <none>           <none>
nginx-76fd89b497-pj6c7   0/2     Pending       0          0s    <none>          node3    <none>           <none>
nginx-76fd89b497-pj6c7   0/2     ContainerCreating   0          0s    <none>          node3    <none>           <none>
nginx-88d877b47-qgfmc    2/2     Terminating         0          18h   10.233.92.45    node3    <none>           <none>
nginx-88d877b47-qgfmc    0/2     Terminating         0          18h   10.233.92.45    node3    <none>           <none>
nginx-76fd89b497-pj6c7   0/2     ContainerCreating   0          2s    <none>          node3    <none>           <none>
nginx-76fd89b497-pj6c7   0/2     Running             0          6s    10.233.92.47    node3    <none>           <none>

nginx pod를 확인하면 변경된 parameter 파일(worker_connections  1024 -> 2048)을 확인 할 수 있습니다.

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k exec -it nginx-76fd89b497-7x624 -- cat /opt/bitnami/nginx/conf/nginx.conf
Defaulting container name to nginx.
Use 'kubectl describe pod/nginx-76fd89b497-7x624 -n nginx' to see all of the containers in this pod.
# Based on https://www.nginx.com/resources/wiki/start/topics/examples/full/#nginx-conf
# user              www www;  ## Default: nobody

worker_processes  auto;
error_log         "/opt/bitnami/nginx/logs/error.log";
pid               "/opt/bitnami/nginx/tmp/nginx.pid";

events {
    worker_connections  2048;
}
(이하 생략)

ConfigMap 수정

만약 worker_connections 2048 -> 4096 으로 변경하시려면 먼저, ConfigMap 파일 수정하시고 POD를 재시작하면 재시작된 POD만 변경된 Parameter(4096)가 적용됩니다. 

 

ConfigMap worker_connections 설정을 수정합니다.

수정된 내용을 적용 합니다.

[spkr@erdia22 nginx-8.9.1 (k3s:nginx)]$ ka nginx-nginxconf-cm.yml 
configmap/nginx-conf-cm configured

 

(ConfigMap 설정을 변경하여도 POD에 자동 적용되지 않고 수동으로 재시작 해야 변경된 내역이 적용됩니다.)

 

아래  nginx-76fd89b497-72wct POD 삭제 합니다.

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ kgp
NAME                     READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
nginx-76fd89b497-72wct   2/2     Running   0          8m7s    10.233.90.192   node1   <none>           <none>
nginx-76fd89b497-7x624   2/2     Running   0          3m38s   10.233.92.49    node3   <none>           <none>
nginx-76fd89b497-pj6c7   2/2     Running   0          7m50s   10.233.92.47    node3   <none>           <none>
[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k delete pod nginx-76fd89b497-72wct 
pod "nginx-76fd89b497-72wct" deleted

POD (nginx-76fd89b497-vmwhm)  새롭게 생성되었습니다. nginx.conf 파일을 확인하면 옵션이 수정된 걸 확인 가능합니다. 

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ kgp
NAME                     READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
nginx-76fd89b497-7x624   2/2     Running   0          4m3s    10.233.92.49    node3   <none>           <none>
nginx-76fd89b497-pj6c7   2/2     Running   0          8m15s   10.233.92.47    node3   <none>           <none>
nginx-76fd89b497-vmwhm   2/2     Running   0          19s     10.233.90.193   node1   <none>           <none>

[spkr@erdia22 nginx-8.9.1 (spkn01:nginx)]$ k exec -it nginx-76fd89b497-vmwhm -- cat /opt/bitnami/nginx/conf/nginx.conf
Defaulting container name to nginx.
Use 'kubectl describe pod/nginx-76fd89b497-vmwhm -n nginx' to see all of the containers in this pod.
# Based on https://www.nginx.com/resources/wiki/start/topics/examples/full/#nginx-conf
# user              www www;  ## Default: nobody

worker_processes  auto;
error_log         "/opt/bitnami/nginx/logs/error.log";
pid               "/opt/bitnami/nginx/tmp/nginx.pid";

events {
    worker_connections  4096;
}

이렇게 Application 설정 내역 변경 시 컨테이너 이미지를 새롭게 생성하는 것이 아니고 ConfigMap만 수정하시고 POD를 재시작하면 됩니다.

 

(참고로 이렇게 ConfigMap, Deployment YAML 파일을 Helm Chart와 분리하면 나중에 히스토리 관리가 어렵습니다. 재 설치 시 Helm 설치하고 다시 Deployment YAML만 Export해서 다시 적용해야 하는 번거로움이 있습니다. Helm Chart 자체를 수정하시는 것을 권고 드립니다.)

 

관련 Deployment POD 전체 재시작

추가로 ConfigMap을 변경 후 관련 Deployment 전체 재시작이 필요한 경우 위 방법처럼 POD를 하나씩 재시작 하지 않고 관련 Deployment POD 전체를 재시작 할 수 있습니다. 첫번째는 k rollout restart deployment 명령어를 사용하면 하나씩 Rollingout 되면서 전체 POD 재시작 됩니다.

[spkr@erdia22 ~ (spkn01:nginx)]$ k rollout restart deployment nginx
deployment.apps/nginx restarted

(화면을 분할하여 POD Restart 상황을 실시간으로 확인해 봅니다.)

[spkr@erdia22 ~ (spkn01:nginx)]$ kgpw
NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
nginx-76fd89b497-7x624     2/2     Running   0          25h   10.233.92.49    node3   <none>           <none>
nginx-76fd89b497-pj6c7     2/2     Running   0          26h   10.233.92.47    node3   <none>           <none>
nginx-76fd89b497-vmwhm     2/2     Running   0          25h   10.233.90.193   node1   <none>           <none>
nginx01-67fdf8d7c7-7wk69   1/1     Running   0          52s   10.233.90.195   node1   <none>           <none>
nginx-6bb5c6bf7d-tqbg7     0/2     Pending   0          0s    <none>          <none>   <none>           <none>
nginx-6bb5c6bf7d-tqbg7     0/2     Pending   0          0s    <none>          node1    <none>           <none>
nginx-6bb5c6bf7d-tqbg7     0/2     ContainerCreating   0          0s    <none>          node1    <none>           <none>
nginx-6bb5c6bf7d-tqbg7     0/2     ContainerCreating   0          1s    <none>          node1    <none>           <none>
nginx-6bb5c6bf7d-tqbg7     0/2     Running             0          5s    10.233.90.196   node1    <none>           <none>
nginx-6bb5c6bf7d-tqbg7     1/2     Running             0          11s   10.233.90.196   node1    <none>           <none>
nginx-6bb5c6bf7d-tqbg7     2/2     Running             0          11s   10.233.90.196   node1    <none>           <none>
nginx-76fd89b497-vmwhm     2/2     Terminating         0          25h   10.233.90.193   node1    <none>           <none>
nginx-6bb5c6bf7d-mn4ps     0/2     Pending             0          0s    <none>          <none>   <none>           <none>
nginx-6bb5c6bf7d-mn4ps     0/2     Pending             0          0s    <none>          node3    <none>           <none>
nginx-6bb5c6bf7d-mn4ps     0/2     ContainerCreating   0          0s    <none>          node3    <none>           <none>
nginx-76fd89b497-vmwhm     2/2     Terminating         0          25h   10.233.90.193   node1    <none>           <none>
nginx-6bb5c6bf7d-mn4ps     0/2     ContainerCreating   0          1s    <none>          node3    <none>           <none>
(생략)

위와 같이 POD 하나씩 자동으로 ContainerCreating - Running - Terminating 됩니다. 완료되면 정상적으로 POD 확인이 가능합니다.

[spkr@erdia22 ~ (spkn01:nginx)]$ kgp
NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
nginx-6bb5c6bf7d-6qr6j     2/2     Running   0          28m   10.233.90.197   node1   <none>           <none>
nginx-6bb5c6bf7d-mn4ps     2/2     Running   0          28m   10.233.92.43    node3   <none>           <none>
nginx-6bb5c6bf7d-tqbg7     2/2     Running   0          28m   10.233.90.196   node1   <none>           <none>
nginx01-67fdf8d7c7-7wk69   1/1     Running   0          29m   10.233.90.195   node1   <none>           <none>

다음 방법으로 ConfigMap을 각 버전별로 관리하여 신규 ConfigMap은 nginx-conf-cm-2라는 새로운 이름의 ConfigMap을 만들어서 관리하는 방법이 있습니다. 이 방법이 번거롭지만 히스토리 관리 및 Rollback이 용이하므로 추천하는 방법 입니다.
 

https://stackoverflow.com/questions/59113591/restart-kubernetes-deployment-after-changing-configmap

 

Restart kubernetes deployment after changing configMap

I have a deployment which includes a configMap, persistentVolumeClaim, and a service. I have changed the configMap and re-applied the deployment to my cluster. I understand that this change does not

stackoverflow.com

이상으로 Kubernetes ConfigMap 사용법에 대하여 알아 보았습니다. Application 설정 파일을 ConfigMap으로 관리하여 관리 노가다를 줄일 수 있기 바랍니다. 

 

반응형