2025. 1. 13. 23:00ㆍ쿠버네티스/쿠버네티스

컨테이너 스토리지 인터페이스 (CSI)
배경
과거에는 Kubernetes가 컨테이너 런타임 엔진으로 Docker만 사용했습니다. 이때 Kubernetes 소스 코드에 Docker와 관련된 모든 코드가 포함되어 있었습니다. 그러나 RKT, CRI-O와 같은 다른 컨테이너 런타임이 등장하면서, Kubernetes는 다양한 컨테이너 런타임을 지원할 수 있도록 확장될 필요가 있었습니다. 이를 위해 **컨테이너 런타임 인터페이스(Container Runtime Interface, CRI)**가 도입되었습니다.
- CRI는 Kubernetes와 Docker 같은 컨테이너 런타임 간의 통신 방법을 표준화한 규격입니다.
- 새로운 컨테이너 런타임이 개발되더라도 CRI 표준만 따르면 Kubernetes와 호환될 수 있습니다.
- 이는 Kubernetes 소스 코드를 수정하거나 Kubernetes 개발팀과 협력할 필요 없이 가능합니다.
비슷한 방식으로, 네트워킹 솔루션을 확장하기 위해 **컨테이너 네트워킹 인터페이스(Container Networking Interface, CNI)**가 도입되었습니다. CNI 표준을 따르면 새로운 네트워킹 플러그인을 Kubernetes와 쉽게 통합할 수 있습니다.
CSI의 등장
마찬가지로, 다양한 스토리지 솔루션을 지원하기 위해 **컨테이너 스토리지 인터페이스(Container Storage Interface, CSI)**가 개발되었습니다.
- CSI를 통해 각 스토리지 벤더는 자신의 드라이버를 작성하여 Kubernetes와 연동할 수 있습니다.
- 예: Portworx, Amazon EBS, Azure Disk, Dell EMC Isilon, NetApp, Nutanix 등 다양한 스토리지 벤더들이 CSI 드라이버를 제공합니다.
- 중요한 점은 CSI가 Kubernetes 전용 표준이 아니라는 것입니다. 이는 범용 표준으로 설계되었으며, 이를 구현하면 Kubernetes뿐만 아니라 Cloud Foundry, Mesos 같은 다른 컨테이너 오케스트레이션 도구에서도 작동할 수 있습니다.
CSI의 작동 방식
CSI는 컨테이너 오케스트레이터(예: Kubernetes)와 스토리지 드라이버 간의 통신을 위한 일련의 **RPC(Remote Procedure Calls)**를 정의합니다. 스토리지 드라이버는 이 RPC를 구현하여 요청을 처리해야 합니다.
주요 RPC 예시
- 볼륨 생성 (Create Volume)
- Pod가 생성되면서 볼륨을 요구하면, Kubernetes는 CreateVolume RPC를 호출합니다.
- 이 호출에는 볼륨 이름 등의 세부 정보가 포함됩니다.
- 스토리지 드라이버는 이 요청을 처리하여 스토리지 배열에 새 볼륨을 프로비저닝(provisioning)하고 결과를 반환합니다.
- 볼륨 삭제 (Delete Volume)
- 볼륨이 삭제될 때 Kubernetes는 DeleteVolume RPC를 호출합니다.
- 스토리지 드라이버는 이 요청에 따라 스토리지 배열에서 해당 볼륨을 해제(decommissioning)해야 합니다.
CSI 명세
CSI 명세는 다음 사항들을 정확히 정의합니다:
- 호출자가 전달해야 할 매개변수
- 솔루션(스토리지 드라이버)이 반환해야 할 값
- 교환되어야 할 오류 코드
요약
- CSI는 다양한 스토리지 솔루션과 컨테이너 오케스트레이션 도구 간의 호환성을 보장하는 범용 표준입니다.
- 이를 통해 새로운 스토리지 솔루션도 쉽게 Kubernetes 및 기타 플랫폼과 통합될 수 있습니다.
- CSI 명세는 GitHub에서 확인할 수 있으며, 세부적인 구현 내용은 명세에 따라 이루어집니다.
Kubernetes 외에도 Cloud Foundry와 Mesos가 CSI를 지원하고 있습니다.
https://kubernetes.io/ko/docs/concepts/storage/storage-classes/
https://kubernetes.io/ko/docs/concepts/storage/volumes/
https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/
https://tech.gluesys.com/blog/2022/06/21/CSI.html
Volume
1. 컨테이너와 데이터의 휘발성
- 컨테이너는 일시적인 존재로, 필요한 작업을 처리한 뒤 삭제됩니다.
- 컨테이너가 삭제되면 내부에 저장된 데이터도 함께 사라집니다.
- 데이터를 유지하려면 **볼륨(Volume)**이라는 저장 공간을 컨테이너에 연결해야 합니다.
- 볼륨은 컨테이너 외부에 데이터를 저장하므로, 컨테이너가 삭제되어도 데이터는 유지됩니다.
2. 쿠버네티스에서의 볼륨
- 쿠버네티스에서도 Pod(컨테이너를 묶은 단위)는 일시적입니다.
- Pod가 삭제되면 그 안에서 생성된 데이터도 사라집니다.
- 이를 해결하기 위해 Pod에 볼륨을 연결합니다.
- 볼륨에 저장된 데이터는 Pod가 삭제되어도 유지됩니다.
3. 볼륨의 간단한 예제
- Pod 생성 및 데이터 처리
- 예제: 랜덤 숫자를 생성해 /opt/number.out 파일에 저장하는 Pod를 만듭니다.
- 문제: Pod가 삭제되면 이 파일과 숫자도 사라집니다.
- 볼륨 추가로 데이터 유지
- 볼륨을 생성하고, 이를 Pod에 연결합니다.
- 볼륨은 호스트(서버)의 특정 디렉터리(예: /data)를 사용하도록 설정합니다.
- Pod 내부의 디렉터리(/opt)와 호스트의 /data 디렉터리를 연결하면, Pod가 삭제되더라도 /data에 데이터가 남아 있습니다.
4. 볼륨 구성 방법
- 볼륨은 다양한 방식으로 저장소를 설정할 수 있습니다.
1) HostPath (호스트 경로)
- 호스트 서버의 특정 디렉터리(예: /data)를 사용하여 데이터를 저장합니다.
- 단점: 여러 노드(서버)가 있는 클러스터에서는 비추천입니다.
- 각 노드의 /data 디렉터리가 서로 다르기 때문에 동일한 데이터를 보장할 수 없습니다.
2) 외부 스토리지 솔루션
- 쿠버네티스는 다양한 스토리지 솔루션을 지원합니다:
- NFS, CephFS, Flocker 등 네트워크 스토리지
- 퍼블릭 클라우드 스토리지:
- AWS EBS (Elastic Block Store)
- Azure Disk
- Google Persistent Disk
- 고급 스토리지 시스템:
- Fiber Channel, ScaleIO 등
3) AWS EBS 예제
- AWS EBS를 볼륨으로 사용하려면 다음과 같이 설정합니다:
volumes:
- name: my-volume
awsElasticBlockStore:
volumeID: "vol-0abcd1234efgh5678"
fsType: "ext4"
- 이렇게 하면 AWS EBS에 데이터가 저장됩니다.
5. 요약
- 쿠버네티스에서 Pod와 데이터는 기본적으로 일시적입니다.
- 데이터를 유지하려면 볼륨을 생성하고 Pod에 연결해야 합니다.
- 여러 종류의 스토리지 옵션이 있으며, 필요에 따라 적합한 것을 선택합니다:
- 단일 노드에서는 HostPath,
- 다중 노드 또는 클라우드 환경에서는 NFS, AWS EBS 등의 외부 스토리지를 권장합니다.
초등학생을 위한 쉬운 설명
- 컴퓨터 안의 상자(Pod)가 일을 하고 숫자를 만들어요.
- 그런데 상자가 없어지면 숫자도 사라져요!
- 그래서 상자 옆에 가방(볼륨)을 두고 숫자를 가방에 넣어요.
- 상자가 없어져도 가방은 남아 있으니까 숫자가 안전해요!
1. 볼륨과 퍼시스턴트 볼륨의 차이
- 이전 강의에서 배운 **볼륨(Volume)**은 Pod 안에 정의되며, Pod가 삭제되면 데이터도 함께 사라질 수 있었습니다.
- 하지만, **퍼시스턴트 볼륨(Persistent Volume)**은 클러스터 전체에서 사용할 수 있는 중앙화된 저장소입니다.
- 관리자가 미리 큰 저장소 풀(pool)을 만들어 놓습니다.
- 사용자는 이 저장소에서 필요한 만큼만 가져다 쓸 수 있습니다.
왜 퍼시스턴트 볼륨이 필요할까요?
- 많은 사용자가 여러 Pod를 배포하는 환경에서는, 매번 각 Pod에 저장소를 설정하는 것이 번거롭습니다.
- 중앙에서 저장소를 관리하면:
- 사용자는 간단히 필요한 저장소를 요청해서 사용할 수 있습니다.
- 관리자는 전체 저장소를 효율적으로 관리할 수 있습니다.
2. 퍼시스턴트 볼륨 만들기
기본 템플릿
퍼시스턴트 볼륨을 생성하려면 다음과 같은 YAML 파일을 작성합니다:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-vol1
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
hostPath:
path: "/data"
주요 구성 요소
- apiVersion과 kind
- apiVersion: API 버전을 지정합니다. 여기서는 v1을 사용합니다.
- kind: 리소스 종류를 지정합니다. 여기서는 PersistentVolume입니다.
- metadata
- 퍼시스턴트 볼륨의 이름을 지정합니다. 예: pv-vol1.
- spec (세부 설정)
- accessModes (접근 모드):
- 볼륨이 어떻게 사용될지 정의합니다.
- 주요 옵션:
- ReadWriteOnce: 하나의 노드에서 읽기/쓰기 가능.
- ReadOnlyMany: 여러 노드에서 읽기만 가능.
- ReadWriteMany: 여러 노드에서 읽기/쓰기 가능.
- capacity (용량):
- 이 볼륨에 할당된 저장 공간 크기를 지정합니다. 예: 1Gi (1GB).
- hostPath (저장소 경로):
- 로컬 디렉터리를 저장소로 사용합니다. 예: /data.
- 주의: 이 옵션은 테스트 환경에서만 사용하고, 실제 운영 환경에서는 적합하지 않습니다.
- accessModes (접근 모드):
3. 퍼시스턴트 볼륨 생성 및 확인
명령어 실행
- YAML 파일을 작성한 뒤, 다음 명령어로 퍼시스턴트 볼륨을 생성합니다
kubectl create -f pv.yaml
kubectl get persistentvolume
4. 퍼시스턴트 볼륨의 다양한 스토리지 옵션
- 이전 강의에서 배운 것처럼, 여러 스토리지 솔루션을 사용할 수 있습니다.
- 로컬 디렉터리(hostPath) 외에도 다음과 같은 옵션이 있습니다:
- AWS EBS (Elastic Block Store)
- Azure Disk
- Google Persistent Disk
- NFS (Network File System)
- CephFS 등
- 로컬 디렉터리(hostPath) 외에도 다음과 같은 옵션이 있습니다:
예: AWS EBS를 사용하는 경우
spec:
awsElasticBlockStore:
volumeID: "vol-0abcd1234efgh5678"
fsType: "ext4"
5. 초등학생을 위한 쉬운 설명
- 쿠버네티스는 여러 사람이 컴퓨터를 나눠 쓰는 놀이터라고 생각해보세요!
- 놀이터에 있는 장난감(Pod)이 데이터를 만들어내는데, 이 데이터를 잃어버리지 않으려면 가방(볼륨)이 필요했죠?
- 그런데 사람들이 많아지면 각자 가방을 준비하기가 너무 힘들어요!
- 그래서 놀이터 관리자(관리자)가 큰 창고(퍼시스턴트 볼륨)를 만들어 놓고, 필요한 사람에게 조금씩 나눠주는 거예요.
- 이제 사람들은 창고에서 필요한 만큼 가져다 쓰면 돼요!
6. 요약
- 퍼시스턴트 볼륨은 클러스터 전체에서 사용할 수 있는 중앙화된 저장소입니다.
- 관리자가 미리 큰 저장소를 만들어 놓으면, 사용자는 간단히 요청해서 사용할 수 있습니다.
- 다양한 스토리지 솔루션과 연동 가능하며, 운영 환경에서는 AWS EBS나 NFS 같은 외부 스토리지를 권장합니다.
Persistent Volume(PV)와 Persistent Volume Claim(PVC)란?
- Persistent Volume(PV): 저장 공간이에요. 선생님(관리자)이 미리 만들어 둔 큰 상자라고 생각하면 돼요.
- Persistent Volume Claim(PVC): 학생(사용자)이 "이만큼 공간이 필요해요!"라고 요청하는 메모지예요.
PVC를 사용하면 필요한 만큼 저장 공간을 가져다 쓸 수 있어요. Kubernetes는 PVC를 보고 알맞은 크기의 PV를 찾아서 연결해줘요.
PVC가 어떻게 작동하나요?
- 선생님(관리자)이 여러 개의 PV(저장 상자)를 준비해 둡니다.
- 학생(사용자)은 PVC를 작성해서 "저는 500MB가 필요해요!"라고 요청합니다.
- Kubernetes는 PVC를 읽고, 조건에 맞는 PV를 찾아 연결합니다.
- 예: 요청한 크기(500MB), 접근 방식(ReadWriteOnce 등), 저장소 종류(Storage Class) 등을 확인합니다.
- 만약 조건에 맞는 PV가 없으면, PVC는 대기 상태에 머물러 있어요. 새로운 PV가 생기면 자동으로 연결됩니다.
중요한 특징
- 1:1 관계: 하나의 PVC는 하나의 PV만 사용할 수 있어요. 남은 공간은 다른 사람이 쓸 수 없어요.
- 작은 요청, 큰 상자: 요청한 크기보다 큰 PV가 있으면, 그 상자를 사용할 수도 있어요.
- 대기 상태: 조건에 맞는 PV가 없으면 PVC는 기다립니다.
PVC 만들기
PVC를 만들 때는 다음과 같이 설정해요:
- 이름: "My Claim"
- 접근 모드: ReadWriteOnce (읽고 쓰기 가능)
- 요청 크기: 500MB
PVC를 만들고 나면, Kubernetes가 자동으로 알맞은 PV를 찾아 연결합니다. 예를 들어, 1GB 크기의 PV가 있다면, 500MB 요청도 그 상자에 연결될 수 있어요.
PVC 삭제 시 발생하는 일
PVC를 삭제하면 PV에는 세 가지 옵션이 있어요:
- 유지(Retain): PV는 그대로 남아 있고, 관리자만 삭제할 수 있어요.
- 삭제(Delete): PVC가 삭제되면 PV도 자동으로 삭제돼요.
- 재활용(Recycle): 기존 데이터를 삭제하고 다른 사용자가 다시 쓸 수 있도록 준비돼요.
정리
- PV: 저장 공간 (큰 상자)
- PVC: 저장 공간 요청 (메모지)
- PVC와 PV는 1:1로 연결돼요.
- PVC 삭제 후에는 데이터를 유지하거나 삭제하거나 재활용할 수 있어요.


