Storage
- 이번 장에서는 Certified Kubernetes Administrator (CKA) 을 준비하며 "스토리지"에 대해서 자세하게 알아보도록 한다.
Storage in Docker
도커 데이터 저장 위치

- 도커는 기본적으로
/var/lib/docker
디렉토리에 데이터를 저장한다. - 이 디렉토리에는
aufs
,containers
,image
,volumes
등의 하위 디렉토리가 있다.conatiners
: 컨테이너 관련 파일 저장image
: 이미지 관련 파일 저장volumes
: 볼륨 관련 파일 저장
도커 레이어 아키텍처

- 도커 이미지는 레이어 구조로 빌드된다.
- Dockerfile의 각 명령어에는 새로운 레이어를 생성하며, 각 레이어에는 이전 레이어의 변경 사항만 저장한다.
- 예시:
- Ubuntu 기본 운영 체제 레이어
- APT 패키지 설치 레이어
- Python 패키지 설치 레이어
- 소스 코드 복사 레이어
- 이미지 엔트리 포인트 업데이트 레이어
- 레이어 구조의 장점:
- 이미지 빌드 속도 향상: 동일한 레이어 재사용 (캐시 활용)
- 디스크 공간 효율성 향상: 변경 사항만 저장
- 이미지 업데이트 속도 향상: 변경된 레이어만 재빌드
이미지 레이어와 컨테이너 레이어

이미지 레이어
docker build
명령어로 생성된 레이어- 읽기 전용(read-only)
- 이미지 빌드 후에는 수정 불가
- 여러 컨테이너에서 공유
컨테이너 레이어
docker run
명령어로 컨테이너 실행 시 생성되는 쓰기 가능(writable) 레이어- 컨테이너에서 생성된 데이터(로그 파일, 임시 파일, 수정된 파일 등) 저장
- 컨테이너 삭제 시 함께 삭제
Copy-on-Write 메커니즘

- 이미지 레이어의 파일 수정
- 컨테이너 내부에서 이미지 레이어의 파일을 수정하면 도커는 해당 파일의 복사본을 컨테이너 레이어에 생성한다.
- 이후 수정은 컨테이너 레이어의 복사본으로 적용된다.
- 이미지 레이어의 원본 파일은 변경되지 않는다.
- 장점
- 이미지 레이어의 무결성 유지
- 컨테이너별로 독립적인 파일 수정 가능
컨테이너 삭제 시 데이터 손실
- 컨테이너 삭제 시 컨테이너 레이어의 모든 데이터가 삭제된다.
- 수정된 파일 및 새로 생성된 파일도 함께 삭제된다.
- 데이터 영속성을 위해 볼륨(volumes)을 사용해야 한다.
데이터 영속성(Persistent Data)
- 컨테이너 삭제 시 데이터 손실: 컨테이너 레이어는 컨테이너 삭제 시 함께 삭제되므로 데이터가 손실된다.
- 데이터 영속성을 위한 볼륨(Volumes) 사용: 컨테이너 삭제 후에도 데이터를 유지하려면 볼륨을 사용해야 한다.
도커 볼륨 생성 및 마운트

