쿠버네티스 불륨설명
쿠버네티스에 볼륨은 다양한 볼륨을 지원한다. 로컬,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
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를 생성