IMG-LOGO
공지사항 :

Kubernetes ConfigMap과 Secret을 이용한 애플리케이션 설정 관리

lmkfox - 2026-08-31 07:24:16 2 Views 0 Comment

Kubernetes 환경에서 애플리케이션을 운영하다 보면 반드시 만나게 되는 문제가 있습니다. 바로 애플리케이션 설정값을 어떻게 관리할 것인가입니다.

개발 환경에서는 소스 코드에 데이터베이스 주소나 포트, API 주소 등을 직접 입력해도 큰 문제가 없을 수 있습니다. 하지만 운영 환경에서는 개발 서버와 운영 서버의 설정이 다르고, 데이터베이스 비밀번호나 API Key처럼 외부에 노출되어서는 안 되는 정보도 존재합니다.

예를 들어 다음과 같은 FastAPI 애플리케이션이 있다고 가정해 보겠습니다.

DB_HOST=postgres
DB_PORT=5432
DB_NAME=taxdb
DB_USER=taxuser
DB_PASSWORD=비밀번호

이러한 정보를 Docker Image나 애플리케이션 소스 코드에 직접 넣는 것은 좋은 방법이 아닙니다.

Kubernetes에서는 이러한 설정을 애플리케이션과 분리하기 위해 ConfigMapSecret을 제공합니다.

이번 글에서는 ConfigMap과 Secret의 개념부터 생성 방법, Pod에 적용하는 방법, 환경변수와 파일로 사용하는 방법, 그리고 실무에서 주의해야 할 보안 문제까지 알아보겠습니다.


1. 애플리케이션 설정을 분리해야 하는 이유

먼저 설정값을 소스 코드에 직접 넣는 방식의 문제를 생각해 보겠습니다.

DATABASE_HOST = "192.168.10.100"
DATABASE_PASSWORD = "123456"

개발 환경에서는 작동할 수 있지만 운영 환경에서는 여러 가지 문제가 발생합니다.

첫 번째는 환경별 설정 변경이 어렵다는 것입니다.

개발 서버
DB_HOST=192.168.10.100

운영 서버
DB_HOST=192.168.20.100

소스 코드를 수정해야 한다면 배포 과정이 복잡해집니다.

두 번째는 보안 문제입니다.

Git에 소스 코드를 저장하는 경우 데이터베이스 비밀번호가 그대로 노출될 수 있습니다.

Git Repository
      │
      └── application.py
             │
             └── DB_PASSWORD="123456"

따라서 애플리케이션 코드와 환경별 설정을 분리하는 것이 중요합니다.

Kubernetes에서는 다음과 같은 구조를 사용할 수 있습니다.

Application
     │
     ├── ConfigMap
     │      ├── DB_HOST
     │      ├── DB_PORT
     │      └── API_URL
     │
     └── Secret
            ├── DB_PASSWORD
            ├── API_KEY
            └── TOKEN

2. ConfigMap이란 무엇인가?

ConfigMap은 애플리케이션에서 사용하는 일반적인 설정값을 저장하는 Kubernetes 객체입니다.

대표적인 설정값은 다음과 같습니다.

서버 주소
포트 번호
환경 이름
API URL
로그 레벨
애플리케이션 옵션

예를 들어 다음과 같은 설정을 만들 수 있습니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  DB_HOST: "postgres-service"
  DB_PORT: "5432"
  LOG_LEVEL: "INFO"

파일 이름을 configmap.yaml로 저장합니다.

kubectl apply -f configmap.yaml

생성 여부를 확인합니다.

kubectl get configmap

상세 내용을 확인하려면 다음 명령어를 사용합니다.

kubectl describe configmap app-config

3. ConfigMap을 환경변수로 사용하는 방법

ConfigMap을 생성했다고 해서 Pod가 자동으로 설정값을 사용하는 것은 아닙니다.

Deployment에서 ConfigMap을 환경변수로 연결해야 합니다.

예를 들어 다음과 같이 작성할 수 있습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          env:
            - name: APP_ENV
              valueFrom:
                configMapKeyRef:
                  name: app-config
                  key: APP_ENV
            - name: DB_HOST
              valueFrom:
                configMapKeyRef:
                  name: app-config
                  key: DB_HOST

이렇게 하면 컨테이너 내부에서 환경변수로 사용할 수 있습니다.

echo $APP_ENV

결과:

production

