Openshift 4.12.0 PV, PVC (NFS) 를 이용한 Volume 추가
한번 가동된 Pod (Container) 에서 데이터 입력, 수정, 삭제 등의 작업 후 중지, 재시작을 하게 되면 그동안 작업한 모든 데이터는 날아갑니다.
때문에 Volume 을 특정 디렉토리로 마운트 하고 사용하면 해당 디렉토리의 파일은 컨테이너가 중지 되어도 데이터가 유지되는데요.
데이터 유지와 용량 증설 목적을 가지는 Volume 을 어떻게 설정하고 사용하는지 예제를 통해 알아보도록 하겠습니다.
이 예제는 Deployment 오브젝트를 통해 Python 애플리케이션을 배포하고, Persistent Volume Claim (PVC) 을 사용하여 데이터를 보관하기 위한 Volume 1Gi 를 생성, 컨테이너의 /data 디렉토리에 연결하는 것을 보여주고 있습니다.
1. 설명
본 매뉴얼 하단부에서 소개될 yaml 파일과 옵션에 대한 설명으로 시작하겠습니다.
1) PV 와 PVC
PersistentVolume (PV) 은 클러스터 레벨에서 관리되는 볼륨이며 스토리지 저장소라고 생각하면 이해가 쉽습니다.
PersistentVolume (PV) 과 PersistentVolumeClaim (PVC) 은 1:1 매칭이 가장 일반적인 사용 방식입니다.
즉, 하나의 PV 는 하나의 PVC 와 바인딩됩니다. 이는 PV 가 실제 스토리지 리소스를 나타내고, PVC 가 해당 스토리지 리소스에 대한 요청을 표현하기 때문입니다.
하지만 1:n 매핑도 가능합니다. 즉, 하나의 PV 가 여러 개의 PVC 와 바인딩될 수 있습니다. 이 경우 PVC 는 동일한 PV 의 스토리지를 공유하게 됩니다. 이는 여러 개의 애플리케이션이 동일한 스토리지를 사용해야 하는 경우에 유용할 수 있습니다.
대신 1:n 매핑을 위해서는 다음 사항을 고려해야 합니다.
- PV 와 PVC 의 스토리지 클래스 이름 (storageClassName) 이 일치해야 합니다.
- PV 의 용량은 PVC 들이 요청한 총 용량 이상이어야 합니다.
- PVC 의 액세스 모드 (accessModes) 가 PV 의 액세스 모드와 호환되어야 합니다.
예를 들어 PV 의 액세스 모드가 ReadWriteOnce 이면, PVC 액세스 모드가 ReadWriteOnce 이여야 합니다.
1:n 매핑은 특정 상황에서 유용할 수 있지만, 주의할 점도 있습니다. 여러 PVC 가 동일한 스토리지를 공유하게 되므로 애플리케이션 간의 스토리지 충돌이 발생할 수 있습니다. 따라서 신중하게 구성해야 합니다.
2) accessModes
위에서 말한 액세스 모드 (accessModes) 는 PersistentVolumeClaim (PVC) 에서 지정하는 볼륨의 액세스 모드를 정의합니다. accessModes 필드는 다음과 같은 값을 가질 수 있습니다.
- ReadWriteOnce (RWO) : 단일 노드에서 읽기/쓰기 액세스를 지원
- ReadOnlyMany (ROX) : 여러 노드에서 읽기 전용 액세스를 지원 (동시 마운트 가능)
- ReadWriteMany (RWX) : 여러 노드에서 읽기/쓰기 액세스를 지원 (동시 마운트 가능)
액세스 모드는 PVC 에서 요청한 볼륨을 할당할 때 PersistentVolume (PV) 의 액세스 모드와 일치해야 합니다. PV 의 액세스 모드는 볼륨이 생성될 때 설정되며 PVC 와 일치하지 않는 경우 PVC 는 해당 PV 에 바인딩될 수 없습니다.
3) persistentVolumeReclaimPolicy
persistentVolumeReclaimPolicy 는 PV 에서 사용되는 속성입니다. 이 속성은 PV 와 연결된 PVC 가 삭제될 때 PV 에서 어떻게 처리할지를 지정합니다. 사용 가능한 옵션은 아래와 같습니다.
- Retain : PV 데이터를 그대로 보존
- Recycle : PV 데이터를 모두 삭제 후 재사용
- Delete : 사용 종료시 삭제
4) Volume 유형
PV 에서 구성 가능한 Volume 유형은 여러가지가 있습니다.
볼륨을 로컬 디스크에서 생성할 수 있는 emptyDir 과 hostPath 가 있으며, 전용 스토리지를 이용한 NFS 등의 연결도 가능합니다.
- emptyDir : Pod 내에 존재하는 볼륨입니다.
emptyDir 은 Pod 가 생성될 때 생성되며 Pod 의 수명 동안 유지됩니다.
(단점) 때문에 Pod 가 삭제되면 emptyDir 에 저장된 모든 데이터가 사라집니다.
노드의 로컬 디스크에 생성되며 여러 Pod 들 사이에서 데이터를 공유할 목적으로 사용될 수 있습니다.
- hostPath : 호스트 노드 내에 존재하는 볼륨입니다.
hostPath 를 사용하면 Pod 내부의 컨테이너가 호스트 노드의 파일 시스템에 직접 액세스할 수 있습니다.
때문에 Pod 가 삭제되어도 볼륨의 데이터는 삭제되지 않습니다.
여러 컨테이너가 동일한 hostPath를 공유할 수 있습니다.
(단점) Worker node 가 여러개일때, Pod 가 재생성되면 다른 노드에 Pod 가 생성되므로 기존 노드의 볼륨 사용 불가
- PV, PVC : '1)' 에서 소개된 내용과 동일합니다.
전용 스토리지를 이용하여 Pod 에 영속성 있는 볼륨을 제공합니다. (Local Disk 또는 외부 Storage 원격 연결 가능)
Pod 는 이러한 PV 에 바로 연결하지 않고 PVC 를 통하여 연결됩니다.
2. NFS Volume 생성
본 예제는 PV, PVC 볼륨 유형으로 작성된 NFS 활용 예제입니다.
1) PV 생성
다음은 PersistentVolume (PV) 을 생성하는 yaml 파일입니다.
여기에서는 PV 와 PVC 의 용량을 1:1 매칭으로 구성하였습니다.
# vi pv.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: pv-example spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce nfs: server: 115.68.248.217 # NFS 서버 IP path: /data # NFS 서버에서 공유하는 디렉토리 경로 |
작성한 yaml 파일을 적용하여 PV 를 생성합니다.
# oc apply -f pv.yaml
persistentvolume/pv-example created
생성된 PV 를 확인합니다.
# oc get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-example 1Gi RWO Retain Available standard 6s
2) PVC 생성
PersistentVolumeClaim (PVC) yaml 파일을 작성합니다.
# vi pvc.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-example spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi |
작성한 yaml 파일을 적용하여 PVC 를 생성합니다.
# oc apply -f pvc.yaml
persistentvolumeclaim/pvc-example created
생성된 PVC 를 확인합니다.
# oc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-example Bound pv-example 1Gi RWO standard 12s
3) Pod 생성 및 Volume 연결
Pod yaml 를 생성하여 볼륨을 붙일 수 있지만 본 예제에서는 Deployment 를 이용해 Pod 를 생성해 보겠습니다.
# vi deployment_volume.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: app-example spec: replicas: 1 selector: matchLabels: app: app-example template: metadata: labels: app: app-example spec: securityContext: seccompProfile: type: RuntimeDefault containers: - name: app-example image: default-route-openshift-image-registry.apps.az1.sysdocu.kr:5000/project412/python ports: - containerPort: 8080 protocol: TCP securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] runAsNonRoot: true volumeMounts: - name: my-pvc-volume mountPath: /data_client # 컨테이너 내부의 마운트 위치 (디렉토리는 자동 생성됩니다) volumes: - name: my-pvc-volume persistentVolumeClaim: claimName: pvc-example imagePullSecrets: - name: sysdocu |
위에서 imagePullSecrets 는 이미지를 Registry 에서 다운로드 하기위해 만든 secret 입니다.
claimName 에는 PVC 이름을 넣고, volumeMounts: name: 은 volumes: name: 이름과 동일하게 해주어야 합니다.
작성한 yaml 파일을 적용하여 Pod 를 생성합니다.
# oc apply -f deployment_volume.yaml
deployment.apps/app-example created
생성된 Pod 를 확인합니다.
# oc get pod
NAME READY STATUS RESTARTS AGE
app-example-5589d49b8d-j77kc 1/1 Running 0 4s
4) 마운트 확인
/data 에 저장된 데이터가 유지되고, 용량이 1Gi 로 제한 되고 있는지 확인해봅니다.
(NFS 서버에서)
테스트 파일을 하나 만들었습니다.
# ll /data
합계 4
-rw-r--r-- 1 root root 3 5월 12 15:16 test.txt
(Pod 에서)
Pod 이름을 확인하고 쉘 접속을 합니다.
# oc get pod
NAME READY STATUS RESTARTS AGE
app-example-5589d49b8d-j77kc 1/1 Running 0 90s
# oc rsh app-example-5589d49b8d-j77kc
마운트 디렉토리로 이동합니다.
$ cd /data_client
디렉토리를 만들지 않아도 deployment yaml 에 지정한 디렉토리가 자동 생성되어 있습니다.
$ pwd
/data_client
NFS 서버에서 생성한 파일이 보이는 것을 확인하였습니다.
$ ls -al
total 4
drwxr-xr-x. 2 root root 21 May 12 06:16 .
dr-xr-xr-x. 1 root root 47 May 12 07:31 ..
-rw-r--r--. 1 root root 3 May 12 06:16 test.txt
* 참고
Pod 에서 보이는 시간이 국제 표준시로 출력됩니다. (한국보다 9시간 느림)
일단 넘어가고, 추후에 한국 시간으로 출력하는 방법을 찾으면 업데이트 하겠습니다.
'리눅스 > OpenShift' 카테고리의 다른 글
[OC & Kubernetes] Kubernetes 관리도구 helm 3.12 설치하기 (0) | 2023.05.19 |
---|---|
[참고] Openshift 에서 PV 에 연결된 PVC 정보 확인 및 PV 삭제하기 (0) | 2023.05.11 |
[Openshift] Pod (Container) 에 도메인 및 SSL 인증서 추가하기 (0) | 2023.05.10 |
[참고] Openshift 의 Service 와 Route 차이점 / Ingress 와 Route 차이점 (0) | 2023.05.10 |
[참고] Openshift 의 oc new-project 와 oc create ns 의 차이점 (0) | 2023.05.10 |