
쿠버네티스 시크릿(Secret)은
비밀번호, 토큰, 인증서 키처럼 민감한 데이터를 저장하기 위한 API 오브젝트이다.
컨테이너 이미지나 파드 매니페스트 안에 비밀번호를 그대로 적어두면,
시크릿을 쓰면 이런 민감한 값을 파드 스펙과 분리해서 별도 오브젝트로 관리할 수 있다.
파드는 시크릿을 환경 변수(env)나 볼륨(volume) 으로만 받아서 사용하고,
실제 값은 시크릿 오브젝트 안에만 들어 있는 구조이다.
기본적으로 시크릿의 data 필드는 Base64 인코딩 문자열로 저장된다.
(보안 암호화가 아니라 인코딩이기 때문에, etcd 암호화 같은 추가 보안 설정도 함께 고려해야 한다.)
쿠버네티스 공식 문서 기준으로, 시크릿을 쓰는 이유는 대략 이렇게 정리할 수 있다.
대표적인 타입은 다음과 같다. (공식 문서 기준 요약)
| 타입 | 용도 (요약) |
|---|---|
Opaque | 기본형. 임의의 키/값 데이터 저장 |
kubernetes.io/service-account-token | 서비스 어카운트 토큰 |
kubernetes.io/dockerconfigjson | 프라이빗 레지스트리 접속용 자격 증명 |
kubernetes.io/tls | TLS 인증서(tls.crt, tls.key) 저장 |
실습에서는 가장 흔한 Opaque 타입만 사용한다.
이번 실습 흐름은 이렇게 3단계로 잡았다.
먼저 MySQL 계정 정보를 담을 mysql-cred 시크릿을 만든다.
kubectl create secret generic mysql-cred \
--from-literal=username='db-user' \
--from-literal=password='nh' \
-n default
kubectl get secret mysql-cred -n default
kubectl describe secret mysql-cred -n default

이렇게 mysql-cred로 시크릿이 생성된 것을 확인할 수 있다.
kubectl get secret mysql-cred -n default -o yaml

필드 해석:
| 필드 | 설명 |
|---|---|
type | Opaque = 기본 임의 데이터 시크릿 |
data | Base64 인코딩된 키-값 쌍 |
username | 키 이름. 값은 Base64 인코딩된 문자열 |

kubectl get sc 해서 나오는 standard와 연결해주었다.
파일 명 : mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
pvc 적용
kubectl apply -f mysql-pvc.yaml
kubectl get pvc mysql-pvc

이제 방금 만든 mysql-cred 시크릿을
Deployment 안 컨테이너 환경 변수로 주입해서 쓰는 실습이다.
시크릿 관련 부분만 핵심 위주로 정리했다.
파일명: mysql-deploy-with-secret.yaml
# 파일명: mysql-deploy-with-secret.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-with-secret
labels:
app: mysql-with-secret
spec:
replicas: 1
selector:
matchLabels:
app: mysql-with-secret
template:
metadata:
labels:
app: mysql-with-secret
spec:
containers:
- name: mysql
image: mysql:8.0
env:
# 루트 계정 비밀번호 (예시라서 그냥 value 사용)
- name: MYSQL_ROOT_PASSWORD
value: rootpassword
# 사용자 ID 를 Secret 에서 가져오기
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-cred # 1단계에서 만든 Secret
key: username # db-user
# 사용자 PW 를 Secret 에서 가져오기
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-cred # 같은 Secret
key: password # nh
# 자동으로 만들 DB 이름
- name: MYSQL_DATABASE
value: testdb
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql # 데이터 파일 저장 위치
volumes:
- name: mysql-pvc
persistentVolumeClaim:
claimName: mysql-pvc # 2단계에서 만든 pvc 이름
포인트 정리
env[*].valueFrom.secretKeyRef.name: mysql-cred
→ 1단계에서 만든 시크릿 객체 이름
key: username, key: password
→ 시크릿 안에 들어 있는 키 이름 (username=db-user, password=nh)
MySQL 공식 이미지는 아래 env 를 보고 초기 설정을 한다.
즉, 이 디플로이먼트를 생성하면
이런 조합으로 MySQL 이 한 번에 초기화된다.
적용&확인
# 디플로이 생성
kubectl apply -f mysql-deploy-with-secret.yaml
# 파드 상태 확인
kubectl get pods -l app=mysql-with-secret

이렇게 파드가 Running 이 되면 시크릿 + PVC 조합이 정상 동작 중인 것이다.
운영 환경에서는 실수로 시크릿 내용을 덮어쓰는 사고를 막고 싶을 때가 많다.
쿠버네티스는 이런 경우를 위해 immutable Secret 기능을 제공한다.
한 번 immutable 로 만들면, 내용을 수정할 수 없고 삭제 후 재생성만 가능하다.
4-1) 기존 시크릿을 immutable 로 변경
아래처럼 시크릿 정의에 immutable: true 를 추가해서 다시 적용할 수 있다.
(기존 시크릿을 kubectl apply 로 관리한다고 가정)
파일명: mysql-cred-immutable.yaml
# 파일명: mysql-cred-immutable.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-cred
namespace: default
type: Opaque
immutable: true
data:
username: ZGItdXNlcg== # db-user (Base64)
password: bmg= # nh (Base64)
이미 kubectl create secret ... 로 만들어둔 시크릿이 있으니까,
위 YAML 을 저장한 다음 그대로 apply 하면 된다.
kubectl apply -f mysql-cred-immutable.yaml

배포를 하게 되면 이렇게 warning 메세지가 뜨게 된다.
메세지를 해석해보면 다음과 같다.
“이 시크릿은 immutable 이라서 내용(data)을 바꿀 수 없다.
바꾸고 싶으면 시크릿을 삭제하고 새로 만들어라.”
kubectl describe secret mysql-cred -n default
describe로 확인해보면,

비밀번호가 바뀌지 않은 것을 확인할 수 있다.
실제 운영에서는:
등에 immutable 을 걸어두면, 사람 실수로 인한 장애를 줄이는 데 도움이 된다.
| 단계 | 내용 | 핵심 포인트 |
|---|---|---|
| 1 | mysql-cred 시크릿 생성 | Opaque 타입, username/password 저장 |
| 2 | mysql-pvc 생성 | MySQL 데이터 저장용 PVC, SC=standard |
| 3 | mysql-with-secret 디플로이 생성 | Secret 을 env 로 주입, MySQL 초기화 |
| 4 | 시크릿에 immutable: true 설정 | 이후 내용 수정 불가, 삭제 후 재생성만 가능 |
참고자료:
[쿠버네티스 공식 문서 – Secret]
https://kubernetes.io/docs/concepts/configuration/secret/?utm_source=chatgpt.com
[쿠버네티스 공식 문서 – Distribute Credentials Securely Using Secrets]
https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/?utm_source=chatgpt.com