클라우드/Kubernetes

쿠버네티스 불륨설명

Cloud_Park 2020. 1. 10. 13:22

쿠버네티스에 볼륨은 다양한 볼륨을 지원한다. 로컬,NFS, iSCSI, Fiber Channel에 일반적인 외장 디스크, 오픈소스(GlusterFS나, Ceph), 퍼블릭클라우드 볼륨(AWS EBS, GCP Persistent)

 자세한내용 보기   https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes
 

파드에 들어가는 볼륨이기 떄문에  파드안에 있는 컨테이너는 서로 공유가능하다.

 

볼륨의 종류에는 3개지가 있다.

 

 

Temp :

emptyDir

  pod의 생성,삭제주기와 같은 볼륨이다. 파드안에 컨테이너가 죽어도 파드는 죽이 않아서 볼륨이 살아있다는 장점이 있다.  emptyDir.medium 필드를 통해  지정된다.

Pod에 nginx와 redis 컨테이너를 기동 시키고, emptyDir 볼륨을 생성

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

apiVersion: v1

kind: Pod

metadata:

  name: shared-volumes  

spec:

  containers:

  - name: redis

    image: redis

    volumeMounts:

    - name: shared-storage

      mountPath: /data/shared

  - name: nginx

    image: nginx

    volumeMounts:

    - name: shared-storage

      mountPath: /data/shared

  volumes:

  - name : shared-storage 

    emptyDir: {}

접속해서 보기

# kubectl exec -it shared-volumes --container redis -- /bin/bash

# ls

 

 

Local :

hostPath

 노드의  로컬디스트의 경로를 Pod에서 마운트하여 사용한다. 이것도 한 파드안에 있는 컨테이너들끼리 공유가능하다.

 emptyDir 와의 차이점은 생성주기가  다르다  해당 pod가 삭제되면 hostPaht는 남아있다.

주의사항은 pod가 재시작될 때  다른 노드에서 재기동된다면 엑세스가 불가능하다 -> 노드를 지정해주는 방안이 필요

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

apiVersion: v1

kind: Pod

metadata:

  name: hostpath

spec:

  containers:

  - name: redis

    image: redis

    volumeMounts:

    - name: terrypath

      mountPath: /data/shared

  volumes:

  - name : terrypath

    hostPath:

      path: /tmp

      type: Directory

설명 : 

/tmp 디렉토리를 hostPath를 이용하여 /data/shared 디렉토리에 마운트 하여 사용

pod를 배포하여  pod 의 id를 얻어보자

# kubectl describe pod hostpath

노드에 ssh로 접속하여  파일을 생성하고  파드에 접속하여  파일을 확인

# kubectl exec -it hostpath --/bin/bash

 

Network :

GlusterFS

 git에서 특정 리비전의 내용을 clone하여  내려받고 디스크 볼륨을 생성하는 방식. emptyDir이 생성되고 git  레파지토리 내용을 clone으로 다운받는다.

자세히 알아보기 https://github.com/gluster/gluster-kubernetes

 

gluster/gluster-kubernetes

GlusterFS Native Storage Service for Kubernetes. Contribute to gluster/gluster-kubernetes development by creating an account on GitHub.

github.com

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

apiVersion: v1

kind: Pod

metadata:

 name: gitrepo-volume-pod

spec:

 containers:

 - image: nginx:alpine

   name: web-server

   volumeMounts:

   - name: html

     mountPath: /usr/share/nginx/html

     readOnly: true

   ports:

   - containerPort: 80

     protocol: TCP

 volumes:

 - name: html

   gitRepo:

        repository: https://github.com/luksa/kubia-website-example.git

        revision: master

        directory: .

https://github.com/luksa/kubia-website-example.git 의 master 리비전을 클론으로 다운받아서 /usr/share/nginx/html에 마운트 시키는 설정

 

 

PersistentVolume and PersistentVolumeClaim

디스크 볼륨을 설정하려면 물리적 디스크를 생성해야 하고, 이러한 물리적 디스크에 대한 설정을 자세하게 이해해야한다.

 

쿠버네티스는 인프라에 대한 복잡성을 추상화를 통해서 간단하게 하고, 개발자들이 손쉽게 필요한 인프라 (컨테이너,디스크, 네트워크)를 설정할 수 있도록 하는 개념을 가지고 있다

그래서 인프라에 종속적인 부분은 시스템 관리자가 설정하도록 하고, 개발자는 이에 대한 이해 없이 간단하게 사용할 수 있도록 디스크 볼륨 부분에 PersistentVolumeClaim (이하 PVC)와 PersistentVolume (이하 PV)라는 개념을 도입하였다.

 

