본문 바로가기
클라우드/쿠버네티스

🔐 Kubernetes Secret: API 키와 DB 비밀번호, 이제 안전하게 관리하세요!

by gasbugs 2025. 9. 2.

안녕하세요! 👋 오늘은 쿠버네티스 환경에서 애플리케이션을 운영할 때 가장 중요하지만, 자칫 소홀하기 쉬운 주제인 민감 정보 관리에 대해 이야기해보려고 합니다.

 

DB 접속 비밀번호, 외부 API 키, TLS 인증서... 이런 민감한 정보들을 혹시 코드에 그대로 하드코딩하거나, 누구나 볼 수 있는 설정 파일에 평문으로 저장하고 계시진 않나요? 🙅‍♂️ 이런 방식은 보안 사고로 이어지는 지름길입니다!

 

쿠버네티스는 이런 위험한 상황을 방지하고 민감 정보를 안전하게 관리할 수 있도록 Secret이라는 아주 중요한 오브젝트를 제공합니다. 오늘은 Secret이 무엇인지, 어떻게 만들고 사용하는지 A to Z까지 파헤쳐 보겠습니다!

 


🤔 Secret이란? 민감 정보를 위한 특별 금고

Secret은 이름 그대로 비밀스러운 데이터를 저장하기 위한 쿠버네티스 오브젝트입니다. 지난 시간에 배운 ConfigMap과 역할은 비슷하지만, 결정적인 차이가 있습니다.

  • ConfigMap: 일반적인 설정 정보 (Key-Value)
  • Secret: 비밀번호, 토큰, API 키 등 민감한 정보 (Key-Value)

Secret은 ConfigMap과 마찬가지로 파드(Pod)의 코드와 민감 정보를 분리하여 보안과 유연성을 높여줍니다.

 

⚠️ 잠깐! Base64는 암호화가 아니에요!

한 가지 매우 중요한 사실을 짚고 넘어가야 합니다. Secret에 저장된 데이터는 기본적으로 Base64로 인코딩(Encoding)되어 etcd에 저장됩니다.

Bash
# 'my-super-secret-password'를 Base64로 인코딩
$ echo -n 'my-super-secret-password' | base64
bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk

하지만 Base64 인코딩은 누구나 쉽게 원래의 문자열로 디코딩(Decoding)할 수 있습니다. 즉, 암호화(Encryption)가 아닙니다!

Bash
# Base64 문자열을 다시 원래대로 디코딩
$ echo 'bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk' | base64 --decode
my-super-secret-password

 

그렇다면 Secret을 왜 쓸까요? Secret의 진정한 가치는 다음과 같습니다.

  1. 접근 제어: 쿠버네티스의 RBAC(역할 기반 접근 제어)를 통해 특정 사용자나 서비스 계정만 Secret을 읽거나 쓸 수 있도록 권한을 통제할 수 있습니다.
  2. 분리: 민감 정보를 코드나 이미지로부터 분리하여 Git 같은 버전 관리 시스템에 우발적으로 노출되는 것을 방지합니다.
  3. 통합: 파드에 안전하게 민감 정보를 주입하는 표준화된 방법을 제공하며, Vault와 같은 외부 Secret 관리 솔루션과 통합할 수 있습니다.

🛠️ Secret 생성하기: 명령어 방식 vs. 선언형 방식

Secret을 생성하는 방법은 크게 두 가지가 있습니다.

1. 명령형 방식 (Imperative)

kubectl 명령어를 사용하여 빠르고 간편하게 Secret을 만들 수 있습니다.

 

🔹 리터럴(Literal)로부터 생성하기 --from-literal 플래그를 사용하여 Key-Value를 직접 지정합니다.

# DB 사용자 이름과 비밀번호를 담는 Secret 생성
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password='my-super-secret-password'

 

 

🔹 파일(File)로부터 생성하기 --from-file 플래그를 사용하여 파일의 내용을 Secret 데이터로 사용합니다. 파일 이름이 Key가 됩니다.

# api_key.txt 파일 생성
echo -n 'ABCDEFG12345' > ./api_key.txt

# 파일로부터 Secret 생성
kubectl create secret generic api-key-secret \
  --from-file=./api_key.txt

