공대생 정리노트

6장 - 볼륨(1) 볼륨의 종류 본문

Kubernetes/Kubernetes in ACTION

6장 - 볼륨(1) 볼륨의 종류

woojinger 2021. 1. 6. 23:45

스토리지 볼륨은 파드와 같은 최상위 리소스는 아니지만 파드와 동일한 라이프 사이클을 가진다.

따라서 컨테이너를 다시 사작하더라도 볼륨의 컨텐츠는 지속된다.

 

볼륨 소개

볼륨은 파드 구성 요소로 파드 스펙에서 정의된다. 쿠버네티스 오브젝트가 아니므로 자체적으로 생성, 삭제 될 수 없고 파드의 모든 컨테이너에서 사용 가능하지만 접근하려는 컨테이너에서 각각 마운트가 되야 한다.

볼륨의 유형으로는 emptyDir, gitRepo, hostPath 등이 있다.

emptyDir 볼륨

볼륨이 빈 디렉터리로 시작한다.

동일 파드에서 실행 중인 컨테이너 간 파일을 공유할 때 유용하다.

apiVersion: v1
kind: Pod
metadata:
  name: fortune
spec:
  containers:
  - image: luksa/fortune
    name: html-generator	## 첫번째 컨테이너는 luksa/fortune 이미지 실행
    volumeMounts:
    - name: html
      mountPath: /var/htdocs  ## html이란 이름의 볼륨을 컨테이너의 /var/htdocs에 마운트
  - image: nginx:alpine
    name: web-server  ## 두번째 컨테이너는 nginx:alpine 이미지 실행
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true  ## html 볼륨을 /usr/share/nginx/html에 읽기 전용으로 마운트
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}  ## html이란 단일 emptyDir 볼륨을 마운트

위는 책에 나온 예제로 동일한 볼륨을 공유하는 컨테이너 두 개가 있는 파드이다.

emptyDir은 파드를 호스팅하는 워커 노드의 실제 디스크에 생성되므로 노드 디스크가 어떤 유형인지에 따라 성능이 결정된다.

emptyDir을 메모리를 사용하는 tmpfs 파일 시스템으로 생성할 수 있다.

volumes:
  - name: html
    emptyDir:
      medium: Memory  # emptyDir 파일들이 메모리에 저장

gitRepo 볼륨

기본적으로 emptyDir 볼륨이나 파드가 시작되면 컨테이너 시작 전에 깃 repository를 복제하고 특정 revision을 체크아웃해 데이터로 채운다.

gitRepo 볼륨이 생성된 후에는 참조하는 repository와 동기화하지 않는다. 그러나 replicationController가 관리할 때 파드가 새로 생성되면 최신 커밋을 포함한다.

...
volumes:
- name: html
  gitRepo:
    repository: https://github.com/..  ## git repository 복제
    revision: master  ## master branch checkout
    directory: .  ## 볼륨의 root 디렉토리에 repository 복제

볼륨이 생성되는 시점에 쿠버네티스는 master 브랜치가 가리키는 버전을 체크아웃한다.

 

사이드카 컨테이너

볼륨을 git repository와 항상 동기화하려 추가 프로세스를 실행할 수 있다. 이때 깃 동기화 프로세스는 주 컨테이너를 보완하는 사이드카 컨테이너에서 실행되야 한다. 새로운 로직을 메인 어플리케이션에 밀어 넣어 복잡성을 증가시키는 대신 사이드카를 추가해 기존 이미지 재사용성을 높인다. 

도커 허브에 "git sync"를 검색해보면 로컬 디렉토리를 git repository와 동기화되도록 하는 컨테이너 이미지가 많다. 

또한 private git repository를 복제하려면 사이드카 컨테이너가 필요하다.

hostPath 볼륨

대부분의 파드는 호스트 노드를 인식하지 못한다. 그러나 특정 시스템 레벨의 파드(데몬셋으로 관리되는)가 노드의 파일을 읽거나 파일시스템을 통해 노드 디바이스를 접근하기 위해 노드 파일시스템을 사용해야 한다. 이를 hostPath 볼륨이 가능하게 한다.

hostPath 볼륨은 노드 파일시스템의 특정 파일이나 디렉터리를 가리킨다.

즉, 워커 노드의 특정 파일이나 디렉토리를 컨테이너 파일시스템에 마운트한다. 따라서 persistent storage 중 하나로 파드가 종료되도 삭제되지 않는다.이전 파드와 동일한 노드와 스케줄링 된다는 조건에서 새로운 파드는 이전 파드가 남긴 모든 항목을 볼 수 있다.

특정 노드의 파일시스템에 콘텐츠가 저장되므로 파드가 다른 노드로 스케줄링 되면 더이상 이전 데이터를 볼 수 없다.

Persistent Storage

어떤 클러스터 노드에서도 접근이 필요한 경우 사용된다.

예제로 MongoDB를 실행하는 파드를 생각해보자. 적절한 유형의 볼륨을 파드에 추가하고 MongoDB 컨테이너에 마운트 해야한다.

먼저 persistent Disk를 생성해야 한다. 기반 스토리지를 provision하는 것이다. 구글 쿠버네티스 엔진에서 실행중이라면 GCE persistent Disk 볼륨을, AWS EC2에서 실행중이라면 awsElasticBlockStore 등을 사용할 수 있다.

책에서는 예제로 GCE persistent Disk를 생성하고 이를 사용하였다.

apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  volumes:
  - name: mongodb-data
    gcePersistentDisk:  ## 볼륨의 유형은 GCE Persistent Disk
      pdName: mongodb  ## persistent disk 이름은 이전에 생성한 persistent disk와 같아야함
      fsType: ext4  ## 파일시스템 유형. 리눅스 파일시스템 유형 중 하나
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db  ## MongoDB가 데이터를 저장할 경로
    ports:
    - containerPort: 27017
      protocol: TCP

파드는 생성한 GCE persistentdisk를 기반으로 한 단일 볼륨과 단일 컨테이너로 이뤄진다.

PersistentVolume과 PersistentVolumeClaim

파드의 볼륨이 실제 기반 인프라를 참조하는 것은 쿠버네티스가 추구하는 바가 아니다.

이를 개선하는 방법이 Persistent Volume과 PersistentVolumeClaim이다. 

이는 다음 게시글에서 더 자세히 알아보겠다.

Comments