쿠버네티스,쿠버플로우

쿠버네티스(스토리지)

세용용용용 2023. 7. 5. 22:22

6.1 볼륨 개요

파드의 컨테이너는 이미지로부터 파일 시스템을 제공받는다. 그러나 파드가 종료되면 파드 내에 변경된 데이터는 더 이상 사용할 수 없다. 컨트롤러에 의해 새로운 파드가 생성이 되면 이미지로부터 새로운 파일 시스템을 제공받는다. 즉, 컨테이너는 기본적으로 데이터를 유지하지 않으며, 이런 형태를 상태가 없다라고한다

 

쿠버네티스 파드는 새로 생성된 데이터를 보존하기 위해 외부 저장소 볼륨을 생성하고, 이런 볼륨을 컨테이너에 마운트 해서 사용한다. 볼륨은 여러 파드에서 동시에 접근이 가능하다.

 

2) 볼륨 종류

(1) emptyDir : 임시로 데이터를 저장하는빈 볼륨

(2) gitRepo : 내부적으로 emptyDir 기능을 이용하여, 초기에 git 리포지토리의 내용을 채워서 제공하는 볼륨, 더 이상 사용되지 않음(Deprecated)

(3) hostPath : 쿠버네티스 클러스터 노드의 파일 시스템일 제공하는 볼륨

(4) 네트워크 스토리지 볼륨

(5) 클라우드 스토리지 볼륨

(6) 정적/동적 프로비저닝 볼륨 : persistentVolumeClaim

(7) 특수 유형 볼륨 : configMap, secret

 

 

6.2 emptyDir볼륨

아무 데이터도 없는 빈 디렉토리를 제공해 주는 볼륨이다. 파드가 생성하는 데이터를 저장할 수 있으며, 동일한 파드 내의 컨테이너 간에 데이터를 공유할 때 유용하게 사용할 수 있다. 또한, 빅 데이터와 같은 큰 데이터 셋트를 처리하기 위한 임시 저장소로도 사용 가능하다.

(파드를 지우면 같이 지워짐 즉, 데이터를 영구적으로 저장하기 위한 목적으로 사용할수 없음)

(멀티 컨테이너 일경우 컨테이너가 데이터를 공유하기 위한 목적으로 사용)

 

 

2)  emptyDir 볼륨 생성

EmptyDir 볼륨을 사용하는 레플리카셋을 정의

vim myapp-rs-emptydir.yaml


.spec.volumes :

.spec.volumes.emptyDir : emptyDir 타입의 볼륨 정의

- {} : 값을 비워두면 호스트의 로컬 디스크를 사용

- { Memory } : tmpfs(RAM 기반 파일시스템)을 사용해 고성능의 볼륨을 제공

- .spec.volumes.name : 볼륨의 이름

- .spec.containers.volumeMonunts : 컨테이너 마운트 할 볼륨을 선언

- .spec.containers.volumeMounts : 사용할 볼륨 이름().spec.volumes 필드와 이름 참조)

- .spec.containers.volumeMounts.mountPath : 컨테이너 내의 마운트 포인트

 

web-fortune란 이름의 EmptyDir 볼륨을 정의했으며, web-server 컨테이너는 nginx 웹 서버로 이미지로 /usr/share/nginx/html 디렉토리에 볼륨을 마운트하며, html-generator 컨테이너는 ghcr.io/c1t1d0s7/fortune 이미지를 사용해 같은 볼륨을 /var/htodcs 디레토리에 마운트 한다!!!

 

함께 사용할 서비스도 생성한다.

vim myapp-svc-emptydir.yaml


포트는 80번 포트이다. nginx 이미지는 기본적으로 80번 포트로 서비스한다.

 

3) emptyDir 볼륨 생성 및 확인

래플리카셋과 서비스를 생성한다

kubectl create -f myapp-rs-emptydir.yaml -f myapp-svc-emptydir.yaml

 

컨트롤러의 상태를 확인한다

kubectl get replicasets.apps

파드의 상태를 확인한다. 두 개의 파드가 준비된 것을 확인할 수 있다.

kubectl get pods

 

서비스도 확인한다

kubectl get services myapp-svc-fortune

 

web-server 컨테이너의 /share/nginx/html/index.html 파일을 확인해보자

kubectl exec myapp-rs-fortune-rgrr4 -c web-server -- cat /usr/share/nginx.html/index.html

kubectl exec myapp-rs-fortune-rgrr4 -c html-generator -- cat /var/htdocs/index.html

 