다음과 같이 확인할 수도 있습니다.

echo $DB_HOST

결과:

postgres-service

4. ConfigMap 전체를 환경변수로 가져오기

설정값이 많다면 하나씩 지정하는 것보다 ConfigMap 전체를 환경변수로 가져오는 방법도 있습니다.

envFrom:
  - configMapRef:
      name: app-config

예를 들어 다음과 같이 사용할 수 있습니다.

containers:
  - name: application
    image: myapp:1.0
    envFrom:
      - configMapRef:
          name: app-config

그러면 ConfigMap의 모든 key가 환경변수로 전달됩니다.

APP_ENV
DB_HOST
DB_PORT
LOG_LEVEL

애플리케이션에서는 일반적인 환경변수처럼 사용할 수 있습니다.

Python이라면 다음과 같은 방식입니다.

import os

db_host = os.getenv("DB_HOST")
db_port = os.getenv("DB_PORT")

이 구조는 FastAPI와 같은 서버 애플리케이션에서 매우 유용합니다.


5. ConfigMap을 파일로 사용하는 방법

ConfigMap은 환경변수뿐만 아니라 파일 형태로 Pod에 전달할 수도 있습니다.

예를 들어 다음 ConfigMap을 생성합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    server {
        listen 80;

        location / {
            root /usr/share/nginx/html;
        }
    }

Deployment에서는 ConfigMap을 Volume으로 연결합니다.

volumes:
  - name: nginx-config
    configMap:
      name: nginx-config

그리고 컨테이너에 Mount합니다.

volumeMounts:
  - name: nginx-config
    mountPath: /etc/nginx/conf.d

그러면 컨테이너 내부에 설정 파일이 생성됩니다.

/etc/nginx/conf.d/nginx.conf

이 방식은 Nginx, Apache 등의 설정 파일을 Kubernetes에서 관리할 때 유용합니다.


6. Secret이란 무엇인가?

ConfigMap이 일반적인 설정값을 저장한다면 Secret은 비밀번호, 토큰, 인증서 등 민감한 정보를 관리하기 위한 Kubernetes 객체입니다.

대표적으로 다음과 같은 정보가 있습니다.

Database Password
API Key
Access Token
TLS Certificate
SSH Key
Cloud Credential

예를 들어 PostgreSQL 접속 정보를 관리한다고 가정하겠습니다.

DB_USER=taxuser
DB_PASSWORD=비밀번호

이때 비밀번호를 ConfigMap에 저장하는 것보다는 Secret을 사용하는 것이 적절합니다.


7. Secret 생성하기

Secret은 YAML을 이용하여 만들 수 있습니다.

예를 들어 다음과 같이 작성할 수 있습니다.

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  DB_USER: "taxuser"
  DB_PASSWORD: "StrongPassword"

적용합니다.

kubectl apply -f secret.yaml

확인합니다.

kubectl get secret

다음과 비슷한 결과가 나옵니다.

NAME         TYPE     DATA   AGE
db-secret    Opaque   2      10s

Secret의 상세 정보를 확인할 수도 있습니다.

kubectl describe secret db-secret

여기서 중요한 점은 kubectl get secret을 사용한다고 해서 평문 비밀번호가 그대로 화면에 표시되는 것은 아니라는 것입니다.


8. Secret을 환경변수로 사용하는 방법

Deployment에서 Secret 값을 환경변수로 연결할 수 있습니다.

env:
  - name: DB_USER
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: DB_USER

  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: DB_PASSWORD

그러면 컨테이너에서는 다음과 같이 사용할 수 있습니다.

echo $DB_USER
taxuser

비밀번호 역시 환경변수로 전달됩니다.

echo $DB_PASSWORD

다만 실무에서는 비밀번호를 터미널에 직접 출력하는 행동은 피해야 합니다.


9. ConfigMap과 Secret을 함께 사용하는 구조

실제 애플리케이션에서는 ConfigMap과 Secret을 함께 사용하는 경우가 많습니다.

예를 들어 FastAPI + PostgreSQL 환경을 생각해 보겠습니다.

                    FastAPI Pod
                        │
             ┌──────────┴──────────┐
             │                     │
        ConfigMap               Secret
             │                     │
      ┌──────┼──────┐        ┌─────┴─────┐
      │      │      │        │           │
   DB_HOST DB_PORT LOG_LEVEL DB_USER   DB_PASSWORD
             │                     │
             └──────────┬──────────┘
                        ▼
                  FastAPI Application
                        │
                        ▼
                  PostgreSQL Service
                        │
                        ▼
                  PostgreSQL Pod

