State
- 애플리케이션에서 손실되어서는 안되는 생성되고 사용되는 데이터임

- 컨테이너가 종류 후, 재시작할때도 존재해야하는 데이터가 있기에 volumes이 필요함
k8s & volumes
- k8s는 컨테이너 안에 volumes를 mount할 수 있음
- 다양한 종류의 볼륨 타입/드라이버를 지원함
- 로컬(노드)에 있는 볼륨
- 클라우드 공급자 전용 볼륨
- 볼륨의 생명 주기는 Pod의 생명 주기에 따라 달라짐
- 볼륨은 컨테이너가 재시작(또는 삭제)되어도 유지됨
- pod가 삭제될때 volume도 삭제됨
- k8s volumes vs docker volumes
- k8s volumes
- 다양한 종류의 드라이버와 타입을 지원함
- 볼륨이 반드시 영구적인 것은 아님 (pod삭제시)
- 볼륨은 컨테이너가 재시작되거나 삭제되어도 그대로 유지됨
- docker volumes
- 사실상 드라이버나 타입을 별도로 지원하지 않음
- 볼륨은 사용자가 직접 삭제하지 않으면 계속 남아 있음
- 볼륨은 컨테이너가 재시작되거나 삭제되어도 그대로 유지됨
emptyDir Type
- emptyDir Type volume은 가장 기본적인 임시 volume임
- deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: story-deployment
spec:
replicas: 1
selector:
matchLabels:
app: story
template:
metadata:
labels:
app: story
spec:
containers:
- name: story
image: devminii/kube-data-demo:1
volumeMounts:
- mountPath: /app/story
name: story-volume
volumes:
- name: story-volume
emptyDir: {}
- volumes는 pod 단위에서 공유할 수 있는 저장소를 정의하는 곳
- story-volume으로 volume을 생성했음
- emptyDir을 통해 pod가 노드에서 생성시 임시 디렉토리를 형성함 (pod삭제시 당연히 없어짐)
- 이 디렉토리를 여러 컨테이너가 공유해서 사용할 수 있음
- 통 앱 실행 중 임시 파일 저장, 캐시, 임시 데이터 처리 등에 활용
- volumeMounts는 컨테이너가 앞서 정의된 볼륨(story-volume)을 실제 경로로 연결해서 쓸 수 있게 하는 설정
- name 부분에 내가 쓸 volume을 명시해주면됨
- mountPath를 통해 컨테이너 내부에서 해당 경로로 접근하면 실제 pod의 volume 디렉토리를 가리킴
hostPath Type
- hostPath type
- pod가 올라가 있는 k8s 노드의 파일 시스템 상 실제 경로를 pod의 컨테이너 내부 경로에 직접 마운트하는 방식
- 즉 /data (노드 경로)가 컨테이너 안의 /app/story에 직접 연결됨
- deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: story-deployment
spec:
replicas: 2
selector:
matchLabels:
app: story
template:
metadata:
labels:
app: story
spec:
containers:
- name: story
image: devminii/kube-data-demo:1
volumeMounts:
- mountPath: /app/story
name: story-volume
volumes:
- name: story-volume
hostPath:
path: /data
type: DirectoryOrCreate #/data 디렉토리가 없으면 새로 생성하라는 명령어
- pod가 할당된 노드의 특정 파일 시스템 경로를 직접 파드에 마운트
- pod를 삭제해도 그 노드의 해당 경로에 있던 데이터는 삭제되지 않고 남아 있음
- 만약 pod가 다른 노드로 옮겨가면 그 노드의 동일 경로에 접근하게 되므로, 데이터가 "공유"되는 것이 아니라 실제로는 노드별로 별도 관리됨
- 노드 로컬 파일에 직접 접근하거나, 파드가 삭제되어도 데이터를 보존해야 할 때 사용
(ex: 로그 수집, 노드-파드간 파일 공유 등) - 하지만 단일 노드에서만 좋지, 다중 노드에서는 사용 불가능함(공식문서 참고)
CSI Type(Container Storage Interface)
- k8s를 포함한 다양한 컨테이너 오케스트레이션 플랫폼과 여러 스토리지 시스템(블록, 파일, 클라우드 스토리지 등) 사이를 연결하기 위한 표준화된 스토리지 인터페이스
- 플러그인 표준화: 스토리지 공급자가 각 플랫폼마다 따로 드라이버를 구현할 필요 없이, 한 번 CSI 규격만 맞추면 여러 플랫폼에서 동일하게 동작할 수 있음
- 확장성/유연성: k8s 내장 코드와 분리되어(out-of-tree), 새로운 스토리지 시스템이 등장해도 쿠버네티스 업그레이드 없이 드라이버만 따로 설치·업데이트할 수 있음
- 스토리지 연동 작업 표준화: 볼륨 생성/삭제, 마운트/언마운트, 스냅샷 등 스토리지 볼륨의 생명주기 작업을 위한 표준 API(gRPC 프로토콜 기반)를 정의함
- 동적 프로비저닝 지원: 파드 실행 시 자동으로 볼륨을 생성하거나, 자동 확장/반납 등 고도화된 스토리지 관리를 쉽게 구현할 수 있음
Persistent Volumes
- 보통 pod가 파괴되면 volume역시 없어짐
- 그래서 pod와 독립적인 volumes이 필요함