시스템 관리자가 실제 물리 디스크를 생성한 후에, 이 디스크를 PersistentVolume이라는 이름으로 쿠버네티스에 등록한다.

개발자는 Pod를 생성할때, 볼륨을 정의하고, 이 볼륨 정의 부분에 물리적 디스크에 대한 특성을 정의하는 것이 아니라 PVC를 지정하여, 관리자가 생성한 PV와 연결한다.

 

시스템 관리자가 생성한 물리디스크를 쿠버네티스 클러스터에 표현한 것이 PV이고, Pod의 볼륨과 PV를 연결 하는 관계가 PVC이다.

주의사항으론  볼륨은 생성후에 , 직접 생성하지 않으면 삭제되지 않아 PV 생명주기는  쿠버네시트 클러스터에 의해서 관리 되면 Pod 생성 또는  삭제에 관련 없이  별도 관리된다.

* pod와 상관없이 직접 생성 삭제

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

apiVersion: v1

kind: PersistentVolume

metadata:

 name: pv0003

spec:

 capacity:

   storage: 5Gi

 volumeMode: Filesystem

 accessModes:

   - ReadWriteOne: 

 persistenVolumeReclaimPolicy: Recycle

 storageClassName: slow

 mountOptions:

   - hard

   - nfserver=4.1

 nfs:

  path: /temp

  server: 127.0.0.3

설명

capacity : 용량 , 추가적으러 IOPS,Throughput지원할예정

volumemode: default는 filesyetem이다.  raw 불륨인지 설정가능

reclaim Policy: pv는 연결된 pvc가 삭제된 후 다시 다른 pvc에 의해서 재 사용이 가능, 재사용시 디스크 삭제유무를 설정가능하다. 디스크의 특성에 따라 선택적으로 지원가능하다고 한다.

 retain :유지

 recycle:재사용 가능하며  내용을 자동적으로 지운후 사용가능

 delete : 볼륨 사용이 끝나면 삭제                 예시) aws ebs, gcp pd, azure disk에 해당

 

pv의 라이프 사이클 : 생성되면 available상태,  pvc에 바인딩되면 bound 상태로 사용되며, 바인딩된 pvc가 삭제되면  pv가 삭제되는게 아니라 Released상태가 된다.(avaliable상태여야  사용가능하다.)

pv생성 :  yaml로도 생성가능하지만  설정에 따라서 자동으로 생성가능하다->  dynamic provisioning이라한다.

 

PersistentVolumeClaim: pvc는 pod의 볼륨과 pvc를 연결한느 관계선언이다

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

 name: myclaim

spec:

 accessModes:

   - ReadWriteOne

 volumeMode: Filesystem

 resource:

  requests:

   storage: 5Gi

 storageClassName: slow

 selecctor :

  matchLabels:

   release: "stable"

  matchExpressions:

   - {key: environment, operator: In, valuse: [dev]}

 

accessMode, VolumeMode는 PV와 동일하다.

resources는 PV와 같이, 필요한 볼륨의 사이즈를 정의한다.selector를 통해서 볼륨을 선택할 수 있는데, label selector 방식으로 이미 생성되어 있는 PV 중에, label이 매칭되는 볼륨을 찾아서 연결하게 된다.

 

 

 

 

 

PV/PVC 예제PV/PVC 예제
그러면 예제를 통해서 PV를 생성하고, 이 PV를 PVC에 연결한후에, PVC를 Pod에 할당하여 사용하는 방법을 살펴보도록 하자. 예제는 구글 클라우드 환경을 사용하였다.

1.물리 디스크 생성
먼저 구글 클라우드 콘솔에서 Compute Engine 부분에서 아래와 같이 Disks 부분에서 물리 디스크를 생성한다.

그러면 예제를 통해서 PV를 생성하고, 이 PV를 PVC에 연결한후에, PVC를 Pod에 할당하여 사용하는 방법을 살펴보도록 하자. 예제는 구글 클라우드 환경을 사용하였다.

1.물리 디스크 생성

먼저 구글 클라우드 콘솔에서 Compute Engine 부분에서 아래와 같이 Disks 부분에서 물리 디스크를 생성한다.

 

디스크를 pv-demo-disk라는 이름으로 생성하였다.

이때 주의할점은 디스크의 region과 zone이 쿠베네티스 클러스터가 배포된 region과 zone에 동일해야 한다.

 

2.생성된 디스크로 PV를 선언

생성된 디스크를 이용하여 PV를 생성한다. 아래는 PV를 생성하기 위한 yaml 파일이다.