2. 선언형 방식 (Declarative)

YAML 파일을 작성하여 Secret을 관리하는 방식으로, GitOps 등 형상 관리에 유리합니다. 이 방법을 사용하려면 데이터 값을 직접 Base64로 인코딩해야 합니다.

 

db-secret.yaml 예시:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret-from-yaml
type: Opaque # 가장 일반적인 Secret 타입
data:
  # echo -n 'admin' | base64 -> YWRtaW4=
  username: YWRtaW4=
  # echo -n 'my-super-secret-password' | base64 -> bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk
  password: bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk

 

YAML 파일을 작성한 후 kubectl apply -f db-secret.yaml 명령어로 클러스터에 적용하면 됩니다.


🚀 Pod에서 Secret 사용하기: 안전하게 주입하는 2가지 방법

생성된 Secret은 ConfigMap과 마찬가지로 파드에 환경 변수 또는 볼륨 파일 형태로 주입할 수 있습니다.

1. 환경 변수(Environment Variables)로 주입하기

Secret의 데이터를 컨테이너의 환경 변수로 전달합니다. 간단하지만, 환경 변수는 로깅되거나 다른 프로세스에 노출될 가능성이 있어 보안상 덜 선호될 수 있습니다.

 

secret-env-pod.yaml 예시:

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: my-container
    image: busybox
    command: [ "/bin/sh", "-c", "env | grep DB" ]
    env:
      # 특정 Key의 값을 환경 변수로 주입
      - name: DB_USERNAME
        valueFrom:
          secretKeyRef:
            name: db-secret # 사용할 Secret 이름
            key: username   # 사용할 Key
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: db-secret
            key: password

 

2. 볼륨(Volume)으로 마운트하기 (✨ 추천)

Secret의 데이터를 파일 형태로 컨테이너의 특정 경로에 마운트합니다. 환경 변수보다 더 안전한 방법으로 권장됩니다.

  • 파일 시스템에 존재하므로 필요한 애플리케이션만 접근 가능
  • 파일 접근 권한(permission) 설정 가능
  • 파드 재시작 없이도 Secret 변경 사항이 자동으로 파일에 반영됨

secret-volume-pod.yaml 예시:

apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-pod
spec:
  containers:
  - name: my-container
    image: busybox
    command: [ "/bin/sh", "-c", "ls -l /etc/secrets && cat /etc/secrets/username" ]
    volumeMounts:
    - name: secret-volume
      mountPath: "/etc/secrets" # 컨테이너 내부에 마운트할 경로
      readOnly: true # 읽기 전용으로 마운트하는 것이 안전함
  volumes:
  - name: secret-volume
    secret:
      secretName: db-secret # 사용할 Secret 이름

이 파드를 실행하면, 컨테이너의 /etc/secrets 디렉토리 아래에 username과 password라는 파일이 생성되고, 각 파일의 내용은 Secret에 저장된 디코딩된 값입니다.


✨ 정리하며: 보안의 첫걸음, Secret

오늘은 쿠버네티스에서 민감한 정보를 다루는 표준 방법인 Secret에 대해 알아보았습니다.

  • Secret은 비밀번호, API 키 등 민감 정보를 코드와 분리하여 저장하는 오브젝트입니다.
  • Base64는 암호화가 아니며, Secret의 진짜 힘은 RBAC을 통한 접근 제어안전한 주입 방식에 있습니다.
  • kubectl 명령어나 YAML 파일을 통해 생성할 수 있습니다.
  • 보안을 위해 환경 변수보다는 볼륨으로 마운트하여 사용하는 것을 권장합니다.
  • 더 높은 수준의 보안이 필요하다면 HashiCorp Vault 같은 외부 Secret 관리 솔루션과 연동하는 것을 고려해야 합니다.

더 이상 민감 정보를 위험하게 방치하지 마세요. Secret을 사용하여 여러분의 애플리케이션을 더 안전하고 견고하게 만드시길 바랍니다! 🛡️


태그: Kubernetes, Secret, K8s, 쿠버네티스, 보안, 비밀번호 관리, DevOps, MSA, API 키, YAML