클라우드/쿠버네티스

[Kubernetes] 15. 쿠버네티스 Configmap과 Secret (컨피그맵, 시크릿)

윤창이 2023. 4. 4. 00:53
728x90

[주의] 개인 공부를 위해 쓴 글이기 때문에 주관적인 내용은 물론, 쓰여진 정보가 틀린 것일 수도 있습니다!

피드백 부탁드립니다. (- -)(_ _) 꾸벅

 


 

 

컨피그맵(ConfigMap)

컨피그맵은 키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트이다. 파드는 볼륨에서 환경 변수, 커맨드-라인 인수 또는 구성 파일로 컨피그맵을 사용할 수 있다. 컨피그맵

kubernetes.io

 

애플리케이션을 배포하다 보면 환경에 따라 다른 설정 값을 사용하는 경우가 있는데, 도커 이미지는 정적이므로 각 환경에 따라 유연하게 변경할 수 없다는 단점이 있다. 대안으로 Yaml를 작성할 때 env 필드에서 환경 변수들을 작성하는 방법이 있지만 이 역시 하드코딩이다.

 

이러한 YMAL 파일과 설정값을 분리할 수 있는 것이 컨피그맵(Configmap)시크릿(Secret)이다.

컨피그맵에는 설정값을, 시크릿에는 노출이 되어서는 안 되는 비밀 값을 저장하여 사용하며, 값을 Pod로 넘기는 방법은 크게 두 가지가 있다.

  1. Pod의 환경 변수 (Environment variable)로 넘기는 방법
  2. Pod의 디스크 볼륨으로 마운트 하는 방법

 


[ ConfigMap ]

컨피그맵도 마찬가지로 create로 생성할 수 있고, --from-literal 파라미터로 키-값 쌍을 저장할 수 있다.

$ kubectl create configmap test --from-literal player_initial_lives=3 \
> --from-literal ui_properties_file_name=user-interface.properties
configmap/test created

$ kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      88d
test               1      6s

$ kubectl describe cm test
Name:         test
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
ui_properties_file_name:
----
user-interface.properties
player_initial_lives:
----
3

위에서 명령으로 컨피그맵을 만들었고 describe 명령을 통해 Data에 어떤 키-값 쌍이 있는지 확인할 수 있다.

 

또한 아래와 같이 data 필드를 활용하여 YAML 파일로 정의가 가능하다. (아래는 위에서 만든 컨피그맵을 YAML로 생성해봤다.) 절취 선 밑에 내용은 뒤에 예시를 위해 추가한건데, 파일과 비슷한 키 역할을 한다.

$ kubectl get cm test -o yaml > test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: test
  namespace: default

data:
  player_initial_lives: "3"
  ui_properties_file_name: user-interface.properties
 
 --- 아래는 제가 추가했습니다 ---
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

 

위 내용의 컨피그맵을 이용하여 아래에서 Pod를 생성할 때 사용할 수 있다.

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # 환경 변수 정의
        - name: PLAYER_INITIAL_LIVES # 이 값은 해당 컨테이너에서 사용할 환경변수 이름
          valueFrom:
            configMapKeyRef:
              name: test                # 가져올 컨피그맵 이름.
              key: player_initial_lives # 가져올 키.
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: test
              key: ui_properties_file_name
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
    # 파드 레벨에서 볼륨을 설정한 다음, 해당 파드 내의 컨테이너에 마운트한다.
    - name: config
      configMap:
        name: test          # 마운트하려는 컨피그맵의 이름을 제공한다.
        # 컨피그맵에서 파일로 생성할 키 배열
        items:
        - key: "game.properties"
          path: "game.properties"
        - key: "user-interface.properties"
          path: "user-interface.properties"

위에 예시처럼 컨피그맵으로 Pod에 변수를 전달하는 방법은 2가지가 있다.

  • env 구문을 이용하여 전달하는 방법
  • 볼륨을 마운트하여 파일로 제공하는 방법

컨테이너에 env 필드에서 valueFrom: configMapKeyRef 필드를 통해 컨피그맵 키-값 쌍을 가져올 수 있다.

