실습
- 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
그럼, 설치를 시작합니다.
[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
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
이상으로 Kubernetes ConfigMap 사용법에 대하여 알아 보았습니다. Application 설정 파일을 ConfigMap으로 관리하여 관리 노가다를 줄일 수 있기 바랍니다.
'쿠버네티스 교육' 카테고리의 다른 글
14. Kube 교육 - Readiness/Liveness Probe (0) | 2021.06.04 |
---|---|
13. Kube 교육 - Label & Affinity (0) | 2021.06.04 |
06. Kube 교육 - Helm 이용한 Application 배포 (4) | 2021.06.04 |
05. Kube 교육 - YAML 기본 문법 (0) | 2021.06.04 |
04. Kube 교육 - Kube tool 이용(kctx, kns, kps, kubetail, k neat) (2) | 2021.06.04 |