쿠버네티스/이론

쿠버네티스 Volume 이란?

황동리 2024. 11. 11. 16:37
반응형

쿠버네티스 Volume 이란?

Pod가 생성되고 삭제되는 동안 데이터를 유지할 수 있도록 해주는 리소스 입니다.

기본적으로 컨테이너에서 비휘발성 스토리지를 사용하지 않기 때문에, Pod가 삭제되면 컨테이너 안에 있는 데이터도 같이 삭제가 됩니다.

이러한 문제를 해결하기 위해 사용되는 것이 Volume 입니다.

 

볼륨은 파드의 모든 컨테이너에서 사용 가능하지만 접근하려는 컨테이너에서 각각 마운트 되어야 합니다.

 

Yaml 파일을 작성 해보면서 좀 더 자세히 알아보겠습니다.


Volume 유형

  • emptyDir: 일시적인 데이터를 저장할 때 사용되는 디렉터리 입니다.
    POD가 삭제될 때 함께 삭제됩니다.
  • gitRepo: 기본적으로 emptyDir 볼륨과 같지만, POD가 시작되면 Git 레포지터리에 있는 내용들을 복제하여 사용할 수 있습니다.
  • hostPath: 주로 파드가 생성되는 워커 노드의 파일 시스템의 디렉터리를 파드에 마운트 해서 사용됩니다.
  • nfs: NFS(네트워크 파일 시스템)을 사용하여 파드에 마운트 하여 사용합니다.

이제 Volume이 어떻게 사용되는지 Yaml 파일 예시를 통해 알아보도록 하겠습니다.

 


emptyDir

emptyDir 볼륨은 Pod의 라이프사이클 동안에만 존재합니다. Pod가 삭제되거나 재시작될 때,

 

emptyDir 볼륨안에 있는 내용은 모두 사라집니다.

 

emptyDir 볼륨은 spec.volumes 섹션에 정의를 하고, volumeMounts로 마운트하여 사용합니다.

 

실습을 통해 좀 더 자세히 알아보도록 하겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: fortune
spec:
  containers:
  - image: luksa/fortune
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}


위의 내용대로 POD를 생성하면, 두개의 컨테이너가 하나의 Volume을 공유하는 파드가 생성이 됩니다.

그리고 파드가 삭제되면 volume 안에 있는 내용들도 삭제가 됩니다.

각 컨테이너에 대해 설명을 해보자면,

  • luksa/fortune 이미지로 생성하는 컨테이너는 무작위로 index.html 파일을 계속 생성하는 컨테이너
  • nginx:alpine 이미지로 생성하는 컨테이너는 웹 서버로 사용할 컨테이너

그리고 두 컨테이너가 공유할 volume 타입을 emptyDir로 설정해줍니다.

이렇게 POD를 생성하면, html-generator 컨테이너에서 index.html 파일을 무작위로 계속 생성하고 web-server 컨테이너에서 생성된 index.html 내용을 보여줍니다.

결과를 확인하기 위해서 fortune 파드를 포트포워딩 해서 결과를 확인해보면 아래와 같습니다.

# kubectl port-forward fortune 8080:80



gitRepo

gitRepo 볼륨은 기본적으로 emptyDir와 동일한 볼륨입니다.

 

다만, gitRepo 볼륨으로 생성을 하면, Git 레포지터리에 있는 브랜치의 디렉터리를 볼륨에서 사용할 수 있습니다.

 

실습을 통해 좀 더 자세히 알아보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: gitrepo-volume-pod
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    gitRepo:
      repository: https://github.com/luksa/kubia-website-example.git
      revision: master
      directory: .


웹 서버로 사용할 nginx 이미지로 컨테이너를 정의해주고 mountPath에 gitRepo 볼륨을 사용해줍니다.

gitRepo 볼륨에 대해 좀 더 설명하자면,

gitRepo:
	  # git 레포지토리의 주소
      repository: https://github.com/luksa/kubia-website-example.git
      # 레포지토리의 브랜치 주소
      revision: master
      # 해당 브랜치의 디렉터리 위치 정의
      directory: .


그러면, gitRepo 주소의 브랜치에 있는 내용들을 해당 mountPath에서 사용할 수 있습니다.

위 yaml 파일의 내용대로 POD를 생성하고 서비스를 LoadBalancer 타입으로 노출 시켜준 후, 결과를 확인하면 아래
와 같습니다.

 

 

gitRepo 볼륨의 단점으로는,

 

레포지토리에 변경을 푸시할 때 마다 파드를 삭제하고 다시 시작해주어야 합니다.



hostPath

hostPath 볼륨 방식은 노드의 특정 디렉터리 Path를

 

파드의 특정 디렉터리 Path와 연결하여 사용 할 수 있도록 해줍니다.

 

앞서 소개 했던 emptyDir 이나 gitRepo는 파드가 사라지면 볼륨도 같이 사라지지만,

 

hostPath 볼륨은 파드가 사라져도 hostPath로 지정해둔 디렉터리 내 파일들은 사라지지 않습니다.

실습을 통해 좀 더 자세히 알아보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  volumes:
  - name: mongodb-data
    hostPath:
      path: /tmp/mongodb # 워커 노드에서 사용할 디렉터리 정의
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db # 파드에서 저장할 데이터 디렉터리 정의
    ports:
    - containerPort: 27017
      protocol: TCP


hostPath에서 정의한 디렉터리는 워커 노드에서 생성을 해주어야 합니다.

해당 yaml 파일의 내용대로 생성한 결과를 확인해보면 아래와 같습니다.

우선 워커 노드(node4)에 /tmp/mongodb 디렉터리를 생성 해줍니다.


그리고 파드가 정상적으로 생성되었는지 확인 해줍니다.


hostPath에 정의한 디렉터리를 워커노드(node4)에서 들어가서 확인해줍니다.


hostPath로 볼륨을 정의 해주면, 파드 삭제 후에도 파일들이 사라지지 않습니다.



nfs

nfs 방식은 파드에서 nfs 서버의 원하는 path를 지정하고,

 

해당 path에 원하는 데이터, 파일 등을 저장 할 수 있습니다.

Yaml 파일을 통해 좀 더 자세히 알아보도록 하겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: mongodb-nfs
spec:
  volumes:
  - name: mongodb-data
    nfs:
      server: 1.2.3.4 # nfs 서버 주소
      path: /some/path # nfs 서버에서 정의한 디렉터리
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db # mongob 컨테이너에서 사용할 디렉터리
    ports:
    - containerPort: 27017
      protocol: TCP


nfs 서버의 주소를 정의 해주고, 경로를 정의해서 사용해주면 됩니다.

 


 

참고
Kubernetes-In-Action 책에 있는 내용을 참고 하였습니다.

 

이상 입니다.

반응형