앞에서 Docker의 스토리지 드라이버(overlay2 등) 와 볼륨 드라이버(local/외부 플러그인) 를 구분했죠.
Kubernetes로 오면 이 구분이 더 명확해집니다.
- 컨테이너 런타임(예: containerd)은 이미지/컨테이너 레이어 파일시스템을 관리(overlayfs 같은 메커니즘)
- Kubernetes는 “영구 스토리지”를 붙이기 위해 CSI(Container Storage Interface) 라는 표준을 통해 외부 스토리지를 연결
이 글에서는 “왜 CSI가 나왔는지”, “CRI/CNI/CSI가 각각 뭘 표준화하는지”, “CSI가 실제로 어떤 RPC를 정의하는지”, “Kubernetes에서 PVC/StorageClass로 어떻게 이어지는지”까지 흐름대로 정리합니다.
1) 왜 ‘인터페이스 표준’이 필요했나: CRI → CNI → CSI
초기 Kubernetes는 특정 런타임/네트워크/스토리지 구현과 결합이 강했습니다. 그러다 보니 새로운 런타임/네트워크/스토리지 벤더가 들어오려면 Kubernetes 코드 변경(또는 릴리스 주기 동기화)이 필요했고, 생태계를 확장하기 어렵습니다.
그래서 Kubernetes는 영역별로 “플러그인 인터페이스 표준”을 만들었습니다.
CRI (Container Runtime Interface)
- kubelet ↔ 컨테이너 런타임 사이 통신 표준(gRPC 프로토콜)
- 목적: kubelet이 다양한 런타임을 쓰도록 “재컴파일 없이” 플러그인처럼 갈아끼우게 함 (Kubernetes)
강의 스크립트에서 “예전엔 containerd만 쓰고 런타임 코드가 Kubernetes에 내장”처럼 들리는데, 실제 역사적으로는 Docker(dockershim) 등과의 결합/통합 이슈가 있었고, 핵심은 “쿠버네티스가 특정 런타임에 종속되지 않도록 표준(CRI)을 만든 것”입니다. (Kubernetes)
CNI (Container Network Interface)
- 컨테이너 네트워크 플러그인 표준
- 목적: Calico/Cilium/Flannel 같은 네트워크 벤더가 “표준 인터페이스”만 맞추면 Kubernetes에서 동작하게 함(네트워크 namespace에 인터페이스를 붙이고 IP 할당/라우팅 설정 등) (Red Hat)
CSI (Container Storage Interface)
- 컨테이너 오케스트레이터 ↔ 스토리지 드라이버 사이 표준
- 목적: AWS EBS, Azure Disk, NetApp, Portworx, Dell EMC, Pure 등 다양한 스토리지를 Kubernetes 코드 바깥(out-of-tree) 에서 드라이버로 제공 (GitHub)
- CSI는 Kubernetes 전용이 아니라 “범용 표준”이며, 여러 오케스트레이터가 채택합니다(예: Kubernetes, Cloud Foundry, Mesos, Nomad 등) (GitHub)
2) CSI는 “무엇을 표준화”하나? — gRPC RPC 목록을 표준으로 고정
CSI의 본질은 단순합니다.
오케스트레이터가 스토리지를 쓰려면 “볼륨 생성/삭제/Attach/Detach/Mount/Unmount” 같은 작업이 필요한데,
이 작업들의 RPC 이름, 입력 파라미터, 반환/에러 규격을 표준으로 박아둔 것.
그래서 벤더는 CSI 스펙에 맞춰 gRPC 서버(드라이버)를 구현하면 되고, 오케스트레이터는 스펙대로 RPC를 호출하면 됩니다. (GitHub)
대표적으로 이런 계열 RPC가 등장합니다(이름은 예시/요지 수준):
- CreateVolume / DeleteVolume: 볼륨 프로비저닝/해제
- ControllerPublishVolume / ControllerUnpublishVolume: (블록 스토리지 계열에서) 노드에 Attach/Detach 성격
- NodeStageVolume / NodeUnstageVolume: 노드에서 준비(스테이징)
- NodePublishVolume / NodeUnpublishVolume: 파드에 최종 마운트/언마운트
이 구조 덕분에 “벤더 스토리지 API가 무엇이든” Kubernetes 입장에서는 동일한 흐름으로 다룹니다.
3) Kubernetes에서 CSI는 어떻게 쓰이나: StorageClass → PVC → Pod 흐름
Kubernetes 사용자는 보통 CSI를 직접 호출하지 않습니다. 대신 다음 리소스를 씁니다.
- StorageClass: “어떤 스토리지 프로비저너(=CSI 드라이버)를 어떤 설정으로 쓸지”
- PVC(PersistentVolumeClaim): “이만큼의 스토리지를 달라”
- PV(PersistentVolume): 실제 할당된 볼륨(동적 프로비저닝이면 자동 생성)
- Pod: PVC를 마운트해서 사용
(1) StorageClass 예시(개념)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: ebs.csi.aws.com # 예시: 실제 값은 환경별 CSI 드라이버에 따라 다름
volumeBindingMode: WaitForFirstConsumer
(2) PVC 예시
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: fast
resources:
requests:
storage: 20Gi
(3) Pod에서 PVC 마운트
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mysql
image: mysql:8
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-pvc
이 흐름에서 “PVC가 생겼는데 실제 볼륨이 만들어지고, 노드에 붙고, 파드 경로에 마운트되는” 모든 과정이 CSI 드라이버 RPC로 이어집니다.
4) “오케스트레이터가 CSI 드라이버를 호출한다”는 말이 실무에서 의미하는 것
Kubernetes에서 발생하는 대표 시나리오는 아래입니다.
파드가 올라가면서 볼륨이 필요할 때
- PVC 생성 → StorageClass 확인
- (동적 프로비저닝이면) CSI 드라이버 쪽으로 CreateVolume 계열 호출
- 스케줄링된 노드에 볼륨을 Attach/Detach 해야 하면 Controller 계열 RPC 호출
- 노드에서 파일시스템 준비/마운트(Node 계열 RPC)
- 컨테이너에서
/var/lib/mysql같은 경로로 사용
PVC/PV 삭제로 볼륨이 회수될 때
- 정책에 따라 DeleteVolume 계열 호출로 실제 스토리지에서도 볼륨 삭제
5) 확인/디버깅에 바로 쓰는 커맨드
CSI가 “지금 클러스터에 어떤 드라이버로 들어왔는지”부터 확인하는 게 좋습니다.
# 어떤 CSI 드라이버가 등록되어 있는지
kubectl get csidrivers
# StorageClass 목록과 provisioner 확인
kubectl get storageclass -o wide
# PVC/PV 상태 확인 (Pending이면 프로비저닝/바인딩 문제 가능)
kubectl get pvc,pv
# 특정 PVC 이벤트/에러 확인
kubectl describe pvc mysql-pvc
그리고 런타임 쪽(CRI) 확인도 같이 해두면 원인 분리가 빨라집니다.
# 노드가 어떤 컨테이너 런타임을 쓰는지(각 노드 정보)
kubectl get nodes -o wide
kubectl describe node <node> | grep -i "Container Runtime"
6) 핵심 정리
- CRI: kubelet이 다양한 컨테이너 런타임과 통신하는 표준(gRPC) (Kubernetes)
- CNI: 컨테이너 네트워킹 플러그인 표준(인터페이스 붙이기/IP 할당/라우팅) (Red Hat)
- CSI: 컨테이너 오케스트레이터가 스토리지 벤더 드라이버와 통신하는 표준(gRPC), Kubernetes 포함 여러 CO가 채택 (GitHub)
- Docker에서 “볼륨은 볼륨 드라이버가 담당”이었던 것처럼, Kubernetes에서는 “영구 스토리지는 CSI 드라이버가 담당”하는 구조로 일반화된 것
'CKA' 카테고리의 다른 글
| Storage - PV & PVC (0) | 2026.01.03 |
|---|---|
| Storage - Volume (0) | 2026.01.03 |
| Storage - Docker의 Storage Driver vs Volume Driver (0) | 2026.01.03 |
| Storage - Docker의 Storage (0) | 2026.01.03 |
| Security - 정리(2) (1) | 2026.01.02 |