컨테이너의 쓰기 계층에만 둔 파일은 새 컨테이너를 만들 때 그대로 이어지지 않습니다. 데이터를 남기려면 어디에 저장할지 따로 정해야 해요. wk01의 디렉터리를 local PV로 연결하고 Pod 재생성 전후를 비교하겠습니다.
목차
1. local PV의 노드 종속성
local PV는 특정 노드의 디스크를 사용합니다. Pod를 다시 만들 수는 있어도 노드 장애 때 데이터를 다른 노드로 복제해 주지는 않습니다. 이 제한을 확인하는 실습이며, 실서비스 DB를 단일 local PV에 두도록 권장하는 구성은 아닙니다. 다중 노드 스토리지가 필요해지면 CSI와 데이터 복제의 역할을 따로 검토합니다.
# wk01에서 실행. 처음 만드는 빈 실습 디렉터리
sudo install -d -o 1000 -g 1000 -m 0770 /var/local/k8s-lab/data
sudo ls -ld /var/local/k8s-lab/data
컨테이너가 UID/GID 1000으로 접근하므로 호스트 디렉터리의 소유권도 맞춥니다. 권한 오류를 chmod 777로 우회하지 않습니다. 연재는 SELinux permissive를 전제로 합니다. Enforcing 환경에서는 볼륨 레이블과 런타임 정책까지 별도로 확인해야 합니다.
2. StorageClass·PV·PVC
cp01에서 ~/k8s-lab/app/local-storage.yaml에 아래 내용을 저장합니다. StorageClass와 PV는 클러스터 범위이고, PVC는 lab 네임스페이스에 속합니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-lab
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local-wk01
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes: [ReadWriteOnce]
persistentVolumeReclaimPolicy: Retain
storageClassName: local-lab
local:
path: /var/local/k8s-lab/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: [wk01]
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-data
namespace: lab
spec:
accessModes: [ReadWriteOnce]
storageClassName: local-lab
resources:
requests:
storage: 1Gi
kubectl apply -f ~/k8s-lab/app/local-storage.yaml
kubectl get pv
kubectl -n lab get pvc
PVC가 Pending이면 먼저 WaitForFirstConsumer 설정을 확인합니다. 사용할 Pod의 배치 조건을 보고 맞는 노드의 PV와 결합하는 방식이에요. nodeName으로 스케줄러를 우회하지 않습니다. storage: 1Gi도 local 디렉터리에 자동으로 디스크 한도를 거는 설정은 아니므로 실제 여유 공간을 따로 관리합니다.
3. 파일 기록용 Pod
다음 파일을 volume-check.yaml로 저장합니다. 실습용 단독 Pod를 사용해 재생성 전후만 비교하고, 실습이 끝나면 Pod를 삭제합니다.
apiVersion: v1
kind: Pod
metadata:
name: volume-check
namespace: lab
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: writer
image: busybox:1.37.0
command: [sh, -c]
args:
- 'date >> /data/history.log; cat /data/history.log; sleep 3600'
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: local-data
cd ~/k8s-lab/app
kubectl apply -f volume-check.yaml
kubectl -n lab wait --for=condition=Ready pod/volume-check --timeout=120s
kubectl -n lab get pod volume-check -o wide
kubectl -n lab get pvc local-data
kubectl -n lab logs volume-check
Pod의 NODE가 wk01이고 PVC가 Bound인지 확인합니다. ReadWriteOnce는 한 노드에서 읽기·쓰기를 허용한다는 뜻입니다. Pod 하나만 접근한다는 뜻으로 해석하지 않습니다. 여러 Pod가 같은 파일에 쓴다면 별도의 일관성 처리가 필요합니다.
4. Pod 재생성 후 파일 확인
kubectl -n lab delete pod volume-check
kubectl apply -f volume-check.yaml
kubectl -n lab wait --for=condition=Ready pod/volume-check --timeout=120s
kubectl -n lab logs volume-check
# 실습 종료: 이후 drain을 방해하지 않도록 단독 Pod 삭제
kubectl -n lab delete pod volume-check
두 번째 기동 로그에서 이전 기록과 새 기록이 함께 나오는지 봅니다. 이 결과로 확인할 수 있는 것은 같은 wk01 디렉터리를 다시 마운트했는지입니다. 노드 자체의 고장에 대한 복구 시험은 아닙니다. PV와 PVC는 뒤의 백업 실습을 위해 남겨 둡니다.
5. Pending·Released와 Retain
| 상태·증상 | 먼저 확인할 것 |
|---|---|
| Pod 생성 전 PVC Pending | WaitForFirstConsumer 대기인지 |
| Pod 생성 후에도 Pending | 노드 이름·PV affinity·taint·요청 용량·StorageClass |
| Permission denied | 호스트 디렉터리 소유자·UID/GID·SELinux |
| PVC 삭제 후 PV Released | Retain 정책과 이전 claimRef, 데이터 인계 절차 |
| wk01 장애 때 Pod Pending | local PV의 노드 종속성, 복제 기능 부재 |
Retain은 PVC 삭제 시 저장 데이터를 자동 정리하지 않는 회수 정책입니다. 백업을 만들거나 복제를 수행하지는 않습니다. PV를 재사용할 때는 소유권과 잔존 데이터 처리를 먼저 결정합니다. claimRef를 지워 다른 앱에 연결하면 데이터가 섞일 수 있어요. 다중 노드 쓰기는 요구사항에 맞는 CSI 스토리지와 백업을 함께 설계합니다.
참고 자료
공식 문서와 배포 파일 확인 기준: 2026년 10월 18일. 출력은 완료 여부를 판단하기 위한 예시이며 환경별로 달라질 수 있습니다.


![[쿠버네티스 학습 01] Windows 11·VMware와 Rocky Linux 실습 환경](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-photo-107-768x502.jpg)
![[쿠버네티스 학습 02] Rocky Linux 고정 IP·시간·커널 설정](https://blog.maruops.com/wp-content/uploads/2026/10/maruops-photo-088-768x966.jpg)
답글 남기기