[Xshell] 오브젝트 - ConfigMap, Secret
Env(Literal, File), Mount(File)
ConfigMap과 Secret 의 필요성
개발환경에서 일반접근을 하다가, 상용환경으로 배포한다면 보안접속으로 설정을 하고 user와 key값도 변해야한다.
user와 key값은 컨테이너 이미지에 들어있는 값이기 때문에 이 부분을 변경한다는 것은,
개발환경과 상용환경의 컨테이너 이미지를 각각 관리하겠다는 의미이다.
이 값 몇 개 때문에 큰 용량의 이미지를 별도로 관리하는 것은 효율적이지 못하다.
이때, 환경에 따라 변하는 값들을 외부에서 결정할 수 있게 도와주는 오브젝트가 ConfigMap, Seceret이다.
이를 이용해서 이미지를 하나 만들어 놓으면, 개발환경과 상용환경에 사용할 수 있다.
configMap은 일반적인 설정 정보를, secret은 민감한 정보를 관리하는 데 사용한다. key-value 쌍으로 구성된다.
Pod 생성 시, 이 두 오브젝트를 연결할 수 있다.
연결하면, container의 환경변수에 해당 데이터가 들어가게 된다.
ConfigMap과 Secret 처리방식 비교
secret이 configMap과 다른 점은, value를 넣을 때 Base64 인코딩을 해서 만들어야한다. pod의 환경변수로 연결될 때는 자동으로 decoding이 돼서 원래의 값으로 보여진다.
또한, secret은 민감한 정보가 디스크에 기록되지 않도록 memory에 저장된다.
- 생성 : k8s 클러스터에서 configMap, secret 오브젝트를 생성
- 저장 : 이 오브젝트들을 kubernets DB(etcd)에 저장
- 파일로 매핑 : 쿠버네티스는 configMap 또는 secret 오브젝트의 데이터를 파일로 매핑. 이 매핑은 작업 노드의 파일 시스템에 일시적으로 저장된다. Secret의 경우 인메모리 파일 시스템(tmpfs)에 저장될 수 있어 디스크에 민감한 데이터가 기록되지 않도록 보호된다.
- Pod에 mount : 파일로 매핑된 데이터는 Pod의 볼륨으로 마운트되고, 애플리케이션 코드는 이 볼륨을 통해 데이터에 접근할 수 있다.
따라서, secret은 memory에 저장하기 때문에 너무 많이 만들게 되면 시스템 자원에 영향을 끼치므로 주의해야한다.
Tips: 쿠버네티스 아키텍처
쿠버네티스 아키텍처는 크게 Master Node와 Worker Node로 구분되며, 이 두 부분이 합쳐져서 컨테이너화된 애플리케이션의 배포, 확장, 및 관리를 수행한다.
- Master Node (Control Plane):
- API Server (kube-apiserver): 모든 쿠버네티스 클러스터의 통신 중심으로 사용자와 클러스터 간의 모든 상호 작용은 API 서버를 통해 처리한다.
- Controller Manager (kube-controller-manager): 클러스터의 상태를 관리하고, 예상된 상태와 현재 상태를 일치시키는 여러 컨트롤러를 실행한다.
- Scheduler (kube-scheduler): Pod를 적절한 Worker Node에 배치하는 역할을 한다. 스케줄러는 리소스 가용성, 제약 조건, affinity, anti-affinity 등을 고려하여 결정한다.
- etcd: 쿠버네티스의 중앙데이터베이스로 클러스터의 모든 구성 데이터를 저장하는 분산 키-값 저장소이다.
- Worker Node (컴퓨팅 작업을 수행하는 노드):
- Kubelet (k8s CLI): 각 Worker Node에서 실행되는 에이전트로, 해당 노드에서 실행되는 Pod의 상태를 모니터링하고 관리한다.
- Kube Proxy (kube-proxy): 네트워크 프록시 및 로드 밸런싱을 제공하여 Pod 간의 네트워크 통신을 가능하게 한다.
- Container Runtime: 컨테이너를 실행하는 데 필요한 런타임으로, Docker, containerd, rkt 등이 있다.
- Pods: Pod는 하나 이상의 컨테이너와 그 컨테이너의 저장소 및 네트워크 리소스를 캡슐화합니다.
configMap과 Secret을 만들 때 데이터로 [상수, 파일]을 넣을 수 있다.
파일을 넣을 때는 환경변수로 세팅하는 것이 아닌 volume을 mount해서 사용할 수 있다.
[1] Env (Literal)
이는 key-value를 상수로 정의하고 환경변수에 넣는 방법이다.
실습
ConfigMap, Secret, Pod를 각각 만든다.
- ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: cm-dev data: SSH: 'false' User: dev
- Secret
apiVersion: v1 kind: Secret metadata: name: sec-dev data: Key: MTIzNA==
Key: MTIzNA== value에 Base64 인코딩이 들어가지 않으면 에러 발생한다.
- Pod
apiVersion: v1
kind: Pod
metadata:
name: pod-1
spec:
containers:
- name: container
image: kubetm/init
envFrom:
- configMapRef:
name: cm-dev
- secretRef:
name: sec-dev
pod의 container에서 환경변수를 출력해보면 key-value값을 확인할 수 있다.
이때, pod에서는 인코딩된 value값이 디코딩된 것도 확인할 수 있다.
[2] Env (File)
이는 파일을 환경변수에 넣는 방법이다.
file.txt 파일을 통으로 ConfigMap에 담을 수 있다. 파일명이 key이고, 파일내용이 value가 된다.
해당 명령은 텍스트 내용을 Base64 인코딩을 하기 때문에, 이미 텍스트 내용이 Base64인코딩이 되어있다면 두 번 인코딩 되는 경우를 유의해야 한다.
실습
대쉬보드에서 파일로 configMap을 만드는 것을 지원하지 않기 때문에 직접 master의 kubectl을 이용해서 두 오브젝트를 만들어보자.
- ConfigMap
echo "Content" >> file-c.txt kubectl create configmap cm-file --from-file=./file-c.txt
- Secret
echo "Content" >> file-s.txt kubectl create secret generic sec-file --from-file=./file-s.txt
- Pod
apiVersion: v1
kind: Pod
metadata:
name: pod-file
spec:
containers:
- name: container
image: kubetm/init
env:
- name: file-c
valueFrom:
configMapKeyRef:
name: cm-file
key: file-c.txt
- name: file-s
valueFrom:
secretKeyRef:
name: sec-file
key: file-s.txt
pod의 container에 들어가서 환경변수에 configMap과 secret의 key-value가 들어있는 것을 확인할 수 있다.
추가로, 대시보드에서 secret 데이터를 볼 수 있으므로 실제 업무에서는 보안상의 문제로 대시보드 안쓴다.
[3] Volume Mount (File)
파일을 ConfigMap에 담는 것까지 동일하고, pod를 만들 때 container 안에 mount path를 정의한다.
환경변수 방식은 configMap의 데이터가 변해도 반영이 안된다.
파일 마운트는, 마운트라는 게 원본과 연결시켜준다는 개념이므로, configMap의 데이터가 변경되면 pod에 마운팅된 내용도 변한다.
실습
앞에서 만든 파일 file-c.txt, file-s.txt 을 volume으로 mount 해보자.
apiVersion: v1
kind: Pod
metadata:
name: pod-mount
spec:
containers:
- name: container
image: kubetm/init
volumeMounts:
- name: file-volume
mountPath: /mount
volumes:
- name: file-volume
configMap:
name: cm-file
container에서 mount path에 이동하여 확인해보니 volume으로 mount가 잘 되었다.
이때, configMap 파일의 내용이 변경되면 잘 변경이되는지도 확인하였다.
Tips
volumes는 기본적으로 configMap이건 secret건 하나의 아이템만 설정할 수 있다.
함께 주입하고 싶으면 projected라는 속성을 사용해야한다.
apiVersion: v1
kind: Pod
metadata:
name: pod-mount
spec:
containers:
- name: container
image: kubetm/init
volumeMounts:
- name: file-volume
mountPath: /mount
volumes:
- name: file-volume
projected:
sources:
- configMap:
name: cm-file
- secret:
name: sec-file
해당 게시글은 ‘대세는 쿠버네티스 초중급편’ 강의와 ‘컨테이너 인프라 환경 구축을 위한 쿠버네티스.도커_조훈’ 도서를 바탕으로 작성하였습니다.
Leave a comment