DevOps/Kubernetes

쿠버네티스(kubernetes) Namespace, ConfigMap, Secret

알로그 2022. 5. 14. 23:08
반응형

쿠버네티스(kubernetes) Namespace, ConfigMap, Secret

네임스페이스(Namespace): 리소스를 논리적으로 구분하는 장벽

네임스페이스는 일종의 포드, 레플리카셋, 디플로이먼트, 서비스 등과 같은 리소스들이 묶여 있는 하나의 가상공간 또는 그룹이라고 이해하면 됨

$ kubectl get namespaces
$ kubectl get ns

 

default라는 이름의 네임스페이스에 생성된 포드를 확인하려면..

$ kubectl get pods --namespace default

 

--namespace 옵션을 명시하지 않으면 모두 default 네임스페이스에서 수행된다.

 

쿠버네티스 클러스터를 여러 명이 동시에 사용해야 한다면 사용자마다 네임스페이스를 별도로 생성해 사용하도록 설정할 수 있음. 용도에 따라 네임스페이스를 생성해서 특정 네임스페이스에서만 존재하도록 구성하도록 가능

 

* 리눅스 네임스페이스는 컨테이너의 격리된 공간을 생성하기 위해 리눅스 커널 자체 기능을 활용하는 것이며, 일반적으로 네트워크나 마운트, 프로세스 네임스페이스를 의미하며 쿠버네티스의 네임스페이스 오브젝트는 리눅스 네임스페이스와 완전히 다른 것

 

<production-namespace.yaml>

apiVersion: v1
kind: Namespace
metadata:
  name: production
$ kubectl apply -f production-namespace.yaml

 

또는 명령어로 바로 생성할 수 있다.

$ kubectl create namespace production

 

특정 네임스페이스에 리소스를 생성하려면 기존에 작성한 YAML 파일에서 metadata - namespace: production 만 추가해주면 된다.

 

 

쿠버네티스 클러스터 내부에서는 서비스 이름을 통해 포드에 접근할 수 있는데, 이는 같은 네임스페이스 내의 서비스만 가능하다.

 

네임스페이스를 삭제하려면

$ kubectl delete namespace production

 

네임스페이스에 존재하는 모든 리소스가 함께 삭제되니 리소스 목록을 미리 확인할 것

 

 

네임스페이스에 존재하는 오브젝트의 종류를 확인하려면

$ kubectl api-resources --namespaced=true

 

추가로 네임스페이스에는 ResourceQuota와 LimitRange를 설정할 수 있다.

ResourceQuota는 네임스페이스의 자원 한계를 설정하는 오브젝트로 네임스페이스에 들어갈 파드의 전체 requests와 limits을 설정할 수 있다. 이 경우에는 파드에 requests와 limits의 스펙을 명시해야만 한다.

LimitRange는 각 파드마다 네임스페이스에 들어올 수 있는지 자원을 체크하는 오브젝트이다.

 

 

컨피그맵(Configmap), 시크릿(Secret): 설정값을 포드에 전달

설정값을 YAML 파일에 env 옵션을 통해 작성할 수 있지만 이런 경우에는 개발, 운영 파일마다 각각 config 값을 명시해줘야 하는 경우가 생긴다. 각각 관리하는 경우 결국 큰 용량의 컨테이너 이미지를 각각 관리하는 것인데 이는 부담되는 일이다.

 

이러한 제약을 해결하기 위해 컨피그맵을 사용하면 1개의 포드 YAML 파일만을 사용하되 환경에 따라 다른 컨피그맵을 생성해서 사용할 수 있다.

$ kubectl create configmap <컨피그맵이름> <설정값들>
$ kubectl create configmap log-level-configmap --from-literal LOG_LEVEL=DEBUG4
$ kubectl create configmap start-k8s --from-literal k8s=kubernetes --from-literal container=docker

 

확인하려면..

$ kubectl get cm
$ kubectl describe configmap log-level-configmap

컨테이너 내부에서 env 명령어를 통해 확인할 수 있다.

 

생성된 컨피그맵을 포드에서 사용하려면 환경변수로 사용하거나 포드 내부 파일로 마운트해 사용할 수 있다.

컨피그맵의 값을 포드에서 환경변수로 사용하려면..

...

spec:
  containers:
  - name: my-container
    image: busybox
    agrs: ['tail', '-f', '/dev/null']
    envFrom:
    - configMapRef:
        name: log-level-configmap
    - configMapRef:
        name: start-k8s

envFrom 항목은 하나의 컨피그맵에 여러 키-값 쌍이 존재하더라도 모두 환경변수로 가져오도록 설정

따라서 총 3개의 환경변수가 등록되어 있음

 

 

다른 방법으로 컨피그맵에서 특정 데이터만 가져오려면..

...
env:
- name: ENV_KEYNAME_1
  valueFrom:
    configMapKeyRef:
      name: log-level-configmap
      key: LOG_LEVEL
- name: ENV_KEYNAME_2
  valueFrom:
    configMapKeyRef:
      name: start-k8s
      key: k8s

 

 

포드 내부에 마운트하려면..

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-pod
spec:
  containers:
  - name: my-container
    image: busybox
    args: ["tail" "-f", "/dev/null" ]
    volumeMounts:
    - name: configmap-volume 
      mountPath: /etc/config 

  volumes:
  - name: configmap-volume
    configMap:
      name: start-k8s

 