Defining a Persistent Volume
host-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: host-pv
spec:
capacity:
storage: 4Gi
volumeMode: Filesystem
storageClassName: standard
accessModes:
- ReadWriteOnce
hostPath:
path: /data
type: DirectoryOrCreate
# 우리는 단일 노드에서만 지금 실습을하기에 hostpath를 사용해서 함!!
# 멀티 노드에서는 hostpath불가임!!
- storageClassName
- 서로 다른 스토리지 백엔드(예: AWS EBS, GCE PD, NFS, 로컬 디스크 등)와 스토리지 공급자를 추상화한 개념
- k8s 클러스터에는 여러 StorageClass가 있을 수 있으며, 기본 스토리지 클래스를 지정할 수 있음
- 자동 프로비저닝 기능을 통해 PVC 요청 시 자동으로 PV를 생성하는 데 StorageClass가 중요한 역할
- ReadWriteOnce
- 이 PV는 단 한개의 노드에서만 읽기/쓰기가 동시에 가능함
- 즉, 하나의 노드에서 마운트된 pod들이 그 볼륨에 읽고 쓸 수 있음
- 여러 노드에서 동시에 읽거나 쓸 수는 없음
- ReadWriteMany
- 여러 노드에서 동시에 읽기/쓰기 가능
- 즉, 여러 노드의 파드들이 동시에 같은 볼륨을 마운트해서 데이터를 읽고 쓸 수 있음
- ReadOnlyMany
- 읽기만 가능
Persistent Volume Claim
- PVC: 사용자가 클러스터 스토리지 요청을 하기 위한 리소스임
- PVC는 "이런 크기와 접근 모드를 가진 스토리지를 내게 할당해 주세요"라고 신청하는 선언적 요청
- k8s가 PVC 요청에 맞는 PV를 찾아서 bind해줌
host-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: host-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 4Gi
volumeName: host-pv
이렇게 생성한 pvc를 쓰기위해 deployment.yaml의 volumes부분도 아래처럼 수정해줘야함
apiVersion: apps/v1
kind: Deployment
metadata:
name: story-deployment
spec:
replicas: 2
selector:
matchLabels:
app: story
template:
metadata:
labels:
app: story
spec:
containers:
- name: story
image: devminii/kube-data-demo:1
volumeMounts:
- mountPath: /app/story
name: story-volume
volumes:
- name: story-volume
persistentVolumeClaim:
claimName: host-pvc
실행을 해보자
kubectl apply -f=host-pv.yaml
kubectl apply -f=host-pvc.yaml
kubectl apply -f=deployment.yaml
kubectl get pv


- pod가 2개 생성되었고 pod각각에 볼륨을 가지고 있음
- 그러나, 두 pod가 같은 PVC를 마운트하므로 같은 PersistentVolume을 참조하고 있음
- 우리 실습에서는 단일 노드니깐 두 pod가 동시에 pv에 접근할 수 있음
- 하지만, 멀티 노드에서
- accessMode가 ReadWriteOnce이면, 한번에 한노드에서만 읽고 쓰므로
- pod2개가 서로 다른 노드에 있으면 둘 다 연결을 할 수 없게됨
Normal Volumes vs Persistent Volumes
- Normal Volumes
- pod가 살아있으면 살아있고, 죽으면 죽음
- 여러 pod에 데이터를 저장하려면 각 pod마다 볼륨을 따로 정의해야 하므로 관리가 불편함
- Persistent Volumes
- PV는 pod와는 독립적으로 클러스터 내에 미리 만들음
- PVC를 만들어서 필요한 크기/용도를 요청하면, k8s가 적절한 PV를 연결해줌
- 동일한 PV/PVC 조합을 여러 pod, 여러 상황에서 계속 사용할 수 있음
- 데이터가 pod 삭제나 재시작에도 남아 있음
'클라우드 > Docker & Kubernetes' 카테고리의 다른 글
| Virtualization (0) | 2025.08.19 |
|---|---|
| k8s-Deployment (AWS EKS) (0) | 2025.08.11 |
| k8s core concepts & setup (2) (0) | 2025.08.07 |
| k8s Core Concepts & setup (0) | 2025.08.07 |
| Kubernetes Concepts (0) | 2025.08.06 |