본문 바로가기
Cloud

Kubernetese Conifg , Secret 실습 및 정리

by kssosoy 2025. 7. 11.

1.  왜 설정과 코드를 분리해야 할까

애플리케이션 개발 시 설정 정보(데이터베이스 URL, API 키 등)를 코드 안에 직접 작성(하드코딩)하는 경우가 있습니다. 하지만 이는 다음과 같은 문제를 야기합니다.

  • 환경별 변경의 어려움: 개발, 테스트, 운영 환경마다 DB 주소나 로깅 레벨이 다르다면, 환경을 바꿀 때마다 코드를 수정하고 다시 빌드해야 합니다.
  • 보안 취약점: 민감한 정보(비밀번호)가 코드에 포함되면 Git 리포지토리나 이미지에 노출될 위험이 있습니다.
  • 재사용성 저하: 동일한 애플리케이션이지만 설정만 다른 여러 인스턴스를 띄우기 어렵습니다.

쿠버네티스의 ConfigMap과 Secret은 이러한 문제를 해결하고 "설정과 코드의 분리(Separation of Concerns)"라는 모범 사례를 따르게 해줍니다.

 

기존에 진행하던 deployment.yaml 은 다음과 같이 설정 데이터를 직접 하드 코딩해주었습니다. 이 내용을 분리하는 실습을 진행해보겠습니다. 

<이전 코드> 

 env:

            - name: SPRING_DATASOURCE_URL

              value: jdbc:mysql://mysql:3306/test

            - name: SPRING_DATASOURCE_USERNAME

              value: root

            - name: SPRING_DATASOURCE_PASSWORD

              value: password

            - name: SPRING_DATA_MONGODB_URI

              value: mongodb://mongodb:27017/testdb

2. ConfigMap: 민감하지 않은 설정 데이터 관리

ConfigMap은 민감하지 않은 설정 데이터를 키-값(Key-Value) 쌍으로 저장하는 데 사용됩니다. 애플리케이션 환경 변수, 설정 파일 내용 등을 관리할 때 적합합니다.

 

2.1 ConfigMap 생성하기 

# my-app-db-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-db-config # 이 ConfigMap의 이름
data:
  # 환경 변수로 주입될 설정 키-값 쌍
  SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/test
  SPRING_DATASOURCE_USERNAME: root
  SPRING_DATA_MONGODB_URI: mongodb://mongodb:27017/testdb
  
  # 파일로 주입될 설정 내용 (key가 파일 이름이 됨)
  app_custom_settings.txt: |
    # My Custom App Settings
    server.port=8080
    debug.mode=true

 

2.2 적용하기

kubectl apply -f my-app-db-config.yaml

 

명령어로 ConfigMap 생성하기 간단한 키-값 쌍은 명령어로도 빠르게 생성할 수 있습니다.

# 리터럴(literal) 값으로 생성
kubectl create configmap my-app-env-config --from-literal=APP_ENV=dev --from-literal=LOG_LEVEL=DEBUG

# 파일 내용으로 생성 (먼저 my_file.txt 파일 생성: echo "TEST_VALUE=Hello" > my_file.txt)
kubectl create configmap my-app-file-config --from-file=config.txt=my_file.txt

2.2 ConfigMap을 파드에 주입하기

이제 생성한 ConfigMap의 데이터를 my-java-app 파드에 주입해 보겠습니다. 디플로이먼트(Deployment)의 YAML 파일을 수정해야 합니다.

 

방법 A: 환경 변수로 주입 (개별 키-값)

my-java-app 디플로이먼트의 컨테이너 정의 부분에 env 섹션을 추가하여 ConfigMap의 특정 키를 파드의 환경 변수로 매핑합니다.

