궁금한게 많은 개발자 노트

[ k8s ] Kubernetes Persistent Volume 적용하기 본문

DevOps

[ k8s ] Kubernetes Persistent Volume 적용하기

궁금한게 많은 개발자 2023. 4. 18. 17:14

Kubernetes의 데이터 지속성

stateful application이 올바르게 실행되기 위해서는 데이터가 올바르게 저장되고 유지되어, 실행 중에 얻어질 수 있어야합니다. 하지만, stateful application이 kubernetes환경에서 실행될 때, persistent storage가 없다면 pod에 저장되는 데이터는 pod또는 container의 수명 주기에 의존적입니다.

즉, pod에서 conflict 또는 crash가 발생하여 종료되면 저장된 데이터는 손실됩니다.

kubernetes의 데이터 지속성

Pod와 Storage의 수명 주기를 분리하기 위해 필요한 구성 요소

이러한 데이터 손실을 방지하려면 Storage의 수명 주기와 Pod의 수명 주기를 분리하여야 합니다.

그러기 위해서 kubernetes에서는 Persistent Volume을 지원합니다. PV를 사용하면 Application, Container, Pod, Node, Cluster 자체의 수명 주기와 관계없이 데이터가 지속됩니다.

PV는 추상적인 구성 요소이며, 실제 물리적 storage는 어딘가에서 가져와야 합니다. 그 어딘가의 예는 다음과 같습니다.

  • csi: Container Storage Interface(CSI) → (예: Amazon EFS , Amazon EBS , Amazon FSx 등)
  • scsi: iSCSI(SCSI over IP) 스토리지
  • local: 노드에 마운트된 로컬 저장 장치
  • nfs: 네트워크 파일 시스템(NFS) 스토리지

PV는 결국 Pod에서 사용되는 Storage의 리소스 크기, 접근 권한, 지속등 등의 세부 정보를 정의하는 추상적 구성 요소이며, 해당 정보를 통해 사용 가능한 Storage의 resource를 나타냅니다.

 

그렇다면 k8s환경에서 pod를 deployment하려고 할 때, 어떤 Storage를 요구 할 지에 대한 요구사항을 나타내는 추상화된 개체가 필요한데 이것이 PVC(Persistent Volume Claim)이라는 개념입니다.

즉, PVC는 pod에서 사용할 Storage를 얻기 위한 PV요청서라고 생각할 수 있습니다. Pod가 PVC를 참조하면, PVC가 요청한 PV와 bound되어 Pod내부 파일시스템에 mount되는 로직입니다.

이렇게 PV와 PVC는 Storage 추상화를 제공하여 개발자는 k8s cluster내에서 application이 사용하는 Storage에 대한 세부 정보를 알 필요 없이, 요청한 자원에 대한 Storage를 mount하여 사용할 수 있습니다.

Pod에서 PVC를 통해 PV와 연동되는 과정

정리하자면, PV(Persistent Volume)는 실제 Storage를 나타내고, PVC(Persistent Volume Claim)은 Pod가 실제 스토리지를 얻기 위해 수행하는 Storage 요청을 나타냅니다.

이러한 구분이 생긴 이유는 kubernetes환경에서 관리자와 application개발자의 두 유형의 사용자가 있다는 개념과 관련이 있습니다. kubernets관리자는 application개발에 필요한 PV를 미리 생성 및 관리하고, kubernetes application개발자는 관리자가 제공하는 resource를 사용하게 됩니다.

그래서 PV는 관리자 범위에 속하고, PVC는 개발자 범위에 속하게 되며, 개발자가 pod를 deployment할 때 직접적으로 PV를 mount할 수 없습니다. PVC를 통해 명시적으로 요청되어야 하며,

그 요청은 Pod생성 시 PVC객체를 기술함으로써 달성됩니다. 이것이 PV/PVC의 추가 추상화 계층이 존재하는 이유이며, PV와 PVC는 1:1관계가 있습니다.

PV와 PVC가 생성되는 방법

 

Persistent Volume의 생성 방법

이제 kubernetes에서 Pod생성 시 PV를 어떻게 요청하는지에 대해 알아봤다면, PV는 어떤 방식으로 생성 될 수 있는지에 대해 알아보려 합니다.

첫 번째 방법으로는 Static Provisioning이 있습니다. 위에서 설명한 방식과 동일하게 k8s관리자가 미리 사용할 수 있는 적정 용량의 PV들을 deployment해두어,

