[K8S] Volume - emptyDir, HostPath (Deep dive)

앙금빵·2021년 10월 24일
0

쿠버네티스 (k8s)

목록 보기
2/2
post-thumbnail

블로그 이전 안내

더 높은 가독성과 고품질의 글을 작성하기 위해 티스토리로 이전하였습니다.
https://anggeum.tistory.com/entry/Kubernetes-Volume-Deep-Dive

개요

  • Pod는 내부에 프로세스가 실행되고 CPU, RAM, 네트워크 인터페이스 등의 리소스를 공유하는 논리적 호스트와 유사하다.
  • Pod 내부각 컨테이너는 고유하게 분리된 파일시스템을 가진다.
    (파일시스템은 컨테이너 이미지에서 제공되기 때문이다.)

특정 Scenario에서는 물리 머신에서 Process를 다시 시작하는 것과 같이 새로운 컨테이너가 이전에 종료된 위치에서 계속되기를 원할 수 있다.

즉, Stateful한 Application 경우(Pod, Deployment) 데이터를 영속적으로 저장하기 위한 방법이 필요하다.

Storage Volume

쿠버네티스는 Storage Volume을 정의하는 방법으로 이 기능을 제공한다.

Storage Volume은 Pod와 같은 최상위 리소스는 아니지만 Pod의 일부분으로 정의되며 Pod와 동일한 Lifecycle을 가진다.

즉, 파드가 시작되면 Volume이 생성되고, 파드가 삭제되면 볼륨이 삭제된다는 것을 의미한다.

이를 통해 생성되는 새로운 컨테이너는 이전 컨테이너가 볼륨에 기록한 모든 파일들을 볼 수 있다. 또한 파드가 여러 개의 컨테이너를 가진 경우 모든 컨테이너가 볼륨을 공유할 수 있다.

요약

  • 쿠버네티스 Volume은 Pod의 구성 요소로 컨테이너와 동일하게 Pod Spec에서 정의된다.
  • 볼륨은 쿠버네티스 오브젝트가 아니므로 자체적으로 생성, 삭제될 수 없다.
  • 볼륨은 Pod의 모든 컨테이너에서 사용 가능하지만 접근하려는 컨테이너에서 각각 마운트 되어야 한다. 각 컨테이너에서 파이시스템의 어느 경로에나 볼륨을 마운트할 수 있다.

Local Volume: hostPath, emptyDir

로컬 볼륨

자주 사용되는 Volume종류는 아니다.

  • emptyDir: ephemeral Data를 저장하는데 사용되는 간단한 empty 디렉터리이다.
  • hostPath: Node 파일시스템을 Pod의 디렉터리로 마운트하는데 사용한다.

emptyDir Volume


Pod의 컨테이너 간에 Volume을 공유하기 위해 사용하며 컨테이너 간 파일을 공유할 때 유용하다.

Pod가 실행되는 도중에만 필요한 휘발성 데이터를 각 컨테이너가 함께 사용할 수 있도록 임시 저장 공간을 생성한다.

  • emptydir-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: emptydir-pod
    spec:
      containers:
    
    # 첫 컨테이너는 content-creator 이라고 이름 짓고 alicek106/alpine-wget:latest 이미지를 실행
      - name: content-creator
        image: alicek106/alpine-wget:latest
        args: ["tail", "-f", "/dev/null"]
    
    # my-emptydir-volume 이라는 볼륨을 컨테이너의 /var/htdocs에 마운트한다
    # 마운트 = 디스크 파티션을 특정한 위치(디렉토리)에 연결시켜주는 과정
        volumeMounts:
        - name: my-emptydir-volume
          mountPath: /data                      # 1. 이 컨테이너가 /data 에 파일을 생성하면
    
    # my-emptydir-volume이라는 볼륨을 컨테이너의 /usr/local/apache2/htdocs/에 마운트한다
      - name: apache-webserver
        image: httpd:2
        volumeMounts:
        - name: my-emptydir-volume
          mountPath: /usr/local/apache2/htdocs/  # 2. 아파치 웹 서버에서 접근 가능합니다.
    
    # my-emptydir-volume 이란 단일 볼륨을 위의 컨테이너 2개에 마운트한다.
      volumes:
        - name: my-emptydir-volume
          emptyDir: {}                             # 포드 내에서 파일을 공유하는 emptyDir

root@k8s-m:~# kubectl apply -f emptydir-pod.yaml
pod/emptydir-pod created

root@k8s-m:~# kubectl exec -it emptydir-pod -c content-creator sh
/ # echo Hello, Kubernetes! >> /data/test.html

root@k8s-m:~# kubectl describe pod emptydir-pod | grep IP
              cni.projectcalico.org/podIP: 172.16.197.4/32
              cni.projectcalico.org/podIPs: 172.16.197.4/32
IP:           172.16.197.4
IPs:

# Pod 안에 있는 모든 컨테이너는 동일한 루프백 네트워크 인터페이스를 가지기에 컨테이너들이 Localhost를 통해 서로 통신할 수 있다.
root@k8s-m:~# kubectl run -i --tty --rm debug --image=alicek106/ubuntu:curl --restart=Never -- curl 172.16.197.4/test.html
Hello, Kubernetes!

HostPath Volume

gitRepo나 emptyDir Volume 은 Pod가 종료되면 삭제되는 반면 HostPath Volume은 그렇지 않다.

HostPath Volume은 호스트의 디렉터리(Node 단위)를 Pod와 공유하여 데이터를 저장한다.

  • hostpath-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: hostpath-pod
    spec:
    
    # my-container이라는 이름의 컨테이너에 /etc/data에 my-hostpath-volume 의 볼륨을 마운트
      containers:
        - name: my-container
          image: busybox
          args: [ "tail", "-f", "/dev/null" ]
          volumeMounts:
          - name: my-hostpath-volume
            mountPath: /etc/data
    
    # /tmp 경로에 마운트
      volumes:
        - name: my-hostpath-volume
          hostPath:
            path: /tmp

# 컨테이너 內 /etc/data 디렉터리에 mydata 이름의 파일 생성
root@k8s-m:~# kubectl exec -it hostpath-pod -- touch /etc/data/mydata

# Pod가 생성된 Workernode로 접속
(admin-k8s:default) root@k8s-m:~# kubectl get po -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
hostpath-pod   1/1     Running   0          17m   172.16.46.7   k8s-w2   <none>           <none>

# 노드에 파일 생성 확인
root@k8s-w2:~# ls /tmp/mydata
/tmp/mydata

HostPathvolume을 데이터 저장소로 채택하기에는 적합하지 않다.

  • 특정 노드의 FileSystem에 저장되므로 파드가 다른 노드로 Scheduling이 되면 더 이상 이전 데이터를 볼 수 없다.
  • Pod가 어떤 노드에 Scheduling 되느냐에 따라 민감하기 때문에 일반적인 Pod에 사용하는 것은 좋은 생각이 아니다.
    특수한 경우를 제외한다면 hostPath를 사용하는 것은 보안 및 활용성 측면에서 바람직하지 않다.

참조

kubernetes in-action
시작하세요 도커 쿠버네티스

profile
Cloud 관련 개인 공부 지식들을 기록하는 공간입니다.

0개의 댓글