Post

[쿠버네티스] 컨피그맵, 시크릿으로 환경변수 관리하기

0. 환경변수 관리

Spring 부트 서버의 application.yml과 같이 사용될 환경변수들을 쿠버네티스에서 관리하는 방법이다.

우선

  • application.yml
1
2
3
4
5
6
7
spring :  
  application :  
    name : demo  
  
secret :  
  data1 : 'data1'  
  data2 : 'data2'

과 같은 상황에서 부트서버에서 위 변수들을 사용하고 싶을때

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController  
class AppController(  
    @Value("\${secret.data1}")  
    private val data1 : String,  
    @Value("\${secret.data2}")  
    private val data2 : String  
) {  
    @GetMapping("/")  
    fun home() : String{  
        return "Version 1.0"  
    }  
  
    @GetMapping("/data")  
    fun data() : String{  
        return "$data1 $data2";  
    }  
}

이와 같이 가져와 줄 수 있다.

이때 여러 파드에서 해당 변수 (예를들어 db 개정이나 ip 등)을 공통적으로 관리하면 중복된 변수 설정이나 보안적으로 안전하게 관리할 수 있게 된다.

1. deployment에서 관리하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: apps/v1  
kind: Deployment  
  
metadata:  
  name: spring-deployment  
  
spec:  
  replicas: 3  
  selector:  
    matchLabels:  
      app: backend-app  
  
  template:  
    metadata:  
      labels:  
        app: backend-app  
    spec:  
      containers:  
        - name: spring-container  
          image: spring-server  
          imagePullPolicy: IfNotPresent  
          ports:  
            - containerPort: 8080  
	      
	      ## 여기서 설정함
          env:  
            - name: secret.data1  
              value: config_data1  
            - name: secret.data2  
              value: config_data2

위와 같이 관리할 경우 기존 스프링에서 환경 변수를 설정할 것을 덮어서 관리할 수 있다.

이후 k8s를 띄우고 접속해보면

deployment_set.png

다음과 같이 출력되는 것을 확인할 수 있다.

이 후 해당 파드에 접속하여 env를 확인해보면

1
2
3
4
5
kubectl exec -it spring-deployment-**** -- bash
bash-4.4# env
## 생략
secret.data2=config_data2
secret.data1=config_data1

환경변수도 변경된 것을 확인할 수 있다.

하지만 위와 같이 deployment에서 관리를 할 경우 다른 환경에서 서버를 실행할때 유연하게 교체하기 힘들다.

2. ConfigMap에서 관리하기

Springboot에서는 설정값(properties)를 application.yml로 관리를 한다.

이때 dev, test, product 환경에따라 yml을 분리하여 관리할 수 있는데 k8s에서도 이를 분리하여 관리할 수 있다.

ConfigMap은 위와 같이 환경변수를 환경에 따라 분리하여 관리를 해주는 오브젝트이다.

  • spring-config.yml
1
2
3
4
5
6
7
8
9
apiVersion: v1  
kind: ConfigMap  
  
metadata:  
  name: spring-config  
  
data:  
  secret.data1: 'config_map_data1'  
  secret.data2: 'config_map_data2'

이렇게 할 경우 configmap에서 secret.data1에는 해당 값을 저장하는 식으로 운영을 하게된다.

이 후 deployments.yaml에서는

  • deployments.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    ### 생략
    
    template:  
      
          ### 생략
          env:  
              ### 환경변수명
            - name: secret.data1  
              ### 외부에서 가져오겠다는 의미
              valueFrom:  
              .  ### configmap을 사용하겠다는 의미
                configMapKeyRef:  
                  ### 사용할 configmap 이름
                  name: spring-config  
                  ### 사용할 키
                  key: secret.data1  
    		  
            - name: secret.data2  
              valueFrom:  
                configMapKeyRef:  
                  name: spring-config  
                  key: secret.data2
    

3. Secret에서 관리하기

컨피그맵과 비슷하게 환경변수를 관리하는 오브젝트

비밀번호와 같이 보안적으로 중요한 값을 관리하기 위한 오브젝트이다.

  • spring-secret.yaml
1
2
3
4
5
6
7
8
9
apiVersion: v1  
kind: Secret  
  
metadata:  
  name: spring-secret  
  
stringData:  
  data1: secret-data-1  
  data2: secret-data-2

다음과 같이 설정하며 stringData에 key-value로 넣으면 된다

deployment에 적용을 할때에는

1
2
3
4
5
6
## 생략
		  - name: secret.data2  
			valueFrom:  
			  secretKeyRef: 
				name: spring-secret 
				key: data2

와 같이 사용하면된다.

사용하거나 작성법은 configmap과 secret과 큰 차이가 없다.

4. Secret과 Configmap의 차이점

Config는 공통적으로 쓰일 환경변수를 관리하기 위해 사용이된다면

Secret은 암호와 같이 노출됐을때 치명적인 정보를 사용된다.

1
kubectl get secret spring-secret -o yaml

위 명령어를 통해 secret을 읽어보면

1
2
3
4
5
6
apiVersion: v1
data:
  data1: c2VjcmV0LWRhdGEtMQ==
  data2: c2VjcmV0LWRhdGEtMg==
## 생략

이와 같이 출력되는데 위 data1, data2가 암호화되어 저장되는 것을 확인할 수 있다. (암호화 방식은 base64이다)

출처

비전공자 쿠버네티스 입문 실전

This post is licensed under CC BY 4.0 by the author.