K8S - Volume

반영환·2023년 9월 16일
0

k8s

목록 보기
8/14
post-thumbnail

K8S - Volume

POD는 Stateless 상태로 관리되어야 한다.
POD는 언제든 Down 될 수 있는 자원이기 때문에 POD 외부에 볼륨을 마운트 해놓아야 한다.
Volume은 Storage의 추상화 개념으로 컨테이너는 POD에 바인딩 되는 볼륨을 마운트하고, 마치 로컬 스토리지에 있는 것처럼 스토리지에 접근한다.

Volume의 종류

emptyDir

POD가 Node에 할당될 때 생성되고, POD가 삭제될 때 같이 삭제되는 임시 볼륨이다.

동일한 POD에서 실행되는 컨테이너 간에 파일을 공유할 때 사용한다.

사용할 미디어도 지정할 수 있는데 기본값은 Disk고, 빠른 연산을 위해 Memory를 미디어로 사용할 수도 있다.

volumes:
- name: html
  emptyDir: {}
  
---
  
volumes:
- name: html
  emptyDir:
  	medium: Memory

hostPath

POD가 Host Node의 File System에 있는 파일이나 디렉토리의 볼륨을 마운트한다.

같은 Node에서 동작하는 POD들은 볼륨을 공유해 같은 파일을 바라볼 수 있다.

배포방식이 DaemonSet 인 경우에 사용한다.

type

  • 생략 : hostPath 볼륨은 마운트 하기 전에 아무런 검사도 수행되지 않는다.

  • DirectoryOrCreate : 주어진 경로에 아무것도 없다면, 필요에 따라 kubelet의 소유권, 권한을 0755로 설정한 빈 디렉토리를 생성

  • Directory : 주어진 경로에 디렉토리가 있어야 함

  • FileOrCreate : 주어진 경로에 아무것도 없다면, 필요에 따라 kubelet의 소유권, 권한을 0755 로 설정한 file을 생성

  • File : 주어진 경로에 파일이 있어야 함

  • Socket : 주어진 경로에 UNIX 소켓이 있어야 함

  • CharDevice : 주어진 경로에 문자 디바이스가 있어야 함 BlockDevice : 주어진 경로에 블록 디바이스가 있어야 함

...
volumes:
- name: html
  hostPath:
    - path: /hostdir_or_file
    - type: FileOrCreate

Persistent Storage

여러 POD들이 동일 데이터를 참조한다.

영구 저장소의 의미로 K8S의 Shared Disk를 POD 볼륨으로 사용한다.

Shared Disk 종류

  • awsEBS

  • gkePersistentDisk

  • NFS Volume

  • etc...

GKE 환경

# 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

EKS 환경 EBS

우선 이 볼륨마운팅은 제한이 많이 존재한다.

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

NFS Volume

클러스터가 자체 서버 집합에서 실행되는 경우 외부 스토리지를 마운트하기 위해 스토리지 서버를 지정할 수 있다.

volumes:
- name: webdata
  nfs:
    server: nfs.server.name
    path: /share/dir/path

Volume의 관리

애플리케이션 개발자가 스토리지 운영 기술까지 모두 알고 애플리케이션을 운영한다는것은 사실 상 쉽지 않은 일이다.

그래서 k8s는 스토리지 구성과 애플리케이션 운영을 분리하여 적용할 수 있도록 지원한다.

아키텍처 관리자가 PersistentVolume(PV) 를 미리 생성해 마운트 가능한 볼륨을 생성해놓는다.

어플리케이션 운영자는 PersistentVolumeClain(PVC)를 통해 POD를 배포하며 사용 가능한 PV가 있을 때 비로소 POD가 배포되게 된다.

이러한 PV와 PVC는 K8S의 Persistent Volume Controller에 의해 관리된다.

PV 생성 (EFS 예시)

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>

persistentVolumeReclaimPolicy

  • Retain : 삭제하지 않고, PV의 내용을 유지한다.수동으로 회수가 필요한 볼륨 운영 시 필요

  • Recycle : 재사용이 가능. 재사용 시 데이터의 내용을 자동으로 rm -rf로 삭제한다

  • Delete : 볼륨의 사용이 끝나면, 해당 볼륨 내용이 삭제됨(AWS_EBS, GCE_PD, Azure DISK 등)

accessModes

  • ReadWriteOnce(RWO) : 단일 노드에서 읽기/쓰기 마운트 가능
  • ReadOnlyMany(ROX) : 다수 노드에서 읽기 전용으로 마운트 가능
  • ReadWriteMany(RWX) : 다수 노드에서 읽기/쓰기로 마운트 가능

PVC 생성 (EFS예시)

Pod에 바인딩된 PersistentVolumeClaim을 삭제해 릴리즈 될 때까지 다른 사용자는 동일한 PersistentVolume을 사용할 수 없다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: <pvc-name>
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: <storageClassName>
  resources:
    requests:
      storage: 2Gi

POD에서 PVC 사용

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>
profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글