해당 컨테이너의 PLATER_INITIAL_LIVES라는 환경변수는 "3"으로 지정되게 되는 의미이다.

 

마찬가지로 Volume을 마운트하여 키-값 쌍을 파일로도 가져올 수 있는데, 위에서는 해당 컨테이너 /config 폴더에 총 두 가지 파일 /config/game.properties  /config/user-interface.properties 2개의 파일이 생성된다.

items 배열을 생략하면 완전히 test라는 컨피그맵의 모든 data들을 가져와 추가적으로 /config/player_initial_lives/config/ui_properties_file_name 4개의 파일이 생성된다. (키 값이 파일명이 되어 버린다)

 

 


[ 컨피그맵 실습 ]

Question : Expose Configuration settings

TASK :
All operations in this question should be performed in the < your namespace > Create ConfigMap called web-config that contains the following two entries

connection_string=localhost:80
external_url=cncf.io

Run a pod called web-pod with a single container running the nginx:1.19.8-alpine image, and expose these configuration settings as environment variables inside the container.

 

1. 컨피그 맵 생성

$ kubectl create cm web-config --from-literal=connection_string=localhost:80 --from-literal=external_url=cncf.io
configmap/web-config created

 

2. Pod Yaml 파일 추출 후 수정하여 env 구문 추가

$ kubectl run web-pod --image=nginx:1.19.8-alpine --dry-run=client -o yaml > cm.yaml
$ vi cm.yaml

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: web-pod
  name: web-pod
spec:
  containers:
  - image: nginx:1.19.8-alpine
    name: web-pod
    resources: {}
###########추가###########
    env:
      - name: connection_string
        valueFrom:
          configMapKeyRef:
            name: web-config
            key: connection_string
      - name: external_url
        valueFrom:
          configMapKeyRef:
            name: web-config
            key: external_url
###########추가###########
  dnsPolicy: ClusterFirst
  restartPolicy: Always

 

3. 확인

$ kubectl exec -it web-pod -- env
connection_string=localhost:80
external_url=cncf.io
...

[ Secret ]

시크릿은 비밀번호, OAuth 토큰, SSH 키 값 같은 민감한 정보들을 저장하고 활용하는 용도로 사용한다.

이런 값들은 컨테이너에 하드코드하여 사용하는 것보다 포드가 실행될 때 시크릿을 통해서 컨테이너에 제공하는 형태이다.

$ kubectl create secret generic super-secret --from-literal=password=secretpass
secret/super-secret created

$ kubectl get secret super-secret -o yaml
apiVersion: v1
data:
  password: c2VjcmV0cGFzcw==   # BASE64로 인코딩 되어있다 (암호화는 아님)
kind: Secret
metadata:
  creationTimestamp: "2023-04-23T04:22:36Z"
  name: super-secret
  namespace: default
  resourceVersion: "31896"
  uid: e06f7b5b-0506-439a-9e16-8db8694d16fe
type: Opaque

 

https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod

위에는 Secret 파일을 Pod에서 사용하는 방법에 대한 글이다.

 

1. 볼륨 마운트를 통한 파일로 시크릿을 갖고오는 방법

$ sudo vi pod-secret-via-file.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: pod-secrets-via-file
  name: pod-secrets-via-file
spec:
  containers:
  - image: redis
    name: pod-secrets-via-file
    volumeMounts:
    - name : pod-secret
      mountPath: "/secrets"
  volumes:
  - name: pod-secret
    secret:
      secretName: super-secret

$ sudo kubectl apply -f pod-secret-via-file.yaml

 

2. 환경변수로 가져오는 방법

$ sudo vi pod-secret-via-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secrets-via-env
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: PASSWORD
        valueFrom:
          secretKeyRef:
            name: super-secret
            key: password

$ sudo kubectl apply -f pod-secret-via-env.yaml

 

시크릿은 Base64 형태로 인코딩만 할 뿐 컨피그맵과 큰 차이가 없어서 간단히 작성한다


 

728x90