Kubernetes POD I/O 성능 측정 — fio
현재 사용 중인 Kubernetes POD Disk IO 성능은 어떻게 알 수 있을까?
물리 서버, VM 환경에서 우리는 주로 disk 성능 테스트 툴 fio 사용한다. (물론 대부분은 그냥 memory, disk 등 물리 spec만 좋은 장비 도입하고 제대로 성능 검증도 안 하겠지만)
Kubernetes 환경에서도 동일하게, POD 실행하고 매번 fio 설치하여 검증하면 된다. 하지만 좀 더 시스템 자동화, 재사용 관점에서 접근하면 fio 가 설치된 이미지를 사용하고 fio 실행 스크립트는 configMap, 병렬 작업 실행을 위하여 statefulset 사용 하는게 낫다.
먼저, StatefuleSet YAML 파일이다.
- fio 설치된 이미지 사용 (joshuarobinson/fio:3.19
- configMap, fio-job-config 사용
- PVC storageClassName: high 사용
ConfigMap
fio 설정에 대한 설명은 생략 하겠다. ^^
위 예제는 write 100% 인데, read 100% 혹은 70/30 등을 미리 만들어 놓고 fio 실행 파일 옵션만 변경하면서 사용도 가능하다.
이제 kubectl apply 한다.
[spkr@erdia22 fio-kubernetes (sp01:default)]$ k apply -f fio-configs.yamlconfigmap/fio-job-config configured[spkr@erdia22 fio-kubernetes (sp01:default)]$ k apply -f fio_statefulset.yaml
statefulset.apps/fio configured[spkr@erdia22 fio-kubernetes (sp01:default)]$ k exec -it fio-0 -- sh
/ # fio /configs/fio.job --output=randwrite.out(test file 생성을 위하여 약 1분 정도 기다려야 한다.) / # : 16 (f=16): [w(16)][100.0%][w=3038MiB/s][w=778k IOPS][eta 00m:00s]
/ # cat randwrite.out
write: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
...
fio-3.19
Starting 16 processes
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: (groupid=0, jobs=16): err= 0: pid=71: Thu Feb 4 23:26:45 2021
write: IOPS=776k, BW=3032MiB/s (3179MB/s)(355GiB/120001msec); 0 zone resets
slat (usec): min=2, max=8427, avg= 5.79, stdev= 4.93
clat (usec): min=24, max=10781, avg=323.17, stdev=237.90
lat (usec): min=48, max=10788, avg=329.05, stdev=237.92
clat percentiles (usec):
| 1.00th=[ 147], 5.00th=[ 186], 10.00th=[ 208], 20.00th=[ 239],
| 30.00th=[ 262], 40.00th=[ 281], 50.00th=[ 302], 60.00th=[ 326],
| 70.00th=[ 351], 80.00th=[ 383], 90.00th=[ 437], 95.00th=[ 482],
| 99.00th=[ 594], 99.50th=[ 742], 99.90th=[ 4359], 99.95th=[ 6718],
| 99.99th=[ 8455]
bw ( MiB/s): min= 2755, max= 3161, per=100.00%, avg=3036.65, stdev= 3.93, samples=3824
iops : min=705334, max=809450, avg=777381.18, stdev=1005.28, samples=3824
lat (usec) : 50=0.01%, 100=0.05%, 250=24.57%, 500=71.58%, 750=3.32%
lat (usec) : 1000=0.15%
lat (msec) : 2=0.19%, 4=0.05%, 10=0.10%, 20=0.01%
cpu : usr=9.64%, sys=36.99%, ctx=39357425, majf=0, minf=44114
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,93142086,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=16
Run status group 0 (all jobs):
WRITE: bw=3032MiB/s (3179MB/s), 3032MiB/s-3032MiB/s (3179MB/s-3179MB/s), io=355GiB (382GB), run=120001-120001msec
Disk stats (read/write):
nvme10n1: ios=0/93081886, merge=0/46, ticks=0/29260407, in_queue=34335776, util=100.00%
(동시에 여러 POD에서 실행하면 pod 간 성능 비교 및 단일 물리 노드의 최대 성능을 확인 할 수 있다.)
NVMe 디스크 기반 시스템이라 단일 POD 당 Write IOPS 776K 라는 아주 양호한 성능을 보여준다.
위 결과는 NVMe 기반 서버이다. 결과값 검증을 위하여 동일 테스트를 SSD/HDD Hybrid 서버에서 실행 하였다.
^C[spkr@erdia22 fio-kubernetes (ksp01:default)]$ k exec -it fio-0 -- sh
/ # fio /configs/fio.job --output randwrite.out
/ # : 16 (f=16): [w(16)][100.0%][w=4219KiB/s][w=1054 IOPS][eta 00m:00s]
/ # cat randwrite.out
write: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
...
fio-3.19
Starting 16 processes
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)
write: Laying out IO file (1 file / 5120MiB)write: (groupid=0, jobs=16): err= 0: pid=22: Fri Feb 5 00:13:21 2021
write: IOPS=9533, BW=37.2MiB/s (39.1MB/s)(4469MiB/120010msec); 0 zone resets
slat (usec): min=4, max=1073.5k, avg=806.00, stdev=6801.62
clat (usec): min=44, max=1105.8k, avg=26035.03, stdev=34661.44
lat (msec): min=2, max=1105, avg=26.84, stdev=35.18
clat percentiles (msec):
| 1.00th=[ 7], 5.00th=[ 8], 10.00th=[ 9], 20.00th=[ 12],
| 30.00th=[ 14], 40.00th=[ 17], 50.00th=[ 20], 60.00th=[ 25],
| 70.00th=[ 31], 80.00th=[ 37], 90.00th=[ 49], 95.00th=[ 60],
| 99.00th=[ 89], 99.50th=[ 107], 99.90th=[ 167], 99.95th=[ 1028],
| 99.99th=[ 1053]
bw ( KiB/s): min= 5456, max=63250, per=100.00%, avg=38803.06, stdev=627.64, samples=3760
iops : min= 1356, max=15809, avg=9694.01, stdev=156.90, samples=3760
lat (usec) : 50=0.01%, 250=0.01%, 500=0.01%
lat (msec) : 2=0.01%, 4=0.03%, 10=14.64%, 20=37.25%, 50=39.11%
lat (msec) : 100=8.34%, 250=0.55%, 500=0.01%, 2000=0.09%
cpu : usr=0.50%, sys=1.48%, ctx=263044, majf=0, minf=640
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,1144163,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=16Run status group 0 (all jobs):
WRITE: bw=37.2MiB/s (39.1MB/s), 37.2MiB/s-37.2MiB/s (39.1MB/s-39.1MB/s), io=4469MiB (4686MB), run=120010-120010msecDisk stats (read/write):
dm-0: ios=36/1146284, merge=0/0, ticks=787/19971535, in_queue=20359139, util=100.00%, aggrios=36/1146578, aggrmerge=0/139, aggrticks=787/19075636, aggrin_queue=19080790, aggrutil=100.00%
sda: ios=36/1146578, merge=0/139, ticks=787/19075636, in_queue=19080790, util=100.00%
HDD/SSD Hybrid 시스템인데, 10K로 처참하다… (무려 70배 차이) 내 테스트가 잘못 될 수 있는데(여러 요소를 고려하지 않은.) 하나의 포인트로는 받아들일 수 있다. 물론 단순 disk write 테스트라 실제 application 속도와 전혀 다른 이야기이지만.
하고 싶은 말은 디스크 성능 결과는 아니고 항상 재사용성을 고려하여 코드 기반으로 테스트를 해야 된다는 것이다.
참조
https://joshua-robinson.medium.com/storage-benchmarking-with-fio-in-kubernetes-14cf29dc5375
항상 원문이 이 글보다 훨씬 가치있다.