목차

Kubernetes ConfigMap

  • 개발 환경은 SSH를 통한 보안 접근 해제
  • 테스트환경은 지정된 USER 및 Key를 이용한 SSH 보안 접근 사용
  • 운영환경은 테스트 환경과 다르게 지정된 USER 및 Key를 이용한 보안 접근 허용
  • 애플리케이션 레벨에서 환경 구성 변경시 소스코드와의 의존성이 높고, 설정 값 변경 시마다 코드 수정이 불가피하여 개발속도가 지연 될 수 있다.
  • 민첩성을 강조하는 Cloud Native 환경에서 애플리케이션 개발은 애플리케이션 코드와 분리된 configMap, Secret object 사용을 통해 신속하게 적용 가능
  • configMap, Secret은 중앙 관리 방식으로 애플리케이션 코드에서 구성 및 민감한 정보를 분리하도록 설계된 Kubernetes API object → kubectl api-resources
  • - - Dockerfile
FROM node:21-slim
EXPOSE 8000
COPY runapp.js .
CMD node runapp.js

# node21 이미지에
#8000 port개방하고
#현재 폴더에서 runapp.js 카피
#그 파일을 실행
  • runnapp.js
var http = require('http');
const apiKey = process.env.API_KEY;
if (!apiKey) {
        console.log('API_KEY is not set in the environment variables.');
        http.createServer(function (req, res) {
                res.setHeader('Content-Type', 'text/plain');
                res.end(\"API_KEY is not set in the environment variables.\" + \"\
\");
        }).listen(8000);
} else {
        console.log('API_KEY:', apiKey);
        http.createServer(function (req, res) {
                res.setHeader('Content-Type', 'text/plain');
                res.end(\"Welcome to ConfigMap Kubernetes\" + \"\
\");
        }).listen(8000);
}
#환경변수에서 API_KEY있는지 확인하여
#결과물 다르게 표출
  • configMap 테스트 이미지 도커 빌드 및 테스트
$ docker build -t crimsonpinus/configmaptest:latest --nocache .
#Dockerfile 빌드

$ docker run -d --name nodetest -p 8000:8000 crimsonpinus/configmaptest

$ curl localhost:8000
API_KEY is not set in the environment variables.

$ docker stop nodetest

$ docker rm nodetest

$ docker run -d --name nodetest -e API_KEY hello -p 8000:8000 crimsonpinus/configmaptest

$ curl localhost:8000
Welcome to ConfigMap Kubernetes

#kubernetes에서 사용하기위헤 본의의 계정에 업로드
$ docker push crimsonpinus/configmaptest:latest
  • cmtest-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: cmtest-pod
  name: cmtest-pod
spec:
  containers:
  - image: crimsonpinus/configmaptest
    name: cmtest-pod
    ports:
    - containerPort: 8000
    envFrom:
    - configMapRef:
        name: api-key
# cm-test-pod 생성후 파란색 부분 추가
  • configMap 사용
$ kubectl run cmtest --image crimsonpinus/configmaptest --port 8000

$ kubectl get po,svc -o wide | grep cmtest
pod/cmtest                              1/1     Running   0          13s     10.111.156.89   k8s-node1    <none>           <none>

$ curl 10.111.156.89:8000
API_KEY is not set in the environment variables.

$ kubectl delete po cmtest
pod \"cmtest\" deleted

#configMap
$ kubectl create cm api-key --from-literal=API_KEY=k8scm
configmap/api-key created

$ kubectl get cm
NAME                         DATA   AGE
api-key                      1      26s
kube-root-ca.crt             1      7d20h
kubeshark-config-map         22     7d16h
kubeshark-nginx-config-map   1      7d16h

$ kubectl describe cm api-key
Name:         api-key
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
API_KEY:
----
k8scm

BinaryData
====

Events:  <none>

#configMap 사용
#cmtest-pod.yaml 파일 생성
$ kubectl run cmtest --image crimsonpinus/configmaptest --port 8000 --dry-run=client -o yaml > cmtest-pod.yaml
#cmtest-pod.yaml. 파일 참조하여 수정

$ kubectl apply -f cmtest-pod.yaml

$ kubectl get po,svc -o wide | grep cmtest
pod/cmtest-pod                          1/1     Running   0          98s     10.111.156.90   k8s-node1    <none>           <none>

$ curl 10.111.156.90:8000
Welcome to ConfigMap Kubernetes

$ kubectl exec -it cmtest-pod -- env | grep -i api
API_KEY=k8scm
  • configMap 값 변경
$ kubectl edit cm api-key
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  API_KEY: k8scm-edit #값변경
kind: ConfigMap
metadata:
  creationTimestamp: \"2024-04-12T04:56:56Z\"
  name: api-key
  namespace: default
  resourceVersion: \"1320379\"
  uid: 56d43ca7-3a6e-47b7-ab6a-1460a0725bc7

 $ kubectl exec -it cmtest-pod -- env | grep -i api
API_KEY=k8scm
#변경 안되었음

#강제 재시작
$ kubectl replace --force -f ./cmtest-pod.yaml
pod \"cmtest-pod\" deleted
pod/cmtest-pod replaced

$ kubectl exec -it cmtest-pod -- env | grep -i api
API_KEY=k8scm-edit
- 선언형 YAML 코드 작성 - kubectl api-resource | grep configmap
- 명령형 → kubectl create configmap(or cm) configmap_name {설정1 | 설정2 | 설정3}
  • 설정1 → –from-literal key=value [ –from-literal key2=value2 ] ….
  • 설정2 → –from-file file_name (파일 안에 다수의 설정값 저장)
  • 설정3 → –from-env-file file_name (key=value의 환경 변수가 저장된 파일)
  • 부가기능-불변(immutable)
    • immutable: true
    • 실행 중인 애플리케이션의 값이 변경될경우 의도치 않은 중단을 야기하는 값에 사용
    • 불변 설정으로 configMap에 대한 APIserver의 감시 중단, 클러스터 성능 향상에 기여
apiVersion: v1
kind: ConfigMap
metadata:
	name: my-configmap
data:
	string-value: \"Hello, world!\" #스트링 형식 공백이 없으면 \"없어도 됨
	number-value: \"42\" #숫자형식 #없어도 됨
	boolean-value: \"true\" #불린타입 \"무조건 필요
	multiline-value: | #|표시는 아래 줄과 이어진다는 표시
		This is a multiline value
		that spans multiple lines
	list-value: |
		- item1
		- item2
		- item3
	object-value: |
		key1: value1
		key2: value2
	json-value: |-
		{
			\"key\": \"value\",
			\"array\": [1, 2, 3],
			\"nested\": {
				\"innerKey\": \"innerValue\"
			}
		}
	yaml-value: |-
		key: value
		array:
			- 1
			- 2
			- 3
  • Pod 적용 박식
    • Pod 속 환경 변수로 등록 → envForm.configMapRef.name
    • Pod Volume으로 mount → volumes.configMap.name
    • mountPath : 해당 디렉토리 전체를 업데이트
    • mount된 configMap, Secret은 업데이트 시 Pod에 자동 반영됨
    • subPath : 해당 디렉토리 안의 지정된 파일만 업데이트
    • Pod 속 컨테이너의 환경번수 값으로 KEY 지정
    • valueForm.configMapRef.name
    • valueForm.configMapRef.key
$ kubectl create configmap k8s-env \\
--from-literal orchestrator=kubernetes \\
--from-literal runtime=containerd

$ kubectl describe cm k8s-env
Name:         k8s-env
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
orchestrator:
----
kubernetes
runtime:
----
containerd

BinaryData
====

Events:  <none>

#yaml로 보기
$ kubectl get cm k8s-env -o yaml
apiVersion: v1
data:
  orchestrator: kubernetes
  runtime: containerd
kind: ConfigMap
metadata:
  creationTimestamp: \"2024-04-12T05:51:16Z\"
  name: k8s-env
  namespace: default
  resourceVersion: \"1326898\"
  uid: 3bcdf040-6174-497f-903e-a6b3bedf9db2

#JSON으로 보기
$ kubectl get cm k8s-env -o json
{
    \"apiVersion\": \"v1\",
    \"data\": {
        \"orchestrator\": \"kubernetes\",
        \"runtime\": \"containerd\"
    },
    \"kind\": \"ConfigMap\",
    \"metadata\": {
        \"creationTimestamp\": \"2024-04-12T05:51:16Z\",
        \"name\": \"k8s-env\",
        \"namespace\": \"default\",
        \"resourceVersion\": \"1326898\",
        \"uid\": \"3bcdf040-6174-497f-903e-a6b3bedf9db2\"
    }
}

