Openshift 4.12.0 PV, PVC (NFS) 를 이용한 Volume 추가

리눅스/OpenShift|2023. 5. 10. 15:05
반응형

한번 가동된 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시간 느림)

일단 넘어가고, 추후에 한국 시간으로 출력하는 방법을 찾으면 업데이트 하겠습니다.

 

 

반응형

댓글()