본문 바로가기

kubernetes(cka)

[cka] Storage (PV, PVC)

Docker Storage

Docker 는 이미지를 왼쪽과 같이 처음 빌드 했다고 하면, 각 상태별로 layer를 기록해 두고, 다음에 레이어 4부터가 바꼈다고하면

이전꺼는 그대로 쓰고 바뀐 부분만 빌드 해서 용량을 차지함. 빌드 속도도 빨라짐.

 

위처럼 도커에서 이미지를 사용해서 컨테이너를 만들면 같은 이미지를 사용하는건 같은 이미지 레이어를 사용함. 공통 이미지 레이어 말고 각각의 컨테이너 레이어 부분의 용량만 추가해서 사용함.

예를 들어서 

• 이미지 레이어: 380MB (두 컨테이너가 공유)
• 첫 번째 컨테이너의 쓰기 레이어: 5MB
• 두 번째 컨테이너의 쓰기 레이어: 3MB
총차지하는 공간은 : 380MB + 5MB + 3MB = 388MB  이렇게 됨.

또 예를들어 그럼 컨테이너에서 공통레이어 파일에 속한 app.py가 (50mb)파일이라 가정하고 지워도 실제로 그만큼 용량 줄어드는게 아니라, 지웠다는 사실만 컨테이너 레이어에 기록함.

 

Docker Volumn

- 사용하는 이유는 컨테이너는 기본적으로 일시적이라 컨테이너가 삭제되면 그 안의 데이터도 함께 삭제되기때문.
- 볼륨을 컨테이너에 마운트하면, 컨테이너가 삭제되어도 데이터는 유지

- docker volumn 명령어를 사용하고 오른쪽처럼 -v 옵션으로 묶어 주면됨. (근데 먼저 create 안하고 해도 자동으로 생김)

볼륨 안쓰고 실제 서버에 있는 경로 묶어줘도됨.

볼륨쓰는건 volumn mount, 실제 경로 쓰는건 bind mount

- docker run --mount 옵션써도됨. 

CSI (Container Storage Interface)

스토리지 종류에는 여러 종류가 있는데 이걸 컨테이너 와 인터페이스 해주는게 CSI 라는것도 있음 

볼륨삭제, 생성 같은걸 해줄거임.

 

Volumn in Kubernetes

- hostvolumn

서버의 디스크 경로를 컨테이너와 마운트 해서 사용 가능. 근데 단일서버에서나 가능하고 다중이면 파드가 생성될때마다 노드 바뀌니 무의미. 모든 서버에서 그 경로가 

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: example-container
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: example-volume
  volumes:
  - name: example-volume
    hostPath:
      path: "/data"
      type: Directory

 

PV(Persistanent Volumn)

클러스터에서 사라지지 않는 영구스토리지.

hostpath는 모든 노드의 같은 공간에 생성되고, 실제로 kubernetes에 의해 관리 되지 않고,

local volumn 방식은 생성될 노드 affinity를 지정해서 그 노드에 mount되는건데 파드의 위치가 변경되면 그 이전 데이터 활용이 안됨.

 

그래서 쿠버네티스에서 pv로는 각 노드의 디스크를 쓰려고 하면 안되고, 동적 스토리지 프로비저닝을 사용하거나 분산 스토리지 시스템을 사용하는게 맞는걸로 보임

 

아래는 yaml 에서 사용되는 설정 옵션

1. accessModes (PV 및 PVC에서 사용)

읽기 또는 쓰기 가능한 방식과 여러 노드에서 동시에 접근할 수 있는지 여부를 나타냄

• ReadWriteOnce (RWO): 하나의 노드에서만 읽기 및 쓰기 가능.
• ReadOnlyMany (ROX): 여러 노드에서 읽기만 가능.
• ReadWriteMany (RWX): 여러 노드에서 읽기 및 쓰기 가능.
• ReadWriteOncePod (RWO-P): 하나의 파드에서만 읽기 및 쓰기 가능.

 

2. persistentVolumeReclaimPolicy (PV에서 사용)

persistentVolumeReclaimPolicy는 PVC가 삭제된 후 PV가 어떻게 처리될지를 정의

Retain: PV는 그대로 유지되며, 관리자가 수동으로 삭제해야 함.

Delete: PVC가 삭제되면 PV도 자동으로 삭제되고, 스토리지도 반환됨.

Recycle: PVC가 삭제되면 PV의 데이터를 간단히 삭제하고 PV를 재사용할 수 있도록 설정.

 

3. storageClassName (PV 및 PVC에서 사용)

storageClassName은 스토리지 프로비저닝 시 어떤 스토리지 클래스를 사용할지를 정의.

Kubernetes에서 스토리지 클래스는 동적 스토리지 프로비저닝을 위해 사용.

예시: standard, fast, slow 등으로 스토리지의 성능, 타입을 지정할 수 있음.

비워 두면 기본 스토리지 클래스

없음으로 설정하면 동적 프로비저닝 없이 수동으로 PV를 할당.

 

근데 PV 를 hostpath로 지정하면 클러스터링된 여러 노드에서 분산저장을 지원하지 않아 하나의 노드에서만 사용됨.

그 pv를 처음 사용하는 파드가 스케줄된 노드에서 실제 데이터 적재가 처음 일어나고, 다음에 다른 노드에서 그 pv를 사용한다 하면 처음 생성된 위치의 노드의 데이터를 사용하는거임.

 

 

Storage Class

특정 스토리지 제공자(외부 제공자가 될수도 있고 직접 분산 시스템같은걸 구축할수도 있음.)를 사용하여 자동으로 스토리지를 프로비저닝하는 역할

스토리지를 수동으로 pv로 부여한다면이건 정적 프로비저닝. 자동으로 리소스를 할당하게 하면 그건 동적 프로비저닝.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-sc
provisioner: kubernetes.io/rbd  # Ceph RBD 프로비저너
parameters:
  monitors: "192.168.0.1:6789,192.168.0.2:6789"  # Ceph 모니터 IP
  pool: rbd
  user: admin
  secretNamespace: kube-system
  secretName: ceph-secret
  fsType: ext4

 

 

PVC (Persistent Volume Claim)

위에서 생성된 storage class 를 사용해서 (분산 스토리지) pvc 를 연결해주면 동적 프로비저닝을 해줌

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ceph-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: ceph-sc  # Ceph 스토리지 클래스를 지정
apiVersion: v1
kind: Pod
metadata:
  name: ceph-pod
spec:
  containers:
  - name: app-container
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"  # PVC가 마운트될 컨테이너 내부 경로
      name: ceph-storage
  volumes:
  - name: ceph-storage
    persistentVolumeClaim:
      claimName: ceph-pvc  # 위에서 생성한 PVC와 연결

 

 

그외에 분산 시스템을 구축하는게 아니라면, nfs를 구축하는방법도 있음. 그외 기타 등등

 

https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/