myapp-svc-fortune 서비스에 접근해 내용을 확인해보자

web-server 컨테이너와 html-generator 컨테이너는 같은 emptyDIr 볼륨을 공유하고 있으며, html-generator 컨테이너는 컨텐츠를 생성하고, web-server 컨테이너는 컨텐츠를 읽어 외부에 제공해 준다!!!

 

 

4) gitRepo 볼륨

gitRepo 볼륨은 EmptyDir 볼륨에 지정한 Git 리포지토리의 파일을 채워서 제공해 주는 볼륨이다

 

 

5) 초기화 컨테이너

gitRepo 볼륨 유형은 더이상 사용하지 않기 때문에 대신, git 저장소가 있는 컨테이너를 프로비전 하려면 초기화 컨테이너에 EmptyDir 볼륨을 마운트하고, 여기에 git 명령을 사용해 Git 저장소를 복제하고, 파드 컨테이너에서 emptyDir 볼륨을 마운트한다.

 

초기화 컨테이너를 사용하여 git 저장소를 제공하는 예제

vim myapp-pod-git.yaml

초기화 컨테이너(.spec.initContainers)는 쿠버네티스 저장소를 Git으로 클론하며 이를 /repo 디렉터리에 저장하게 된다.

/repo 디렉토리는 emptyDir 타입의 볼륨인 git-repository로 제공된다. 초기화 컨테이너가 성공하면, git-container 컨테이너에서 똑같은 git-repository 볼륨을 마운트 하게 된다. 초기화 컨테이너를 가지고 있는 파드를 생성해보자.

kubectl create -f myapp-pod-git.yaml

 

곧바로 파드의 상태를 추적 해보자

kubectl get pods --watch

파드의 상태가 초기화(init:0/1) 에서 파드 초기화중(PodInitializing)으로 전환되고, 마지막으로 초기화가 성공하면 애플리케이션 컨테이너가 실행(Running) 상태가 된다.

 

실제 git 저장소가 클론 됐는지 확인해보자

kubectl exec myapp-pod-git -- ls -l /repo

/repo 디렉토리에 정상적으로 쿠버네티스 저장소가 클론 되었다.

 

6) 컨트롤러, 파드 및 서비스 삭제

kubectl delete -f myapp-rs-emptydir.yaml -f myapp-svc-emptydir.yaml -f myapp-pod-git.yaml

 

 

6.3 hostPath 볼륨

같은 노드에 배치된 파드 및 컨테이너 에게 공유 디렉터리를 제공할 목적으로 사용될 수 있지지만, 다른 노드에 배치된 파드 및 컨테이너에는 데이터를 공유할 수 없다. 즉, 각 노드에 각각 볼륨이 생성된다.

 

또한 기존에 A노드에 작동하고 있던 X파드가, B노드로 이동하면 더이상 데이터를 접근할 수 없게 된다

 

 

 

6.4 PersistentVolume 및 PersistentVolumeClaim 볼륨

 

지금까지 살펴본 볼륨 제공 방식은 컨트롤러의 템플릿이나 파드에 직접 스토리지 볼륨을 정의해야 한다. 이는 몇 가지 문제점이 있음... 스토리지에 대한 지식이 있어야됨 그리고 볼륨의 생명주기가 컨트롤러 및 파드의 생명주기가 같아 컨트롤러 및 파드가 삭제되면 볼륨도 같이 삭제된다.

 

1) PersistentVolume 및 PersistentVolumeClaim 소개

PV 및 PVC는 컨트롤러 및 파드와 별개의 쿠버네티스 리소스이며, 파드의 생명주기와 별개로 작동한다.

 

PV 리소스는 쿠버네티스 클러스터 외부 스토리지와 연결을 담당하는 리소스이며, PVC는 PV와 파드를 연결하기 위한 리소스이다

스토리지 관리자 <<>> PV <<>> PVC <<>> 파드 <<>> 개발자

 

역할을 나눈다면, 스토리지 지식이 있는 스토리지 관리자는 PV 리소스를 생성해 스토리지와 연갤해 두고, 파드 개발자는 pvc를 생성해 자신의 파드 및 관리자가 제공해 준 PV와 연결해 파드에서 볼륨을 사용할 수 있게 해줄 수 있다.

 

즉, 개발자는 스토리지의 지식이 없어도 PVC를 작성해 사용할 PV를 지정하면 원하는 볼륨을 제공받을 수 있다. 또한 파드의 생명주기와 별도로 볼륨 생명주기를 가지게 된다.

 

 

