[kubnernetes] 디스크 볼륨 타입 유형 비교 (emptyDir vs hostPath)
IT/DevOps

[kubnernetes] 디스크 볼륨 타입 유형 비교 (emptyDir vs hostPath)

반응형

쿠버네티스의 볼륨은 여러가지 유형이 있습니다. 쿠버네티스 공식 홈페이지 https://kubernetes.io/ko/docs/concepts/storage/volumes 에서 오른쪽의(왼쪽아님) 카테고리를 보면 볼륨 유형들이 나열되어있습니다.

확인해보면 로컬 볼륨 부터, 외장 디스크 볼륨(NFS, iSCSI 등), 오픈소스 파일시스템 볼륨 (gluster), 퍼블릭 클라우드 제공 볼륨(AWS, GCP, Azure)들을 지원하고 있습니다.

오늘은 그중 가장 많이 접하게될 emptyDir, hostPath, PV/PVC 를 설명드리도록 하겠습니다.

쿠버네티스의 다양한 볼륨 유형들

awsElasticBlockStore
azureDisk
azureFile
cephfs
cinder
downwardAPI
emptyDir
fc (파이버 채널)
gcePersistentDisk
glusterfs
hostPath
iscsi
local
nfs
persistentVolumeClaim
portworxVolume
projected
quobyte
rbd
secret
storageOS
vsphereVolume

emptyDir

emptyDir 유형은 pod가 생성될때 생성되고, pod가 삭제될때 삭제되는 수명주기를 갖고 있습니다.

pod에 문제가 생겨서 삭제가 되거나 재생성될경우 emptyDir볼륨에 저장되어있는 데이터가 삭제되므로 emptyDir은 파드간 공유해야 하는 휘발성 데이터를 저장하기 위해 사용 해야합니다.

하지만 여기서 주의할점은 수명주기가 컨테이너 단위가 아닌 Pod 단위로 관리 되기때문에 Pod 내부 컨테이너 오류로 삭제나 재시작이 되어도 emptyDir은 삭제 되지 않고 계속 사용이 가능합니다.

emptyDir이라는 이름처럼 처음에는 데이터가 비어있는 상태이기 때문에 지어진 이름이며, emptyDir은 노드에서 할당해주는 디스크에 저장이 됩니다.

emptyDir 예제

멀티 컨테이너 형태로 하나의 pod에 두개의 컨테이너 nginx (app01), redis(app02)를 생성합니다.

nginx의 마운트포인트는 nginx에서 기본으로 생성해주는 /var/log/nginx 경로로 설정하고

redis의 마운트포인트는 /ata-app02 로 설정하며, pod를 실행할때 args필드로 nginx에서 생성하는 logs를 읽도록 설정합니다.

namespace 생성

kubectl create ns test-emptydir

yaml 파일 생성

vi emptydir-exam.yaml

yaml 내용 입력

apiVersion: v1
kind: Pod
metadata:
  name: emptydir-exam
  namespace: test-emptydir
spec:
  containers: 
    - image: nginx 
      name: app01
      volumeMounts:
        - mountPath: /var/log/nginx
          name: empty-volume
    - image: redis
      name: app02
      args: ["tail","-f", "/data-app02/access.log"]
      volumeMounts:
        - mountPath: /data-app02
          name: empty-volume
  volumes:
    - name: empty-volume
      emptyDir: {}

yaml 적용

## yaml 적용
kubectl apply -f emptydir-exam.yaml

emptyDir를 이용하여 pod간 데이터 공유 확인

  • app02에서는 app01에서 발생하는 access log를 잘 읽어오는지 확인합니다.
  • app01에서는 nginx의 accesslog를 인의적으로 생성하기위해 curl으로 접근하여 로그를 쌓도록 합니다.
# 터미널창1에 app02 pod의 로그를 확인하는 명령어 실행
kubectl logs -f emptydir-exam -c app02 -n test-emptydir

## 다른 터미널창2에 app01로 접속하여 nginx의 access 발생 시킴
kubectl exec -it emptydir-exam -c app01 -n test-emptydir -- bash
curl localhost

hostPath

hostPath 유형은 노드의 로컬 디스크의 경로를 Pod에서 마운트해서 사용하는 방식입니다. Docker에서 -v 옵션줘서 Volume 을 연결하는 것과 동일하다고 보시면됩니다.

emptyDir과 가장 큰 차이점은 볼륨의 path를 pod들이 공유하는 방식이기 때문에 파드가 죽어도 노드의 볼륨은 죽지 않는 다는 점입니다.

하지만 여기서 주의할점이 있습니다. 만약 node가 2개이고 node selector같은 설정으로 특정 노드에만 pod가 생성되도록 하지 않았다라고 하면 아래 그림처럼 pod가 다른 노드에 ReCreation될 수 있으며 이 때 hostPath로 설정한 node에 생성되지 않을 수 있기 때문에 해당 볼륨을 사용할 수 없게 됩니다.

이 hostPath는 로컬에 데이터를 쌓아야하는 경우에 유용하게 사용 할 수 있으며 주로 각각의 노드의 metrics 정보를 수집을 해야할 경우가 대표적입니다.

hostPath 예제

멀티 컨테이너 형태로 하나의 pod에 두개의 컨테이너 nginx (app01), redis(app02)를 생성합니다.

nginx의 마운트포인트는 nginx에서 기본으로 생성해주는 /var/log/nginx 경로로 설정하고

redis의 마운트포인트는 /data-app02 로 설정하며, pod를 실행할때 args필드로 nginx에서 생성하는 logs를 읽도록 설정합니다.

namespace 생성

kubectl create ns test-hostpath

yaml 파일 생성

vi hostpath-exam.yaml

yaml 내용 입력

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-exam
  namespace: test-hostpath
spec:
  containers:
    - name: app01
      image: nginx 
      volumeMounts:
        - mountPath: /var/log/nginx
          name: hostpath-volume
    - name: app02
      image: redis
      args: ["tail","-f", "/data-app02/access.log"]
      volumeMounts:
        - mountPath: /data-app02
          name: hostpath-volume
  volumes:
    - name: hostpath-volume
      hostPath:
        path: /  ## 여기서 path는 node에 이미 생성이 되어있는 경로이어야 함
        type: Directory

yaml 적용

## yaml 적용
kubectl apply -f hostpath-exam.yaml

hostPath를 이용하여 pod간 데이터 공유 확인

  • app02에서는 app01에서 발생하는 access log를 잘 읽어오는지 확인합니다.
  • app01에서는 nginx의 accesslog를 인의적으로 생성하기위해 curl으로 접근하여 로그를 쌓도록 합니다.
# 터미널창1에 app02 pod의 로그를 확인하는 명령어 실행
kubectl logs -f hostpath-exam -c app02 -n test-hostpath

## 다른 터미널창2에 app01로 접속하여 nginx의 access 발생 시킴
kubectl exec -it hostpath-exam -c app01 -n test-hostpath -- bash
curl localhost
반응형