- Stateless vs Stateful
- 기본 디플로이먼트(Pod)는 상태가 없어서, 삭제 시 데이터도 함께 사라짐.
- 도커 볼륨 한계
- docker volume이나 hostPath는 특정 노드에만 데이터가 저장되어, Pod가 다른 노드로 이동하면 데이터 접근 불가.
- PV/PVC 도입 배경
- 네트워크 스토리지(NFS, AWS EBS 등)를 워커 노드 어디서든 마운트해 데이터를 영속화하기 위해
Persistent Volume(PV)과 이를 요청하는 Persistent Volume Claim(PVC) 오브젝트를 제공.
- 네트워크 스토리지(NFS, AWS EBS 등)를 워커 노드 어디서든 마운트해 데이터를 영속화하기 위해
로컬 볼륨 : hostPath, emptyDir
hostPath, emptyDir 관련하여 공식문서 찾고 정리하는거 추가
사진도 추가
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: my-container
image: busybox
args: [ "tail", "-f", "/dev/null" ]
volumeMounts:
- name: my-hostpath-volume
mountPath: /etc/data
volumes:
- name: my-hostpath-volume
hostPath:
path: /tmp
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: content-creator
image: alicek106/alpine-wget:latest
args: ["tail", "-f", "/dev/null"]
volumeMounts:
- name: my-emptydir-volume
mountPath: /data # 1. 이 컨테이너가 /data 에 파일을 생성하면
- name: apache-webserver
image: httpd:2
volumeMounts:
- name: my-emptydir-volume
mountPath: /usr/local/apache2/htdocs/ # 2. 아파치 웹 서버에서 접근 가능합니다.
volumes:
- name: my-emptydir-volume
emptyDir: {} # 포드 내에서 파일을 공유하는 emptyDir
네트워크 볼륨
NFS 를 네트워크 볼륨으로 사용하기
- [Deployment] spec.selector.matchLabels
- Pod 생명주기 관리용
- Deployment가 관리할 Pod들을 식별하는 기준
- role: nfs-server 라벨을 가진 Pod들을 선택
- [Service] spec.selector
- 네트워크 트래픽 라우팅용
- Service가 트래픽을 전달할 Pod들을 선택하는 기준
- role: nfs-server 라벨을 가진 모든 Pod를 찾고 해당 Pod에게 네트워크 트래픽을 전달
1. 쿠버네티스 클러스터 내부에서 임시 NFS서버를 생성
- nfs-deployment.yaml
- nfs-service.yaml
# chapter9/nfs-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-server
spec:
selector:
matchLabels:
role: nfs-server
template:
metadata:
labels:
role: nfs-server
spec:
containers:
- name: nfs-server
image: gcr.io/google_containers/volume-nfs:0.8
ports:
- name: nfs
containerPort: 2049
- name: mountd
containerPort: 20048
- name: rpcbind
containerPort: 111
securityContext:
privileged: true
# chapter9/nfs-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nfs-service
spec:
ports:
- name: nfs
port: 2049
- name: mountd
port: 20048
- name: rpcbind
port: 111
selector:
role: nfs-server
# NFS 서버에 접근하기 위한 서비스의 Cluster IP를 얻습니다
export NFS_CLUSTER_IP=$(kubectl get svc/nfs-service -o jsonpath='{.spec.clusterIP}')
cat nfs-pod.yaml | sed "s/{NFS_SERVICE_IP}/$NFS_CLUSTER_IP/g" | kubectl apply -f -
# chapter9/nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- name: nfs-mount-container
image: busybox
args: [ "tail", "-f", "/dev/null" ]
volumeMounts:
- name: nfs-volume
mountPath: /mnt # 포드 컨테이너 내부의 /mnt 디렉터리에 마운트합니다.
volumes:
- name : nfs-volume
nfs: # NFS 서버의 볼륨을 포드의 컨테이너에 마운트합니다.
path: /
server: {NFS_SERVICE_IP}
PV, PVC를 이용한 볼륨 관리
PV 미사용 : YAML 파일에 NFS_SERVICE_IP가 노출
PV 사용 : YAML 파일을에 PVC 정보만 노출
GPT로 만들어본 SC, PV, PVC 네컷 만화
![]() |
![]() |
AWS에서 EBS를 PV로 사용하기 (수동 Provisoning)
PV를 선택하기 위한 조건 명시
- accessModes
- 볼륨크기
- 스토리지 클래스
- 라벨 셀렉터
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
accessModes
access Modes | kubectl get 출력형식 | 속성 설명 |
ReadWriteOnce | RWO | 단일 노드에서 읽기-쓰기로 마운트 가능. ("Once"는 Pod가 아닌 Node를 의미) 동일 노드의 여러 Pod 접근 가능 |
ReadOnlyMany | ROX | 여러 노드에서 읽기 전용으로 마운트 가능 |
ReadWriteMany | RWX | 여러 노드에서 읽기-쓰기로 마운트 가능 |
ReadWriteOncePod | RWOP | 단일 Pod에서만 읽기-쓰기로 마운트 가능 (v1.29 stable) 전체 클러스터에서 단 하나의 파드만 해당 PVC를 읽거나 쓸 수 있도록 보장 |
볼륨 크기
스토리지 클래스
레이블 셀렉터
PV의 라이프사이클, Reclaim Policy
PV 생명주기 상태
- Available: PV가 생성되었지만 아직 PVC에 바인딩되지 않은 상태
- Bound: PV가 PVC와 바인딩된 상태
- Released: PVC가 삭제되었지만 PV의 리클레임 정책이 "Retain"이어서 PV가 유지되는 상태
- Failed: PV가 자동/수동 리클레임에 실패한 상태
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#phase
[Released 상태 개념]
- PV가 이전에 PVC와 바인딩되어 있었음
- PVC가 삭제되었지만 PV는 여전히 존재함
- PV에는 이전 클레임의 데이터가 남아있을 수 있음
- 새로운 PVC가 이 PV에 바인딩될 수 없음 (재사용 불가)
Storage Class와 Dynamic Provisioning