2) PV 및 PVC 생명주기

 

(1) 프로비저닝 : PV가 만들어지는 단계

PV를 제공하는 방법은 PV를 직정 생성하고 사용하는 "정적 프로비저닝" 과 추가 리소스가 필요하지만 볼륨 사용 요청이 있을 떄마다 자동으로 생성하는 "동적 프로비저닝"이 있다.

 

(2) 바인딩 : PVC 리소스를 만들어 준비된 PV 리소스와 연결하는 단계 이다.

PV와 PVC는 반드시 1:1로만 연결된다.

 

(3) 사용 : PVC에서 제공한 볼륨을 파드가 마운트 해서 사용하고 있는 단계. 파드가 사용 중인 PVC 및 PVC가 사용 중인 PV는 임의로 삭제되지 않는다.

 

(4) 회수 : 사용이 끝난 PVC가 종료/삭제되면 연결된 PV를 회수하는 단계이다.

 

 

6.5 정적 볼륨 프로비저닝

정적 볼륨은 PV및 PVC리소스를 직접 생성하고 사용하는 방식이다.

 

1) NFS 스토리지 구성

(1) NFS 서버 구성(kube-control1)

이 작업은 NFS 서버로 구성할 kube-control1 호스트에서 작업한다

 

nfs 서버 패키지를 설치

sudo apt install -y nfs-kernel-server

 

nfs 공유 디렉터리를 설정한다

sudo mkdir /srv/nfs-volume

 

NFS 내보내기를 설정한다

echo "/srv/nfs-volume *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee /etc/exports

 

NFS 공유 디렉터리에 파드가 사용할 index.html 파일을 생성한다.

echo "hello NFS volume" | sudo tee /srv/nfs-volume/index.html

 

NFS 내보내기 설정을 다시 읽어 들인다.

sudo exportfs -arv

 

(옵션) 방화벽이 설정되어 있는 경우, NFS 서비스 포트인 2049번 포트를 방화벽에서 연다.

sudo iptables -A INPUT -p tcp --dport 2049 -j ACCEPT

sudo iptables -A INPUT -p udp --dport 2049 -j ACCEPT

 

(2) NFS 클라이언트 구성(노드1, 노드2, 노드3)

NFS클라이언트로 설정할 노드1, 노드2, 노드3에 NFS 클라이언트 패키지를 설치한다!!

vargrant ssh kube-node1

sudo apt install -y nfs-common

vargrant ssh kube-node2

sudo apt install -y nfs-common

vargrant ssh kube-node3

sudo apt install -y nfs-common

 

 

2) PV 생성 및 확인

vim myapp-pv-nfs.yaml

.spec.capacity.storage : 스토리지 용량 지정

.spec.accessMode : 접근 방식 관련 옵션 (스토리지에 따라 지원 옵션 다름)

- ReadWriteOnce : 하나의 파드만 읽기/쓰기 가능

- ReadWriteMany : 여러 파드 읽기/쓰기 가능

- ReadOnlyMany : 여러 파드 읽기만 가능

 

.spec.persistentVolumeReclaimPolicy : 회수 정책

- Retain

- Delete

- Recycle

 

.spec.nfs : NFS 볼륨

앞서 살펴본 emptuDir, hostPath와 같은 볼륨을 지정

볼륨에 따른 하위 필드는 달라진다

 

PV리소스를 생성한다

kubectl create -f myapp-pv-nfs.yaml

 

PV리소스의 상태를 확인한다.

kubectl get persistentvolumes

현재 myapp-pv-nfs 볼륨의 접근 모드는 RWX이며, 회수 정책은 유지(Retain), 상태는 사용가능한(Available) 상태로 보고하고 있다.

 

PV 리소스의 네가지 상태(status):

- Available : 다른 PVC에 연결되지 않은 상태, 사용 가능 상태

- Bound : 특정 PVC에 연결됨

- Released : 연결되었던 PVC가 해체되었으며, 리소스를 회수하지 않은 상태

- Failed : 회수 실패

 

 

3) PVC생성 및 확인

vim myapp-pvc-nfs.yaml

.spec.accessModes : PV의 필드와 같다.

.spec.requests.storage : PV에 요청하는 크기

.spec.volumeName : PV리소스 이름을 지정

.spec.storageClassName : 스토리지 클래스 이름(지금 지정하지 않음)

 

PVC리소스를 생성한다

kubectl create -f myapp-pvc-nfs.yaml

PVC 리소스를 확인

kubectl get persistentvolumeclaims

 

