본문 바로가기

About/Kubernetes

[k8s] Volume - (emptyDir, hostPath, PV/PVC)

Volume

Docker에서도 Volume의 개념은 존재한다. Docker의 Volume은 디스크에 있는 디렉터리이거나 다른 컨테이너에 있다. Volume 드라이버를 제공하지만, 기능이 다소 제한된다.

쿠버네티스에서는 다양한 유형의 Volume을 지원한다. 파드는 여러 볼륨 유형을 동시에 사용할 수 있다. 
기본적으로 Volume은 디렉토리이며, 일부 데이터가 있을 수 있고, 파드 내 컨테이너에서 접근할 수 있다. 디렉토리의 생성 방식, 이를 지원하는 매체와 내용은 사용된 특정 볼륨의 유형에 따라 결정된다.

emptyDir

emptyDir Volume은 파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재한다. 이름에서 알 수 있듯이 emptyDir 볼륨은 처음에는 비어있다. 파드 내 모든 컨테이너는 emptyDir 볼륨에서 동일한 파일을 읽고 쓸 수 있지만, 해당 볼륨은 각각의 컨테이너에서 동일하거나 다른 경로에 마운트될 수 있다. 어떤 이유로든 노드에서 파드가 제거되면 emptyDir의 데이터가 영구적으로 삭제된다.

컨테이너가 크래쉬되더라도 노드에서 파드를 제거하지 않는다. emptyDir 볼륨의 데이터는 컨테이너 크래시로부터 안전하다.

Pod 생성 시 만들어지고 삭제 시 없어지므로 일시적인 데이터 보관을 하는 경우에 사용한다.

emptyDir 구성 예시

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-1
spec:
  containers:
  - name: container1
    image: kubetm/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount1
  - name: container2
    image: kubetm/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount2
  volumes:
  - name : empty-dir
    emptyDir: {}

 

hostPath

hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 직접 마운트한다. emptyDir과 다르게 Pod가 죽어도 볼륨의 데이터는 삭제되지 않는다. 대부분의 파드들이 필요한 것은 아니지만, 일부 애플리케이션에서는 강력한 역할을 한다.

예를들면 다음과 같이 사용할 수 있다.
- Docker 내부에 접근할 필요가 있는 실행중인 컨테이너 - /var/lib/docker를 hostPath로 이용
- 컨테이너에서 cAdvisor 실행 - /sys를 hostPath로 이용

hostPath에 볼륨에 대한 type을 지정할 수 있는데 지원하는 type은 다음과 같다.

내용
  빈 문자열 (기본값)은 이전 버전과의 호환성을 위한 것으로, hostPath 볼륨은 마운트 하기 전에 아무런 검사도 수행되지 않는다.
DirectoryOrCreate 만약 주어진 경로에 아무것도 없다면, 필요에 따라 Kubelet이 가지고 있는 동일한 그룹과 소유권, 권한을 0755로 설정한 빈 디렉터리를 생성한다.
Directory 주어진 경로에 디렉터리가 있어야 함
FileOrCreate 만약 주어진 경로에 아무것도 없다면, 필요에 따라 Kubelet이 가지고 있는 동일한 그룹과 소유권, 권한을 0644로 설정한 빈 파일을 생성한다.
File 주어진 경로에 파일이 있어야 함
Socket 주어진 경로에 UNIX 소캣이 있어야 함
CharDevice 주어진 경로에 문자 디바이스가 있어야 함
BlockDevice 주어진 경로에 블록 디바이스가 있어야 함

반면 hostPath는 사용시 주의할 점이 많다. 우선 쿠버네티스 공식 문서에서는 다음과 같이 경고한다.

보안 상의 문제로 가능하면 사용하지 않는 것이 좋다고 명시되어 있다.  


이 뿐만 아니라 파드를 재생성하거나 추가로 생성하는 경우 동일한 구성을 가진 파드더라도 노드에 있는 파일이 다르기 때문에 노드마다 다르게 동작할 수 있다는 문제도 있다.

hostPath 구성 예시

apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-1
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1
  containers:
  - name: container
    image: kubetm/init
    volumeMounts:
    - name: host-path
      mountPath: /mount1 # hostPath와 /mount1 디렉토리를 마운트함
  volumes:
  - name : host-path 
    hostPath: 
      path: /node-v # node의 node-v 경로와 마운트
      type: DirectoryOrCreate # 경로에 아무것도 없는 경우 디렉토리 생성

 

PV/PVC

퍼시스턴트볼륨(PV, Persistent volume)은 관리자(Admin) 영역에서 다양한 스토리지 클래스를 사용해서 동적으로 할당한 클러스터의 스토리지이다. 노드가 클러스터의 리소스인 것 처럼 PV 또한 하나의 클러스터의 리소스이다. PV는 Volumes와 같은 볼륨 플러그인이지만, PV는 파드들과는 별개의 라이프 사이클을 가진다.  Local Volume을 사용할 수도있지만 aws, git, azure 등 외부의 스토리지 볼륨을 사용할 수 도 있다.

퍼시스턴트볼륨클레임(PVC, Persistent volume claim)은 사용자 영역(User)에서 스토리지에 대한 요청으로 파드와 비슷하다. 파드는 노드의 리소스를 사용하고 PVC는 PV의 리소스를 사용한다.  PVC는 특정 크기 및 접근 모드를 요청할 수 있다. 

접근 모드는 다음과 같다.

ReadWriteOnce 하나의 노드에서 해당 볼륨이 읽기-쓰기로 마운트될 수 있다.
ReadWriteMany 다수의 노두에서 해당 볼륨이 읽기 전용으로 마운트될 수 있다.
ReadWriteOncePod 볼륨이 단일 파드에서 읽기-쓰기로 마운트될 수 있다.

PV/PVC의 처리 흐름은 다음과 같다.

1. 최초 Admin 이 PV 를 만들어 둔다.
2. 사용자 (User) 가 PVC 를 만든다.
3. k8s 가 PVC 내용에 맞는 적정한 Volume 에 연결 해준다.
4. 이후 Pod 생성시 PVC 를 사용한다.

PersistentVolume 구성 예시

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-04
  labels:
    pv: pv-04
spec:
  capacity:
    storage: 2G
  accessModes:
  - ReadWriteOnce
  local:
    path: /node-v
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - {key: kubernetes.io/hostname, operator: In, values: [k8s-node1]}

PersistentVolumeClaim 구성 예시

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-04
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2G
  storageClassName: ""
  selector:
    matchLabels:
      pv: pv-04

쿠버네티스의 Volume(emptyDir, hostPath, PV/PVC)에 대하여 알아보았습니다.

참고

더보기