티스토리 뷰

□ PV(Persistent Volume)

스토리지 볼륨을 마운트 하여 사용할때 Kubernetes에서는 PV라고 명칭하고 있습니다. 관리자가 PV를 생성하면 PVC는 사용자가 볼륨을 사용하기 위해 PV에 요청을 하게 됩니다.

 

□ PVC(PersistentVolumeClaim)

사용자는 Pod를 생성할때 볼륨을 정의하는데 PVC를 지정하여 위에서 관리자가 생성한 PV와 연결하게 됩니다.

위와 같이 Storage를 PV형태로 추가하고 PVC로 Service에 할당해 주는 방식으로 구성됩니다.

또한, PVC는 Namespace Object이기 때문에 Namespace에 디펜던시가 걸리지만 PV는  Cluster Role과 비슷하게 클러스터에서 공용으로 사용할 수 있는 객체입니다.

□ PV는 4가지 상태 종류가 있습니다.

  • Available: PV가 생성되고 나면 사용 가능한 상태

  • Bound: PVC 요청에 의해 바인딩 되었을 때

  • Released: PVC가 삭제되어 요청이 없을 경우

  • Fail: 어떤 기타 이유로 문제가 생겼을 경우

 

□ PV와 PVC의 Lifecycle은 4가지로 나눌 수 있습니다.

1. 프로비저닝(provisioning)

정적 또는 동적의 PV를 생성하는 단계이고 PV생성이 정상적으로 성공하면 Available 상태가 됩니다. 정적 프로비저닝은 특정 용량을 가진 PV를 미리 생성해두고 PVC로부터 요청이 있을시에 미리 생성한 PV를 할당하여 사용하게 됩니다. 동적 프로비저닝은 정적과 다르게 사용자가 요청할 때 PV를 생성하는데 대표적으로 Storage Class를 사용하여 사용자가 원하는 만큼의 용량을 생성해서 자유롭게 사용할 수 있도록 합니다.

 

2. 바인딩(binding)

PV를 PVC에 연결시키는 단계로 PVC는 사용자가 요청하는 볼륨을 PV에 요청하고 PV는 사용자가 요청한 볼륨에 맞는 볼륨을 할당해줍니다. PVC가 요청하는 볼륨이 PV에 없다면 계속 대기상태로 남게 됩니다. 정상적으로 완료되면 bound 상태가 됩니다.

 

아래처럼 사용자가 PVC에게 20GB를 요청하면 PVC는 PV에게 20GB를 요청합니다 PV가 20GB가 있으면 OK 정상적으로완료되면 bound가 됩니다.

 

3. 사용(Using)

Pod(Service)는 PVC를 볼륨으로 사용합니다. 바인딩된 PV를 찾고 해당 볼륨을 Pod에서 사용가능하도록 만들어줍니다.

 

4. 회수(Reclamiming)

PV는 기존에 사용했던 PVC가 아니더라도 다른 PVC로 재활용이 가능합니다. 그래서 사용이 종료된 PVC를 삭제할 때, 사용했던 PV의 데이터를 어떻게 처리할지에 대한 설정을 합니다.

    • Retain: PV의 데이터를 그대로 보존합니다.

    • Recycle: 재사용하게될 경우 기존의 PV 데이터들을 모두 삭제 후 재사용 합니다.

    • Delete: 사용이 종료되면 해당 볼륨을 삭제합니다.

정적으로 PV 할당하기

  • PV를 생성

시나리오 -> 현재 테스트 환경은 K8S 클러스터에 NAS 500GB를 붙여 놓았습니다. 관리자가 정적으로 10GB짜리 PV를 생성합니다. Pod를 생성할때 볼륨을 정의하고 그 부분에 PVC를 지정하여 시스템 관리자가 생성한 PV와 연결 합니다.

 

 

 

현재 NFS는 /mnt/nas01과 mount 해놓았습니다.

 

 

아래처럼 pv를 apply 하게 되면 정상적으로 생성되었으며 status는 Available상태이므로 사용 가능한 상태가 됩니다. yaml 파일에서 spec.accessModes는 Pod의 접근 제어를 하는것인데 RedWriteOnce는 하나의 Pod에서만 읽고 쓸 수 있습니다.

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: hskim-pv
  labels:
    name: hskim-pv
spec:
  storageClassName: ""
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  nfs:
    server: 10.10.10.10
    path: /n123456_cluster
  • spec.accessModes: Pod의 접근제어를 합니다.

         -> ReadWriteOnce: 하나의 Pod에서만 읽고 쓸 수 있습니다.

         -> ReadOnlyMany: 여러개의 Pod에서 읽을 수 있습니다.

         -> ReadWriteMany: 여러개의 Pod에서 읽고 쓸 수 있습니다.

  • spec.storageClassName: 스토리지 클래스를 지정하고 해당 클래스에 맞는 PVC와 연결할 수 있습니다. 지금은 공백이지만 뒤에서 동적으로 PV를 생성할때는 스토리지클래스에 이름을 명시할 것입니다.

  • spec.persistentVolumeReclaimPolicy: Delete는 볼륨의 사용이 종료되면 볼륨을 삭제합니다. 위의 회수단계에서 설명한 부분입니다.

  • 원래는 hostpath나 emptypath를 사용하지만 NFS를 사용할것이므로 아래처럼 입력해줍니다. 위에서 해당 NFS는 /mnt/nas01로 되어있으므로 local mount path는 /mnt/nas01로 볼 수 있습니다.

