클라우드 + DevOps/Kubernetes (k8s)

Kubernetes 쿠버네티스 :: PV, PVC 이해와 활용

gamjadori 2024. 4. 18. 15:52
728x90

<Kubernetes 쿠버네티스 :: PV, PVC 이해와 활용>

<Kubernetes PV, PVC 이해와 활용>

  • hostPath 방식은 리소스 관리 및 보안 측면에서 권장하지 않음
  • 쿠버네티스는 PV object로 스토리지를 추상화하고 PVC object로 스토리지를 할당받아 사용할 수 있게 구현
  • PV (Persistent Volume): 관리자나 StorageClass에 의해 생성되는 볼륨
  • PVC (Persistent Volume Claim): 사용자가 볼륨을 사용하기 위해 PV에 요청
  • 프로비저닝: PV를 만드는 단계로, PV를 미리 만들고 사용하는 정적 방법과 요청이 있을 때 PV를 만드는 동적 방법 존재
  • 바인딩 (Binding): 생성한 PV를 PVC와 연결하는 단계로, PVC는 스토리지 용량과 접근 방법에 따라 PV와 연결, 대응되는 PV가 생길 때까지 Pending
  • PV와 PVC는 1:1 관계
  • 사용 (Using): PVC는 포드에서 사용되고, 포드는 PVC를 볼륨으로 인식하여 사용하는 단계
  • 회수: 사용이 끝난 PVC가 초기화되는 단계
    • Retain: PVC가 삭제될 때 대응되는 PV 상태는 bound > Released로 바뀌여, 다른 PVC가 연결될 수 없고 PV 속 데이터는 유지
    • Delete: PVC가 삭제될 때 대응되는 PV도 같이 삭제
    • Recylce: PVC가 삭제될 때 대응되는 상태는 bound > Pending으로 변경, 다른 PVC 대기
  • accessMode: PV 생성 시 설정하는 접근 권한RWX: 읽기 - 쓰기 가능, 모든 노드에서 접근 가능
  • RWO: 단일 노드에서 읽기 - 쓰리고 마운트 가능
  • ROX: 읽기만 가능, 모든 노드에서 접근 가능

 

1. accessMode을 설정한 PersistentVolume 파일 생성 및 적용

<pv.yaml>

  • 세 개의 PersistentVolume 정의
  • 각 PersistentVolume은 "/DATA2" 경로에 로컬 스토리지로 정의
  • pv1: k8s-node1 / ReadWriteOnce 엑세스 모드
  • pv2: k8s-node1 / ReadOnlyMany 엑세스 모드
  • pv3: k8s-node1 / ReadWriteMany 엑세스 모드
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  local:
    path: /DATA2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadOnlyMany
  local:
    path: /DATA2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv3
spec:
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteMany
  local:
    path: /DATA2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}

<파일 적용>

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f pv.yaml
persistentvolume/pv1 created
persistentvolume/pv2 created
persistentvolume/pv3 created

<확인> kubectl pv -o wide

 

2. PersistentVolumeClaim 정의 파일 생성

<pvc.yaml>

  • 네 개의 PersistentVolumeClaim 정의
  • pvc1: 읽기 전용 모드로 1Gi의 스토리지를 요청
  • pvc2: 읽기/쓰기 모드로 1Gi의 스토리지를 요청
  • pvc3: 읽기/쓰기 모드로 5Gi의 스토리지를 요청
  • pvc4: 읽기/쓰기 모드로 1Gi의 스토리지를 요청
apiVersion: v1
kind: PersistentVolumClaim
metadata:
	name: pvc1
spec:
	accessModes:
	- ReadOnlyMany
	resources:
		requests:
			storage: 1G
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumClaim
metadata:
	name: pvc3
spec:
	accessModes:
	- ReadWriteOnce
	resources:
		requests:
			storage: 5G
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc4
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

<적용>

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
persistentvolumeclaim/pvc4 created

 

3. pod (mynode-pod) 정의

<mynode-pod.yaml>

  • mynode-container"라는 이름의 컨테이너를 포함
  • pvc1이라는 이름의 PersistentVolumeClaim에 매핑된 볼륨 마운트
apiVersion: v1
kind: Pod
metadata:
  name: mynode-pod
