서비스에서 사용하는 저장소를 분리하기 위해 로컬 PV(Persistent Volume)를 설정하였다.
기존 Docker의 mount는 단순히 컨테이너와 호스트 간의 디렉토리 연결이지만, 로컬 PV는 k8s 스케줄러가 해당 볼륨이 어느 노드에 있는지 인식하고 그 노드에서만 파드가 실행되도록 스케줄링한다.
사실 k8s에서도 굳이 PV를 사용할 필요 없이 볼륨을 mount해도 된다.
예를 들어 아래 매니페스트는 서비스가 배포되는 노드에서 직접 로컬 저장소에 접근한다.
하지만 이 저장소는 k8s가 아니라 서비스 수준에서 관리된다는 문제가 있다.
# jupyterlab 매니페스트 파일 중 containers: - name: jupyterlab image: jupyter/base-notebook volumeMounts: - name: hdd-storage mountPath: /home/jovyan/work volumes: - name: hdd-storage hostPath: path: /storage/hdd1/jupyter type: Directory
1. PV 구축
먼저 다음과 같이 매니페스트를 구성한다.
gpu-id가 1인 노드에서 /storage/hdd1/jupyter에 1TiB의 공간을 사용하며 저장소를 단일 서비스가 사용할 수 있도록 강제하는 내용이다.
또한 서비스를 삭제하는 경우 PV는 삭제되지 않도록 설정되어 있다.
apiVersion: v1 kind: PersistentVolume metadata: name: local-pv-gpu1 spec: capacity: storage: 1Ti accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage-gpu1 local: path: /storage/hdd1/jupyter nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: gpu-id operator: In values: - "1"
2. PVC 설정
이제 위에서 생성한 PV를 사용하는 서비스를 만들어보자.
PV를 사용하기 위해서는 PV 사용에 대한 요청(Claim)이 선행되어야 한다.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gpu1-pvc namespace: jupyter spec: accessModes: - ReadWriteOnce storageClassName: local-storage-gpu1 resources: requests: storage: 1Ti
서비스에서는 기존의 volume 부분을 이렇게 바꿔주면 된다.
volumeMounts: - name: hdd-storage mountPath: /home/jovyan/work volumes: - name: hdd-storage persistentVolumeClaim: claimName: gpu1-pvc
3. PV 재사용
PV의 persistentVolumeReclaimPolicy가 Retain으로 설정되어있기 때문에 PVC가 삭제된 이후에는 PV를 곧바로 사용할 수 없다.
실제로 PV의 상태를 조회해보면 Available이 아니라 Released 상태인 걸 확인할 수 있는데, 이는 PV를 다시 사용할 수 있는 상태로 직접 바꿔줘야 함을 의미한다.
다음 명령어는 Released 상태의 PV를 다시 Available 상태로 바꾸는 명령어이다.
$ kubectl patch pv gpu1-pvc -p '{"spec":{"claimRef": null}}'