SSD 와 HDD 가 섞여 있는 클러스터에 Viya 4 를 올릴 때, StorageClass 하나로 전부 처리하면 지연 스파이크와 병목이 한곳에 몰린다. 용도별로 티어를 나누는 편이 안전하다. 최소한 nfs-ssd 와 nfs-hdd 두 가지를 만들어 두고 구성 요소별로 지정한다.
| 구성 요소 | 권장 | 이유 |
|---|---|---|
| PostgreSQL(Crunchy) | SSD 기반 스토리지 | fsync 와 지연에 민감하다. PVC 접근 모드는 RWO 만 지원한다 |
| RabbitMQ | 가능하면 로컬 SSD, 어려우면 SSD 기반 | 디스크 I/O 특성에 민감하다 |
| Redis | SSD 기반 | 영속화 기록이 디스크로 간다 |
| Consul · Configuration Server | SSD 기반 | 배포 후 StorageClass 변경 시 데이터 손실 위험이 있으므로 신규 배포에서 정한다 |
| OpenSearch | 로컬 스토리지 | SAS 문서가 NFS 같은 원격 파일시스템에 인덱스를 두지 말라고 명시한다 |
| SASWORK | 노드 로컬 SSD·NVMe | 정렬·조인의 임시 파일이 몰린다 |
| CAS 디스크 캐시 | 노드 로컬 SSD | 성능 경로다. 공유 NFS 는 권장하지 않는다 |
| sasdata(공유 데이터) | NFS. 접근이 잦으면 SSD NFS, 보관 위주면 HDD NFS | 여러 파드가 함께 읽고 쓴다 |
| 사용자 홈 · 리포트 · 공용 파일 | HDD NFS | 지연에 덜 민감하다 |
| 백업 저장소 | 용량 우선이면 HDD NFS, 복구 시간이 중요하면 SSD |
정리하면 상태를 가진 데이터베이스·메시징은 SSD, 공유 파일은 NFS, SASWORK 와 CAS 임시 영역은 로컬 SSD 다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-ssd
provisioner: nfs.csi.k8s.io
mountOptions:
- nfsvers=4.1
- hard
- noatime
- nodiratime
- rsize=1048576
- wsize=1048576
- timeo=600
- retrans=2
리눅스 NFS 클라이언트의 기본 마운트 방식은 hard 다. 명시하지 않아도 hard 로 붙지만, 설정 의도를 남기기 위해 적어 두는 편이 낫다. soft 는 타임아웃 시 I/O 를 오류로 되돌려 데이터 손상 위험이 있으므로 쓰지 않는다. timeo 의 단위는 0.1초이므로 timeo=600 은 60초다.
StorageClass 의 mountOptions 는 PV 가 만들어질 때만 반영된다. 이미 Bound 된 PVC 에는 소급 적용되지 않으므로, 옵션을 바꾸면 해당 PVC 를 쓰는 파드를 다시 띄워 재마운트가 일어나게 해야 한다. 재마운트는 연결을 다시 맺는 것일 뿐이라 데이터가 사라지지는 않는다.
/export *(rw,sync,no_root_squash,no_subtree_check)
메타데이터 성격의 영역(Consul, Catalog)은 sync 로 두고, 캐시성 데이터에만 async 를 검토한다.
[nfsd]
vers4=y
threads=128
sunrpc.tcp_slot_table_entries = 128
sunrpc.max_tcp_slot_table_entries = 128
프로비저너 파드의 리소스가 기본값 그대로면 PVC 가 많을 때 병목이 된다. 최소 2 CPU / 2Gi 정도를 확보한다.
영속 데이터를 NFS PVC 에 두더라도 노드 로컬 디스크는 여전히 쓰인다. 컨테이너 이미지, 쓰기 가능 레이어, 파드 로그, emptyDir, kubelet 관리 영역이 모두 로컬 ephemeral storage 를 소비한다.
| 노드 역할 | 로컬 디스크 |
|---|---|
| stateless 마이크로서비스 | 250~400GB. 고성능 SSD 가 필수는 아니다 |
| stateful(데이터는 NFS PVC) | 300~500GB |
| Compute · SASWORK | 500GB~1TB 이상, SSD·NVMe |
| CAS | 1~2TB SSD·NVMe |
| OpenSearch | 로컬 SSD 별도 검토 |
위 수치는 공식 요구사항이 아니라 운영 경험에서 나온 시작점이다 (확인 필요). 실제 산정은 동시 세션 수와 작업 크기로 다시 계산해야 한다.
디스크가 가득 차면 kubelet 이 파드를 축출하므로, 용량보다 여유 확보와 영역 분리가 더 중요하다.
같은 물리 디스크를 파티션으로 나누면 논리적으로만 분리될 뿐 I/O 경로와 장애 범위는 그대로 공유한다. 디스크를 분리하면 다음이 달라진다.
실무 권장 구조는 다음과 같다.
디스크 1 (OS) /
디스크 2 (SSD) /var/lib/containerd
디스크 3 /var/log
디스크 4 (SSD) SASWORK · CAS 캐시
디스크 5 (HDD/NFS) sasdata
파티션 분리는 최소한의 보호 장치이고, 성능과 안정성 확보는 디스크 분리로 한다.
emptyDir 을 다른 스토리지로 바꾸는 절차.