Kubernetes Persistent Volume (PV)와 Persistent Volume Claim (PVC) 예시
Kubernetes에서 **Persistent Volume (PV)**는 클러스터의 저장소 자원을 나타내며, **Persistent Volume Claim (PVC)**는 사용자가 특정 저장소를 요청하는 객체입니다. 아래는 PV와 PVC를 설정하고 사용하는 예시를 YAML 파일과 함께 단계별로 설명합니다.
1. Persistent Volume (PV) 생성
먼저, 클러스터에 저장소를 정의하는 PV를 생성합니다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/data
- capacity: 10Gi(기가바이트)의 저장 공간을 제공합니다.
- accessModes: ReadWriteOnce로 설정하여 하나의 노드에서 읽기/쓰기 가능하도록 합니다.
- persistentVolumeReclaimPolicy: Retain으로 설정하여 PVC가 삭제되더라도 PV는 유지됩니다.
- hostPath: /mnt/data 경로를 로컬 스토리지로 사용합니다.
2. Persistent Volume Claim (PVC) 생성
PVC를 생성하여 위에서 만든 PV를 요청합니다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
- accessModes: ReadWriteOnce로 설정하여 PVC가 PV와 동일한 접근 모드를 요구합니다.
- resources.requests.storage: 5Gi의 저장 공간을 요청합니다. PV의 크기(10Gi)가 요청 크기(5Gi)보다 크므로 바인딩이 가능합니다.
- storageClassName: manual로 설정하여 동일한 스토리지 클래스를 사용하는 PV와 매칭됩니다.
3. PVC와 PV 바인딩 확인
PVC가 PV에 성공적으로 바인딩되었는지 확인합니다.
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
example-pvc Bound example-pv 10Gi RWO manual 2m
4. Pod에서 PVC 사용
PVC를 Pod에 연결하여 데이터를 저장할 수 있도록 합니다.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: storage-volume
volumes:
- name: storage-volume
persistentVolumeClaim:
claimName: example-pvc
- volumeMounts.mountPath: 컨테이너 내부에서 /usr/share/nginx/html 경로에 PVC를 마운트합니다.
- volumes.persistentVolumeClaim.claimName: 앞서 생성한 PVC(example-pvc)를 참조합니다.
6. PVC 삭제 시 동작
PVC 삭제 후 PV의 동작은 persistentVolumeReclaimPolicy에 따라 달라집니다:
- Retain (유지):
- PVC 삭제 후에도 PV는 유지됩니다.
- 관리자가 수동으로 삭제해야 합니다.
- Delete (삭제):
- PVC 삭제 시 PV도 자동으로 삭제됩니다.
- Recycle (재활용):
- 데이터가 삭제된 후 다른 PVC에서 재사용 가능합니다.
Once you create a PVC use it in a POD definition file by specifying the PVC Claim name under persistentVolumeClaim section in the volumes section like this:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
The same is true for ReplicaSets or Deployments. Add this to the pod template section of a Deployment on ReplicaSet.
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes
Persistent Volumes
This document describes persistent volumes in Kubernetes. Familiarity with volumes, StorageClasses and VolumeAttributesClasses is suggested. Introduction Managing storage is a distinct problem from managing compute instances. The PersistentVolume subsystem
kubernetes.io
The application stores logs at location /log/app.log. View the logs.
You can exec in to the container and open the file:
kubectl exec webapp -- cat /log/app.log
[2025-01-13 13:18:44,494] INFO in event-simulator: USER2 logged out
[2025-01-13 13:18:45,495] INFO in event-simulator: USER1 is viewing page3
[2025-01-13 13:18:46,495] INFO in event-simulator: USER1 logged out
[2025-01-13 13:18:47,496] INFO in event-simulator: USER4 is viewing page1
[2025-01-13 13:18:48,497] INFO in event-simulator: USER3 logged in
[2025-01-13 13:18:49,498] WARNING in event-simulator: USER5 Failed to Login as the account is locked due to MANY FAILED ATTEMPTS.
[2025-01-13 13:18:49,499] INFO in event-simulator: USER2 is viewing page3
[2025-01-13 13:18:50,500] INFO in event-simulator: USER4 logged in
[2025-01-13 13:18:51,501] INFO in event-simulator: USER4 logged in
[2025-01-13 13:18:52,502] WARNING in event-simulator: USER7 Order failed as the item is OUT OF STOCK.
[2025-01-13 13:18:52,503] INFO in event-simulator: USER4 is viewing page3
Configure a volume to store these logs at /var/log/webapp on the host.
Use the spec provided below.
- Name: webapp
- Image Name: kodekloud/event-simulator
- Volume HostPath: /var/log/webapp
- Volume Mount: /log
k edit pod webapp
## 볼륨 추가
volumes:
- name: log-volume
hostPath:
path: /var/log/webapp
## 볼륨마운트 추가
volumeMounts:
- mountPath: /log
name: log-volume
Create a Persistent Volume with the given specification.
Volume Name: pv-log
Storage: 100Mi
Access Modes: ReadWriteMany
Host Path: /pv/log
Reclaim Policy: Retain
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-log
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /pv/log
Let us claim some of that storage for our application. Create a Persistent Volume Claim with the given specification.
Persistent Volume Claim: claim-log-1
Storage Request: 50Mi
Access Modes: ReadWriteOnce
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim-log-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
Update the webapp pod to use the persistent volume claim as its storage.
Replace hostPath configured earlier with the newly created PersistentVolumeClaim.