spec:
  containers:
  - name: mynode-container
    image: *****/k8s-lab:initial
    volumeMounts:
    - name: mynode-path
      mountPath: /mynode
    ports:
    - containerPort: 8000
  volumes:
  - name: mynode-path
    persistentVolumeClaim:
      claimName: pvc1

<적용>

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f mynode-pod.yaml
pod/mynode-pod created

 

4. 제작한 pod 접속

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl exec -it mynode-pod -- bash
root@mynode-pod:/#
  • /mynode/ 디렉토리에 k8s-pvc.txt라는 파일을 생성
  • welcome to *****. mynode-pod라는 내용 기록
root@mynode-pod:/# cd /mynode/
root@mynode-pod:/#/mynode# ls
lost+found
root@mynode-pod:/#/mynode# echo "welcome to *****. mynode-pod" > k8s-pvc.txt
root@mynode-pod:/#/mynode# ls
lost+found   k8s-pvc.txt
root@mynode-pod:/#/mynode# cat k8s-pvc.txt
welcome to *****. mynode-pod
  • k8s-node1의 /DATA2 (볼륨 마운트 위치)에 접속하여 k8s-pvc.txt 파일 유무 확인
ubuntu@k8s-node1:~$ cd /DATA2
ubuntu@k8s-node1:/DATA2$ ls
lost+found   k8s-pvc.txt
ubuntu@k8s-node1:/DATA2$ cat k8s-pvc.txt
welcome to *****. mynode-pod

 

5. PV / PVC 정의 파일 생성 및 적용

<pv2.yaml>

  • pv4라는 PersistentVolume 정의
  • 읽기/쓰기 모드로 1Gi의 스토리지 요청
  • k8s-node1 노드에 로컬 경로 "/DATA2"에 연결
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv4
  labels:
    name: pv4
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  local:
    path: /DATA2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}

<pvc2.yaml>

  • pvc5라는 이름의 PersistentVolumeClaim 정의
  • 읽기/쓰기 모드로 1Gi의 스토리지 요청
  • PersistentVolume pv4과 매핑 (PersistentVolume을 PersistentVolumeClaim과 연결)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc5
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      name: pv4

<pv3.yaml>

  • pv-nfs (PersistentVolume) 정의: 1Gi 용량의 NFS 스토리지
  • "/DATA1" 경로에 마운트
  • 서버 주소: 192.168.56.101
  • PersistentVolume의 재사용 정책: Recycle
    • Recycle: PersistentVolume을 사용한 후에 해당 볼륨을 삭제하기 전에 이전 데이터를 제거하고 초기 상태로 되돌리는 것
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
  labels:
    name: pv-nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  volumeMode: Filesystem
  mountOptions:
  - hard
  nfs:
    path: /DATA1
    server: 192.168.56.101
  persistentVolumeReclaimPolicy: Recycle

<pvc3.yaml>

  • PersistentVolumeClaim 을 정의
  • NFS 서버에서 1GB 용량을 가진 볼륨 요청
  • pv-nfs라는 이름을 가진 PV와 매핑
  • 읽기/쓰기 모드로 1Gi의 스토리지를 요청
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      name: pv-nfs

<파일 적용>

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f pv3.taml
persistentvolume/pv-nfs created
[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f pvc3.taml
persistentvolume/pvc-nfs created

<결과 확인> kubectl get pv, pvc -o wide

 

6. Pod 정의

<mynode-nfs-pod.yaml>

  • mynode-nfs-pod 라는 포드 생성
  • pvc-nfs라는 PersistentVolumeClaim에 매핑된 볼륨 마운트
apiVersion: v1
kind: Pod
metadata:
  name: mynode-nfs-pod
spec:
  containers:
  - name: mynode-container
    image: *****/mynode:1.0
    volumeMounts:
    - name: mynode-nfs-pod
      mountPath: /mount1
    ports:
    - containerPort: 8000
  volumes:
  - name: mynode-nfs-pod
    persistentVolumeClaim:
      claimName: pvc-nfs

<적용 및 확인>

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl apply -f mynode-nfs-pod.yaml
pod/mynode-nfs-pod created

 

** 하나가 계속 Pending 상태

>> 해결 방법 kubectl edit을 이용해 수정

[PS C:\\Users\\admin\\Desktop\\k8s-pods> kubectl edit pv pv-nfs
  • storage: 1G > storage: 5G로 변경