컨피그맵을 생성한 후 etc/config 맵을 조회해보면 값을 출력할 수 있다.

$ kubectl apply -f volume-mount-configmap.yaml
$ kubectl exec configmap-volume-pod ls /etc/config
$ kubectl exec configmap-volume-pod cat /etc/config/k8s

 

 

items와 path 항목을 통해 원하는 키-쌍 데이터만 선택해서 포드에 파일로 가져올 수 있음

 

파일로부터 컨피그맵을 생성하려면..

$ kubectl create configmap <컨피그맵이름> --from-file <파일이름>

 

기본적으로 파일 이름이 키로, 내용이 값으로 저장된다.

--from-env-file 옵션으로 여러 개의 키-값, 여러 줄로 구성된 설정 파일을 한번에 컨피그맵으로 가져올 수도 있음

 

 

출력 내용을 YAML 파일로 작성한 뒤, kubectl 명령어로 컨피그맵 생성 가능

$ kubectl create configmap my-configmap --from-literal mykey=myvalue --dry-run -o yaml >my-configmap.yaml
$ kubectl apply -f my-configmap.yaml

 

 

시크릿은 SSH 키, 비밀번호 등과 같이 민감 정보를 저장하기 위한 용도로 사용되며, 네임스페이스에 종속되는 쿠버네티스 오브젝트로 컨피그맵과 사용 방법이 비슷하다. 일반적인 쿠버네티스 오브젝트 값들은 쿠버네티스 DB에 저장되는데, 시크릿은 메모리에 저장된다. 컨피그맵의 경우 key, value 쌍을 무한히 넣을 수 있지만 시크릿은 1Mbyte까지 가능하다.

$ kubectl create secret generic my-password --from-literal password=123123

 

--from-file 이나 --from-env-file 옵션도 사용 가능

 

$ kubectl get secrets my-password -o yaml

패스워드는 인코딩한 값으로 저장되어 있음

 

컨피그맵과 사용 방법이 비슷하므로 YAML 파일에서 secretRef로 가져오거나 secretKeyRef로 특정 데이터만 선택해 원하는 이름의 환경변수로도 가져올 수 있고, 볼륨 마운트도 가능하다.

 

시크릿의 종류는 Type으로 볼 수 있는데, 기본은 Opaque이며 생성할 때 generic이라고 명시했던 것이 Opaque 타입에 해당하는 종류임

 

도커 허브에 공개돼있는 이미지는 다운받는데 문제없지만 사설 레지스트리 또는 도커 허브, 클라우드 레지스트리를 사용한다면 인증 절차가 필요하다.

 

쿠버네티스에서는 docker login 명령어 대신 별도의 시크릿을 생성해서 사용한다.

두 가지 방법이 있는데 첫 번째는 docker login 명령어로 성공했을 때 도커 엔진이 생성하는 ~/.docker/config.json 파일을 이용하는 것이다.

$ kubectl create secret generic registry-auth \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--type=kubernetes.io/dockerconfigjson

또는 직접 --docker-username과 --docker-password 옵션을 통해 직접 입력하면 된다.

 

이렇게 생성한 시크릿은 디플로이먼트 또는 포드 등에서 imagePullSecrets, name 항목을 통해 이미지를 받아올 때 사용할 수 있다.

 

 

시크릿의 데이터가 많아질수록 YAML 파일에 데이터를 저장하는 것은 가독성이나 관리에 있어 바람직하지 않다.

이러한 단점을 해결하기 위해 시크릿이나 컨피그맵을 배포하기 위해 YAML 파일을 작성할 때 데이터를 YAML 파일로부터 분리할 수 있는 kustomize 기능을 사용할 수 있다.

secretGenerator:
- name: kustomize-secret
  type: kubernetes.io/tls
  files:
  - tls.crt=cert.crt
  - tls.key=cert.key

 

시크릿을 생성하기 전에 kustomize로부터 생성될 시크릿의 정보를 미리 확인하려면..

$ kubectl kustomize ./

 

kustomize.yaml 파일로부터 시크릿을 생성하려면..

$ kubectl apply -k ./

 

 

컨피그맵이나 시크릿을 포드에 제공하는 방법으로 두 가지 중 환경변수로 설정 값을 제공하는 방법과 볼륨 파일로 마운트하는 방법이 있었는데, 첫 번째는 컨피그맵이나 시크릿 값을 변경해도 자동으로 재설정되지 않으며 디플로이먼트의 포드를 다시 생성해야만 한다. 파일로 포드 내부에 마운트 된 설정 파일은 컨피그맵이나 시크릿을 변경하면 내용도 자동으로 갱신된다.

 

단, 포드 내부에 마운트된 설정 파일이 변경됐다고 해서 실행중인 애플리케이션의 설정이 자동으로 변경되는 것은 아니니 로직을 직접 구현해야 한다.

 

요약 이미지

 

 

References:

https://kubetm.github.io/k8s/03-beginner-basic-resource/configmap/

 

ConfigMap, Secret

Env(Literal, File), Mount(File)

kubetm.github.io

http://www.yes24.com/Product/Goods/84927385

 

시작하세요! 도커/쿠버네티스 - YES24

본서는 도커를 처음 접하는 개발자를 위한 도커 컨테이너와 이미지의 기본적인 개념을 먼저 설명한 뒤, 도커 컴포즈와 스웜 모드를 통해 컨테이너 애플리케이션을 YAML 파일로 작성하고 클러스

www.yes24.com

 

반응형