IT/Kubernetes

[Kubernetes] Kubernetes Study: "기본 오브젝트 - ConfigMap & Secret"

wookiist 2021. 6. 29. 00:10

Prologue

본 포스트는 인프런 쿠버네티스 스터디 그룹에서 진행하는 스터디 자료의 일환으로 작성하였습니다. 기본적으론 [대세는 쿠버네티스] 강의를 보고 내용을 정리합니다. 그리고 제 경험이나 이해를 곁들여 포스트를 작성했습니다. 그동안 공식 문서나 블로그 포스트, CKA 강의 등 다양한 경로로 쿠버네티스를 익혀왔지만, 한국어로 잘 정리된 강좌를 한번 듣고 깔끔하게 다듬어보는 시간을 가지면 좋겠다는 생각이 들었습니다.

강의와는 조금 다를 수 있지만, 쿠버네티스 공식 문서를 보고 내용을 정리해보겠습니다.

이번 포스트에선 "기본 오브젝트 - ConfigMap & Secret"을 다뤄봅니다.

ConfigMap & Secret

컨피그맵은 키-값 쌍으로 보안이 필요하지 않은 데이터를 보관하는 데 사용하는 오브젝트입니다. 컨피그맵을 사용하면 컨테이너 이미지에서 환경별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있습니다. 예를 들면, 컨테이너 이미지를 빌드할 때, 환경이 development면 개발 환경으로 동작하도록 설계하고, production 환경이면 상용 환경으로 동작하도록 설계해두었다면, 이를 컨피그맵을 활용해 지정할 수 있습니다. 이렇듯 환경별 구성 분리가 필요할 때 자주 사용하게 됩니다.

시크릿은 컨피그맵과 유사한 오브젝트이지만, 비밀번호, OAuth 토큰, SSH 키와 같은 민감한 정보를 저장하고 관리하는 역할을 하는 오브젝트입니다.

강의 내용

ConfigMap & Secret

개발 환경과 상용 환경을 분리하여 운용하는 것은 일반적입니다. 그런데 개발 환경 이미지와 상용 환경 이미지를 별도로 관리해야 한다면 어떨까요? 스토리지나 빌드 시간이 두 배가 되는 등의 불편함이 있습니다. 그리고 generic하다고 보기 어려울 것입니다. 이럴 때 컨피그맵과 시크릿을 사용하면 하나의 이미지로 두 동작을 하도록 설정할 수 있습니다.

강의에서 소개한 이미지를 2차 편집했습니다. 문제가 있을 시 삭제하겠습니다.

https://user-images.githubusercontent.com/16011260/123532537-e2588000-d748-11eb-82b7-2b900497486f.png

위 그림처럼 서로 다른 환경에서 운용 중인 파드이지만, Container Image A라는 같은 이미지 하나로 배포된 상태입니다. 이러한 방식이 가능한 이유는 컨테이너 이미지에 이용될 환경 변수를 ConfigMap과 Secret으로 Decouple 해두었기 때문입니다.

이외에도 컨피그맵은 애플리케이션이 필요로 하는 변수를 보관한 파일을 키-값 쌍으로 보관해서 volume으로 해당 컨피그맵을 파일로 마운트해서 쓸 수도 있습니다.

시크릿은 1MB까지만 생성이 가능합니다. 또한 메모리에 들고 있게 되기 때문에 너무 많이 생성하게 되면 시스템에 영향을 줄 수 있다는 문제가 있습니다.

컨피그맵과 시크릿을 만드는 방법은 크게 세가지가 있습니다.

Env (Literal)

먼저 데이터를 매니페스트 파일에 넣어 그대로 생성하는 방식입니다. 컨피그맵과 시크릿은 유사하게 생성할 수 있습니다.

apiVersion: v1
kind: ConfigMap
metadata:
    name: configmap-dev
data:
    SSH: False
    User: dev
apiVersion: v1
kind: Secret
metadata:
    name: secret-dev
data:
    Key: ABC # 값을 base64로 변환하여 넣으셔야 합니다. 파드에 마운트되면 자동으로 decoding 됩니다.

그리고 이를 파드에 마운트하려면 다음처럼 매니페스트 파일을 작성하시면 됩니다.

apiVersion: v1
kind: Pod
metadata:
    name: pod-dev
spec:
    containers:
    - name: container-1
        image: busybox
        **envFrom:
        - configMapRef:
              name: configmap-dev
        - secretRef:
                name: secret-dev**

Env (File)

다음은 파일을 통째로 value에 넣는 방식입니다. 이 방식으로 생성하면 파일의 이름이 Key가 되고, 파일의 내용이 Value가 됩니다. 보통 kubectl 명령을 이용해 생성하는 것이 간단하며 현명합니다.

# ConfigMap
$ kubectl create configmap configmap-file --from-file ./file.txt

# Secret (주의: 시크릿이 생성될 때 파일의 내용이 base64로 자동 변환되므로 
#              이미 base64로 변환된 파일을 넣을 땐 유의해야 한다.)
$ kubectl create secret generic secret-file --from-file ./file.txt

이렇게 파일을 이용해 생성한 컨피그맵과 시크릿은 파드를 생성할 때 다음처럼 연결해주어야 합니다.

apiVersion: v1
kind: Pod
metadata:
    name: pod-dev
spec:
    containers:
    - name: container-2
        image: busybox
        **env:
        - name: file
            valueFrom:
                configMapREf:
                    name: configmap-file
                    key: file.txt**

Volume Mount (File)

컨테이너 안에 마운트할 경로를 정의해주고, 해당 경로에 파일을 마운트하는 방법입니다. 생성하는 방식까지는 똑같은데, 파드를 생성할 때 사용할 매니페스트가 조금 다릅니다.

apiVersion: v1
kind: Pod
metadata:
    name: pod-dev
spec:
    containers:
    - name: container-3
        image: busybox
        **volumeMounts:
        - name: file-volume
            mountPath: /mount
    volumes:
    - name: file-volume
        configMap:
            name: configmap-file**

파일 마운트를 하게 되면, 원본 컨피그맵의 데이터가 변경되면, 자동으로 내부 데이터도 바뀐 상태가 됩니다. 반면 Env로 데이터를 주입한 경우, 파드가 처음 생성될 때 불러온 환경 변수의 값이므로, 그 데이터가 변하지 않는다는 차이가 있습니다. 이를 주의해서 사용해야 합니다.

마무리

이렇게 해서 인프런 강의의 "기본 오브젝트 - ConfigMap & Secret"을 다뤄봤습니다. 내용이 많이 부실하고, 설명이 어렵게 되어 있는 등의 문제가 있을 것으로 보입니다. 추후 수정을 통해 다듬어보겠습니다.

여기까지 따라오시느라 고생이 많으셨습니다. 만약 이 글이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.

혹시라도 글에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊

반응형