Kubernetes

이번 포스팅에서는 ConfigMap
과 Secret
에 관한 설명이다.
설명하기에 앞서 해당 오브젝트를 사용해야 하는 상황은 어떤 경우일까?
개발 환경과 상용 환경이 있다고 하자.
또한, A라는 서비스가 있다고 가정하자. 이때, A 서비스에는 일반 접근과 보안 접근이 가능하다.
A 서비스(개발 환경)
- SSH: False
- User: Dev
- Key: LS0tLs...
따라서, 개발 환경에서는 해당 보안 접근을 해제할 수 있는 옵션이 있다.(SSH : False
)
만약, 보안 접근을 한다면 접근 유저와 키를 세팅할 수도 있다.(User: Dev
, Key: LS0tLs
)
개발 환경에서는 위처럼 사용한다고 하고, 상용 환경에서 배포를 해야 한다면 해당 값은 변경되어야 할 것이다.
A 서비스(상용 환경)
- SSH: True
- User: Prod
- Key: MII3Ld...
다시 보안 접속으로 설정을 해야 될 것이며, 유저와 키 값도 변해야 한다.
그러나, 이 값은 컨테이너 안에 있는 서비스 이미지에 들어있는 값이기 때문에,
해당 내용을 바꾼다는 건 개발 환경과 상용 환경에 관한 컨테이너 이미지를 각각 관리하겠다는 것을 말한다.
Container for Dev
- A 서비스(개발 환경)
- SSH: False
- User: Dev
- Key: LS0tLs..
Container for Prod
- A 서비스(상용 환경)
- SSH: True
- User: Prod
- Key: MII3Ld...
이런식으로 각각 관리해주어야 한다.
값 몇 개 때문에 큰 용량의 이미지를 별도로 관리하는 것은 정말 부담되는 일이다.
따라서, 환경에 따라 변하는 값들을 외부에서 결정할 수 있게 도와주는 것이 ConfigMap
과 Secret
이라는 오브젝트이다.
분리해야 되는 일반적인 상수들을 모아 ConfigMap
을 만들고,
키와 같이 보안적인 관리가 필요한 값을 모아 Secret
를 만든다.
그리고 Pod
가 생성될 때 이 두 오브젝트를 연결하여 컨테이너의 환경변수에 해당 데이터들을 넣는다.
그러면 A 서비스 입장에서는 해당 환경변수 값을 읽어서 로직을 처리함으로 위와 똑같은 작업을 할 수 있게 된다.
즉, 이미지를 하나 만들어 넣으면 개발 환경/상용 환경에 맞춰 사용이 가능하다.
(상용 환경에서는 ConfigMap
과 Secret
에 데이터만 바꿔주면)
(똑같은 컨테이너 이미지를 사용해 원하는 기능을 사용이 가능하다.)
ConfigMap 및 Secret 사용 방법