#YMAL파일로 생성
$ kubectl create configmap k8s-env \\
--from-literal orchestrator=kubernetes \\
--from-literal runtime=containerd \\
--dry-run=client -o yaml > k8s-env.yaml

$ kubectl apply -f k8s-env.yaml
  • cm-volume-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: cm-volume-pod
  name: cm-volume-pod
spec:
  containers:
  - image: nginx:1.25.3-alpine
    name: cm-volume-pod
    ports:
    - containerPort: 80
    volumeMounts:
    - name: cm-volume
      mountPath: /etc/config
  volumes:
  - name: cm-volume
    configMap:
      name: k8s-env
      key: orchestrator #key를 이용하여 일부의 값만 가져올 수 있음
  • 활용
$ kubectl apply -f cm-volume-pod.yaml
pod/cm-volume-pod created

$ kubectl get po,svc -o wide | grep cm
pod/cm-volume-pod                       1/1     Running   0          31s     10.109.131.17   k8s-node2    <none>           <none>

$ kubectl exec cm-volume-pod -- ls -la /etc/config
total 0
drwxrwxrwx    3 root     root            95 Apr 12 06:11 .
drwxr-xr-x    1 root     root            52 Apr 12 06:11 ..
drwxr-xr-x    2 root     root            41 Apr 12 06:11 ..2024_04_12_06_11_12.4261600263
lrwxrwxrwx    1 root     root            32 Apr 12 06:11 ..data -> ..2024_04_12_06_11_12.4261600263
lrwxrwxrwx    1 root     root            19 Apr 12 06:11 orchestrator -> ..data/orchestrator
lrwxrwxrwx    1 root     root            14 Apr 12 06:11 runtime -> ..data/runtime

