Section 8-1. Volumes
udemy의 Certified Kubernetes Administrator (CKA) with Practice Tests 강의 및 쿠버네티스 인 액션 (마르코 룩샤)를 참고하여 정리한 글입니다.
Section08. Storage
Volumes
- 컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너가 크래시될 때 파일이 손실된다. 즉 로그 파일을 보관해야 한다거나, 데이터 베이스를 사용할 경우 실시간으로 생성되던 데이터가 사라질 위험이 있다.
- 쿠버네티스는 이러한 이유로 실제 데이터가 있는 디렉터리를 보존하기 위해 저장소 볼륨을 정의한다.
볼륨은 컨테이너 단위가 아닌 파드 단위이기 때문에 그 파드 안에 속해 있는 여러 개의 컨테이너가 공유해서 사용될 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
apiVersion: v1 kind: Pod metadata: name: random-bynber-genarator spec: containers: - name: alpine image: alpine command: ["/bin/sh", "-c"] args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"] volumeMounts: - mountPath: /opt name: data-volume volumes: - name: data-volume hostpath: path: /data type: Directory
- 이 예제의 경우 노드의 로컬 디스크 경로를 볼륨으로 사용하는
hostPath 볼륨
이다. 파드가 생성된 노드의 /data 디렉터리에 저장된다. - 볼륨이 생성되면 컨테이너에서 그에 액세스하기 위해 컨테이너 내부의 디렉터리에 그 볼륨을 마운트한다.
- 파드가 삭제 되더라도 hostPath에 있는 파일들은 삭제되지 않으므로 다른 파드가 같은 hostPath에 마운트하게 되면 남아 있는 파일에 액세스할 수 있다.
- 그러나 노드의 해당 경로에 볼륨을 마운트한 파드가 다른 노드에서 재생성될 경우 그 노드의 볼륨에 마운트할 수 없다.
- 이 예제의 경우 노드의 로컬 디스크 경로를 볼륨으로 사용하는
Volume의 종류
- emptyDir: 일시적인 데이터를 저장하는 빈 디렉토리
Persistent Volumes
- 퍼시스턴트볼륨 (PV)은 관리자가 프로비저닝하거나 스토리지 클래스를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지이다.
- 노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스이다.
Volume은 Pod과 동일한 라이프사이클을 가지지만 PV는 리소스를 사용하는 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: pv-voll spec: accessModes: - ReadWriteOnce capacity: storage: 1Gi hostPath: path: /tmp/data $ kubectl create -f pv-definition.yaml persistentvolume/pv-vol1 created $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-vol1 1Gi RWO Retain Available 3min
- accessModes: 호스트에 볼륨이 어떻게 마운트되어야 하는지 정의한다. (ReadOnly, ReadWriteOnce, ReadWriteMany)
- capacity: PV를 위해 예약될 저장소 크기를 정의한다.
- hostPath: hostPath는 노드의 로컬 디렉토리에 저장소를 둔다.
Persistent Volume Claims
- PVC는 사용자의 스토리지에 대한 요청이다.
- 특정 크기 및 접근 모드를 요청할 수 있다(예: ReadWriteOnce, ReadOnlyMany 또는 ReadWriteMany로 마운트 할 수 있다)
- 모든 PVC는 단일 PV에 묶인다.
- 쿠버네티스는 PVC에서 요구하는 storage 용량을 확보할 수 있는 쪽으로 access mode, volume mode, storage class, sufficient capacity를 고려하여 PV를 바인딩한다. ```
pvc-definition.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: myclaim spec: accessModes:
- ReadWriteOnce resources: requests: storage: 500Mi
$ kubectl create -f pvc-definition.yaml persistentvolumeclaim/myclaim created
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim Pending
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim Bound pv-vol1 1Gi RWO 43m ```
- 위와 같이 PVC를 생성하면 PV 중 accessModes가 일치하고 storage 용량을 확보할 수 있는 pv에 바운딩된다
- 쿠버네티스는 PVC에서 요구하는 storage 용량을 확보할 수 있는 쪽으로 access mode, volume mode, storage class, sufficient capacity를 고려하여 PV를 바인딩한다. ```
PV와 PVC의 생명주기
- PV와 PVC는 프로비저닝 -> 바인딩 -> 사용 -> 반환의 생명주기를 따른다.
프로비저닝
- PV를 프로비저닝 할 수 있는 방법은 정적(static) 프로비저닝과 동적(dynamic) 프로비저닝 두 가지 방법이 있다:
정적 프로비저닝
- 클러스터 관리자는 여러 PV를 만든다. 클러스터 사용자가 사용할 수 있는 실제 스토리지의 세부 사항을 제공한다. 이 PV들은 쿠버네티스 API에 존재하며 사용할 수 있다
동적 프로비저닝
- 관리자가 생성한 정적 PV가 사용자의 퍼시스턴트볼륨클레임과 일치하지 않으면 클러스터는 PVC를 위해 특별히 볼륨을 동적으로 프로비저닝 하려고 시도할 수 있다.
클러스터 관리자는 PV를 생성하는 대신에, 퍼시스턴트 볼륨 프로비저너를 배포해 사용자가 선택 가능한 볼륨 타입을 하나 이상의 스토리지클래스 오브젝트로 정의하면 사용자가 퍼시스턴트볼륨클레임에서 스토리지클래스를 참조하여 프로비저너가 이를 프로비저닝할 시에 처리한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# storage-definition.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: silver provisioner: kubernetes.io/gce-pd parameters: type: pd-standard replication-type: none # storageClass-pvc-definition.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mongodb-pvc spec: resources: requests: storage: 100Mi accessModes: - ReadWriteOnce storageClassName: silver
- storageClassName 항목에 생성한 storage class의 이름을 명시한다.
- storage class에 참조한 프로비저너가 알아서 PV를 생성해주고, PVC와 연결도 해준다.
바인딩
- 마스터의 컨트롤 루프는 새로운 PVC를 감시하고 일치하는 PV(가능한 경우)를 찾아 서로 바인딩한다.
- PV가 새 PVC에 대해 동적으로 프로비저닝된 경우 루프는 항상 해당 PV를 PVC에 바인딩한다.
- 일치하는 볼륨이 없는 경우 클레임은 무한정 바인딩되지 않은 상태로 남아 있다. 일치하는 볼륨이 제공되면 클레임이 바인딩된다
- 예를 들어 많은 수의 50Gi PV로 프로비저닝된 클러스터는 100Gi를 요청하는 PVC와 일치하지 않는다. 100Gi PV가 클러스터에 추가되면 PVC를 바인딩할 수 있다.
사용
- 파드는 클레임을 볼륨으로 사용하고, 클러스터는 클레임을 검사하여 바인딩된 볼륨을 찾고 해당 볼륨을 파드에 마운트 한다. 일단 클레임이 바인딩되면 PV는 사용자가 필요로 하는 한 사용자에게 속하게 된다.
반환
- 사용자가 볼륨을 다 사용하고나면 리소스를 반환할 수 있는 API를 사용하여 PVC 오브젝트를 삭제할 수 있다.
- 퍼시스턴트볼륨의 반환 정책은 볼륨에서 클레임을 해제한 후 볼륨에 수행할 작업을 클러스터에 알려준다.
반환 정책
- Retain: 리소스를 수동으로 반환할 수 있게 하는 정책이다. PVC가 삭제되어도 PV는 여전히 존재하며, 따라서 다른 요청에 대해서는 사용이 불가능하다. 따라서 관리자가 수동으로 볼륨을 반환해야 한다.
- Delete: PV와 외부 인프라와 관련된 스토리지 자산을 모두 삭제한다. 동적으로 프로비저닝 된 볼륨은 Storage Class의 반환 정책을 상속한다.
정리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# pv-definition.yaml => # pvc-definition.yaml => # pod-definition.yaml
apiVersion: v1 apiVersion: v1 apiVersion: v1
kind: PersistentVolume kind: PersistentVolumeClaim kind: Pod
metadata: metadata: metadata:
name: pv-voll name: myclaim name: ramdom-number-generator
spec: spec: spec:
accessModes: accessModes: containers:
- ReadWriteOnce - ReadWriteOnce - name: alpine
capacity: resources: image: alpine
storage: 1Gi requests: command: ["/bin/sh", "-c"]
hostPath: storage: 500Mi args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
path: /tmp/data volumeMounts:
- mountPath: /opt
name: data-volume
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: myclaim