[k8s 기초 5편] 파드가 죽어도 데이터는 살려야 한다: PV, PVC, ConfigMap
jay
2026년 1월 20일 08:00
지난 4편까지 우리는 쿠버네티스 위에 웹 서버를 띄우고(Deployment), 외부에서 접속(Ingress)하는 것까지 성공했다. 이제 Stateless(상태가 없는) 애플리케이션은 얼마든지 운영할 수 있다.
하지만 데이터베이스(DB)처럼 데이터가 계속 저장되어야 하는 애플리케이션이라면 이야기가 달라진다. 파드는 언제든 죽을 수 있고, 파드가 죽으면 그 안에 있던 파일도 함께 증발한다.
마지막 5편에서는 데이터를 영구적으로 저장하는 Volume(볼륨) 시스템과, 환경 설정값을 코드에서 분리하는 ConfigMap에 대해 정리하며 시리즈를 마무리한다.
목차
1. 파드는 믿지 마라 (Ephemeral Storage)
다시 한번 강조하지만, 파드는 ‘임시적(Ephemeral)’이다. 도커 컨테이너를 쓸 때 -v(볼륨) 옵션 없이 컨테이너를 지웠다 다시 띄우면 데이터가 다 날아갔던 것을 알 수 있을 것이다. 쿠버네티스도 똑같다.
MySQL 파드를 띄워서 데이터를 잔뜩 저장해 놨어도, 파드가 재시작되거나 다른 노드로 옮겨가는 순간 그 데이터는 초기화된다. 이것이 기본 설정이다.
그래서 우리는 파드의 수명과 관계없이 데이터를 보존할 별도의 저장소가 필요하다. 이것을 쿠버네티스에서는 Volume(볼륨)이라고 부른다.
2. 저장소의 두 얼굴: PV와 PVC
쿠버네티스의 스토리지 개념이 처음엔 좀 헷갈리는데, “관리자(인프라)”와 “사용자(개발자)”의 역할을 분리해 놨기 때문이다.
① PV (Persistent Volume) : 실제 저장 공간 (하드웨어)
- 정의: 클러스터 내에 존재하는 실제 스토리지 자원이다.
- 비유: 데이터센터에 꽂혀 있는 1TB짜리 외장 하드 혹은 AWS EBS 볼륨 그 자체.
- 역할: “여기에 100GB짜리 공간이 있어”라고 정의해 둔 것.
② PVC (Persistent Volume Claim) : 요청서 (영수증)
- 정의: 사용자가 PV를 쓰겠다고 요청하는 것.
- 비유: 개발자가 인프라 담당자에게 내미는 결재 서류.
- 역할: “나 DB 띄울 건데, 10GB 정도 필요하고 읽기/쓰기 다 되어야 해(Claim)”라고 쿠버네티스에게 요청한다.
작동 원리
개발자가 PVC(요청서)를 만들면, 쿠버네티스는 현재 준비된 PV(저장소)들 중에서 조건에 맞는 것을 찾아 자동으로 연결(Binding)해 준다. 파드는 이 PVC를 마치 USB 꽂듯이 마운트 해서 쓰면 된다.

💡 k3s Tip (Dynamic Provisioning) 홈서버(k3s)에서는 PV를 일일이 손으로 만들 필요가 없다. k3s에는 ‘Local Path Provisioner’라는 게 기본으로 깔려 있어서, PVC만 만들면 알아서 호스트 서버의 특정 경로(
/var/lib/rancher/k3s/storage)에 폴더를 만들고 PV를 생성해서 연결해 준다. 만약, 원하는 경로가 있으면 변경하면 된다.
3. 실전 YAML: PVC 만들고 파드에 연결하기
실제로 데이터를 영구 저장하는 PVC를 만들고 Nginx에 연결해 보자.
1단계: PVC 작성 (요청서)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-data-pvc
spec:
accessModes:
- ReadWriteOnce # 하나의 노드에서만 읽기/쓰기 가능
resources:
requests:
storage: 1Gi # 1GB 주세요
2단계: Pod에서 PVC 사용
apiVersion: v1
kind: Pod
metadata:
name: nginx-with-volume
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html" # 컨테이너 내부 경로
name: my-storage # 아래 volumes 이름과 매칭
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-data-pvc # 위에서 만든 PVC 이름
이렇게 하면 파드가 죽었다 살아나도, /usr/share/nginx/html 경로에 저장된 파일은 영원히 살아남는다.
4. 설정 관리: ConfigMap과 Secret
이미지를 빌드할 때 설정값(DB 주소, 비밀번호 등)을 코드 안에 하드코딩해서 넣는 것은 최악의 패턴이다. 설정이 바뀔 때마다 이미지를 다시 빌드해야 하기 때문이다.
쿠버네티스는 설정값을 코드에서 분리해서 관리하는 객체를 제공한다.
① ConfigMap
- 용도: 민감하지 않은 일반 설정값 (환경변수, 설정 파일 내용).
- 예시:
LOG_LEVEL=DEBUG,nginx.conf파일 내용 등.
② Secret
- 용도: 노출되면 안 되는 민감한 정보.
- 예시:
DB_PASSWORD,API_KEY등. - 특징: 기본적으로 Base64로 인코딩되어 저장되며, 메모리에만 마운트 되는 등 보안적인 처리가 되어 있다. (물론 etcd 암호화 등 추가 조치가 필요할 수 있다.)
이들을 사용하면 “애플리케이션 이미지(변경 없음)” + “환경 설정(변경 가능)” 구조를 만들 수 있어, 개발/운영 환경 차이를 쉽게 관리할 수 있다.
5. 시리즈를 마치며: 이제 시작이다

이렇게 총 5편에 걸쳐 쿠버네티스의 기본기를 정리해 봤다.
- Why: 도커의 한계를 넘어 오케스트레이션이 필요한 이유.
- Architecture: 마스터와 워커, 조타수와 선원들의 역할.
- Workload: 파드(Pod)와 디플로이먼트(Deployment).
- Network: 서비스(Service)와 인그레스(Ingress).
- Storage: PV/PVC와 설정 관리.
이 정도 개념만 확실히 잡고 있어도, 인터넷에 굴러다니는 예제 YAML 파일들이 “어떤 의도로 작성되었는지” 읽을 수 있는 눈이 생겼을 것이다.
나의 홈서버 k3s 구축은 이제부터가 진짜 시작이다. 다음엔 모니터링(Prometheus+Grafana)을 붙이거나, CI/CD 파이프라인(ArgoCD)을 구축하는 과정도 기회가 되면 정리해 보겠다.
쿠버네티스는 배우면 배울수록 어렵지만, 그만큼 강력하고 매력적인 도구임은 틀림없다. 이 시리즈가 막막했던 쿠버네티스 입문에 작은 이정표가 되었기를 바란다.
끝.
이 시리즈가 도움이 되었다면 댓글과 공유 부탁드립니다. 질문은 언제나 환영입니다!
You might also like
Comments (0)
Leave a Reply
Or login to comment with your account.
No comments yet. Be the first to share your thoughts!