https://waspro.tistory.com/580

https://nice-engineer.tistory.com/entry/Kubernetes-Object-Volume%EC%9D%B4%EB%9E%80-2
[Kubernetes] Object - Volume이란 (2)
✔️ Network 볼륨 (Persistent Storage) Pod 내부에서 특정 데이터를 보유해야 하는 stateful한(ex. DB) app의 경우 stateless한(Pod, deployment) 데이터를 영속적으로 저장하기 위한 방법이 필요하다. Pod에서 실행
nice-engineer.tistory.com

## pv 정의
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 2Gi # 스토리지 용량
volumeMode: Filesystem # 파일 시스템 형식
accessModes:
- ReadWriteOnce # 하나의 노드만 읽기/쓰기 가능
persistentVolumeReclaimPolicy: Retain # PV 반환 정책
hostPath:
path: /data/pv-example # 클러스터 노드의 경로
## pvc정의
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce # 읽기/쓰기 접근 모드
volumeMode: Filesystem # 파일 시스템 형식
resources:
requests:
storage: 1Gi # 요청한 용량
### pod
apiVersion: v1
kind: Pod
metadata:
name: pod-example
spec:
containers:
- name: app-container
image: nginx # 컨테이너 이미지
volumeMounts:
- name: app-storage
mountPath: /usr/share/nginx/html # 컨테이너 내부 경로
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: pvc-example # 참조할 PVC 이름
'쿠버네티스 > 쿠버네티스' 카테고리의 다른 글
Networking - Pod Networking (0) | 2025.01.15 |
---|---|
Networking - Docker Networking - CNI - CLuster Networking (0) | 2025.01.15 |
Storage - Introduction to Docker Storage (0) | 2025.01.13 |
Secrets test/Encrypting Confidential Data at Rest (0) | 2025.01.09 |
Scheduling-Configuring Scheduler Profiles (1) | 2025.01.01 |