임시 볼륨
임시 볼륨 (Ephemeral Volumes)
이 문서는 Kubernetes의 임시(ephemeral) 볼륨을 설명해요. 볼륨, 특히 PersistentVolumeClaim과 PersistentVolume에 익숙해지는 것이 권장돼요.
일부 애플리케이션은 추가 스토리지가 필요하지만, 그 데이터가 재시작 후에도 영구적으로 저장되는지는 신경 쓰지 않아요. 예를 들어 캐싱 서비스는 종종 메모리 크기에 제한을 받고, 덜 자주 사용되는 데이터를 메모리보다 느린 스토리지로 옮겨도 전체 성능에 미치는 영향이 작아요.
다른 애플리케이션은 구성 데이터나 시크릿 키 같은 읽기 전용 입력 데이터가 파일에 존재할 것으로 기대해요.
임시 볼륨은 이런 사용 사례를 위해 설계되었어요. 볼륨이 파드의 수명을 따르고 파드와 함께 생성·삭제되므로, 어떤 영구 볼륨이 가용한 곳에 제한되지 않고 파드를 중지하고 재시작할 수 있어요.
임시 볼륨은 Pod 사양에 인라인으로 지정되므로, 애플리케이션 배포와 관리가 단순해져요.
출처: 문서
본문
임시 볼륨의 종류
Kubernetes는 다양한 목적의 여러 가지 임시 볼륨을 지원해요.
- emptyDir: Pod 시작 시 비어 있으며, 스토리지를 kubelet 기본 디렉터리(보통 루트 디스크)나 RAM에서 로컬로 가져와요.
- configMap, downwardAPI, secret: 다양한 종류의 Kubernetes 데이터를 파드에 주입해요.
- image: 컨테이너 이미지 파일이나 아티팩트를 파드에 직접 마운트하게 해줘요.
- CSI 임시 볼륨: 이전 볼륨 종류와 비슷하지만, 이 기능을 특별히 지원하는 특수 CSI 드라이버가 제공해요.
- 일반 임시 볼륨: 영구 볼륨도 지원하는 모든 스토리지 드라이버가 제공할 수 있어요.
emptyDir, configMap, downwardAPI, secret은 로컬 임시 스토리지로 제공돼요. 각 노드의 kubelet이 관리해요.
CSI 임시 볼륨은 서드파티 CSI 스토리지 드라이버가 제공해야 해요.
일반 임시 볼륨은 서드파티 CSI 스토리지 드라이버뿐 아니라 동적 프로비저닝을 지원하는 다른 스토리지 드라이버도 제공할 수 있어요. 일부 CSI 드라이버는 CSI 임시 볼륨 전용으로 작성되어 동적 프로비저닝을 지원하지 않는데, 그런 드라이버는 일반 임시 볼륨에는 사용할 수 없어요.
서드파티 드라이버를 사용하는 이점은 Kubernetes 자체가 지원하지 않는 기능을 제공할 수 있다는 거예요. 예를 들어 kubelet이 관리하는 디스크와 다른 성능 특성을 가진 스토리지나, 다른 데이터를 주입하는 경우죠.
CSI 임시 볼륨
개념적으로 CSI 임시 볼륨은 configMap, downwardAPI, secret 볼륨 유형과 비슷해요. 스토리지가 각 노드에서 로컬로 관리되고, 파드가 노드에 스케줄링된 후 다른 로컬 리소스와 함께 생성돼요. Kubernetes는 이 단계에서는 더 이상 파드 재스케줄링 개념이 없어요. 볼륨 생성이 실패할 가능성이 낮아야 하며, 그렇지 않으면 파드 시작이 막혀요. 특히 이 볼륨들에 대해서는 스토리지 용량 인식 파드 스케줄링이 지원되지 않아요. 또한 이것들은 현재 파드의 스토리지 리소스 사용량 한도에도 포함되지 않아요. kubelet이 스스로 관리하는 스토리지에 대해서만 강제할 수 있기 때문이에요.
다음은 CSI 임시 스토리지를 사용하는 파드의 예시 매니페스트예요.
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: [ "sleep", "1000000" ]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
volumeAttributes는 드라이버가 준비하는 볼륨을 결정해요. 이 속성들은 드라이버마다 특화되어 있고 표준화되어 있지 않아요. 각 CSI 드라이버의 문서를 참고해요.
CSI 드라이버 제한
CSI 임시 볼륨은 사용자가 Pod 사양의 일부로 volumeAttributes를 CSI 드라이버에 직접 제공할 수 있게 해요. 보통 관리자에게만 제한되는 volumeAttributes를 허용하는 CSI 드라이버는 인라인 임시 볼륨에 사용하기에 적합하지 않아요. 예를 들어 일반적으로 StorageClass에 정의되는 매개변수는 인라인 임시 볼륨 사용을 통해 사용자에게 노출되지 않아야 해요.
Pod 사양 안에서 인라인 볼륨으로 사용이 허용되는 CSI 드라이버를 제한해야 하는 클러스터 관리자는 다음 방법으로 그렇게 할 수 있어요.
- CSIDriver 사양에서
Ephemeral을volumeLifecycleModes에서 제거해, 드라이버가 인라인 임시 볼륨으로 사용되지 못하게 방지 - admission webhook을 사용해 이 드라이버 사용 방식을 제한
일반 임시 볼륨
일반 임시 볼륨은 프로비저닝 후 보통 비어 있는 스크래치 데이터를 위한 파드별 디렉터리를 제공한다는 점에서 emptyDir 볼륨과 비슷해요. 하지만 다음과 같은 추가 기능도 있을 수 있어요.
- 스토리지가 로컬 또는 네트워크 연결일 수 있어요.
- 볼륨이 파드가 초과할 수 없는 고정 크기를 가질 수 있어요.
- 드라이버와 매개변수에 따라 볼륨에 초기 데이터가 있을 수 있어요.
- 드라이버가 지원한다면 볼륨에 대한 일반적인 작업이 지원돼요. 스냅샷, 클로닝, 크기 조정, 스토리지 용량 추적을 포함해요.
예시:
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
command: [ "sleep", "1000000" ]
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
수명주기와 PersistentVolumeClaim
핵심 설계 아이디어는 파드의 볼륨 소스 안에서 볼륨 클레임의 매개변수가 허용된다는 거예요. PersistentVolumeClaim의 라벨, 어노테이션, 전체 필드 집합이 지원돼요. 그런 파드가 생성되면, 임시 볼륨 컨트롤러가 파드와 같은 네임스페이스에 실제 PersistentVolumeClaim 객체를 만들고, 파드가 삭제될 때 PersistentVolumeClaim이 삭제되도록 보장해요.
이것은 볼륨 바인딩 및/또는 프로비저닝을 트리거하는데, StorageClass가 즉시 볼륨 바인딩을 사용하면 바로, 또는 파드가 노드에 잠정적으로 스케줄링될 때(WaitForFirstConsumer 볼륨 바인딩 모드) 진행돼요. 후자는 일반 임시 볼륨에 권장돼요. 스케줄러가 파드에 적합한 노드를 자유롭게 선택할 수 있기 때문이에요. 즉시 바인딩을 사용하면 스케줄러는 볼륨이 가용해지면 그 볼륨에 접근할 수 있는 노드를 선택해야 해요.
리소스 소유권 측면에서, 일반 임시 스토리지를 가진 파드는 그 임시 스토리지를 제공하는 PersistentVolumeClaim의 소유자예요. 파드가 삭제되면 Kubernetes 가비지 컬렉터가 PVC를 삭제하는데, 보통 스토리지 클래스의 기본 회수(reclaim) 정책이 볼륨을 삭제하는 것이므로 이는 볼륨 삭제를 트리거해요. retain 회수 정책을 가진 StorageClass로 준임시(quasi-ephemeral) 로컬 스토리지를 만들 수 있어요. 스토리지가 파드보다 오래 지속되고, 이 경우 볼륨 정리를 별도로 해야 한다는 점을 명심해야 해요.
이 PVC들이 존재하는 동안에는 다른 PVC처럼 사용할 수 있어요. 특히 볼륨 클로닝이나 스냅샷의 데이터 소스로 참조될 수 있어요. PVC 객체는 볼륨의 현재 상태도 보유해요.
PersistentVolumeClaim 이름 정하기
자동으로 생성되는 PVC의 이름은 결정적이에요. 이름은 가운데 하이픈(-)으로 파드 이름과 볼륨 이름을 조합한 거예요. 위 예시에서 PVC 이름은 my-app-scratch-volume이 될 거예요. 이 결정적 이름 지정 덕분에 PVC 이름을 알면 그렇게 검색하지 않아도 되므로 PVC와 상호작용하기 쉬워져요.
결정적 이름 지정은 서로 다른 파드 사이에 잠재적 충돌을 일으키기도 해요. (볼륨 scratch와 파드 pod-a와, 이름 pod와 볼륨 a-scratch를 가진 다른 파드는 둘 다 같은 PVC 이름 pod-a-scratch로 끝나요.) 파드와 수동 생성된 PVC 사이에도 충돌이 있을 수 있어요.
이런 충돌은 감지돼요. PVC는 그것이 파드를 위해 생성된 경우에만 임시 볼륨에 사용돼요. 이 확인은 소유권 관계에 기반해요. 기존 PVC는 덮어쓰거나 수정되지 않아요. 하지만 올바른 PVC가 없으면 파드가 시작될 수 없으므로 이것은 충돌을 해결하지 않아요.
보안 (Security)
일반 임시 볼륨을 사용하면 사용자가 PVC를 직접 만들 권한이 없더라도, 파드를 만들 수 있다면 간접적으로 PVC를 만들 수 있어요. 클러스터 관리자는 이를 인지해야 해요. 이것이 보안 모델에 맞지 않는다면, 일반 임시 볼륨이 있는 파드 같은 객체를 거부하는 admission webhook을 사용해야 해요.
PVC에 대한 일반 네임스페이스 쿼터는 여전히 적용되므로, 사용자가 이 새 메커니즘을 사용하도록 허용되어 있어도 다른 정책을 우회하는 데 사용할 수 없어요.
다음 단계
kubelet이 관리하는 임시 볼륨 — 로컬 임시 스토리지 참고.
CSI 임시 볼륨
- 설계에 대한 더 많은 정보는 Ephemeral Inline CSI volumes KEP 참고.
- 이 기능의 추가 개발에 대한 더 많은 정보는 기능 추적 이슈 #596 참고.
일반 임시 볼륨
- 설계에 대한 더 많은 정보는 Generic ephemeral inline volumes KEP 참고.