Kubernetes 인 액션 6장 볼륨: 컨테이너에 디스크 스토리지 연결
Devops/Kubernetes

Kubernetes 인 액션 6장 볼륨: 컨테이너에 디스크 스토리지 연결

뉴비뉴 2023. 5. 28.

다루는 내용

  • 다중 컨테이너 파드 생성
  • 컨테이너 간 디스크 스토리지를 공유하기 위한 볼륨 생성
  • 파드 내부에 깃 리포지터리 사용
  • 파드에 GCE 퍼시스턴트 디스크와 같은 퍼시스턴트 스토리지 연결
  • 사전 프로비저닝된 퍼시스턴트 스토리지
  • 퍼시스턴트 스토리지의 동적 프로비저닝

파드는 내부에 프로세스가 실행되고 CPU, RAM, 네트워크 인터페이스 등의 리소스를 공유하는 논리적 호스트와 유사하다고 했다. 프로세스가 디스크 또한 공유할 수 있을 것이라 예상하겠지만 사실은 그렇지 않다. 파드 내부의 각 컨테이너는 고유하게 분리된 파일시스템을 가진다 파일시스템은 컨테이너 이미지에서 제공되기 때문이다.

6.1 볼륨 소개

Kubernetes Volume은 파드의 구성 요소로 컨테이너와 동일하게 파드 스펙에서 정의된다.

Volume은 독립적인 Kubernetes 오브젝트가 아니므로 자체적으로 생성, 삭제될 수 없다.

6.1. 공유 스토리지가 없는 동일 파드의 컨테이너 세 개

6.2. 두 개의 볼륨을 공유하고 각 경로에 마운트한 컨테이너 세 개

위 예제의 두 볼륨은 빈 상태로 초기화되므로 emptyDir 유형의 볼륨을 사용할 수 있다.

6.1.2 사용 가능한 볼륨 유형 소개

  • emptyDir: 일시적인 데이터를 저장하는 데 사용되는 간단한 빈 디렉터리다.
  • hostPath: 워커 노드파일시스템을 파드의 디렉터리로 마운트하는 데 사용한다.
  • gitRepo: 깃 리포지터리의 콘텐츠를 체크아웃해 초기화한 볼륨이다.
  • nfs: NFS 공유를 파드에 마운트한다.
  • gcePersistentDisk(Google Compute Engin Persistent Disk), awsElasticBlockStore, azureDisk(Microsoft Azure Disk Volume): 클라우드 제공자의 전용 스토리지를 마운트하는 데 사용한다.
  • cinder, cephfs, iscsi, flocker, glusterfs, quobyte, rbd, flexVolume, vsphere Volume, photonPersistentDisk, scaleIO: 다른 유형의 네트워크 스토리지를 마운트하는 데 사용한다.
  • configMap, secret, downwardAPI: Kubernetes 리소스나 클러스터 정보를 파드에 노출하는 데 사용되는 특별한 유형의 볼륨이다.
  • persistentVolumeClaim: 사전에 혹은 동적으로 프로비저닝된 퍼시스턴트 스토리지를 사용하는 방법이다.

6.2 볼륨을 사용한 컨테이너 간 데이터 공유

6.2.1 emptyDir 볼륨 사용

빈 디렉터리로 시작된다. 파드에 실행중인 애플리케이션은 어떤 파일이든 볼륨에 쓸 수 있다.

볼륨의 라이프사이클이 파드에 묶여 있으므로 파드가 삭제되면 볼륨의 콘텐츠는 사라진다.

emptyDir 볼륨은 동일 파드에서 실행 중인 컨테이너 간 파일을 공유할 때 유용하다.

그러나 단일 컨테이너에서도 가용한 메모리에 넣기에 큰 데이터 세트의 정렬 작업을 수행하는 것과 같이 임시 데이터를 디스크에 쓰는 목적인 경우 사용할 수 있다.

파드 생성하기

readOnly: True 읽기 전용

emptyDir 로 파일을 공유하기 했기 때문에 luksa/fortune and nginx:alpine 컨테이너간에 소통이 가능하다.

emptyDir을 사용하기 위한 매체 지정하기

Kubernetes 에 emptyDir을 디스크가 아닌 메모리를 사용하는 tmpfs 파일시스템으로 생성하도록 요청할 수 있다. 이 작업을 위해 다음과 같이 emptyDir의 medium을 Memory로 지정한다.

volumes:
  - name: html
    emptyDir:
      medium: Memory

