1. 개요
컨테이너 이미지는 환경과 무관하게 같아야 하고, 환경마다 다른 것(DB 주소, 비밀번호)은 밖에서 넣어야 한다. 그리고 Pod 는 일회용이라 안에 쓴 파일은 Pod 와 함께 사라진다. 이 글은 설정과 비밀을 넣는 법, 그리고 지워지면 안 되는 데이터를 두는 법이다.
2. 핵심 내용
2-1. ConfigMap: 환경변수와 파일
ConfigMap 은 민감하지 않은 설정을 key-value 로 담는다. 주입 방식은 둘이다.
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
LOG_LEVEL: info
app.properties: |
feature.x=true
---
# Pod 스펙 일부
containers:
- name: web
envFrom:
- configMapRef: { name: web-config } # 환경변수로
volumeMounts:
- name: cfg
mountPath: /etc/web # 파일로
volumes:
- name: cfg
configMap: { name: web-config }차이는 갱신에 있다. 환경변수는 컨테이너가 뜰 때 한 번 정해진다. ConfigMap 을 고쳐도 떠 있는 Pod 의 환경변수는 안 바뀐다. 볼륨으로 마운트한 파일은 시간이 지나면 갱신되지만, 앱이 파일을 다시 읽어야 반영된다. 어느 쪽이든 보통은 Deployment 를 재시작해서 반영한다.
2-2. Secret 은 암호화가 아니다
Secret 은 사용법이 ConfigMap 과 거의 같다. 다만 값이 base64 로 저장된다.
echo -n 'hunter2' | base64 # aHVudGVyMg==
echo 'aHVudGVyMg==' | base64 -d # hunter2base64 는 인코딩이지 암호화가 아니다. 읽을 수 있는 사람이면 누구나 즉시 푼다. Secret 이 ConfigMap 보다 나은 점은 RBAC 로 접근을 따로 제한할 수 있다는 것, 로그나 출력에서 덜 노출된다는 것, 그리고 etcd 저장 시 암호화를 켤 수 있다는 것(기본은 꺼져 있다)이다. 그래서 YAML 을 git 에 그대로 올리면 안 된다. 그 문제를 푸는 방식과 값을 꺼내지 않고 검증하는 방법은 SealedSecret 을 값 없이 검증하기에 있다.
2-3. 볼륨의 종류
emptyDir 은 Pod 가 뜰 때 생기는 빈 디렉터리이고 Pod 가 사라지면 함께 지워진다. 같은 Pod 안 컨테이너끼리 파일을 주고받거나 임시 캐시를 둘 때 쓴다. 컨테이너만 재시작되면 유지되지만, Pod 가 다시 만들어지면 사라진다.
살아남아야 하는 데이터에는 영속 볼륨을 쓴다.
- PersistentVolume(PV): 실제 저장소 조각.
- PersistentVolumeClaim(PVC): “이만큼 필요하다” 는 요청. Pod 는 PVC 만 안다.
- StorageClass: PVC 가 생길 때 PV 를 어떻게 자동으로 만들지 정한 템플릿(동적 프로비저닝).
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes: [ReadWriteOnce] # 한 노드에서만 읽기·쓰기
storageClassName: longhorn
resources:
requests:
storage: 10GiPod 는 지워져도 PVC 와 PV 는 남는다. 다만 PV 의 reclaimPolicy 가 Delete 면 PVC 를 지울 때 데이터도 지워진다. 어떤 볼륨이 백업 대상에서 조용히 빠질 수도 있는데, 그 사례는 Longhorn 백업은 detached 볼륨을 건너뛴다에 적었다.
2-4. StatefulSet 이 필요한 이유
DB 를 Deployment 로 띄우면 Pod 이름과 볼륨 연결이 매번 무작위다. StatefulSet 은 Pod 에 db-0, db-1 처럼 고정된 이름과 순서를 주고, volumeClaimTemplates 로 Pod 마다 자기 PVC 를 하나씩 붙인다. Pod 가 다시 떠도 같은 이름은 같은 볼륨으로 돌아간다. 상태가 있는 앱에 쓴다. 그렇다고 StatefulSet 이 복제나 장애 조치를 해 주는 것은 아니다. 이름과 저장소를 안정적으로 이어 줄 뿐이다.
2-5. 어디서 실수하나
- Secret 을 암호화된 것으로 믿고 평문 YAML 을 커밋한다.
- ConfigMap 을 고쳤는데 환경변수 주입이라 앱이 옛 값을 계속 쓴다.
- 데이터를 컨테이너 파일시스템이나 emptyDir 에 쓰고 재배포 뒤 사라져서 놀란다.
- ReadWriteOnce 볼륨을 여러 노드의 Pod 가 함께 쓰려 한다.
3. 마무리
요약
- ConfigMap 은 환경변수나 파일로 주입하며, 환경변수는 컨테이너 시작 시점에 고정된다.
- Secret 의 base64 는 암호화가 아니므로 평문 YAML 을 git 에 올리지 않는다.
- emptyDir 은 Pod 와 수명이 같고, 영속 데이터는 PVC 와 StorageClass 로 요청한다.
- StatefulSet 은 고정된 이름과 Pod 별 볼륨을 줄 뿐, 복제나 장애 조치까지 해 주지는 않는다.
다음은 Kubernetes 기초 7 - 스케줄링과 리소스이다.