ConfigMap
과 Secret
을 만들 때 데이터로 상수를 넣을 수 있고 파일을 넣을 수 있다.
그리고 파일을 넣을 때는 환경 변수로 세팅하는 게 아닌 볼륨을 마운트해서 사용을 할 수 있다.
ConfigMap
ConfigMap
은 키와 밸류로 고정이 되어있다.
그래서, 위의 그림처럼 필요한 상수들을 정의해 놓으면 Pod
를 생성할 때,
해당 ConfigMap
을 가져와 컨테이너 안의 환경변수로 세팅을 할 수 있다.
Secret
그리고 Secret
도 똑같은 역할을 하는데 이름처럼 뭔가 보안적인 요소의 값들을 저장하는 용도이다.
주로 패스워드라든지 인증키들은 Secret
에 담는다.
Secret
은 평문으로 쿠버네티스 DB(etcd)에 저장된다.
Secret
의 보안적 요소는 Secret
를 Pod
에 파일로 마운팅해서 사용할 때, Pod
내부에서는 파일이 보이지만,
이런 기능을 구현하기 위해서 Kubernetes
입장에서는 workernode
에 Secret
파일을 만들어 놓고,
Pod
에 이 파일을 마운팅한다. 이때, workernode
에 Secret
파일을 인메모리 파일시스템(tmpfs) 영역에
올려놓고 있다가 Pod
가 삭제되면 지운다.
이렇게 민감한 데이터를 디스크에 저장하지 않기에 Secret
의 경우 ConfigMap
보다 보안에 유리할 수 있다.
주의
Secret
은 사용할 때 ConfigMap
과 달리 Value
를 넣을 때 base64 encoding
을 해서 넣어야 한다.
이게 Secret
의 보안적인 요소는 아니고 단순히 Secret
의 Value
를 만들어야 된다는 규칙이다.
Secret
이 Pod
로 주입이 될 때는 자동으로 decoding
이 되어 환경 변수에서는 원래의 값으로 보인다.
상수 사용

ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-dev
data:
SSH: 'false'
User: dev
YAML 파일 내용을 보면 ConfigMap
을 만드는데 이름을 지정하고 이 데이터에 키-벨류 형태의 상수를 넣는다.
Secret
apiVersion: v1
kind: Secret
metadata:
name: sec-dev
data:
Key: MTIzNA==
마찬가지로, Secret
도 이름을 넣고 데이터에 키를 넣고 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
를 생성할 때 우리가 앞서 만든 ConfigMap
과 Secret
를 지정하여 사용하면 된다.
컨테이너 안에 env-from
이라는 속성으로 ConfigMap
을 래퍼런스하고 가져올 ConfigMap
의 이름은 cm-dev
이다.
마찬가지로, Secret
로 래퍼런스하는데 그 이름은 sec-dev
이다.
파일 사용

다음으로는 파일을 환경변수에 넣는 방법이다.
위의 그림처럼 파일을 통으로 ConfigMap
에 담을 수가 있는데 이럴 때 파일 이름이 키가 된다.
파일 안의 내용은 Value
가 되어 ConfigMap
이 만들어진다.
파일을 ConfigMap
으로 만드는 것은 대시보드에서 지원해주지 않기 때문에
직접 마스터 콘솔로 들어가 kubectl
명령어를 사용해주어야 한다.
kubectl create configmap cm-file --from-file=./file.txt
cm-file
이라는 ConfigMap
을 만들며 ./file.txt
파일을 넣을 거다라는 명령이다.
Secret
의 경우 아래와 같이 명령을 날리면 된다.
kubectl create secret generic sec-file --from-file=./file.txt
여기서 한가지 주의할 점은 파일 텍스트 안의 내용이 Base64
로 변경이 되기 때문에
만약, 이 파일 안에 내용이 이미 Base64
였다면 두번 인코딩이 된다.
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
를 만드는 것을 살펴보면 컨테이너에 환경변수를 넣을 건데,
이 환경변수의 이름은 file-c
이고 그리고 이 파일의 값 valueFrom
을 가져올 건데,
그 값은 ConfigMap
의 키를 래퍼런스할 것이며(configMapKeyRef
) 이름은 cm-file
이다.
Volume Mount

마지막으로, 파일을 마운팅하는 방법이다.
파일을 ConfigMap
에 담는 것까지는 똑같다.
Pod
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
그러나, 다른 부분은 Pod
를 만들 때 컨테이너 안에 Volume
을 마운트 할건데
그 /mountPath
는 /mount
가 되고 마운트할 Volume
의 내용을 보면
해당 Volume
안에는 ConfigMap
을 담는다.
해당 ConfigMap
의 이름은 cm-file
이다.
이렇게만 보면 VolumeMount
와 파일 사용
의 차이를 정확히 알기 어려울 수 있다.
만약 Pod
를 생성한 다음에 각각의 ConfigMap
에 적용된 파일의 내용을 변경하게 된다면 어떻게 될까?
환경변수 방식은 한번 주입을 하면 끝이기 때문에 ConfigMap
의 데이터가 변해도
Pod
의 환경변수 값에는 영향이 없다.
해당 Pod
가 죽어 재생성이 되어야지만, 이 변경된 값을 다시 받아와서 수정을 할 수 있다.
반면에 VolumeMount
방식은 마운트라는게 원본과 연결시켜준다는 개념인것처럼
ConfigMap
의 데이터 내용이 변하게 되면 해당 Pod
에 마운팅된 내용도 변하게 된다.
따라서, 위의 특성을 잘 알고 필요한 상황에 따라 활용을 잘 해야 한다.
실습
ConfigMap
과 Secret
에 관한 실습을 진행하겠다.
ConfigMap
ConfigMap
은 특별한 거 없이 아래 YAML 처럼 키-벨류 형태로 값을 넣어주면 된다.
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-dev
data:
SSH: 'false'
User: dev
여기서 한가지 주의할 점이 있는데 키-벨류는 모두 스트링 값이다.
그렇기 때문에 만약 boolean
값을 넣고 싶다면 위의 YAML 파일 내용처럼 ''
을 달아서 넣어줘야 한다.
만약, 뺀다면 에러가 발생한다.