6.2.2. 깃 리포지터리를 볼륨으로 사용하기 - interesting

gitRepo 볼륨은 기본적으로 emptyDir 볼륨이며 파드가 시작되면 깃 리포지터리를 복제하고 특정 리비전을 체크아웃해 데이터로 채운다.

|노트| gitRepo 볼륨이 생성된 후에는 참조하는 리포지터리와 동기화하지 않는다.

깃 리포지터리에 추가 커밋을 푸시해도 볼륨에 있는 파일은 변경되지 않는다.

그러나 레플리케이션컨트롤러가 파드를 관리하는 경우 파드를 삭제하면 새 파드가 생성되고 이 파드의 볼륨은 최신 커밋을 포함한다.

복제된 깃 리포지터리 파일을 서비스하는 웹 서버 실행하기

파드를 생성하면 볼륨은 먼저 빈 디렉터리를 초기화한 다음 특정 깃 리포지터리를 복제한다. directory를 .(점)으로 지정하지 않으면 의도치 않게 리포지터리가 kubia-website-example 하위 디렉터리로 복제됐을 것이다. 리포지터리는 볼륨의 루트 디렉터리에 복제돼야 한다.

깃 리포지터리와 파일 동기화 여부 확인하기

깃 리포지터리의 master 브랜치에는 변경된 HTML 파일이 들어 있다. gitRepo 볼륨은 깃 리포지터리와 동기화하지 않기 때문에 이 변경 사항이 Nginx 웹 서버에서 보이지 않는다. 파드를 다시 호출해 확인해보자.

웹사이트의 새 버전을 보려면 파드를 삭제하고 다시 생성해야 한다. 변경 사항이 있을 때마다 파드를 삭제하는 대신에 볼륨이 항상 깃 리포지터리와 동기화하도록 추가 프로세스를 실행할 수 있다.

사이드카 컨테이너 소개

깃 동기화 프로세스가 Nginx 웹 서버와 동일 컨테이너에서 실행되면 안 되며 두 번째 컨테이너인 사이드카 컨테이너에서 실행돼야 한다. 사이드카 컨테이너는 파드의 주 컨테이너의 동작을 보완한다. 새로운 로직을 메인 애플리케이션 코드에 밀어 넣어 복잡성을 더하고 재사용성을 떨어뜨리는 대신에 파드에 사이드카를 추가하면 기존 컨테이너 이미지를 사용할 수 있다.

LET ME) 사이드카 컨테이너는 기존 컨테이너의 변경 없이 기능을 확장시키고 향상시킨다. 파드에 컨테이너를 여러 개 배치하는 경우 사이드카 컨테이너는 주로 파드의 파일시스템을 공유하는 형태를 말한다.

https://blog.naver.com/PostView.naver?blogId=isc0304&logNo=222570611200&parentCategoryNo=&categoryNo=105&viewDate=&isShowPopularPosts=true&from=search

사이드카 컨테이너를 사용해 로그에 대한 출력

https://blog.naver.com/PostView.naver?blogId=isc0304&logNo=222570611200&parentCategoryNo=&categoryNo=105&viewDate=&isShowPopularPosts=true&from=search

6.3 워커 노드 파일시스템의 파일 접근

대부분의 파드는 호스트 노드를 인식하지 못하므로 노드의 파일시스템에 있는 어떤 파일에도 접근하면 안 된다.

그러나 특정 시스템 레벨의 파드(보통 데몬셋으로 관리되는 것을 기억하라) 는 노드의 파일을 읽거나 파일시스템을 통해 노드 디바이스를 접근하기 위해 노드의 파일시스템을 사용해야 한다. Kubernetes는 hostPath 볼륨으로 가능케 한다.

6.3.1 hostPath 볼륨 소개

hostPath 볼륨은 노드 파일시스템의 특정 파일이나 디렉터리를 가리킨다.

동일 노드에 실행 중인 파드가 hostPath 볼륨의 동일 경로를 사용 중이면 동일한 파일이 표시된다.

hostPath 볼륨은 워커 노드의 특정 파일이나 디렉터리를 컨테이너의 파일시스템에 마운트한다.

 

gitRepo나 emptyDir 볼륨의 콘텐츠는 파드가 종료되면 삭제되는 반면, hostPath 볼륨의 콘텐츠는 삭제되지 않는다.

파드가 삭제되면 다음 파드가 호스트의 동일 경로를 가리키는 hostPath 볼륨을 사용하고, 이전 파드와 동일한 노드에 스케줄링 된다는 조건에서 새로운 파드는 이전 파드가 남긴 모든 항목을 볼 수 있다. LET ME) 즉 영구 스토리지

 

