Kubernetes ConfigMap
목차
개발 , 테스트, 운영환경에 사용되는 각기 다른 환경 값의 분리 필요한 상황으로 애플리케이션 Image는 동일하게 사용하고 필요한 환경 구성값을 configMap으로 만들어 사용
- 개발 환경은 SSH를 통한 보안 접근 해제
- 테스트환경은 지정된 USER 및 Key를 이용한 SSH 보안 접근 사용
- 운영환경은 테스트 환경과 다르게 지정된 USER 및 Key를 이용한 보안 접근 허용
기밀이 요구되는 데이터는 secret으로 생성해 Pod에 적용해서 사용
애플리케이션 레벨이 아닌 Object레벨의 환경 설정 관리 할때 사용
- 애플리케이션 레벨에서 환경 구성 변경시 소스코드와의 의존성이 높고, 설정 값 변경 시마다 코드 수정이 불가피하여 개발속도가 지연 될 수 있다.
- 민첩성을 강조하는 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—
—
configMap 활용
생성
- 선언형 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의 감시 중단, 클러스터 성능 향상에 기여
configMap.yaml 예시
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—
volume mount
- 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—
다중환경 volume mount
- - 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