상태를 확인하면 myapp-pv-nfs PV 리소스에 연결된(Bound) 것을 확인할 수 있다. 혹시나 상태가 보류(Pending) 상태이면 연결 중 또는 적절한 PV리소스를 찾지 못한 경우.... 이런 경우 kubectl describe 명령으로 PVC리소스의 이벤트에 원인을 찾아 해결하면 된다.

 

PV 리소스의 상태도 확인해보자

kubectl get persistentvolumes

상태가 연결된(Bound) 상태이고 요청 필드에 myapp-pvc-nfs PVC리소스가 연결된 것을 확인할 수 있다.

 

 

4) 레플리카셋 컨트롤러 생성 및 확인

다음은 NFS PVC 볼륨을 사용할 레플리카셋 리소스 정의 파일이다.

사용하라 볼륨을 PVC볼륨으로 지정한다!!

.spec.template.spec.volumes.persistentVolumeClaim : PVC 볼륨

- claimName : PVC 리소스의 이름

 

레플리카셋 리소스를 생성한다

kubectl create -f myapp-rs-nfs.yaml

 

레플리카셋 리소스를 확인한다.

myapp-rs-nfs 두개의 파드 모두 동작중!!

 

파드의 목록도 확인해보자

kubectl get pods

 

 

 

5) PV및 PVC 상세정보확인

kubectl describe persistentvolume myapp-pv-nfs

pvc 요청 정보 및 연결된 스토리지의 정보를 확인할 수 있다.

 

PVC 리소스의 상세 정보를 확인해보자

kubectl describe persistentvolumeclaims myapp-pvc-nfs

 

 

 

6) 서비스 생성 및 확인

다음은 파드 및 볼륨의 데이터를 확인하기 위한 서비스 리소스다.

vim myapp-svc-nfs.yaml

레플리카셋 컨트롤러는 nginx 이미지를 사용하고 있고, 80번 포트를 사용한다.

 

서비스 리소스를 생성한다.

kubectl create -f myapp-svc-nfs.yaml

 

이제 서비스에 접근해서 컨텐츠를 확인해보자!!!

 

kubectl get service 를확인해 myapp-svc-nfs의 external-ip를 확인해보자

curl http://192.168.56.201

 

 

7) 볼륨 상태 전환 확인

레플리카셋을 삭제하여 파드를 중지한다

kubectl delete replicasests.apps myapp-rs-nfs

없어진거 확인했음!!!

 

PVC 상세 정보를 확인하여 마운트 상태를 확인하다.

kubectl descibe persistentvolumeclaims myapp-pvc.nfs

 

레플리카셋을 다시 생성해보자

kubectl create -f myapp-rs-nfs.yaml

 

PVC 상세 정보를 확인하여 다시 마운트 상태를 확인해보자

kubectl describe persistentvolumeclaims myapp-pvc-nfs

새로 생성된 파드가 이상 없이 마운트 한 것을 확인할 수 있다.

 

래플리카셋 컨트롤러를 다시 삭제

kubectl delete replicasets.apps myapp-rs-nfs

PVC 리소스도 삭제

kubectl delete persistentvolumeclaims myapp-pvc-nfs

 

PVC 리소스가 삭제된 후 PV 리소스의 상태를 확인해 보자

kubectl get persistentvolume

상태가 연결이 해제된(released) 상태인 것을 확인할 수 있다.

 

다시 PVC 리소스를 생성해보자.

kubectl create -f myapp-pvc-nfs.yaml

 

생성된 PVC 리소스의 상태를 확인해보자

kubectl get persistentvolumeclaims

PV 리소스가 해제된(Released) 상태이기 떄문에 PVC가 연결할 적절한 PV를 찾지 못했기 때문에 보류(Pending)로 보고하고 있다. 또는 볼륨에 따라서 실패(Failed)로 보고할 수도 있다.

 

 

PV 리소스를 삭제한다

kubectl delete persistentvolume myapp-pv-nfs

PV리소스를 다시 생성하자

kubectl create -f myapp-pv-nfs.yaml

 

 

PV 및 PVC 리소스를 상태를 다시 확인해보자

kubectl get persistentvolume

kubectl get persistentvolumeclaims

다시 바운드(Bound) 상태가 된것을 확인, 즉 다시 이상없이 사용할 수 있다.

 

 

8) 컨트롤러, 서비스, pv, pvc 리소스 삭제

kubectl delete -f myapp-svc-nfs.yaml

kubectl delete -f myapp-pvc-nfs.yaml -f myapp-pv-nfs.yaml