단점)

1. 데이터베이스의 데이터 디렉터리를 저장할 위치로 사용할 생각이라면 다시 고려해볼 필요가 있다.

2. 특정 노드의 파일시스템에 저장되므로 데이터베이스 파드가 다른 노드로 다시 스케줄링되면 더 이상 이전 데이터를 볼 수 없다.

3. hostPath 볼륨은 파드가 어떤 노드에 스케줄링되느냐에 따라 민감하기 때문에 일반적인 파드에 사용하는 것은 좋은 생각이 아니다.

6.3.2 hostPath 볼륨을 사용하는 시스템 파드 검사하기

새로운 파드를 생성하는 대신 이미 이 볼륨 유형을 사용하는 시스템 전역 파드가 있는지 확인해보자.

다른 파드를 검사해보면 그 중 어느 것도 hostPath 볼륨을 자체 데이터를 저장하기 위한 목적으로 사용하지는 않는다는 것을 볼 수 있다. ‘단지 노드 데이터에 접근하기 위해 사용한다.’ LET ME) 보통 로그저장 이나 디렉터리 볼륨

6.4 퍼시스턴트 스토리지 사용

파드에서 실행 중인 애플리케이션이 디스크에 데이터를 유지해야 하고 파드가 다른 노드로 재스케줄링된 경우에도 동일한 데이터를 사용해야 한다면 지금까지 언급한 볼륨 유형은 사용할 수 없다.

볼륨이 없거나 비영구적 볼륨을 통해 데이터베이스를 실행하는 것은 테스트 목적이 아니라면 상식에 맞지 않으므로 적절한 유형의 볼륨을 파드에 추가하고 MongoDB 컨테이너에 마운트한다.

NFS 볼륨 사용하기

클러스터가 여러 대의 서버로 실행되는 경우 외장 스토리지를 볼륨에 마운트하기 위한 다양한 지원 옵션이 제공된다.

LET ME) ‘NFS란 네트워크 상에서 다른 컴퓨터의 파일 시스템을 마운트해서 공유하는 것이다.’ 즉, 다른 컴퓨터의 파일 시스템을 마치 자기 것 처럼 사용할 수 있는 것이다.

https://kgw7401.tistory.com/51

6.5 기반 스토리지 기술과 파드 분리

이상적으로 쿠버네티스에 애플리케이션을 배포하는 개발자는 기저에 어떤 종류의 스토리지 기술이 사용되는지 알 필요가 없어야 하고, 동일한 방식으로 파드를 실행하기 위해 어떤 유형의 물리 서버가 사용되는지 알 필요가 없어야 한다. 인프라스트럭처 관련 처리는 클러스터 관리자만의 영역이어야 한다.

 

개발자가 애플리케이션을 위해 일정량의 퍼시스턴트 스토리지를 필요로 하면 쿠버네티스에 요청할 수 있어야 하고, 동일한 방식으로 파드 생성 시 CPU, 메모리와 다른 리소스를 요청할 수 있어야 한다. 시스템 관리자는 클러스터를 구성해 애플리케이션이 요구한 것을 제공할 수 있어야 한다.

6.5.1 퍼시스턴트볼륨(PV)과 퍼시스턴트볼륨클레임(PVC) 소개

# '쿠버네티스 관리자(서버관리자)'
# 구상 저장소
- 하드디스크(한 컴퓨터)
- NFS(여러 컴퓨터)
- 클라우드에서 제공하는 스토리지
- 원격 폴더

# 추상 저장소
- PV1 (10Gi)
- PV2 (0.5Gi)
- PV3 (5Gi)
-============================-
# '쿠버네티스 사용자(개발자)'
# 추상 저장소 클레임(요청)
- PVC(1Gi, RWO)요구사항
  - Kubernetes 가 '자동'으로 고른다.
  - k8s: 엇 나는 1Gi 가 필요하니까 5Gi, 혹은 10Gi 를 고를거야!
  - 어떤 PV 를 사용할지 명시할 수 없다. 왜? 쿠버네티스 사용자이기 때문에!
  - PVC는 Namespace Object 이고 PV는 Cluster Role 이다.

- 앱
*앱 -> PVC -> PV -> 물리저장소

쿠버네티스 볼륨도 영구적인 데이터를 저장하는 데 사용할 수 있다.