# deployment.yaml 
# ...
          containers:
            - name: my-java-app
              image: dockerhubid/test:2.0 # 당신의 애플리케이션 이미지
              ports:
                - containerPort: 8080
              env: # <--- 이 부분 추가/수정
                - name: SPRING_DATASOURCE_URL # 파드 내에서 사용할 환경 변수 이름
                  valueFrom:
                    configMapKeyRef:
                      name: my-app-db-config # 사용할 ConfigMap 이름
                      key: SPRING_DATASOURCE_URL # ConfigMap 내의 키
                - name: SPRING_DATASOURCE_USERNAME
                  valueFrom:
                    configMapKeyRef:
                      name: my-app-db-config
                      key: SPRING_DATASOURCE_USERNAME
                - name: SPRING_DATA_MONGODB_URI
                  valueFrom:
                    configMapKeyRef:
                      name: my-app-db-config
                      key: SPRING_DATA_MONGODB_URI
# ...

방법 B: 볼륨(파일)으로 주입

ConfigMap에 정의된 app_custom_settings.txt 같은 설정 파일을 파드 내 특정 경로에 마운트하여 사용할 수 있습니다.

YAML
 
# my-java-app-deployment.yaml (수정된 부분)
# ...
          containers:
            - name: my-java-app
              image: qws1566/test:2.0
              ports:
                - containerPort: 8080
              volumeMounts: # <--- 컨테이너 내부에 볼륨 마운트
                - name: app-config-volume # 아래 volumes 섹션과 이름 일치
                  mountPath: "/etc/app-settings" # 파드 내에서 ConfigMap 파일들이 마운트될 경로
                  readOnly: true # 읽기 전용으로 마운트
# ...
      volumes: # <--- spec: 바로 아래에 볼륨 정의
        - name: app-config-volume
          configMap:
            name: my-app-db-config # 마운트할 ConfigMap의 이름
            # items: # (선택 사항) 특정 파일만 마운트하려면 사용
            #   - key: app_custom_settings.txt
            #     path: custom.conf # 파드 내 파일 이름 변경 가능

디플로이먼트 YAML 파일 수정 후 클러스터에 적용하여 롤링 업데이트를 시작합니다.

kubectl apply -f <deployment.yaml_파일>

 

2.3 주입된 ConfigMap 정보 확인하기

새로운 파드들이 실행되면, 파드 내부 셸에 접속하여 환경 변수와 파일 내용을 확인합니다.

  1. 파드 이름 확인:
    kubectl get pods -l app=my-java-app
    
  2. 파드 셸 접속: (새로 생성된 파드 중 아무거나 선택)
    kubectl exec -it <파드_이름> -- bash
    
  3. 정보 확인 (파드 내부 셸에서):
    • 환경 변수 확인:
      echo $SPRING_DATASOURCE_URL
      echo $SPRING_DATASOURCE_USERNAME
      echo $SPRING_DATA_MONGODB_URI
      
    • 파일 내용 확인 (볼륨으로 주입했다면):
      ls /etc/app-settings/
      cat /etc/app-settings/app_custom_settings.txt
      
  4. 파드 셸 종료:
    exit

다음과 같이 잘 저장된 것을 확인 가능합니다. 

 

Secret: 민감한 데이터 안전하게 관리하기

Secret은 비밀번호, API 토큰, 인증서와 같은 민감한 정보를 저장하는 데 사용됩니다. ConfigMap과 유사하지만, 데이터가 Base64로 인코딩되어 저장되며, etcd에 저장 시 암호화될 수 있다는 차이점이 있습니다.

 

3.1 Secret 생성하기

MySQL 데이터베이스 비밀번호 (ex: dsjflksefj) 을 Secret으로 관리해 봅시다. 주의: Secret의 data 필드 값은 반드시 Base64로 인코딩되어야 합니다.

# 비밀번호를 Base64로 인코딩 (터미널에서 실행):
echo -n "바꾸려는 비밀번호 값" | base64
# 출력되는 값을 아래 YAML에 사용합니다.

 

 

# my-app-db-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-app-db-secret # 이 Secret의 이름
type: Opaque # 일반적인 키-값 Secret 타입
data:
  SPRING_DATASOURCE_PASSWORD: <위에서_인코딩한_비밀번호의_Base64_값>
kubectl apply -f my-app-db-secret.yaml

 

명령어로 Secret 생성하기 간단한 Secret은 명령어로도 생성할 수 있습니다. 이 경우 쿠버네티스가 자동으로 Base64 인코딩을 처리해 줍니다.