예를 들어 ConfigMap에는 다음을 저장합니다.

DB_HOST=postgres-service
DB_PORT=5432
DB_NAME=taxdb
LOG_LEVEL=INFO

Secret에는 다음을 저장합니다.

DB_USER=taxuser
DB_PASSWORD=StrongPassword

이렇게 하면 일반 설정과 민감한 정보를 분리할 수 있습니다.


10. Secret의 Base64 인코딩에 대한 중요한 오해

Kubernetes Secret을 처음 배우는 사람들이 가장 많이 오해하는 부분입니다.

Secret 데이터가 Base64로 표현되는 경우가 있지만 Base64는 암호화가 아닙니다.

예를 들어 다음 문자열을 Base64로 인코딩하면 쉽게 다시 원래 값으로 변환할 수 있습니다.

echo -n "StrongPassword" | base64

따라서 다음과 같이 생각하면 안 됩니다.

Base64 = 암호화

정확하게는 다음과 같이 이해해야 합니다.

Base64
  ↓
Encoding
  ↓
암호화가 아님

Kubernetes Secret의 실제 보안 수준은 API 접근 권한, RBAC, etcd 보호, 암호화 설정, 운영 환경의 Secret 관리 체계 등에 의해 결정됩니다.


11. Secret과 RBAC

운영 환경에서는 Secret에 접근할 수 있는 사용자를 제한해야 합니다.

예를 들어 일반 개발자가 모든 Secret을 조회할 수 있도록 권한을 부여하면 보안 문제가 발생할 수 있습니다.

Kubernetes에서는 **RBAC(Role-Based Access Control)**를 이용하여 권한을 제어합니다.

구조는 다음과 같습니다.

사용자
  │
  ▼
Role / ClusterRole
  │
  ▼
RoleBinding
  │
  ▼
Kubernetes Resource

예를 들어 특정 Namespace의 Pod 조회 권한만 부여하거나 특정 Secret에 대한 접근을 제한할 수 있습니다.

실무에서는 "누가 어떤 Secret을 읽을 수 있는가?"를 반드시 관리해야 합니다.


12. Namespace와 ConfigMap, Secret

ConfigMap과 Secret은 Namespace 단위로 관리되는 리소스입니다.

예를 들어 다음과 같이 구성할 수 있습니다.

Namespace: development
 ├── ConfigMap
 └── Secret

Namespace: production
 ├── ConfigMap
 └── Secret

개발 환경과 운영 환경을 분리할 수 있습니다.

예를 들어 개발 환경에서는

DB_HOST=dev-postgres

운영 환경에서는

DB_HOST=prod-postgres

를 사용할 수 있습니다.

애플리케이션 이미지는 동일하게 유지하면서 설정만 변경할 수 있다는 것이 중요한 장점입니다.


13. ConfigMap과 Secret 변경 시 주의사항

운영 중 ConfigMap이나 Secret을 변경했다고 해서 애플리케이션의 모든 환경변수가 즉시 변경되는 것은 아닙니다.

특히 환경변수 방식으로 주입된 설정값은 이미 실행 중인 프로세스에 자동으로 반영되지 않습니다.

따라서 설정을 변경한 후 Deployment를 다시 배포하거나 Pod를 재시작해야 하는 경우가 많습니다.

예를 들어 다음 명령어를 사용할 수 있습니다.

kubectl rollout restart deployment nginx

상태를 확인합니다.

kubectl rollout status deployment nginx

이 부분은 운영 환경에서 매우 중요합니다.

설정 파일을 수정했는데 애플리케이션이 계속 이전 설정을 사용한다면 ConfigMap 변경 여부뿐 아니라 Pod 재시작 여부와 Mount 방식까지 확인해야 합니다.


14. 실무에서 사용하는 FastAPI 구성 예제

앞서 학습한 내용을 FastAPI 서버에 적용해 보겠습니다.

구조는 다음과 같습니다.

Kubernetes
│
├── FastAPI Deployment
│      │
│      ├── ConfigMap
│      │
│      └── Secret
│
├── FastAPI Service
│
└── PostgreSQL Service
       │
       └── PostgreSQL Pod

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: fastapi-config
data:
  DB_HOST: "postgres-service"
  DB_PORT: "5432"
  DB_NAME: "taxdb"
  LOG_LEVEL: "INFO"