클러스터 관리자가 퍼시스턴트볼륨을 프로비저닝하면 파드는 퍼시스턴트볼륨클레임을 통해 이를 사용한다.

 

클러스터 사용자파드에 퍼시스턴트 스토리지를 사용해야 하면 먼저 최소 크기와 필요한 접근 모드를 명시한 퍼시스턴트볼륨클레임 매니페스트를 생성한다. 그런 다음 사용자는 퍼시스턴트볼륨클레임 매니페스트를 쿠버네티스 API 서버에 게시하고 쿠버네티스는 적절한 퍼시스턴트볼륨을 찾아 클레임에 볼륨을 바인딩한다.

 

그런 다음 퍼시스턴트볼륨클레임은 파드 내부의 볼륨 중 하나로 사용될 수 있다.

6.5.2 퍼시스턴트볼륨 생성

persistentVolumeReclaimPolicy 클레임이 해제된 후 퍼시스턴트볼륨은 유지돼야 한다. (지워지거나 삭제되면 안 된다.)

 

퍼시스턴트 볼륨을 생성할 때 관리자는 쿠버네티스에게 용량이 얼마가 되는지 단일 노드나 동시에 다수 노드에 읽거나 쓰기가 가능한지 여부를 알려야 한다.

아직 퍼시스턴트볼륨클레임을 생성하지 않았으므로 퍼시스턴트볼륨이 Available로 표시

|NOTE| 퍼시스턴트볼륨은 특정 네임스페이스에 속하지 않는다. 노드와 같은 클러스터 수준 리소스다. 즉, 최상위에서 퍼시스턴트볼륨이 생성되어 관리한다.

6.5.3 퍼시스턴트볼륨클레임 생성을 통한 퍼시스턴트볼륨 요청

파드가 재스케줄링되더라도 동일한 퍼시스턴트볼륨클레임이 사용 가능한 상태로 유지되기를 원하므로 퍼시스턴트볼륨에 대한 클레임은 파드를 생성하는 것과 별개의 프로세스다.

LET ME) PVC는 Namespace Object 이기 때문에 Namespace에 디펜던시가 걸리지만 PV는 Cluster Role과 비슷하게 클러스터에서 공용으로 사용할 수 있는 객체입니다.

퍼시스턴트볼륨클레임 생성하기

storageClassName ‘동적 프로비저닝’

 

퍼시스턴트볼륨클레임(PVC) 이 생성되자마자 쿠버네티스는 퍼시스턴트볼륨(PV)을 찾고 클레임에 바인딩한다.

PV의 용량은 PVC의 요청을 수용할 만큼 충분히 커야 한다.

LET ME) PV 에서 ReadWriteOnce 권한을 줬기에 PVC 에서도 사용할 수 있다.

  • RWO(ReadWriteOnce): 단일 노드만이 읽기/쓰기용으로 볼륨을 마운트할 수 있다.
  • ROX(ReadOnlyMany): 다수 노드가 읽기용으로 볼륨을 마운트 할 수 있다.
  • RWX(ReadWriteMany): 다수 노드가 읽기/쓰기용으로 볼륨을 마운트할 수 있다.

6.5.4 파드에서 퍼시스턴트볼륨클레임 사용하기

6.5.5 PV과 PVC 사용의 장점 이해하기

퍼시스턴트 디스크를 직접 사용하는 경우와 PVC와 PV를 사용하는 경우

6.5.6 퍼시스턴트볼륨 재사용

연결되어 있는 PVC를 삭제하고 다시 생성하면 클레임의 상태가 Pending 으로 표시된다.

 

PV 상태를 확인하면 Released 로 표시된다. 그 이유는 이미 볼륨을 사용했기 때문에 데이터를 가지고 있으므로 클러스터 관리자가 볼륨을 완전히 비우지 않으면 새로운 클레임에 바인딩할 수 없다.

 

클러스터 관리자가 볼륨을 비우지 않았다면 동일한 퍼시스턴트볼륨을 사용하는 새 파드는 다른 네임스페이스에서 클레임과 파드가 생성됐다고 할지라도 이전 파드가 저장한 데이터를 읽을 수 있다.

퍼시스턴트볼륨을 수동으로 다시 클레임하기

persistentVolumeClaimPolicy를 Retain으로 설정하면 쿠버네티스가 클레임이 해제돼도 볼륨과 콘텐츠를 유지하도록한다.

 