# 리터럴(literal) 값으로 생성
kubectl create secret generic my-app-credential-secret --from-literal=API_KEY=your_super_secret_key

# 파일 내용으로 생성 (예: my_cert.pem 파일의 내용을 cert.pem 키로)
# kubectl create secret generic my-app-cert-secret --from-file=cert.pem=my_cert

 

deployment.yaml 파일을 수정해줍니다. 

# Secret에서 비밀번호 가져오기 (새로 추가)
                - name: SPRING_DATASOURCE_PASSWORD # 파드 내에서 사용할 환경 변수 이름
                  valueFrom:
                    secretKeyRef:
                      name: my-app-db-secret # 사용할 Secret 이름
                      key: SPRING_DATASOURCE_PASSWORD # Secret 내의 키

 

방법 B: 볼륨(파일)으로 주입

Secret의 내용을 파드 내 특정 경로에 파일로 마운트할 수 있습니다.

deployment.yaml 
# ...
          containers:
            - name: my-java-app
              image: qws1566/test:2.0
              ports:
                - containerPort: 8080
              volumeMounts:
                # 기존 ConfigMap 볼륨 마운트 (유지)
                - name: app-config-volume
                  mountPath: "/etc/app-settings"
                  readOnly: true
                # Secret 볼륨 마운트 (새로 추가)
                - name: app-secret-volume
                  mountPath: "/etc/app-secrets" # 파드 내에서 Secret 파일들이 마운트될 경로
                  readOnly: true
# ...
      volumes:
        # 기존 ConfigMap 볼륨 정의 (유지)
        - name: app-config-volume
          configMap:
            name: my-app-db-config
        # Secret 볼륨 정의 (새로 추가)
        - name: app-secret-volume
          secret:
            secretName: my-app-db-secret # 마운트할 Secret의 이름
            # items: # (선택 사항) 특정 파일만 마운트하려면 사용
            #   - key: SPRING_DATASOURCE_PASSWORD
            #     path: db_password.txt # 파드 내 파일 이름 변경 가능

 

kubectl apply -f <deployment.yaml_파일>

 

3.3 주입된 Secret 정보 확인하기

새로운 파드들이 실행되면, 파드 내부 셸에 접속하여 환경 변수와 파일 내용을 확인합니다.

  1. 파드 이름 확인:
    kubectl get pods -l app=my-java-app
    
  2. 파드 셸 접속:
    kubectl exec -it <파드_이름> -- bash
    
  3. 정보 확인 (파드 내부 셸에서):
    • 환경 변수 확인:결과: kimsoyun1! (Base64 인코딩된 값이 아닌 원래 값으로 출력됩니다!)
      echo $SPRING_DATASOURCE_PASSWORD
      
    • 파일 내용 확인 (볼륨으로 주입했다면):결과: kimsoyun1! (파일 내용도 자동으로 디코딩되어 보입니다.)
      ls /etc/app-secrets/
      cat /etc/app-secrets/SPRING_DATASOURCE_PASSWORD
      
  4. 파드 셸 종료:
    exit

4. ConfigMap과 Secret 비교

구분 ConfigMap Secret
목적 민감하지 않은 설정 데이터 저장 (예: DB URL, API 키, 로깅 레벨) 민감한 데이터 저장 (예: 비밀번호, 인증서, 토큰)
데이터 형식 일반 텍스트 (Base64 인코딩 불필요) Base64 인코딩 (저장 시 필수, 파드 주입 시 자동 디코딩)
보안 수준 일반 텍스트로 저장 및 전송되므로, kubectl get configmap 시 내용이 바로 노출 etcd에 저장 시 암호화 가능 (클러스터 설정에 따라 다름). kubectl get secret 시 Base64로 인코딩된 형태로만 보임.
주입 방식 환경 변수, 볼륨(파일) 환경 변수, 볼륨(파일)
용례 애플리케이션의 일반 설정, 환경 설정, 커스텀 파일 데이터베이스 비밀번호, 클라우드 API 키, TLS/SSL 인증서