POD는 Stateless 상태로 관리되어야 한다.
POD는 언제든 Down 될 수 있는 자원이기 때문에 POD 외부에 볼륨을 마운트 해놓아야 한다.
Volume은 Storage의 추상화 개념으로 컨테이너는 POD에 바인딩 되는 볼륨을 마운트하고, 마치 로컬 스토리지에 있는 것처럼 스토리지에 접근한다.
POD가 Node에 할당될 때 생성되고, POD가 삭제될 때 같이 삭제되는 임시 볼륨이다.
동일한 POD에서 실행되는 컨테이너 간에 파일을 공유할 때 사용한다.
사용할 미디어도 지정할 수 있는데 기본값은 Disk고, 빠른 연산을 위해 Memory를 미디어로 사용할 수도 있다.
volumes:
- name: html
emptyDir: {}
---
volumes:
- name: html
emptyDir:
medium: Memory
POD가 Host Node의 File System에 있는 파일이나 디렉토리의 볼륨을 마운트한다.
같은 Node에서 동작하는 POD들은 볼륨을 공유해 같은 파일을 바라볼 수 있다.
배포방식이 DaemonSet 인 경우에 사용한다.
생략 : hostPath 볼륨은 마운트 하기 전에 아무런 검사도 수행되지 않는다.
DirectoryOrCreate
: 주어진 경로에 아무것도 없다면, 필요에 따라 kubelet의 소유권, 권한을 0755로 설정한 빈 디렉토리를 생성
Directory
: 주어진 경로에 디렉토리가 있어야 함
FileOrCreate
: 주어진 경로에 아무것도 없다면, 필요에 따라 kubelet의 소유권, 권한을 0755 로 설정한 file을 생성
File
: 주어진 경로에 파일이 있어야 함
Socket
: 주어진 경로에 UNIX 소켓이 있어야 함
CharDevice
: 주어진 경로에 문자 디바이스가 있어야 함 BlockDevice : 주어진 경로에 블록 디바이스가 있어야 함
...
volumes:
- name: html
hostPath:
- path: /hostdir_or_file
- type: FileOrCreate
여러 POD들이 동일 데이터를 참조한다.
영구 저장소의 의미로 K8S의 Shared Disk
를 POD 볼륨으로 사용한다.
awsEBS
gkePersistentDisk
NFS Volume
etc...
# GKE Persistent Disk 생성
gcloud compute disks create <DISK_NAME> --size <DISK_SIZE> --zone <VALUE>
# POD Mountain
apiVersion: v1
kind: Pod
metadata:
name: gce-volume-pod
spec:
containers:
- image: nginx
name: web
volumeMounts:
- name: webdata
mountPath: /container/dir
volumes:
- name: webdata
gcePersisstenDisk:
pdName: persistentdisk
fsType: ext4
우선 이 볼륨마운팅은 제한이 많이 존재한다.
POD가 실행중인 Node는 EC2 인스턴스여야 하며, EBS 볼륨과 같은 가용영역에 존재해야 한다.
따라서 분산 Node 클러스터 환경에서 POD 를 특정 노드에 고정적으로 배포하는 경우가 아닌 이상 추천하지 않는 볼륨 타입이다.
# EBS 볼륨 생성
aws ec2 create-volume --availability-zone <VALUE> --size <DISK_SIZE> --volume-
type <VALUE>
# POD Mountain
apiVersion: v1
kind: Pod
metadata:
name: ebs-volume-pod
spec:
containers:
- image: nginx
name: web
volumeMounts:
- name: webdata
mountPath: /container/dir
volumes:
- name: webdata
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4
클러스터가 자체 서버 집합에서 실행되는 경우 외부 스토리지를 마운트하기 위해 스토리지 서버를 지정할 수 있다.
volumes:
- name: webdata
nfs:
server: nfs.server.name
path: /share/dir/path
애플리케이션 개발자가 스토리지 운영 기술까지 모두 알고 애플리케이션을 운영한다는것은 사실 상 쉽지 않은 일이다.
그래서 k8s는 스토리지 구성과 애플리케이션 운영을 분리하여 적용할 수 있도록 지원한다.
아키텍처 관리자가 PersistentVolume(PV)
를 미리 생성해 마운트 가능한 볼륨을 생성해놓는다.
어플리케이션 운영자는 PersistentVolumeClain(PVC)
를 통해 POD를 배포하며 사용 가능한 PV가 있을 때 비로소 POD가 배포되게 된다.
이러한 PV와 PVC는 K8S의 Persistent Volume Controller
에 의해 관리된다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: <pv-name>
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: <storageClassName>
csi:
driver: efs.csi.aws.com
volumeHandle: <file-system-id>
Retain
: 삭제하지 않고, PV의 내용을 유지한다.수동으로 회수가 필요한 볼륨 운영 시 필요
Recycle
: 재사용이 가능. 재사용 시 데이터의 내용을 자동으로 rm -rf로 삭제한다
Delete
: 볼륨의 사용이 끝나면, 해당 볼륨 내용이 삭제됨(AWS_EBS, GCE_PD, Azure DISK 등)
ReadWriteOnce(RWO)
: 단일 노드에서 읽기/쓰기 마운트 가능 ReadOnlyMany(ROX)
: 다수 노드에서 읽기 전용으로 마운트 가능 ReadWriteMany(RWX)
: 다수 노드에서 읽기/쓰기로 마운트 가능Pod에 바인딩된 PersistentVolumeClaim을 삭제해 릴리즈 될 때까지 다른 사용자는 동일한 PersistentVolume을 사용할 수 없다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: <pvc-name>
spec:
accessModes:
- ReadWriteMany
storageClassName: <storageClassName>
resources:
requests:
storage: 2Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: label-name
labels:
app: label-name
spec:
replicas: 1
selector:
matchLabels:
app: label-name
template:
metadata:
labels:
app: label-name
spec:
containers:
- name: container-name
image: <image-name>
ports:
- containerPort: 9092
volumeMounts:
- name: volume-name
mountPath: /var
volumes:
- name: volume-name
persistentVolumeClaim:
claimName: <pvc-name>