- 볼륨 생성:
docker volume create <볼륨 이름>
명령어를 사용하여 볼륨을 생성한다.- 예:
docker volume create data_volume
- 생성된 볼륨은
/var/lib/docker/volumes/<볼륨 이름>/_data
디렉토리에 저장된다.
- 예:
- 컨테이너에 볼륨 마운트:
docker run -v <볼륨 이름>:<컨테이너 내부 경로> <이미지 이름>
명령어를 사용하여 컨테이너에 볼륨을 마운트한다.- 예:
docker run -v data_volume:/var/lib/mysql mysql
- 컨테이너 내부에 지정된 경로에 볼륨이 마운트되어 데이터가 저장된다.
- 예:
- 자동 볼륨 생성:
docker run
명령어 실행 시 존재하지 않는 볼륨을 지정하면 도커가 자동으로 볼륨을 생성하고 마운트한다.
바인드 마운트(Bind Mount)
- 호스트 시스템의 디렉토리 마운트: 호스트 시스템의 특정 디렉토리를 컨테이너에 마운트한다.
- 명령어:
docker run -v <호스트 디렉토리 경로>:<컨테이너 내부 경로> <이미지 이름>
- 예:
docker run -v /host/data:/container/data nginx
- 호스트 시스템의
/data/mysql
디렉토리가 컨테이너의/var/lib/mysql
디렉토리에 마운트된다.
- 예:
- 볼륨 마운트 vs 바인드 마운트:
- 볼륨 마운트: 도커가 관리하는 볼륨 사용 (
/var/lib/docker/volumes
) - 바인드 마운트: 호스트 시스템의 임의 디렉토리 사용
- 볼륨 마운트: 도커가 관리하는 볼륨 사용 (
--mount
옵션(권장)
-v
옵션의 대체:--mount
옵션은-v
옵션보다 명시적이고 유연하다.- 명령어:
docker run --mount type=<mount type>,source=<source>,target=<target> <이미지 이름>
type
:volume
또는bind
source
: 볼륨 이름 또는 호스트 디렉토리 경로target
: 컨테이너 내부 경로
- 예시 (바인드 마운트):
docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
스토리지 드라이버(Storage Drivers)

- 역할: 레이어 아키텍처 관리, 쓰기 가능 레이어 생성, Copy-on-Write 구현 등
- 종류: AUFS, VTRFS, Device Mapper, Overlay, Overlay2 등
- 자동 선택: 도커는 운영 체제에 따라 최적의 스토리지 드라이버를 자동으로 선택한다.
- 성능 및 안정성: 스토리지 드라이버마다 성능 및 안정성 특성이 다르므로 애플리케이션 요구 사항에 맞는 드라이버를 선택해야 한다.
Storage Driver
스토리지 드라이버와 볼륨 드라이버의 차이

스토리지 드라이버(Storage Driver)
- 이미지와 컨테이너의 스토리지 관리를 담당한다.
- 레이어 아키텍처, 쓰기 가능 레이어, Copy-on-Write 등을 처리한다.
볼륨 드라이버 플러그인(Volume Driver Plugin)
- 볼륨 관리를 담당한다.
- 데이터 영속성을 위한 볼륨 생성 및 관리를 처리한다.
- 스토리지 드라이버와 볼륨 드라이버는 서로 다른 역할을 수행한다.
기본 볼륨 드라이버 플로그인(Local)
- 기본 플러그인: 도커 설치 시 기본적으로 제공되는 플러그인이다.
- 기능: 도커 호스트에 볼륨을 생성하고 데이터를
/var/lib/docker/volumes
디렉토리에 저장한다.
다양한 볼륨 드라이버 플러그인
- 외부 스토리지 솔루션 지원: 다양한 볼륨 드라이버 플러그인을 사용하여 Azure File Storage, Convoy, DigitalOcean Block Storage, Google Compute Persistent Disks 등과 같은 외부 스토리지 솔루션에 볼륨을 생성할 수 있다.
- 예시:
- Azure File Storage
- Convoy
- DigitalOcean Block Storage
- Flocker
- Google Compute Persistent Disks
- Cluster FS
- NetApp
- REX-Ray
- Portworx
- VMware vSphere Storage
- 다양한 스토리지 제공업체 지원: 일부 볼륨 드라이버는 여러 스토리지 제공업체를 지원한다.
- REX-Ray: AWS EBS, S3, EMC Isilon, ScaleIO, Google Persistent Disk, OpenStack Cinder 등 지원
외부 볼륨 드라이버 플러그인 사용

- 특정 볼륨 드라이버 지정:
docker run
명령어 실행 시 특정 볼륨 드라이버를 지정하여 외부 스토리지에 볼륨을 생성하고 컨테이너에 연결할 수 있다. - 예시: REX-Ray EBS 볼륨 드라이버를 사용하여 AWS EBS에서 볼륨을 프로비저닝하고 컨테이너에 연결한다.
- 데이터 영속성 보장: 컨테이너 종료 후에도 외부 스토리지에 데이터가 안전하게 보관된다.
Container Storage Interface
배경 및 필요성
- 과거 쿠버네티스와 도커: 과거에는 쿠버네티스가 도커만을 컨테이너 런타임 엔진으로 사용했으며, 도커 관련 코드가 쿠버네티스 소스 코드에 내장되어 있었다.

- 다양한 컨테이너 런타임 등장: RKT, CRI-O 등 다양한 컨테이너 런타임이 등장하면서 쿠버네티스는 다양한 런타임을 지원하고 독립성을 유지해야 했다.
- CRI(Container Runtime Interface): 쿠버네티스와 같은 오케스트레이션 솔루션이 도커와 같은 컨테이너 런타임과 통신하는 방식을 정의하는 표준이다.
- 새로운 컨테이너 런타임은 CRI 표준을 준수하여 쿠버네티스 개발팀의 도움 없이 쿠버네티스와 연동될 수 있다.

- CNI(Container Networking Interface): 다양한 네트워킹 솔루션을 지원하기 위해 도입되었다.
- 새로운 네트워킹 공급업체는 CNI 표준을 기반으로 플러그인을 개발하여 쿠버네티스와 연동할 수 있다.

- CSI(Container Storage Interface): 다양한 스토리지 솔루션을 지원하기 위해 개발되었다.
CSI(Container Storage Interface)

- 목적: 쿠버네티스와 다양한 스토리지 벤더의 솔루션을 연동하기 위한 범용 표준이다.
- CSI 드라이버: 각 스토리지 벤더(Portworx, Amazon EBS, Azure Disk, Dell EMC Isilon, NetApp 등)는 자체 CSI 드라이버를 제공한다.
- 범용 표준: CSI는 쿠버네티스 특정 표준이 아니며, 컨테이너 오케스트레이션 도구와 스토리지 벤더를 연결하는 범용 표준이다.
- 쿠버네티스, Cloud Foundry, Mesos 등이 CSI를 지원한다.
CSI 작동 방식
- RPC(Remote Procedure Calls) 정의: CSI는 컨테이너 오케스트레이터가 호출해야 하는 RPC 집합을 정의한다.
- 스토리지 드라이버 구현: 스토리지 드라이버는 CSI에서 정의된 RPC를 구현해야 한다.
- 예시:
- CreateVolume RPC: 파드 생성 시 볼륨이 필요한 경우 쿠버네티스는 CreateVolume RPC를 호출하고 볼륨 이름 등의 정보를 전달한다. 스토리지 드라이버는 이 요청을 처리하고 스토리지 어레이에 새 볼륨을 프로비저닝한 후 결과를 반환한다.
- DeleteVOlume RPC: 볼륨 삭제 시 쿠버네티스는 DeleteVolume RPC를 호출한다. 스토리지 드라이버는 이 요청을 처리하고 스토리지 어레이에서 볼륨을 삭제한다.
- 명세: CSI 명세는 호출자가 전달해야 하는 매개변수, 솔루션이 수신해야 하는 매개변수, 교환해야 하는 오류 코드 등을 상세히 정의한다.
Volumes
쿠버네티스 볼륨의 기본 개념
도커 볼륨과의 유사성

- 도커 컨테이너와 마찬가지로 쿠버네티스 파드도 일시적인 성격을 가진다.
- 파드가 삭제되면 파드 내부의 데이터도 함께 삭제된다.
- 데이터를 영구적으로 유지하기 위해 볼륨을 파드에 연결한다.
파드 데이터의 영속성

- 볼륨에 데이터를 저장하면 파드가 삭제되어도 데이터는 유지된다.
쿠버네티스 볼륨 구현 예시

단일 노드 클러스터
- 1 ~ 100 사이의 난수를 생성하여
/opt/number.out
파일에 기록하는 파드를 생성한다. - 파드 삭제 시 난수 데이터도 함께 삭제된다.
- 데이터 유지를 위해 볼륨을 생성한다.
볼륨 스토리지 설정
- 볼륨 스토리지는 다양한 방식으로 설정할 수 있다.
- 단순화를 위해 호스트 노드의 디렉토리(
/data
)를 스토리지로 사용한다.
볼륨 마운트
- 파드 컨테이너 내부의
/opt
디렉토리에 볼륨을 마운트한다. - 난수는 컨테이너 내부의
/opt
디렉토리에 저장되고, 이는 호스트 노드의/data
디렉토리에 실제로 저장된다.
파드 삭제 후 데이터 유지
- 파드가 삭제되어도 난수 파일은 호스트 노드의
/data
디렉토리에 남아있다.
볼륨 스토리지 옵션
호스트 경로 (hostPath)

- 호스트 노드의 디렉토리를 볼륨 스토리지로 사용한다.

- 단일 노드 클러스터에는 작동하지만 다중 노드 클러스터에서는 권장되지 않는다.

- 다중 노드 클러스터에서는 파드가 모든 노드의
/data
디렉토리를 사용하므로 데이터 불일치가 발생할 수 있다.
다양한 스토리지 솔루션 지원

- 쿠버네티스는 NFS, ClusterFS, Flocker, Fiber Channel, CephFS, ScaleIO와 같은 다양한 스토리지 솔루션을 지원한다.
- AWS EBS, Azure Disk, Google Persistent Disk와 같은 퍼블릭 클라우드 스토리지 솔류션도 지원한다.
AWS EBS 볼륨 설정 예시

- 볼륨의
hostPath
필드를awsElasticBlockStore
필드로 대체한다. - 볼륨 ID와 파일시스템 유형을 지정한다.
- 볼륨 스토리지는 이제 AWS EBS에 위치한다.
Persistent Volume
볼륨의 한계와 영구 볼륨(Persistent Volume)의 필요성

- 기존 볼륨의 설정: 파드 정의 파일 내에 볼륨 설정을 직접 구성했다.

- 대규모 환경의 문제점
- 많은 사용자가 다양한 파드를 배포하는 대규모 환경에서는 각 파드마다 스토리지 설정을 반복해야 한다.
- 스토리지 솔루션 변경 시 모든 파드 정의 파일을 수정해야 한다.
- 중앙 집중적인 스토리지 관리가 필요하다.

- Persistent Volume의 역할
- 관리자가 클러스터 전체에서 사용할 수 있는 스토리지 풀을 미리 구성한다.
- 사용자는 영구 볼륨 클레임(Persistent Volume Claims, VPC)을 통해 필요한 스토리지를 할당받는다.
- 중앙 집중적인 스토리지 관리 및 사용자 편의 성을 제공한다.
영구 볼륨(Persistent Volume, PV) 생성

- 기본 템플릿 및 설정
- API 버전, 종류(PersistentVolume), 이름(pv-vol1), 용량, 액세스 모드, 스토리지 클래스 등을 설정한다.
spec
영역에서 세부 설정을 정의한다.
- 접근 모드(accessMode)
- 볼륨을 호스트에 마운트하는 방식(읽기 전용, 읽기/쓰기 등)을 정의한다.
readOnlyMany
,ReadWriteOnce
,ReadWriteMany
등의 값을 사용할 수 있다.
- 용량(capacity)
- 영구 볼륨에 할당할 스토리지 용량을 지정한다. (예: 1GB)
- 볼륨 유형(volumeType)
- 볼륨 스토리지의 유형을 설정한다.
hostPath
옵션을 사용하여 노드의 로컬 디렉토리를 사용할 수 있다. (개발/테스트 환경에서만 권장)
- 영구 볼륨 생성 및 조회
kubectl create
명령어를 사용하여 영구 볼륨을 생성한다.kubectl get persistentvolume
명령어를 사용하여 생성된 영구 볼륨을 조회한다.
- 스토리지 솔루션 변경
hostPath
옵션을 지원되는 다른 스토리지 솔루션(AWS EBS 등)으로 변경하여 실제 스토리지 환경에 맞게 구성한다.
Persistent Volume Claim
영구 볼륨 클레임(Persistent Volume Claim, PVC)의 역할

- 영구 볼륨(PV)과의 관계: 영구 볼륨과 영구 볼륨 클레임은 쿠버네티스 네임스페이스의 별도 객체다.
- 관리자와 사용자의 역할 분담: 관리자는 영구 볼륨을 생성하고, 사용자는 영구 볼륨 클레임을 생성하여 스토리지를 사용한다.
- 영구 볼륨 바인딩: 쿠버네티스는 클레임의 요청과 볼륨의 속성을 기반으로 영구 볼륨을 클레임에 바인딩한다.
- 1:1 관계: 각 영구 볼륨 클레임은 하나의 영구 볼륨에 바인딩된다.
영구 볼륨 클레임 바인딩 과정

- 용량 확인: 쿠버네티스는 클레임에서 요청한 용량과 일치하거나 충분한 용량을 가진 영구 볼륨을 찾는다.

- 속성 확인: 접근 모드, 볼륨 모드, 스토리지 클래스 등 클레임의 다른 요청과 볼륨의 속성을 비교한다.

- 레이블 및 선택기: 여러 후보 볼륨이 있는 경우 레이블과 선택기를 사용하여 특정 볼륨을 선택할 수 있다.
- 용량 초과 바인딩: 다른 모든 조건이 충족되고 더 나은 옵션이 없는 경우, 더 작은 클레임이 더 큰 볼륨에 바인딩될 수 있다.

- 클레임 대기 상태: 사용 가능한 볼륨이 없는 경우 클레임은 대기 상태로 유지되며, 새 볼륨이 생성되면 자동으로 바인딩된다.
영구 볼륨 클레임 생성


- 기존 템플릿 및 설정
- API 버전, 종류(PersistentVolumeClaim), 이름(My-Claim)을 설정한다.
spec
영역에서 세부 설정을 정의한다.
- 접근 모드(accessModes): 읽기/쓰기 한번(
ReadWriteOnce
)으로 설정한다. - 리소스 요청(resources.requests): 500MB의 스토리지를 요청한다.
- 클레임 생성 및 조회
kubectl create
명령어를 사용하여 영구 볼륨 클레임을 생성한다.kubectl get persistentvolumeclaim
명령어를 사용하여 생성된 영구 볼륨 클레임을 조회한다.

- 바인딩 상태 확인:
kubectl get pv
명령어를 실행하여 클레임이 영구 볼륨에 바인딩되었는지 확인한다.
영구 볼륨 클레임 삭제 시 영구 볼륨 처리

- 삭제 명령어:
kubectl delete persistentvolumeclaim
명령어를 사용하여 클레임을 삭제한다. - 삭제 시 영구 볼륨 처리 옵션:
- 유지(Retain): 기본 설정으로 관리자가 수동으로 삭제할 때까지 영구 볼륨이 유지되며 다른 클레임에서 재사용할 수 없다.
- 삭제(Delete): 클레임 삭제 시 영구 볼륨도 자동으로 삭제되어 스토리지 장치의 공간을 확보한다.
- 재활용(Recycle): 데이터 볼륨의 스크럽(삭제)하여 다른 클레임에서 사용할 수 있도록 한다.
Using PVCs in Pods
- PVC를 생성한 후에는 다음과 같은 볼륨 섹션의
persistentVolumeClaim
섹션에서 PVC 이름을 지정하여 파드 정의 파일에서 사용할 수 있다.
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
- ReplicaSet 또는 Deployment도 동일하게 파드 템플릿 영역에 PVC를 지정하여 사용할 수 있다.
Storage Class

정적 프로비저닝(Static Provisioning)

- 이전에는 PV를 먼저 수동으로 생성하고 PVC를 통해 이를 클레임하는 방식이었다.
- GCP에서 영구 디스크를 사용하려면 먼저 GCP 콘솔에서 디스크를 생성해야 했다.
- 그 다음, 생선한 디스크와 동일한 이름을 사용하여 PV 정의 파일을 수동으로 작성해야 했다.
- 이런한 방식은 애플리케이션이 스토리지를 필요로 할 때마다 수동으로 디스크를 프로비저닝해야 하는 번거로움이 있다.
동적 프로비저닝(Dynamic Provisioning)과 스토리지 클래스

- 스토리지 클래스를 사용하면 애플리케이션이 스토리지를 필요로 할 때 자동으로 볼륨을 프로비저닝할 수 있다.
- 스토리지 클래스는 프로비저너(Provisioner)를 정의하여 자동으로 스토리지 프로비저닝을 수행한다.
- GCP의 경우
kubernetes.io/gce-pd
프로비저너를 사용하여 GCP 영구 디스크를 자동으로 생성할 수 있다.

- PV 정의 파일은 더 이상 필요하지 않다. 스토리지 클래스가 PV와 실제 스토리지를 자동으로 생성하기 때문이다.
- PVC 정의 파일에서
storageClassName
필드를 지정하여 사용할 스토리지 클래스를 선택한다. - PVC가 생성되면 스토리지 클래스는 정의된 프로비저너를 사용하여 GCP에 필요한 크기의 새 디스크를 프로비저닝하고, PV를 생성한 다음 PVC를 해당 볼륨에 바인딩한다.
다양한 프로비저너와 매개변수

- GCP 외에도 AWS EBS, Azure File, Azure Disk, CephFS, Portworx, ScaleIO 등 다양한 프로비저너를 사용할 수 있다.
- 각 프로비저너는 디스크 유형, 복제 모드 등 추가 매개변수를 설정할 수 있다.
- GCP 영구 디스크의 경우
type
(standard, SSD) 및replication mode
(none, regional PD)를 지정할 수 있다.
스토리지 클래스의 활용

- 스토리지 클래스를 사용하여 다양한 서비스 등급(예: silver, gold, platinum)을 정의할 수 있다.
- 각 등급은 다른 유형의 디스크와 설정을 사용하여 성능과 안정성을 조절할 수 있다.
- PVC를 생성할 때 필요한 스토리지 클래스를 지정하여 원하는 서비스 등급의 볼륨을 사용할 수 있다.
참고한 강의
'Infrastructure > Kubernetes' 카테고리의 다른 글
[CKA] Networking (Pre-Requisites) - 2 (0) | 2025.03.11 |
---|---|
[CKA] Networking (Pre-Requisites) - 1 (0) | 2025.03.11 |
[CKA] Security (Custom Resource Definition) (0) | 2025.03.10 |
[CKA] Security (Network Policy) (0) | 2025.03.10 |
[CKA] Security (ClusterRole) (0) | 2025.03.10 |