$ kubectl exec cm-volume-pod -- cat /etc/config/orchestrator
kubernetes
  • 변경후 Pod restart없이 반영
$ kubectl edit cm k8s-env
 orchestrator: k8s #로 변경

#nginx 리로드
$ kubectl exec cm-volume-pod -- nginx -s reload
2024/04/12 06:18:19 [notice] 46#46: signal process started

$ kubectl exec cm-volume-pod -- cat /etc/config/orchestrator
k8s
  • - - redis.conf
REDIS_PRIMARY_SERVICE_HOST=10.0.0.11
REDIS_PRIMARY_SERVICE_PORT=6379
REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcp
REDIS_PRIMARY_PORT_6379_TCP_PORT=6379
REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11
  • cmfille-volume-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: cmfile-volume-pod
  name: cmfile-volume-pod
spec:
  containers:
  - image: nginx:1.25.3-alpine
    name: cmfile-volume-pod
    ports:
    - containerPort: 80
    volumeMounts:
    - name: redis-volume
      mountPath: /opt/redis/config
  volumes:
  - name: redis-volume
    configMap:
      name: redis-config
#녹색부분 추가
#다중환경 설정
$ kubectl create cm redis-config --from-file=redis.conf
configmap/redis-config created

$ kubectl get cm
NAME                         DATA   AGE
k8s-env                      2      30m
kube-root-ca.crt             1      7d22h
kubeshark-config-map         22     7d17h
kubeshark-nginx-config-map   1      7d17h
redis-config                 1      9s

$ kubectl describe cm redis-config
Name:         redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis.conf:
----
REDIS_PRIMARY_SERVICE_HOST=10.0.0.11
REDIS_PRIMARY_SERVICE_PORT=6379
REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcp
REDIS_PRIMARY_PORT_6379_TCP_PORT=6379
REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11



BinaryData
====

Events:  <none>


$ kubectl apply -f cmfile-volume-pod.yaml

$ kubectl exec cmfile-volume-pod -- ls -l /opt/redis/config

$ kubectl exec cmfile-volume-pod -- cat /opt/redis/config/redis.conf