□ PVC 생성

 

이제 위에서 PV를 생성했으므로 PVC를 생성해보겠습니다. 10GB짜리 PV를 생성해 놓았는데 PVC가 10GB 볼륨을 사용하려고 PVC를 생성해줍니다.

 

  • PVC (10GB) 요청

정상적으로 Bound 된 모습을 볼 수 있습니다. namepsace를 ingress-test로 한 이유는 지금 저기에 테스트한 application을 배포했기때문입니다. 뒤에 deployment에서 PVC를 사용할때 설명드리겠습니다.

---
apiVersion: v1
kind : PersistentVolumeClaim
metadata:
  namespace: ingress-test
  name: hskim-pvc
spec:
  accessModes:
     - ReadWriteOnce
  resources:
     requests:
       storage: 10Gi

정상적으로 PVC가 PV에 Bound 된 모습입니다.

 

그럼 지금상태는 아래그림에서 빨간색 파란색 부분까지 완료가 된 상황입니다. 이제 Pod를 생성할때 Volume에 PVC를 넣어주면 됩니다.

 

 

Pod 생성

아래처럼 작성하여 배포합니다.

  • spec.containers.volumeMounts: mountPath는 container 안의 mount할 경로를 입력해 줍니다.
  • spec.volumes.persistentVolumeClaim: 위에서 생성해놓은 PVC 할당해줍니다.
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: ingress-test
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-data
              mountPath: /bin
      volumes:
        - name: nginx-data
          persistentVolumeClaim:
            claimName: hskim-pvc

---
apiVersion: v1
kind: Service
metadata:
  namespace: ingress-test
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80

아래처럼 정상적으로 nginx pod에 hskim-pvc가 할당 되었고, mount 경로에 ingress-test-hskim-pvc-pvc... 생성되는것을 볼 수 있습니다.

 

 

동적으로 PV 할당하기

 

Public cloud를 사용하면서 제공자가 존재해 블록 스토리지 및 NAS를 유동적으로 제공할 수 있는 환경이라면 별도의 PV와 Disk를 생성해놓지 않아도 PV를 자동으로 생성할 수 있습니다. 즉, PVC만 선언해 생성하게 되면 PV와 그에 대응하는 Disk가 자동으로 생성된다는 뜻입니다. 이것을 Dynamic Provisioning 이라고 부릅니다.

 

현재 NBP 기준 NFS Client Provisioner를 설치하였습니다.

helm install nfs-client -n kube-storage \
--set nfs.server=10.10.10.10 \
--set nfs.path=/n123456_cluster \
stable/nfs-client-provisioner

nfs-client-provsioner가 설치가 완료되면 아래명령어로 storageClass를 조회할 수 있습니다.

 

PVC 생성

아래처럼 바뀐 부분은 metadata.name / spec.storageClassName 입니다. metadata.name은 동적 pvc라 그냥 바꾼거고 위에서 생성한 storageclass name을 추가하였습니다.

---
apiVersion: v1
kind : PersistentVolumeClaim
metadata:
  namespace: ingress-test
  name: hskim-dynamic-pvc
spec:
  storageClassName: "nfs-client"
  accessModes:
     - ReadWriteOnce
  resources:
     requests:
       storage: 10Gi

위의 yaml 파일을 apply 하게되면 아래처럼 pvc, pv가 동시에 생성이 됩니다. 다음부터는 똑같이 deployment yaml 파일에서 pvc를 사용하면 됩니다. 아래처럼요. 바뀐 부분은 spec.volumes.claimName 을 위에서 hskim-dynamic-pvc로 설정하였으므로 Name 부분만 바꾸어 주었습니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: ingress-test
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-data
              mountPath: /bin
      volumes:
        - name: nginx-data
          persistentVolumeClaim:
            claimName: hskim-dynamic-pvc

---
apiVersion: v1
kind: Service
metadata:
  namespace: ingress-test
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80

mount된 path에 접근하면 실제로 잘 생성이 되어 있습니다.

 

이 원리를 자세히 설명하자면 사용자가 요청한 PVC의 요구 사항이 인프라 관리자가 미리 생성한 PV 중 어떠한 PV와도 일치하지 않을 시 K8S Dynamic Provisioning을 시도하는데 이 때 Storage Class에 정의된 PV 및 물리적 Disk의 특징에 기반해 Dynamic Provisioning이 수행되는데, 위의 예시에서 nfs-client라는 이름의 storage class를 정의 하였기 때문에 자동으로 생성이 된 것입니다. 즉, Storage class는 Dynamic Provisioning에 의해 새롭게 생성될 PV, 물리적 Disk의 특성을 정의하는 일종의 템플릿이라고 보면 됩니다. 더불어 Dynamic Provisioning을 사용하려면 관리자가 사전에 Sotrage class를 미리 정의해 놓아야 합니다.

 

 

출처: https://m.blog.naver.com/alice_k106/221360005336

 

참고한 글: 

m.blog.naver.com/alice_k106/221360005336

gruuuuu.github.io/cloud/k8s-volume/#

nirsa.tistory.com/157

 

댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31