지금까지 쿠버네티스를 이루는 노드, 그 안의 파드, 그 안의 컨테이너에 대해 알고 어떻게 쓰고 생성하는 지를 배웠다.
파드 안에는 여러 개의 컨테이너가 있을 수 있고 격리된 환경을 가지지만 파드 내의 오브젝트는 리소스를 공유하는 논리적 호스트와 유사하다고 하였다.
그러나 파드 내 컨테이너는 서로 각자의 파일 시스템을 가지며, 즉 서로 공유되는 상태가 아니다.
새로운 컨테이너가 시작할 때마다 컨테이너 이미지를 빌드할 때 추가한 파일들을 갖는 컨테이너를 시작한다. 만약 컨테이너는 사라지면 해당 컨테이너가 사용한 파일시스템도 사라진다....
헉! 만약 컨테이너가 사라져도 남아야하는 중요한 정보라면 어떡하지..? 가령 회원 정보 등의 없어지면 안되는 중요한 정보말이다.
이렇게 컨테이너의 소멸과 무관하게 고유하게 남을 수 있는 그리고 서로 다른 컨테이너가 이 정보에 자유롭게 접근하여 사용할 수 있는 기능을 제공해주는 것이 있다.
스토리지 볼륨은 파드와 같은 최상위 리소스는 아니지만 파드의 일부분으로 정의되며 파드와 동일한 라이프사이클을 가진다. 이는 파드가 시작되면 볼륨이 생성되고, 파드가 삭제되면 볼륨이 삭제되는 것을 의미한다.
따라서 볼륨의 콘텐츠는 컨테이너가 다시 시작해도 지속된다.
컨테이너가 다시 시작되면 새로운 컨테이너는 이전 컨테이너가 볼륨에 기록한 모든 파일들을 볼 수 잇다.
또한 파드가 여러개의 컨테이너를 가졌다면 모든 컨테이너가 볼륨을 공유할 수도 있다.
볼륨은 파드의 구성요소로 컨테이너와 동일하게 파드 스펙에서 정의된다.
다만 볼륨은 독립적인 오브젝트가 아니라서 자체적으로 생성, 삭제될 수 없다.
볼륨은 앞서 말했듯 모든 컨테이너에서 사용 가능하지만 접근하려는 컨테이너에서 각각 마운트되어야한다.
볼륨의 종류 또한 다양하다. 그 중 대표적인 몇가지만 알아보자.
- emptyDir
- hostpath
- gitRepo
- 퍼시스턴스 스토리지
일시적인 데이터를 저장하는 데 사용되는 간단한 빈 디렉토리
파드에 실행 중인 애플리케이션은 어떤 파일이든 볼륨에 쓸 수 있다.
볼륨의 라이프사이클이 파드에 묶여 있으므로 파드가 삭제되면 볼륨의 콘텐츠는 사라진다.
👉 동일한 파드에서 실행 중인 컨테이너 간 파일을 공유할 때 유용하다.
spec:
containers:
- name: grafana
image: 이미지명
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 200Mi
ports:
- containerPort: 3000
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-vol
readOnly: true
volumes:
- name: my-vol
emptyDir: {}
워커 노드의 파일시스템을 파드의 디렉토리로 마운트하는 데 사용
노드 파일시스템의 특정 파일이나 디렉터리를 가리킨다.
hostPath는 볼륨의 콘텐츠라 파드가 종료되도 삭제되지 않는다.
spec:
containers:
- name: grafana
image: 이미지
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 200Mi
ports:
- containerPort: 3000
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-vol
volumes:
- name: my-vol
hostPath:
path: /kakao/pv
type: DirectoryOrCreate # 노드에 해당 디렉토리가 없는 경우 생성하는 옵션
깃 레포지터리의 콘텐츠를 체크아웃해 초기화한 볼륨
기본적으로 emptyDir 볼륨이며 파드가 시작되면 깃 레포지터리를 복제하고 특정 리비전은 체크아웃해 데이터로 채운다.
장점 : 매번 파드가 생길 때 웹사이트의 최신 버전을 가져와 서비스한다.
단점 : gitRepo에 변경을 푸시할 때마다 웹사이트의 새 비전을 서비스하기 위해 파드를 삭제해야한다.
프라이빗 깃 리포지토리는 SSH 프로토콜을 통해 복제하는 방식을 지원하지 않으므로 사용이 불가하다.
파드가 삭제되면 볼륨도 삭제된다.
spec:
containers:
- name: grafana
image: 이미지명
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 200Mi
ports:
- containerPort: 3000
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-vol
readOnly: true
volumes:
- name: my-vol
gitRepo:
repository : 깃 주소
revision: master
directory: .
영구 데이터를 허용하는 볼륨
데이터가 사라지지 않고 보존되도록 파드 외부에 볼륨을 생성해 데이터를 보존하기 위해서는, 퍼시스턴트 볼륨(Persistent Volume, PV)과 퍼시스턴트 볼륨 클레임(Persistent Volume Claim, PVC) 을 사용할 수 있습니다.
쿠버네티스는 볼륨을 파드에 직접 할당하지 않고 중간에 PVC를 두어 파드와 파드가 사용할 스토리지를 분리합니다. 사용자가 PV를 직접 구축하더라도 이를 사용하려면 PVC를 경유해야 합니다. PV와 PVC를 연결하는 단계를 바인딩이라고 합니다. PVC에 원하는 스토리지의 용량과 접근 방법을 명시해서 요청하면 이에 맞는 PV가 할당되는 것입니다.
pv : 쿠버네티스 클러스터 외부 스토리지와 연결을 담당하는 리소스
pvc : pv와 파드를 연결하기 위한 리소스
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: default
spec:
selector:
matchLabels:
app: grafana-app
replicas: 1
template:
metadata:
labels:
app: grafana-app
spec:
containers:
- name: grafana
image: 이미지
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 200Mi
ports:
- containerPort: 3000
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-vol
volumes:
- name: my-vol
persistentVolumeClaim:
claimName: my-pvc