1

2

3

4

5

6

7

8

9

10

11

12

13

apiVersion: v1

kind: PersistentVolume

metadata:

 name: pv-demo

spec:

 storageClassName:

 capacity:

   storage: 20G

 accessModes:

   - ReadWriteOnce

 gcePersistentDisk:

   pdName: pv-demo-disk

   fsType: ext4

PV의이름은 pv-demo이고, gcePersistentDisk에서 앞에서 생성한 pv-demo-disk 를 사용하도록 정의하였다.

파일을 실행하면, 아래와 같이 pv-demo로 PV가 생성된것을 확인할 수 있다

3. 다음 PVC를 생성한다.
 pv-demo PV를 사용하는 PVC를 생성하는 yaml 파일이다. 하나의 Pod에서만 액세스가 가능하도록 accessMode를 ReadWriteOnce로 설정

1

2

3

4

5

6

7

8

9

10

11

12

13

existing-pvc.yaml

apiVersion: v1

kind : PersistentVolumeClaim

metadata:

  name: pv-claim-demo

spec:

  storageClassName: ""

  volumeName: pv-demo

  accessModes:

    - ReadWriteOnce

  resources:

    requests:

      storage: 20G

생성한 PVC pv-claim-demo를 Volume에 연결한후, 이 볼륨을 /data 디렉토리에 마운트된다.

Dynamic Provisioning

앞에서 본것과 같이 PV를 수동으로 생성한후 PVC에 바인딩 한 후에, Pod에서 사용할 수 있지만, 쿠버네티스 1.6에서 부터 Dynamic Provisioning (동적 생성) 기능을 지원한다. 이 동적 생성 기능은 시스템 관리자가 별도로 디스크를 생성하고 PV를 생성할 필요 없이 PVC만 정의하면 이에 맞는 물리 디스크 생성 및 PV 생성을 자동화해주는 기능이다.

 

 

 

PVC를 정의하면, PVC의 내용에 따라서 쿠버네티스 클러스터가 물리 Disk를 생성하고, 이에 연결된 PV를 생성한다.

실 환경에서는 성능에 따라 다양한 디스크(nVME, SSD, HDD, NFS 등)를 사용할 수 있다. 그래서 디스크를 생성할때, 필요한 디스크의 타입을 정의할 수 있는데, 이를 storageClass 라고 하고, PVC에서 storage class를 지정하면, 이에 맞는 디스크를 생성하도록 한다.

Storage class를 지정하지 않으면, 디폴트로 설정된 storage class 값을 사용하게 된다.

 

동적 생성 방법은 어렵지 않다. PVC에 필요한 디스크 용량을 지정해놓으면, 자동으로 이에 해당하는 물리 디스크 및 PV가 생성이 된다. 아래는 동적으로 PV를 생성하는 PVC 예제이다.

 

dynamic-pvc.yaml

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

 name: mydisk

spec:

 accessModes:

   - ReadWriteOnce

 resources:

   requests:

     storage: 30Gi

 

다음 Pod를 생성한다.

apiVersion: v1

kind: Pod

metadata:

 name: redis

spec:

 containers:

 - name: redis

   image: redis

   volumeMounts:

   - name: terrypath

     mountPath: /data/shared

 volumes:

 - name : terrypath

   persistentVolumeClaim:

     claimName: mydisk

 

Pod를 생성한후에, kubectl get pvc 명령어를 이용하여, 생성된 PVC와 PV를 확인할 수 있다.

PVC는 위에서 정의한것과 같이 mydisk라는 이름으로 생성되었고, Volume (PV)는 pvc-4a…. 식으로 새롭게 생성되었다.

Storage class

스토리지 클래스를 살펴보자,

아래는  AWS EBS 디스크에 대한 스토리지 클래스를 지정한 예로, slow 라는 이름으로 스토리지 클래스를 지정하였다. EBS 타입은 io1을 사용하고, GB당 IOPS는 10을 할당하도록 하였고, 존은 us-east-1d와 us-east-1c에 디스크를 생성하도록 하였다.

 

 

아래는 구글 클라우드의 Persistent Disk (pd)의 예로, slow라는 이름으로 스토리지 클래스를 지정하고, pd-standard (HDD)타입으로 디스크를 생성하되 us-central1-a와 us-central1-b 존에 디스크를 생성하도록 하였다.

이렇게 정의한 스토리지 클래스는  PVC 정의시에, storageClassName에 적으면 PVC에 연결이 되고, 스토리지 클래스에 정해진 스펙에 따라서 물리 디스크와 PV를 생성