DevOps/Kubernetes

[Kubernetes] 환경변수 관리(ConfigMap, Secret)

seungwook_TIL 2025. 5. 11. 00:25

이 글은 인프런의 지식 공유자 박재성님의 강의를 듣고 개인적으로 정리하는 글임을 알립니다.


ConfigMap

  • Spring Boot에서는 설정값을 application.yml으로 분리해서 관리한다.
  • 별도의 파일로 분리를 해서 관리함으로써 유지보수가 편리해지고 개발, 테스트, 프로덕션과 같은 환경 분리가 편해진다. 
  • 쿠버네티스에서는 파드(Pod), 디플로이먼트(Deployment), 서비스(Service)가 각각의 역할을 가지고 있는 것처럼 환경 변수를 관리하는 역할을 가진 오브젝트가 따로 존재한다.
  • 그게 바로 컨피그맵(ConfigMap)이다.

 

spring-config.yaml

apiVersion: v1
kind: ConfigMap

# ConfigMap 기본 정보
metadata:
  name: spring-config # ConfigMap 이름

# Key, Value 형식으로 설정값 저장
data:
  my-account: jscode
  my-password: password123

 

spring-deployment.yaml

apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 5 # 생성할 파드의 복제본 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app'이라는 값을 가진 파드를 선택

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블 (= 카테고리)
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너를 생성할 때 사용할 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 없으면 레지스트리에서 가져온다.
          ports:
            - containerPort: 8080  # 컨테이너에서 사용하는 포트를 명시적으로 표현
          env:
            - name: MY_ACCOUNT
              valueFrom:
                configMapKeyRef:
                  name: spring-config # ConfigMap의 이름
                  key: my-account # ConfigMap에 설정되어 있는 Key값
            - name: MY_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: spring-config
                  key: my-password

 

Manifest File 반영

kubectl apply -f spring-config.yaml
kubectl apply -f spring-deployment.yaml

 

이렇게 하면 환경변수를 외부에서 주입받을 수 있다.

 

 

Secret

  • 시크릿(Secret)은 컨피그맵(ConfigMap)과 비슷하게 환경 변수를 분리해서 관리하는 오브젝트이다.
  • 차이점은 시크릿(Secret)은 비밀번호와 같이 보안적으로 중요한 값을 관리하기 위한 오브젝트이다.
항목 ConfigMap Secret
용도 일반 설정값 (예: 서비스 이름, 포트 번호) 민감 정보 (예: 비밀번호, API 키, 토큰 등)
저장 방식 일반 텍스트 (Base64 인코딩 없이) Base64로 인코딩된 형태
디스크 저장 kubelet이 평문으로 저장 kubelet이 /tmpfs에 암호화 저장 (가능하면 메모리상)
API 접근 제어 기본적으로 접근 가능 접근 권한 제한 (권한 관리로 보호 가능)
자동 암호화 ❌ 없음 ✅ 가능 (EncryptionConfiguration으로 etcd 암호화 설정 시)
  • ConfigMap : 아무나 쉽게 볼 수 있고 민감하지 않음
  • Secret : 꺼내보려면 권한이 필요함

즉, 누가 Kubernetes API 서버에 접근하더라도 Secret은 RBAC 권한이 없다면 볼 수 없도록 설계되어 있고, etcd에 저장될 때도 암호화 설정이 가능하다.

 

단순히 Secret 리소스를 생성하고 끝내면 보안은 절반만 한 셈이다.

Secret은 보호 장치를 연동했을 때만 진짜로 ‘보안적 의미’를 갖는다.

조치 설명
RBAC 설정 특정 사용자만 Secret을 get, list, watch할 수 있도록 제한
etcd 암호화 설정 EncryptionConfiguration을 이용해 Secret만 암호화 저장되도록 설정
NetworkPolicy 적용 Secret이 mount된 Pod에 외부 접근 제한
PodSecurityPolicy / OPA / Kyverno Secret을 민감하지 않은 리소스에서 사용하지 못하게 정책 적용
Audit Log 활성화 누가 Secret을 열람하거나 변경했는지 추적 가능하게 설정

이 글에서 보호 장치를 연동하는 방법은 다루지 않는다.

 

spring-config.yaml

apiVersion: v1
kind: Secret

# ConfigMap 기본 정보
metadata:
  name: spring-config # ConfigMap 이름

# Key, Value 형식으로 설정값 저장
data:
  my-account: jscode
  • 여기서는 민감한 정보를 삭제한다.

 

spring-secret.yaml

apiVersion: v1
kind: Secret

# Secret 기본 정보
metadata:
  name: spring-secret # Secret 이름

# Key, Value 형식으로 값 저장
stringData:
  my-password: my-secret-password

 

spring-deployment.yaml

apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 5 # 생성할 파드의 복제본 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app'이라는 값을 가진 파드를 선택

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블 (= 카테고리)
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너를 생성할 때 사용할 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 없으면 레지스트리에서 가져온다.
          ports:
            - containerPort: 8080  # 컨테이너에서 사용하는 포트를 명시적으로 표현
          env:
            - name: MY_ACCOUNT
              valueFrom:
                configMapKeyRef:
                  name: spring-config # ConfigMap의 이름
                  key: my-account # ConfigMap에 설정되어 있는 Key값
            - name: MY_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: spring-secret
                  key: my-password

 

Manifest File 반영

kubectl apply -f spring-secret.yaml
kubectl apply -f spring-config.yaml
kubectl apply -f spring-deployment.yaml

 

이렇게 하면 일반 환경변수는 ConfigMap에서 관리하고, 민감한 환경변수는 Secret에 저장하여 안전하게 서비스를 운영할 수 있다.