퍼시스턴트볼륨을 수동으로 재사용할 수 있는 유일한 방법은 퍼시스턴트볼륨 리소스를 삭제하고 다시 생성하는 것이다. 삭제할 수도 있고 다음 파드에서 다시 사용하도록 남겨둘 수도 있다.

퍼시스턴트볼륨을 자동으로 다시 클레임하기

리클레임 정책은 Recycle과 Delete다.

Recycle은 볼륨의 콘텐츠를 삭제하고 볼륨이 다시 클레임될 수 있도록 볼륨을 사용 가능하게 만든다.

반대로 Delete 정책은 기반 스토리지를 삭제한다.

6.6 퍼시스턴트볼륨의 동적 프로비저닝(자동화)

더보기

동적 프로비저닝: 스토리지 클래스(StorageClass) 리소스만 정의해 놓고 개발자가 PVC를 요청하면 스토리지 클래스 리소스에 의해 ‘PV가 자동으로 프로비저닝되어 사용할 수 있도록 동적 프로비저닝 기능을 제공한다.’

 

자동으로 볼륨을 생성/할당하는 StorageClass 사용

 

클러스터에 애플리케이션이 많은수록 정적 생성보다 동적 생성을 사용하는 것이 유리하다.

 

PV, PVC를 활용하면 개발자가 내부 스토리지 기술을 몰라도 Persistent Storage를 사용할 수 있다는 장점이 있다. 그러나 정적 프로비저닝의 경우 관리자가 실제 스토리지를 미리 PV로 다 만들어놓아야 한다는 관리 상 귀찮음이 있다.

 

관리자가 많은 퍼시스턴트볼륨을 미리 프로비저닝하는 대신 하나 혹은 그 이상의 스토리지클래스를 정의하면 시스템은 누군가 퍼시스턴트볼륨클레임을 통해 요청 시 새로운 퍼시스턴트볼륨을 생성한다. 가장 큰 장점은 퍼시스턴트볼륨이 부족할 일이 없다는 것이다. (물론, 스토리지 용량이 부족할 수 있다.)

관리자가 많은 퍼시스턴트볼륨을 미리 프로비저닝하는 대신 하나 혹은 그 이상의 스토리지클래스를 정의하면 시스템은 누군가 퍼시스턴트볼륨클레임을 통해 요청 시 새로운 퍼시스턴트볼륨을 생성한다. 가장 큰 장점은 퍼시스턴트볼륨이 부족할 일이 없다는 것이다. (물론, 스토리지 용량이 부족할 수 있다.)

6.6.1 스토리지클래스 리소스를 통한 사용 가능한 스토리지 유형 정의하기

스토리지클래스 리소스는 PVC이 스토리지 클래스에 요청할 때 어떤 프로비저너가 퍼시스턴트볼륨을 프로비저닝하는 데 사용돼야 할지를 지정한다. / PD = 퍼시스턴트 디스크

6.6.2 퍼시스턴트볼륨클레임에서 스토리지 클래스 요청하기

스토리지클래스 리소스가 생성되면 사용자는 퍼시스턴트볼륨클레임의 이름에 스토리지클래스를 참조할 수 있다.

특정 스토리지클래스를 요청하는 PVC 정의 생성하기

클레임(PVC)을 생성하면 fast 스토리지클래스 리소스에 참조된 프로비저너가 퍼시스턴트볼륨을 생성한다. 프로비저너는 수동으로 프로비저닝된 퍼시스턴트 볼륨과 퍼시스턴트 볼륨클레임을 매핑하는 데도 사용된다.

6.7 요약

  • 다중 컨테이너 파드 생성과 파드의 컨테이너들이 볼륨을 파드에 추가하고 각 컨테이너에 마운트해 동일한 파일로 동작하게 한다.
  • emptyDir 볼륨을 사용해 임시, 비영구 데이터를 저장한다. LET ME) 정말 임시
  • gitRepo 볼륨을 사용해 파드의 시작 시점에 깃 리포지터리의 콘텐츠로 디렉터리를 쉽게 채운다.
  • hostPath 볼륨을 사용해 호스트 노드의 파일에 접근한다. LET ME) A 노드에 hostPath(데이터)를 저장하였는데 B 노드로 파드가 이동했고, A 노드의 hostPath(데이터)를 읽을 수 없다.
  • 외부 스토리지를 볼륨에 마운트해 파드가 재시작돼도 파드의 데이터를 유지한다.
  • 퍼시스턴트볼륨과 퍼시스턴트볼륨클레임을 사용해 파드와 스토리지 인프라스트럭처를 분리한다.

댓글

💲 추천 글