application 개발자가 요청하는 크기에 맞는 PV가 매칭되게 됩니다. 사용해야 하는 용량의 제한이 있을 때 유용합니다.

예를 들어 100GB의 PV들이 관리자에 의해 미리 생성되어 있을 때, 개발자에 의해 Pod에서 150GB의 Storage에 대한 요청이 올 경우 실패합니다.

PV Static Provisioning

두 번째 방법은 Dynamic Provisioning입니다. 이름에서 알 수 있듯 Static과 반대로 미리 PV를 생성해 둘 필요가 없습니다. 이를 위해서는 StorageClass를 사용해야 합니다.

StorageClass는 PV를 동적으로 생성할 때 필요한 세부 정보를 제공합니다. 정해진 용량의 생성된 PV중에서 사용하는 것이 아니라, 동적으로 필요한 만큼 Storage를 생성해서 사용할 수 있다는 장점이 있습니다.

PV Dynamic Provisioning

 

동적으로 PV를 생성해주는 StorageClass에 대해서 좀 더 알아봐야 합니다. StorageClass는 기본적으로 Provisioner와 생성될 PV의 유형 및 bindingMode등의 설정이 가능합니다.

여기서 Provisioner가 중요한데, PV의 생성하는 역할을 수행할 특정 Storage Plugin입니다. 각 스토리지 유형에 따른 provisioner가 존재한다고 생각하면 됩니다.

ex) AWS EBS용 - kubernetes.io/aws-ebs, ebs.csi.aws.com AWS EFS용 kubernetes.io/aws-efs, efs.csi.aws.com

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
reclaimPolicy: Retain
mountOptions:
  - debug
volumeBindingMode: WaitForFirstConsumer

위 예시에서 볼 수 있듯, aws-ebs provisioner를 사용하여 AWS EBS volume을 PV로 생성하려 하고, 생성될 PV의 속성을 지정하는 parameters옵션에서 gp3 type을 지정하였습니다.

또한, reclaimPolicy를 통해 PV가 삭제될 때 실제 사용하던 Storage를 유지/삭제/재사용 할 지에 대해 설정할 수 있습니다.

volumeBindingMode옵션은 PV와 PVC사이의 바인딩 옵션을 지정하는 것으로, Immediate(즉시), WaitForFirstConsumer(지연) 방식이 있습니다.

그런데 이 과정에서 k8s환경의 pod에서 실행되는 container는 어떻게 AWS EBS Volume을 요청할 수 있을까요?

k8s의 service account를 생성하여 pod에서 실행되는 container에 PV, PVC, StorageClass들에 대한 권한을 부여해야 할 것 같습니다.

또한, 해당 pod가 생성된 EC2 intance에 AWS EBS Volume에 대한 접근 권한도 필요할 것 같습니다.

 

이런한 과정을 대신 해주는 CSI 드라이버가 존재합니다. kubernets에서 다양한 스토리지 솔류션을 쉽게 사용할 수 있도록 설계된 추상화이며, 

Amazon EBS CSI Driver를 설치하면 위에서 필요한 권한들을 가진 ebs-csi-controller들이 k8s의 kube-system namespace에 설치되어,

각 namespace의 pod에서 kubernetes api server로 요청한 ebs volume request를 Amazon EBS API와 상호 작용하여 처리해주는 역할을 해줍니다.

물론 이러한 과정에서 EBS CSI Driver를 설치하는 것 뿐만 아니라 kube-sytem namespace에 존재하는 ebs-csi-controller-sa에 aws ebs volume에 대한 policy를 가진 role을 annotation해주어야 합니다.

자세한 내용은 아래 링크를 참고하실 수 있습니다.

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/csi-iam-role.html

 

 

kubernetes환경에서 persistent volume을 사용하기 위해 필요한 사항들을 위에서 정리해봤습니다. 

요약을 위해 k8s에서 pod생성 시 pv를 동적으로 생성하는 방법은 아래와 같습니다.

1. AWS EBS CSI Driver를 kubernetes node에 설치

2. 설치된 driver에서 사용하는 service account에 AmazonEBSCSIDriverPolicy를 가지는 IAM Role annotation

3. dynamic provisioning을 위한 PVC, StorageClass deployment

4. PV를 사용하기 위한 Pod생성 시 위에서 deployment한 PVC 지정하여 StorageClass가 PV 동적으로 생성 및 연결하도록 deployment

Comments