Secret:

apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
type: Opaque
stringData:
  DB_USER: "taxuser"
  DB_PASSWORD: "StrongPassword"

FastAPI Deployment에서는 다음과 같이 연결할 수 있습니다.

envFrom:
  - configMapRef:
      name: fastapi-config

  - secretRef:
      name: postgres-secret

그러면 FastAPI 애플리케이션은 다음과 같이 환경변수를 사용할 수 있습니다.

import os

DB_HOST = os.getenv("DB_HOST")
DB_PORT = os.getenv("DB_PORT")
DB_NAME = os.getenv("DB_NAME")
DB_USER = os.getenv("DB_USER")
DB_PASSWORD = os.getenv("DB_PASSWORD")

이 구조를 사용하면 Docker Image 안에 데이터베이스 비밀번호를 포함하지 않아도 됩니다.


15. 시스템 엔지니어가 자주 사용하는 확인 명령어

ConfigMap을 확인합니다.

kubectl get configmap

특정 ConfigMap을 확인합니다.

kubectl describe configmap fastapi-config

Secret 목록을 확인합니다.

kubectl get secret

Secret의 상세 정보를 확인합니다.

kubectl describe secret postgres-secret

Pod에 전달된 환경변수를 확인하려면 다음과 같이 접근할 수 있습니다.

kubectl exec -it <pod-name> -- env

Pod 내부 파일을 확인할 수도 있습니다.

kubectl exec -it <pod-name> -- ls -l /etc/config

문제가 발생했다면 Pod 상태도 함께 확인합니다.

kubectl get pods

그리고 로그를 확인합니다.

kubectl logs <pod-name>

16. ConfigMap과 Secret 운영 시 주의사항

실무에서 가장 중요한 부분입니다.

첫째, 비밀번호를 Git 저장소에 평문으로 저장하지 않는 것이 중요합니다.

다음과 같은 파일은 주의해야 합니다.

password.yaml
database-secret.yaml
production.env
.env

둘째, Kubernetes Secret이라고 해서 모든 보안 문제가 자동으로 해결되는 것은 아닙니다.

셋째, RBAC를 이용하여 Secret 접근 권한을 최소화해야 합니다.

넷째, 운영 환경에서는 etcd에 저장되는 데이터에 대한 보호와 암호화 정책도 검토해야 합니다.

다섯째, 규모가 큰 환경에서는 외부 Secret 관리 시스템과 Kubernetes를 연동하는 방법도 고려할 수 있습니다.

중요한 것은 애플리케이션 설정과 민감한 정보를 애플리케이션 코드와 분리한다는 원칙입니다.


마무리

Kubernetes의 ConfigMap과 Secret은 단순한 설정 파일 저장 기능이 아닙니다. 컨테이너 애플리케이션과 운영 환경의 설정을 분리하기 위한 핵심 기능입니다.

전체 구조를 정리하면 다음과 같습니다.

                  Application
                       │
          ┌────────────┴────────────┐
          │                         │
     ConfigMap                    Secret
          │                         │
    일반 설정값                  민감한 정보
          │                         │
    ┌─────┼─────┐              ┌────┼────┐
    │     │     │              │    │    │
   Host  Port  Log            ID  Password Token
          │                         │
          └────────────┬────────────┘
                       ▼
                  Application

ConfigMap에는 일반적인 애플리케이션 설정을 저장하고 Secret에는 비밀번호, API Key, 인증서와 같은 민감한 정보를 저장합니다.

그리고 Kubernetes Deployment에서 이를 환경변수 또는 파일 형태로 Pod에 전달합니다.

시스템 엔지니어 입장에서 가장 중요한 개념은 다음 네 가지입니다.

ConfigMap
→ 일반적인 설정 관리

Secret
→ 민감한 정보 관리

Deployment
→ 설정을 Pod에 주입

RBAC
→ 설정과 Secret에 대한 접근 권한 관리

앞으로 Kubernetes를 실제 운영 환경에 적용하려면 여기에서 한 단계 더 나아가야 합니다. 특히 여러 애플리케이션을 운영할 때는 설정값을 체계적으로 관리하고, 환경별 설정을 분리하며, 민감한 정보를 안전하게 저장하는 구조가 필요합니다.


댓글