Secret
Secret
도 마찬가지로 주의해야 할 점은 Key
의 Value
값에 Base64 Enconding
을 하지 않게 되면 오류가 발생한다.
apiVersion: v1
kind: Secret
metadata:
name: sec-dev
data:
Key: MTIzNA==

대시보드에서는 Key
의 값을 볼 수 있는 기능이 있어 실습시 편리하지만,
실질적으로 대시보드를 실제 운영에서 사용하지 않는 이유가 이런 중요한 값이 쉽게 노출되기 때문이다.
따라서, 보안상의 이유로 대시보드는 잘 사용하지 않는다고 한다.
이제는 해당 ConfigMap
과 Secret
을 연동한 Pod
를 생성해보자.
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
YAML 파일을 살펴보면 Pod
의 컨테이너 안에 환경변수로 방금 만든 ConfigMap
과 Secret
의 이름을 지정해주었다.
그래서, 실제로 접속해서 환경변수를 확인해보면 아래와 같이 잘 적용이 된 것을 확인할 수 있다.
Key값을 보면 base64 decoding
이 된것을 확인할 수 있다.

다음으로는 file
로 ConfigMap
과 Secret
을 만들어보자.
ConfigMap(file)
앞서, 이론에서 언급했던 것처럼 파일로 ConfigMap
을 만드는 것은 대시보드에서 지원해주지 않는다.
따라서, 직접 마스터의 콘솔로 만들어야 한다.

이런식으로, ConfigMap
에 사용될 파일을 만든 뒤 kubectl
명령어를 활용하여 ConfigMap
을 생성한다.

실제로, Key
는 파일 이름으로 되어있는 형태로 ConfigMap
이 잘 생성되었다.
Secret(file)
Secret
도 마찬가지로, 콘솔에서 kubectl
명령어를 통해 만들어준다.

이때, base64 encoding
을 하지 않아도 명령어에 의해 알아서 encoding
을 해준다.

Secret
도 Key
값을 파일이름으로 갖으며 잘 생성이 되었다.
자, 이제는 관련해서 `Pod를 생성해보자.
Pod(file)
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
기존의 envFrom
키워드와는 달리 env
키워드를 사용해서 환경변수를 명시를 한다.
이때, 이 환경변수에 방금 만든 ConfigMap
의 키를 매칭시킨다.
Secret
도 마찬가지로, 키를 매칭시켜준다.

생성한 Pod
를 살펴보면 ConfigMap
과 Secret
의 내용이 잘 들어가있는 것을 확인할 수 있다.
마지막으로는 VolumeMount(File)
에 관해 알아보겠다.
VolumeMount(File)
Pod
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

마운트 경로에 file-c.txt
가 잘 있는 것을 확인할 수 있다.
이론에서 설명했던 것처럼 VolumeMount
의 경우 file
의 데이터가 변경되었을 때 적용이 된다고 말했었다.
한번 확인해보자.

file-c.txt
의 값을 변경한 뒤 확인해보면

잘 변경된 것을 확인할 수 있다.
'Infra > Kubernetes' 카테고리의 다른 글
[Kubernetes] Replication Controller, ReplicaSet - Template, Replicas, Selector (0) | 2024.09.05 |
---|---|
[Kubernetes] Namespace, ResourceQuota, LimitRange (0) | 2024.09.04 |
[Kubernetes] Volume - emptyDir, hostPath, PV/PVC (0) | 2024.08.28 |
[Kubernetes] Service - ClusterIP, NodePort, LoadBalancer (0) | 2024.08.27 |
[Kubernetes] Pod - Container, Label, NodeSchedule (0) | 2024.08.12 |