참고 사이트

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

 

Persistent Volumes

This document describes persistent volumes in Kubernetes. Familiarity with volumes, StorageClasses and VolumeAttributesClasses is suggested. Introduction Managing storage is a distinct problem from managing compute instances. The PersistentVolume subsystem

kubernetes.io

 

 

개요

아래와 같이 nfs 로 제공되는 pv 및 hostpath pv 를 이용하여 몇 가지 test 를 진행해보고자 한다.

여기서 nfs 서버는 exports 의 설정과 같이 모든 노드에서 접속이 가능하고 read, write 권한을 준다.

root@k8s-master:~/pvc# k get sc
NAME                   PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client (default)   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  77d
root@k8s-master:~/pvc# k get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-5c24786a-c2dc-4f07-ba64-89aaa4ca5319   1Mi        RWO            Delete           Bound    default/small-pvc   nfs-client     <unset>                          5m3s
root@k8s-master:/etc/systemd/system# cat /etc/exports
/srv/nfs-volume *(rw,insecure,sync,no_subtree_check,no_root_squash)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: django-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: jingukang/django:1.0.0
          volumeMounts:
            - name: django-storage
              mountPath: /etc/pv
      volumes:
        - name: django-storage
          persistentVolumeClaim:
            claimName: small-pvc
root@k8s-master:~/pvc# k get po -o wide | grep django
django-deploy-d656b9768-2mxzn             1/1     Running   0              62m    10.32.0.9    k8s-master    <none>           <none>
django-deploy-d656b9768-zg8dg             1/1     Running   0              62m    10.44.0.13   k8s-worker1   <none>           <none>

 

 

1. nfs 로 생성된 pv 의 경우 capacity 에 상관없이 용량이 사용되는 것을 확인
root@django-deploy-d656b9768-2mxzn:/etc/pv# du -sh /etc/pv/*
1.5M    /etc/pv/project-new.tar
0       /etc/pv/test
0       /etc/pv/test2
4.0K    /etc/pv/test3
4.0K    /etc/pv/test4

위와 같이 1Mi 의 용량이 초과했음에도 아래와 같이 쓰기 작업은 계속 이뤄진다.

즉, capacity 는 해당 용량을 맵핑하기 위한 형식적인 것이지 실제 강제적인 제한은 아닌 것을 알 수 있다.

root@django-deploy-d656b9768-2mxzn:/etc/pv# echo "hello" > test5
root@django-deploy-d656b9768-2mxzn:/etc/pv# ls
project-new.tar  test  test2  test3  test4  test5

 

 

2. nfs 로 생성된 pv 의 경우 RWO 임에도 여러 노드에서 쓰기 작업이 되는 지 확인

아래와 같이 서로 다른 두 노드에서 쓰기 작업이 모두 가능함을 확인 가능

즉, nfs 를 통한 pv 는 nfs 의 설정에 따라 저장소가 사용되는 것을 알 수 있다.

 

 

3. hostpath pv 에서 RWO 확인

아래와 같이 pv, pvc 준비

root@k8s-master:~/pv# cat hostpath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
spec:
  capacity:
    storage: 1Mi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: local-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Mi

 

확인 결과 hostpath 이기 때문에 서로 다른 노드에서 pod 에 접근 시 mount 된 디렉토리가 서로 달라 RWO 의 의미가 퇴색된다.

즉, 모든 pod 에서 읽기 / 쓰기가 가능하다.

 

 

4. hostpath pv 에서 capacity 확인

실제 mount 된 노드에서 1Mi 가 넘는 파일을 아래와 같이 옮긴 후 첫번째 노드에서 쓰기 작업을 해보자.

root@django-deploy-598bb6f74d-w2vb4:/etc/pv# ls -lh
total 1.5M
-rw-r--r-- 1 root root    6 Jul 17 08:55 hello
-rw-rw-r-- 1 root root 1.5M Jul 15 06:46 project-new.tar

 

그 결과 아래와 같이 capacity 를 무시한 채 더 많은 용량 사용이 가능하다.

root@django-deploy-598bb6f74d-w2vb4:/etc/pv# echo "test" > test
root@django-deploy-598bb6f74d-w2vb4:/etc/pv# ls
hello  project-new.tar  test
root@django-deploy-598bb6f74d-w2vb4:/etc/pv# cat test
test
root@django-deploy-598bb6f74d-w2vb4:/etc/pv# du -sh ./*
4.0K    ./hello
1.5M    ./project-new.tar
4.0K    ./test
root@k8s-master:/mnt/data# ls -lh
total 1.5M
-rw-r--r-- 1 root root    6 Jul 17 17:55 hello
-rw-rw-r-- 1 root root 1.5M Jul 15 15:46 project-new.tar
-rw-r--r-- 1 root root    5 Jul 22 17:39 test

 

 

5. hostpath pv 에서 RWOP 확인
root@k8s-master:~/pv# k get pv local-pv
NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
local-pv   1Mi        RWOP           Retain           Bound    default/local-pvc                  <unset>                          7m45s
root@k8s-master:~/pv# k get pvc local-pvc
NAME        STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
local-pvc   Bound    local-pv   1Mi        RWOP                          <unset>                 7m48s

위와 같이 모든 리소스를 정리 후 RWOP 의 pv, pvc 생성 완료

 

root@k8s-master:~/pv# k get po -o wide | grep django
django-deploy-598bb6f74d-5nb7q            1/1     Running   0               8m9s   10.44.0.5   k8s-worker1   <none>           <none>
django-deploy-598bb6f74d-8b6jb            0/1     Pending   0               8m9s   <none>      <none>        <none>           <none>
django-deploy-598bb6f74d-gppdn            0/1     Pending   0               8m9s   <none>      <none>        <none>           <none>
django-deploy-598bb6f74d-s7k9g            0/1     Pending   0               8m9s   <none>      <none>        <none>           <none>

해당 pv 를 사용하는 deploy 생성 결과 위와 같이 하나의 pod 만 생성된다.

즉, RWOP 가 잘 적용된다. 실제로 pending 중인 pod 에서는 아래와 같은 로그가 남는다.

 

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  2m52s  default-scheduler  0/2 nodes are available: 2 node has pod using PersistentVolumeClaim with the same name and ReadWriteOncePod access mode. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod.

'k8s' 카테고리의 다른 글

node join 및 delete  (0) 2025.08.28
ansible 을 활용한 k8s 클러스터 구축  (0) 2025.08.01
Prometheus 와 Grafana 설치  (1) 2025.07.11
Pod Garbage Collector  (3) 2025.07.10
DNAT  (2) 2025.07.10

+ Recent posts