DevOps/Kubernetes

[Kubernetes] ConfigMap / Secret: config 정보를 container 외부에서 가져오기

ooeunz 2020. 7. 22. 10:06
반응형

ConfigMap이란?

일반적으로 컨테이너를 사용할 때 Dev용 컨테이너와 Product용 컨테이너는 같아야 합니다. 그래야만 개발과 서비스 사이의 환경적인 차이에서 오는 문제점을 방지할 수 있습니다. 하지만, 개발을 하다 보면 dev용과 product는 서로 다른 설정이 필요한 경우가 있습니다. 예를 들면 개발용 컨테이너는 Test용 데이터베이스를 사용합니다. 개발 또는 테스트를 하는 중에 문제가 생겨 실 서비스에서 사용하는 데이터베이스에 문제를 일으킬 수 있기 때문입니다. 이와 같이 서비스마다 다른 설정이 필요할 때 사용하는 것이 바로 컨피그맵(ConfigMap)입니다. 컨피그맵은 컨테이너에 필요한 환경 설정을 컨테이너와 분리해서 제공하는 방식으로 하나의 컨테이너로 개발용, 스테이지용, 서비스용과 같은 다양한 방식으로 사용할 수 있습니다.

 

설정한 환경변수 값은 템플릿을 통해 할당해줄 수 있으며, 해당 템플릿에 의해 생성된 컨테이너에서 접근할 수 있습니다. (예를 들어 노드의 경우 process.env.<컨피그맵의 환경변수 이름>과 같이 접근할 수 있습니다.

 

ConfigMap template

컨피그맵 템플릿을 사용하는 방법을 살펴보겠습니다. 아래의 코드와 같이 컨피그맵은 data필드 하위에 사용할 환경 설정 값들을 작성하게 됩니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-dev
  namespace: default
data:
  THIS_IS_EXAMPLE01: configexample01
  THIS_IS_EXAMPLE02: configexample02
  THIS_IS_EXAMPLE03: configexample03

위의 템플릿을 작성한 다음 kubectl apply -f <템플릿 이름>으로 컨피그맵을 실행 합니다. 정상적으로 실행했다면 kubectl describe configmap <컨피그맵 이름> 명령어로 방금 입력한 설정 값이 제대로 들어갔는지 확인해봅니다.

 

 

ConfigMap에서 data 불러와서 사용하기 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: configsample
  labels:
    app: configsample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: configsample
  template:
    metadata:
      labels:
        app: configsample
    spec:
      containers:
      - name: testconfig
        image: arisu1000/simple-container-app:latest
        ports:
        - containerPort: 8080
        env:
        - name: DEBUG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: sisko
              key: THIS_IS_EXAMPLE01
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: configapp
  name: configapp-svc
  namespace: default
spec:
  ports:
  - nodePort: 30800
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: configsample
  type: NodePort

이위의 템플릿 중에 컨피그맵의 설정을 불러오는 영역은 .envFrom.configMapRef 필드입니다. name 필드에 컨피그맵의 이름을 지정하고, key 필드에 원하는 key의 이름을 지정하면 해당 컨피그맵의 원하는 환경 변수만 불러올 수 있습니다. 만약 전체 컨피그맵 환경설정을 불러오고 싶다면 key 필드를 제외하고 name 필드만 지정해주면 됩니다. 

 

이제 컨테이너에서 컨피그맵 환경 변수를 정상적으로 가져왔는지 확인해보겠습니다. 로컬 호스트라면 localhost:30800으로, 또는 클라우드 서비스라면 해당 서비스의 ip주소의 30800 포트로 접근하면 환경변수 목록에 THIS_IS_EXAMPLE01 값이 추가된 것을 확인할 수 있습니다.

 


Secret

시크릿은 password, OAuth Token, SSH KEY와 같은 민감한 정보들을 저장하는 용도로 사용됩니다. 이러한 정보들을 컨테이너 안에 저장하지 않고 별도로 보관했다가 실제 파드를 실행할 때 템플릿으로 컨테이너에 제공하게 됩니다. 시크릿은 내장 시크릿과 사용자 정의 시크릿이 있는데, 그중 내장 시크릿은 쿠버네티스 클러스터 안에서 쿠버네티스 api에 접근할 때 사용합니다. 해당 시크릿으로 ServiceAccount가 사용 권한을 갖는 api에 접근할 수 있습니다. 반면 사용자 정의 시크릿은 사용자가 만든 시크릿으로, kubectl create secret 명령어로 생성할 수 있고, 다른 리소스처럼 템플릿으로 만들 수도 있습니다. 앞서 설명했던 컨피그맵과 차이가 있다면 시크릿은 저장할 때 설정 값을 Base64로 인코딩해서 저장해야 한다는 점입니다. 하나의 시크릿 사이즈는 최대 1MB까지 지원이 되는데, 메모리에 저장되기 때문에 보안적으로 꼭 필요한 정보만 저장하는 것이 좋습니다.

 

명령어로 시크릿 만들기

echo -n  명령어로 사용자 이름과 비밀번호를 설정하는 파일을 만든 다음 kubectl create secret generic <시크릿 이름> 명령어로 user-secret이라는 이름의 시크릿을 만듭니다. 시크릿을 만든 다음에는 kubectl get secret <시크릿 이름> -o yaml 명령어로 생성한 시크릿에 대한 정보를 확인할 수 있습니다.

위의 이미지를 보면  data 하위 필드에 password.txt와 username.txt를 확인할 수 있는데, 필드 값이 우리가 저장한 문자열이 아닌 Base64로 인코딩 된 형태인 것을 알 수 있습니다. echo <디코딩할 base64 값> | base64 decode 명령어로 필드 값들을 디코딩해서 원래 값을 확인할 수 있습니다.

 

템플릿으로 시크릿 만들기

apiVersion: v1
kind: Secret
metadata:
  name: user-secret-yaml
type: Opaque
data:
  username: cGFzc3dvcmQ=
  password: dXNlcm5hbWU=

템플릿으로 시크릿을 만들 때. type 값을 지정할 수 있는데 시크릿 타입은 아래와 같습니다.

  • Opaque : 키-값 형태로 임의의 데이터를 설정할 수 있습니다. 기본 값입니다.
  • kubernetes.io/service-account-token : k8s 인증 토큰을 저장합니다.
  • kubernetes.io/dockerconfigjson : 도커 저장소 인증 정보를 저장합니다.
  • kubernetes.io/tls : TLS 인증서를 저장합니다.

 

그런데 템플릿으로 시크릿을 저장할 때 주의 점이 하나 있는데, 명령어로 시크릿을 설정하는 것과 다르게 base64 인코딩 값으로 넣어줘야 한다는 것입니다. base64 인코딩은 echo -n <인코딩 하려는 문자열> | base64 명령어로 인코딩할 수 있습니다.

반응형