개발서버에 A라는 Service에는 일반접근과 보안접근을 지원하고 있다고 가정해보자.
개발환경에서는 보안접근을 해제할 수 있는 옵션이 있고 보안접근을 한다면 접근User와 key를 세팅할 수 있다.
하지만 개발 서버를 운영 서버로 배포를 해야 한다면 이 값들이 변경되어야 한다.
그렇지만 이 값들은 컨테이너 안에 있는 Service 이미지 안에 들어있는 값이기 때문에 이 값들을 바꾼다는 것은 개발서버와 운영서버에 컨테이너 이미지를 각각 관리한다는 의미다.
하지만 이 값 몇개 때문에 큰 용량의 이미지를 별도로 관리하는 것은 부담스럽다.
그래서 보통 이렇게 환경에 따라 변하는 값들은 외부에서 값들을 결정할 수 있게 하는데 이러한 결정을 도와주기 쉽게 하는 것이 바로 ConfigMap과 Sercret이다.
내가 분리해야하는 일반적인 상수들을 모아서 ConfigMap을 만들고 Key와 같이 보안적인 관리가 필요한 값들을 모아서 Secret을 만든다.
그리고 Pod 생성시에 이 두 Object들을 연결할 수 있는데 연결하게 되면 컨테이너의 환경변수에 Object들의 값이 들어가게 된다.
그리고 A Service 입장에서는 이 환경변수의 값을 읽어서 로직을 처리하게 되면 위와 똑같은 역할을 할 수 있다.
그렇게해서 이러한 이미지를 하나 만들어 놓고 ConfigMap과 Secret의 데이터 값들만 변경해주면 개발환경과 운영환경 모두에서 사용 가능하다.
ConfigMap과 Secert을 만들 때 데이터로 상수를 넣을 수도 있고 파일을 넣을 수도 있다.
그리고 파일을 넣을 때는 환경변수로 세팅하는 것이 아닌 볼륨을 Mount해서 사용할 수 있다.
ConfigMap은 key와 value로 구성되어 있다.
따라서 필요한 상수들을 정의해 놓으면 Pod를 생성할 때 이 ConfigMap을 가져와서 컨테이너안에 환경변수에 세팅할 수 있다.
Secret도 ConfigMap과 똑같은 역할을 하는데
이름에서 알 수 있다 싶이 보안적인 요소의 값(패스워드, 인증키)들을 저장하는 용도로 사용된다.
또한 value를 넣을 때 Base64 인코딩을 해서 만들어야 한다.
하지만 Pod로 주입이 될때는 자동으로 디코딩되서 환경변수에서는 원래의 값들이 보이게 된다.
Secret의 보안적인 요소는 일반적인 Object 값들은 쿠버네티스 DB에 저장되는데 Secret은 메모리에 저장된다.
또한 ConfigMap은 key, value를 무한히 넣을 수 있는 반면에 Secret은 1Mbyte까지만 key, value를 넣을 수 있다.
apiVersion: v1
kind: ConfigMap
metadata:
name: configMap-dev
data:
SSH: False
User: dev
apiVersion: v1
kind: Secret
metadata:
name: secret-dev
data:
key: MTlzNA==
apiVersion: v1
kind: Pod
metadata:
name: pod-1
spec:
containers:
- name: container
image: nginx:1.14
envFrom:
- configMapRef:
name: config-dev
- secretRef:
name: secret-dev
ConfigMap을 만드는데 이름을 지정하고 이 데이터에 Key, Value형태의 상수를 넣으면된다.
마찬가지로 Secret을 만드는데 이름을 지정하고 이 데이터에 Key와 Base64로 인코딩된 Value를 넣으면 된다.
Pod를 만들 때 container안에 envFrom이라는 속성으로 ConfigMap과 Secret을 이름을 통해 참조하면 된다.
파일을 통으로 ConfigMap에 담을 수 있는데 이럴 때 파일 이름이 key가 되고 파일 안에 내용이 value가 된다.
이걸 Pod의 환경변수로 넣을 때 그대로 넣게 된다면 파일이름이 Key가 되어버리기 때문에 key를 새로 정의해서 넣으면 된다.
# kubectl create configmap configMap-file --from-file=./file-c.txt
# kubectl create secret generic secret-file --from-file=./file-s.txt
apiVersion: v1
kind: Pod
metadata:
name: pod-file
spec:
containers:
- name: container
image: nginx:1.14
env:
- name: file-c
valueFrom:
configMapKeyRef:
name: configMap-file
key: file-c.txt
- name: file-s
valueFrom:
secretKeyRef:
name: secret-file
key: file-s.txt
파일을 ConfigMap, Secret안에 넣는것 까지는 똑같지만 Pod를 만들 때 컨테이너 안에 mountPath를 정의하고 이 path안에 파일을 Mounting 할 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: pod-mount
spec:
containers:
- name: container
image: nginx:1.14
volumeMounts:
- name: file-volume
mountPath: /mount
volumes:
- name: file-volume
configMap:
name: configMap-file
볼륨안에 ConfigMap을 담고 마운트하면 된다.
만약 이렇게 Pod를 생성한 다음에 ConfigMap을 변경하게 된다면??
--> 환경변수 방식은 한번 주입을하면 끝이기 때문에 ConfigMap의 값이 변하더라도 환경변수의 값은 그대로다. Pod가 죽고 다시 재생성 되야지만 변경된 ConfigMap 값이 적용된다.
---> Mount 방식은 Mount 자체가 원본과 연결시켜놓다는 개념이디. 때문에 그 원본이 ConfigMap이므로 ConfigMap이 변하게되면 Pod에 Mount된 내용도 변하게 된다. 따라서 값이 변하게 된다.