쿠버네티스 클러스터 스토리지 관리
1. 파드 내부의 각 컨테이너는 고유하게 분리된 파일시스템을 가진다.
2. 컨테이너의 파일 시스템은 컨테이너 이미지에서 제공되기 때문에 컨테이너가 재 시작할 때마다 컨테이너 이미지내의 파일시스템으로만 시작한다.
3. 재 시작된 컨테이너는 이전 컨테이너에 쓰여진 파일시스템의 내용을 볼 수 없다.
컨테이너는 원본 이미지로만 재 시작된다.
4. 스토리지 볼륨은 파드와 동일한 라이프 사이클을 가진다. 이는 파드가 시작되면 볼륨이 생성되고 파드가 삭제되면 볼륨이 삭제된다는 의미를 가지므로 볼륨의 컨텐츠는 컨테이너를 다시 시작해도 지속된다.
5. 파드내의 모든 컨테이너가 볼륨을 공유할 수 있다.
쿠버네티스 클러스터 스토리지 컴포넌트
볼륨 관리
1. 볼륨(volume)은 파드의 컨테이너와 동일하게 파드 스펙에서 정의된다. 볼륨만 별도로 생성, 삭제할 수 없다.
2. 볼륨은 파드의 컨테이너에서 각각 마운트 돼야한다. 컨테이너에서 파드내의 볼륨에 접근하려면 VoumeMount를 컨테이너 스펙에 정의한다.
3. 볼륨은 컨테이너 단위가 아니라 Pod 단위이기 때문에, 그 Pod에 속해 있는 여러 개의 컨테이너가 공유해서 사용될 수 있다.
4. 볼륨을 채우거나 마운트 하는 프로세스는 파드의 컨테이너가 시작되기 전에 수행된다.
5. 볼륨은 이미지 내에 지정된 경로에 마운트된다. 볼륨은 다른 볼륨에 마운트할 수 없거나 다른 볼륨에 대한 하드 링크를 가질 수 없다. 파드 구성의 각 컨테이너는 각 볼륨을 마운트할 위치를 독립적으로 지정해야 한다.
볼륨종류
1. emptyDir 볼륨
1. emptyDir은 Pod가 생성, 삭제될 때 같이 생성, 삭제되는 임시 볼륨이다.
- 임시 데이터를 저장하는 용도로 사용한다.
- 파드가 노드에 할당될 때 처음 생성되고 파드가 제거되면 데이터가 영구적으로 삭제된다.
2. emptyDir 볼륨은 디스크에 아무 내용이 없는 빈 볼륨으로 emptyDir이라고 한다.
3. 같은 파드 내에서 실행 중인 모든 컨테이너는 볼륨내 데이터를 공유한다.
4. emptyDir은 노드에서 할당해주는 디스크에 저장이 되는데 그 외에도 네트워크 디스크, 메모리 등을 저장소로 사용할 수 있다. emptyDir.medium 필드에 “Memory”라고 지정 시메모리에 데이터 임시저장이 가능하다.
emptyDir을 사용하기 위한 매체 지정하기
1. 기본적으로, emptyDir 볼륨은 노드를 지원하는 모든 매체에 저장된다(환경에 따라 디스크, SSD 또는 네트워크 스토리지일 수 있다).
2. emptyDir.medium 필드를 "Memory" 로 설정 tmpfs(RAM 기반 파일 시스템)를 마운트 하도록 할 수 있다. tmpfs는 매우 빠르지만, 노드 재 부팅 시 데이터는 자동 삭제된다.
emptyDir을 사용한 볼륨
- 하나의 파드에 여러 개 컨테이너가 데이터를 공유하는 방법 ( emptyDir 볼륨 사용 )
- emptyDir은 Pod가 생성될 때 생성되고 Pod가 삭제될 때 같이 삭제되는 임시 볼륨이다.
2. hostPath 볼륨
hostPath 볼륨이란?
1. hostPath는 워커노드의 디스크를 Pod에서 마운트하여 사용한다.
2. hostPath에 있는 볼륨은 여러 Pod 사이에서 공유하여 사용할 수 있다.
3. Pod가 삭제 되더라도 hostPath에 있는 파일들은 삭제되지 않는다.
여러개의 pod를 한개의 hostPath를 마운트 하여 기존의 데이터를 사용할 수 있다.
4. Pod가 재 배포되어 다른 노드에서 실행되는 경우, 새로 배포된 노드의 hostPath를 사용하기 때문에, 이전 노드에서 사용한 hostPath의 data는 접근할 수 없다. 파드의 무작위 배포 때문에 이전의 노드로만 연결 된다는 것은 장담할 수 없다.
5. 데몬셋으로 관리중인 파드는 노드의 파일을 읽거나 파일시스템을 통해 노드 디바이스를 접근하기 위해 노드의 파일시스템을 사용해야 한다. 이를 hostpath 볼륨으로 구현가능 하다.
6. hostPath는 워커 노드의 하드디스크를 사용하므로 파드가 배포되는 노드에 있는 데이터를 사용하도록 설정되므로 노드마다 다르게 동작할 수 있음을 주의하자.
hostPath 볼륨의 단점과 실습
- 디플로이먼트로 파드를 여러개 배포할 경우 여러 워커노드에 배포된 파드들은 각기 다른 hostPath를 사용하게된다. (볼륨의 공용 사용이 힘들다.)
퍼시스턴트볼륨(PV: PersistenVolume)과 퍼시스턴트볼륨클레임(PVC : PersistentVolumeClaim)
클러스터 관리자:
- 인프라 구성 (PV)
- 시스템 관리자가 스토리지를 생성하고, 이 디스크를 PV로 등록한다.
- 네트워크 스토리지 유형 설정
- 퍼시스턴트볼륨(PV) 생성
개발자:
- 개발 업무 (PVC)
- 개발자는 파드를 생성할 때, 볼륨을 정의하고 PVC를 지정하여 관리자가 생성한 PV와 연결한다.
- 퍼시스턴트볼륨클레임(PVC)을 생성: 최소 크기와 필요한 접근 모드를 명시한 PVC 생성
- PVC를 참조하는 볼륨을 가진 파드를 생성
- 정리
1. 관리자가 생성한 물리 디스크를 PV로 생성, Pod의 볼륨과 이 PV를 연결하는 관계가 PVC가 된다.
2. 관리자가 물리 디스크를 생성한 후 PersistentVolume(PV)으로 등록한다.
3. 개발자는 PVC를 API서버에 게시하고 클러스터가 적절한 PV를 찾아 클레임에 볼륨을 바인딩한다. 즉 개발자는 Pod를 생성 할 때, 볼륨을 정의하고, 이 볼륨 정의 부분에 물리적 디스크에 대한 특성을 정의하는 것이 아니라 PVC를 지정하여, 관리자가 생성한 PV와 연결한다
4. PVC의 바인딩을 삭제해 릴리스 될 때까지 다른 사용자는 동일한 PV를 사용할 수 없다.
PV와 PVC 사용관계 (바인딩)
1. 개발자가 요구하는 특정 용량의 스토리지와 접근모드로 PVC를 생성하거나 동적 프로비저닝한 상태로 이미 PV가 생성된 상태여야 한다.
- 개발자는 퍼시스턴트 스토리지가 필요한 pod를 배포하기 위해 클레임을 먼저 해야 한다.
(*pod를 배포하기 위해서는 pvc를 먼저 생성해야한다.)
2. PVC를 감시하고 일치하는 PV를 찾아 서로 바인딩한다.
- PV가 새 PVC에 동적프로비저닝되어 항상 바인딩된다.
- PVC대 PV바인딩은 1:1 바인딩을 사용한다.
결론적으로 생성 순서는 : PV -> PVC ->POD가 된다.
반환 정책(persistentVolumeReclaimPolicy) 3가지
(Retain:보존 Recycle:재활용 Delete:삭제)
- persistentVolumeReclaimPolicy를 Retain으로 설정하면 클레임이 해제돼도 볼륨과 컨텐츠를 보존한다.
- 퍼시스턴트볼륨을 수동으로 재사용할 수 있는 방법은 퍼시스턴트볼륨(PV) 리소스를 삭제하고 다시 생성하는 것이 유일한 방법이다.
- 기반 스토리지 (PD)의 파일을 삭제할지 남겨둘지 결정해야 한다. 정상화하기 위한 작업 (기존의 PV, PVC를 수동으로 삭제한다. 그리고 다시 PV → PVC순으로 만든다.)
1. Delete정책: PV와 PD를 모두 삭제한다.
동적 프로비저닝된 볼륨은 SC의 반환정책을 상속받으며 기본값이 Delete이다.
2. Retain(보존)정책: 리소스를 수동으로 반환한다.
PVC가 삭제되면 PV는 여전히 존재하며 “release”로 간주된다. 이전 데이터가 볼륨에 남아있어 다른 요청에 대하여 아직 사용할 수 없으므로 관리자는 볼륨을 수동으로 반환한다.
- 클러스터 관리자가 볼륨을 수동으로 삭제하지 않으면 동일 PV를 사용하는 새 PVC, 새pod는 이전 pod에서 저장한 데이터를 사용할 수 있다.
- 서로 다른 네임스페이스에서 새로운 PVC, pod를 생성하더라도 이전 pod가 저장한 데이터를 사용할 수 있다.
=>반환정책은
PVC(PersistentVolumeClaim) 접근모드
ReadWriteOnce (RWO) : 단일 노드만 읽기/쓰기 마운트
ReadOnlyMany (ROX) : 다수 노드가 읽기전용 마운트
ReadWriteMany (RWX) : 다수 노드가 읽기/쓰기 마운트
=>NFS를 사용하는 이유!! 3가지 접근모드를 모두 사용가능하며 오픈소스이다.
동적 프로비저닝
1. 프로비저닝(provisioning)은 사용자의 요구에 맞게 시스템 자원을 할당, 배치, 배포해 두었다가 필요시 시스템을 즉시 사용할 수 있는 상태로 미리 준비해 두는 것을 말한다.
- 서버 자원 프로비저닝
- OS 프로비저닝
- 소프트웨어 프로비저닝
- 스토리지 프로비저닝
- 계정 프로비저닝
- 수동으로 처리하는 '수동 프로비저닝’
- 자동화 툴을 이용해 처리하는 '자동 프로비저닝'이 있다.
2. 클러스터 관리자가 퍼시스턴트볼륨을 생성하는 대신 퍼시스턴트볼륨 프로비저너를 배포하고 사용자가 선택 가능한 PV의 타입을 하나 이상의 스토리지클래스(StorageClass) 오브젝트로 정의할 수 있다.
3. 사용자가 PVC에서 스토리지클래스를 참조하면 프로비저너(provisioner)가 퍼시스턴트 스토리지(PD)를 프로비저닝 할 때 이를 처리한다.
4. 스토리지클래스(SC) 리소스는 네임스페이스를 사용하지 않는다.
5. 스토리지클래스를 정의하면 PVC요청 시 새로운 PV를 자동 생성해준다.
StorageClass(SC) 리소스
퍼시스턴트 볼륨(PV)을 동적으로 프로비저닝할 때 사용되는 provisioner, parameters와 reclaimPolicy 필드가 포함된다.
예)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd # 각 스토리지클래스에는 PV 프로비저닝에 사용되는 볼륨 플러그인을 결정하는 프로비저너가 있다. 이 필드는 반드시 지정해야 한다.
parameters:
type: pd-standard
..................
동적 프로비저너 지정
- AWS의 EKS, GCP의 GKE에서 Kubernetes를 사용할 시 Default로 각 Public Cloud에서 제공하는 Storage와 매칭 되어있는 StorageClass가 기본 지원된다.
- on-premise 환경의 경우 default StorageClass는 없다. on-premise 환경에서 Volume을 Dynamic Provisioning 방식으로 사용하고 과금을 피하기 위해 NFS Server를 Dynamic Provisioning StorageClass로 사용하기도 한다.
동적 프로비저닝 기본 동작
1. 스토리지 클래스가 지정되지 않은 경우 모든 클레임이 동적으로 프로비전이 되도록 클러스터에서 동적 프로비저닝을 활성화할 수 있다.
2. StorageClass 오브젝트를 default 로 표시한다.
3. DefaultStorageClass 어드미션 컨트롤러를 사용 설정한다.
4. 기본 StorageClass가 클러스터에 존재하고 사용자가 storageClassName를 지정하지 않은PersistentVolumeClaim을 작성하면, DefaultStorageClass 어드미션 컨트롤러가 디폴트 스토리지 클래스를 가리키는 storageClassName 필드를 자동으로 추가한다.
5. 클러스터에는 최대 하나의 default 스토리지 클래스가 있을 수 있다. 그렇지 않은 경우storageClassName을 명시적으로 지정하지 않은 PersistentVolumeClaim을 생성할 수 없다.
6. PVC에서 StorageClassName 속성을 “” 빈문자열 처리시 PVC가 새로운 PV를 동적 프로비저닝하는 대신 미리 프로비저닝된 PV에 바인딩된다.
NFS 퍼시스턴트 스토리지 사용 목적
1. 지속적 연결을 지원하기 위한 볼륨
2. 파드에 실행중인 애플리케이션이 디스크에 데이터를 유지해야 하고 파드가 다른 노드로 재 스케줄링 된 경우에도 동일한 데이터를 사용해야 한다.
3. 클러스터 관리자는 스토리지클래스(StorageClasses)를 사용하여 동적 프로비저닝을 설정할 수도 있다.
NFS 동적 프로비저닝
1. 동적 프로비저닝 기능을 사용하면 클러스터 관리자가 스토리지를 사전 프로비저닝 할 필요없이 사용자가 요청하면 자동으로 스토리지를 프로비저닝 할 수 있다.
2. 이미지 샘플에 대한 사이트 소개
quay.io
Red Hat Quay
엔터프라이즈 환경을 위한 분산된 고가용성 컨테이너 이미지 레지스트리
Red Hat® Quay 컨테이너 이미지 레지스트리는 스토리지를 제공하고 사용자가 컨테이를
구축, 분산 및 배포할 수 있도록 지원한다.
쿠버네티스 환경에서 스토리지를 관리하는것은 매우 중요한 부분이다.
스토리지의 구성이 어떻게 이루어지는지 확인했으며
새로운 파드를 생성할때 마다 스토리지 연결 / 반환은 어떻게 이루어지고
NFS를 활용하여 동적 프로비저닝은 어떻게 구성이 되는건지 확인해보았다.
다음 포스팅에서는 동적/정적 프로비저닝을 GKE(Google Kubernetes Engine)환경에서 직접 만드는 실습을 해보겠다.
댓글