CloudNet@팀의 EKS 스터디 AEWS 3기에 작성된 자료를 토대로 작성합니다.
이번 포스팅에서는 최근 제 관심사인 diskio와 cpu 성능의 관계성에 대해서 알아보도록 하겠습니다.
그리고 이를 추적하는 ebpf 툴인 bcc, bpftrace를 활용해보겠습니다.
✅ diskio 와 그로 인한 iowait 발생
실제 운영환경을 운영하다 보면, diskio와 CPU가 서로 인과관계를 가지며 시스템 운영자를 괴롭히는 상황이 많은것 같습니다.
당연히 diskio를 발생시키는 프로세스를 많이 켜놓으면 우리들은 리눅스에서도 버벅이는것을 확인 할수 있습니다.
이는 top,iotop,vmstat등을 통해서 시스템 전반에 어떤 영향이 있는지를 파악하는데는 이견이 없습니다.
하지만, 위에 고전적인 툴들으로는 원인의 가장 근원을 찾기에는 부족할수도 있습니다.
- dd 프로세스를 10개 한번에 동시에 발생시켜서 iowait를 90퍼 이상 높입니다.
- vmstat 확인했을때 10개중에 9개는 대기하고 있는 상태를 유도합니다.
[root@ip-192-168-2-98 ~]# vi dd.sh
dd if=/dev/zero of=/large_files_1 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_2 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_3 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_4 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_5 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_6 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_7 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_8 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_9 bs=1G count=30 oflag=direct &
dd if=/dev/zero of=/large_files_10 bs=1G count=30 oflag=direct &
- top 명령어를 통해 cpu 사용률은 높지 않지만 load average는 높아지는 상황을 유도합니다.
[root@ip-192-168-2-98 ~]# top
top - 14:20:54 up 1:55, 2 users, load average: 8.54, 6.05, 3.02
Tasks: 127 total, 1 running, 80 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.8 us, 1.0 sy, 0.0 ni, 3.6 id, 91.3 wa, 0.0 hi, 0.0 si, 2.3 st
KiB Mem : 3943300 total, 165832 free, 3469348 used, 308120 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 255228 avail Mem
- iotop 명령어를 통해 total DISK WRITE는 그다지 높지 않은것을 확인했습니다.
Total DISK READ : 987.46 K/s | Total DISK WRITE : 122.59 M/s
Actual DISK READ: 987.46 K/s | Actual DISK WRITE: 122.69 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
47457 be/4 65532 472.09 K/s 0.00 B/s 0.00 % 99.99 % coredns -conf /etc/coredns/Corefile
47229 be/4 root 0.00 B/s 31.69 M/s 0.00 % 99.99 % dd if=/dev/zero of=/larg~=1G count=30 oflag=direct
1190 be/4 root 0.00 B/s 0.00 B/s 0.00 % 99.92 % [xfsaild/nvme0n1]
47230 be/4 root 0.00 B/s 43.27 M/s 0.00 % 99.50 % dd if=/dev/zero of=/larg~=1G count=30 oflag=direct
47228 be/4 root 0.00 B/s 47.60 M/s 0.00 % 98.95 % dd if=/dev/zero of=/larg~=1G count=30 oflag=direct
47594 be/4 65532 507.50 K/s 0.00 B/s 0.00 % 93.92 % coredns -conf /etc/coredns/Corefile
38939 be/4 root 0.00 B/s 0.00 B/s 0.00 % 90.49 % [kworker/u4:2+flush-259:0]
36535 be/4 root 7.87 K/s 0.00 B/s 0.00 % 36.14 % containerd
1250 be/4 root 0.00 B/s 23.60 K/s 0.00 % 0.00 % systemd-journald
47616 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % runc --root /run/contain~e1d7be8c2bc73dca4e65b7c76
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --switched-root --system --deserialize 21
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
3 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_gp]
4 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_par_gp]
47621 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % runc --root /run/contain~e1d7be8c2bc73dca4e65b7c76
6 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/0:0H-events_highpri]
47617 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % runc --root /run/contain~e1d7be8c2bc73dca4e65b7c76
8 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [mm_percpu_wq]
9 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_tasks_rude_]
10 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_tasks_trace]
- vmstat을 통해 10개 프로세스중 1개 또는 2개만 Running중이며, 나머지는 모두 대기하고 있는 현상을 확인합니다.
[root@ip-192-168-2-98 ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 9 0 338308 0 170964 0 0 201 6946 468 921 2 1 87 8 2
[root@ip-192-168-2-98 ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 6 0 281948 0 217212 0 0 204 7038 468 921 2 1 87 8 2
[root@ip-192-168-2-98 ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 8 0 281096 0 223084 0 0 204 7125 469 921 2 1 86 8 2
[root@ip-192-168-2-98 ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 10 0 266208 0 235536 0 0 205 7165 469 922 2 1 86 9 2
✅ 이와 같은 현상의 이유는?
- CPU는 사용률에는 io을 기다리는 시간이 포함되어 있다는 사실을 주목 해보겠습니다.
- CPU는 idle 상태가 아닌 모든 상태를 busy 상태로 봅니다. 하지만 세부적으로 그 안을 들여다 본다면 이 안에는 IO를 기다리는 시간들이 포함되어 있습니다. 즉, memory IO , disk IO , network IO를 기다리는 시간도 CPU를 사용하고 있는 시간으로 시스템은 인식한다는 이야기죠.
- 따라서 IO의 급등은 CPU가 기다리는 시간을 증가하게 만들어 CPU 경합을 발생시킵니다. 이를 load average라고 하죠.
- 1973년 이전의 리눅스 버전에서는 load averages는 오직 CPU의 수요에만 초점을 맞췄습니다. runnning 중인 프로세스와 waiting 하는 프로세스를 더한 값에 초점이 맞춰져 있던 것이죠.
1973년 이전에는 로드 애버리지(load average) 를 단순히 CPU demand(수요) 로 간주했으며, 이는 실행 중이거나 실행을 기다리는 프로세스의 수를 평균 내어 계산한 값이었습니다.
RFC 546 (1973년 8월)의 설명에 따르면, 당시 로드 애버리지는 단순히 실행 가능한(runnable) 프로세스의 평균 개수 를 의미했습니다. 여기서 runnable 프로세스란
- 현재 CPU에서 실행 중이거나,
- 실행을 기다리고 있지만 I/O 등의 이유로 블로킹되지 않은 프로세스
를 의미합니다.
즉, 당시 개념에서는 디스크 I/O 대기 등의 이유로 블로킹된(uninterruptible) 프로세스는 로드 애버리지 계산에서 제외 되었습니다.
예를 들어, 단일 CPU 시스템에서 로드 애버리지가 10 이라면,
- 평균적으로 1개의 프로세스가 CPU에서 실행 중 이고,
- 9개의 프로세스가 실행을 기다리고 있음 (디스크 I/O 등으로 블로킹된 것이 아님)
을 의미합니다.
즉, 1973년 당시에는 로드 애버리지를 CPU 사용량(수요)만을 측정하는 지표 로 사용했으며, 디스크 I/O 등의 대기 상태는 포함되지 않았습니다.
The original load averages show only CPU demand: the number of processes running plus those waiting to run. There's a nice description of this in RFC 546 titled "TENEX Load Averages", August 1973:
[1] The TENEX load average is a measure of CPU demand. The load average is an average of the number of runnable processes over a given time period. For example, an hourly load average of 10 would mean that (for a single CPU system) at any time during that hour one could expect to see 1 process running and 9 others ready to run (i.e., not blocked for I/O) waiting for the CPU.
✅ 하지만 최근의 CPU 성능 저하가 IO의 부하로 부터 야기되는 현상..
"The point of "load average" is to arrive at a number relating how busy the system is from a human point of view. TASK_UNINTERRUPTIBLE means (meant?) that the process is waiting for something like a disk read which contributes to system load. A heavily disk-bound system might be extremely sluggish but only have a TASK_RUNNING average of 0.1, which doesn't help anybody."
1973년 당시에는 CPU 속도, 메모리 I/O, 디스크 I/O 간의 성능 차이가 지금처럼 극단적으로 크지 않았기 때문에, 로드 애버리지(load average) 계산에서 I/O 대기 시간을 포함시키지 않아도 큰 문제가 없었을 것입니다.
1. 1970년대 컴퓨터 성능 특성
- 당시의 컴퓨터는 현대적인 개념의 멀티코어 CPU가 아니라 단일 CPU(single CPU) 시스템이었음.
- 프로세스 실행 속도와 메모리 접근 속도 차이가 지금보다 크지 않았음.
- 디스크는 여전히 상대적으로 느렸지만, 주요 작업이 CPU에서 직접 수행되었고, 입출력(I/O) 자체가 시스템 성능을 결정짓는 주요 요인이 아니었음.
2. 로드 애버리지 개념의 단순성
- 당시 시스템에서는 CPU에서 실행 중인 프로세스 + 실행을 기다리는 프로세스만 계산하면 CPU 부하를 직관적으로 파악할 수 있었음.
- 디스크 I/O 대기 시간이 지금처럼 길지 않았고, CPU가 프로세스를 처리하는 속도와 비교했을 때 상대적으로 중요한 변수로 고려되지 않았음.
3. I/O 병목이 중요해진 이유
- 이후 컴퓨터 기술이 발전하면서, CPU 성능은 기하급수적으로 향상되었지만, 디스크 I/O 속도는 상대적으로 느리게 발전했음.
- 특히 1990년대 이후부터 네트워크 및 디스크 입출력이 병목이 되는 경우가 많아지면서, 단순한 CPU 부하 측정보다는 디스크 I/O로 인해 블로킹된(uninterruptible) 프로세스까지 고려하는 것이 필요해짐.
- 그 결과, 현대 Linux에서는 TASK_UNINTERRUPTIBLE 상태의 프로세스(디스크 I/O 대기 중인 프로세스)도 로드 애버리지 계산에 포함하게 됨.
결론
1973년 당시에는 CPU와 메모리, 디스크 간의 성능 차이가 지금보다 적었기 때문에 로드 애버리지를 단순히 CPU에서 실행 가능(runnable)한 프로세스의 개수로만 계산 해도 충분했을 가능성이 높습니다.
하지만 이후 기술 발전으로 인해 디스크 I/O가 병목이 되는 경우가 많아지면서, 현대의 로드 애버리지 개념에는 I/O 대기 시간도 포함시키게 된 것입니다.
하지만 제 경험상에서도 CPU의 성능 저하가 IO의 부하와 연관성이 깊은 이슈들이 운영단계에서 많이 발생되는것 같습니다.
우리가 사용하는 Linux의 성능 저하가 어디서 오는지 알수 있는 방법이 없을까요?
최근 커널에 대한 관심이 서비스 엔지니어들에게 커지면서 그동안 블랙박스 영역이던 커널에 대한 관측 과 가시성이 점차
조금씩 어둠을 걷어가고 있습니다.
그로인해 엔지니어들은 그에 걸맞는 지식과 도구들을 확보해야 하는 상황이고 그래서 다음과 같은 ebpf 도구들이
관심을 받고 있습니다.
거창한 내용은 아니고, ebpf가 무엇인지 소개하고, 간단하게 코드 한줄을 커널에 프로그래밍 하는 예제를 소개하겠습니다.
✅ ebpf를 통해 무엇을 할수 있는가?
- BPF(1992년)을 확장해서 eBPF가 (2014년,Alexei Starovoitov)가 나왔고, eBPF를 다양한 영역에서 (보안,추적,네트워킹,모니터링) 사용하기 시작했습니다.
- 커널 내부에 프로그래밍이 가능하게 됨-> 커널 내에(샌드박스 내에서 프로그래밍 하기 때문에 실제 서버엔 영향을 주지 않음) 자유롭게 프로그래밍 하여 사용할수 있습니다.
- 커널 Space 안에서 사용자가 보지 못하던 블랙박스 영역을 bytecode로 프로그래밍하여 가시성을 확보
- 커널 내부에 개발이 가능한 여러가지 프레임워크들을 개발함 (bcc, bpftrace 등 )
✅ bpftrace 설치
- worker node 접속 후 bpftrace 설치
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo $N1, $N2
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no ec2-user@$N1 hostname
ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no ec2-user@$N2 hostname
ssh ec2-user@$N1
### yum install bpftrace
yum install -y bpftrace
- Chapter 1. bpf traces syscall 리스트 전부 불러오기
# syscalls란
# user spaces와 커널 spaces를 연결해주는 인터페이스
[root@ip-192-168-2-98 ~]# bpftrace -l 'tracepoint:syscalls:sys_enter_*'
tracepoint:syscalls:sys_enter_accept
tracepoint:syscalls:sys_enter_accept4
tracepoint:syscalls:sys_enter_access
tracepoint:syscalls:sys_enter_acct
tracepoint:syscalls:sys_enter_add_key
tracepoint:syscalls:sys_enter_adjtimex
tracepoint:syscalls:sys_enter_alarm
tracepoint:syscalls:sys_enter_arch_prctl
tracepoint:syscalls:sys_enter_bind
tracepoint:syscalls:sys_enter_bpf
tracepoint:syscalls:sys_enter_brk
tracepoint:syscalls:sys_enter_capget
tracepoint:syscalls:sys_enter_capset
tracepoint:syscalls:sys_enter_chdir
tracepoint:syscalls:sys_enter_chmod
tracepoint:syscalls:sys_enter_chown
tracepoint:syscalls:sys_enter_chroot
tracepoint:syscalls:sys_enter_clock_adjtime
tracepoint:syscalls:sys_enter_clock_getres
tracepoint:syscalls:sys_enter_clock_gettime
tracepoint:syscalls:sys_enter_clock_nanosleep
tracepoint:syscalls:sys_enter_clock_settime
tracepoint:syscalls:sys_enter_clone
tracepoint:syscalls:sys_enter_clone3
tracepoint:syscalls:sys_enter_close
tracepoint:syscalls:sys_enter_close_range
tracepoint:syscalls:sys_enter_connect
tracepoint:syscalls:sys_enter_copy_file_range
tracepoint:syscalls:sys_enter_creat
tracepoint:syscalls:sys_enter_delete_module
tracepoint:syscalls:sys_enter_dup
tracepoint:syscalls:sys_enter_dup2
tracepoint:syscalls:sys_enter_dup3
tracepoint:syscalls:sys_enter_epoll_create
tracepoint:syscalls:sys_enter_epoll_create1
tracepoint:syscalls:sys_enter_epoll_ctl
tracepoint:syscalls:sys_enter_epoll_pwait
tracepoint:syscalls:sys_enter_epoll_wait
tracepoint:syscalls:sys_enter_eventfd
tracepoint:syscalls:sys_enter_eventfd2
tracepoint:syscalls:sys_enter_execve
tracepoint:syscalls:sys_enter_execveat
tracepoint:syscalls:sys_enter_exit
tracepoint:syscalls:sys_enter_exit_group
tracepoint:syscalls:sys_enter_faccessat
tracepoint:syscalls:sys_enter_faccessat2
tracepoint:syscalls:sys_enter_fadvise64
tracepoint:syscalls:sys_enter_fallocate
tracepoint:syscalls:sys_enter_fanotify_init
tracepoint:syscalls:sys_enter_fanotify_mark
tracepoint:syscalls:sys_enter_fchdir
tracepoint:syscalls:sys_enter_fchmod
tracepoint:syscalls:sys_enter_fchmodat
tracepoint:syscalls:sys_enter_fchown
tracepoint:syscalls:sys_enter_fchownat
tracepoint:syscalls:sys_enter_fcntl
tracepoint:syscalls:sys_enter_fdatasync
tracepoint:syscalls:sys_enter_fgetxattr
tracepoint:syscalls:sys_enter_finit_module
tracepoint:syscalls:sys_enter_flistxattr
tracepoint:syscalls:sys_enter_flock
tracepoint:syscalls:sys_enter_fork
tracepoint:syscalls:sys_enter_fremovexattr
tracepoint:syscalls:sys_enter_fsconfig
tracepoint:syscalls:sys_enter_fsetxattr
tracepoint:syscalls:sys_enter_fsmount
tracepoint:syscalls:sys_enter_fsopen
tracepoint:syscalls:sys_enter_fspick
tracepoint:syscalls:sys_enter_fstatfs
tracepoint:syscalls:sys_enter_fsync
tracepoint:syscalls:sys_enter_ftruncate
tracepoint:syscalls:sys_enter_futex
tracepoint:syscalls:sys_enter_futimesat
tracepoint:syscalls:sys_enter_get_mempolicy
tracepoint:syscalls:sys_enter_get_robust_list
tracepoint:syscalls:sys_enter_getcpu
tracepoint:syscalls:sys_enter_getcwd
tracepoint:syscalls:sys_enter_getdents
tracepoint:syscalls:sys_enter_getdents64
tracepoint:syscalls:sys_enter_getegid
tracepoint:syscalls:sys_enter_geteuid
tracepoint:syscalls:sys_enter_getgid
tracepoint:syscalls:sys_enter_getgroups
tracepoint:syscalls:sys_enter_getitimer
tracepoint:syscalls:sys_enter_getpeername
tracepoint:syscalls:sys_enter_getpgid
tracepoint:syscalls:sys_enter_getpgrp
tracepoint:syscalls:sys_enter_getpid
tracepoint:syscalls:sys_enter_getppid
tracepoint:syscalls:sys_enter_getpriority
tracepoint:syscalls:sys_enter_getrandom
tracepoint:syscalls:sys_enter_getresgid
tracepoint:syscalls:sys_enter_getresuid
tracepoint:syscalls:sys_enter_getrlimit
tracepoint:syscalls:sys_enter_getrusage
tracepoint:syscalls:sys_enter_getsid
tracepoint:syscalls:sys_enter_getsockname
tracepoint:syscalls:sys_enter_getsockopt
tracepoint:syscalls:sys_enter_gettid
tracepoint:syscalls:sys_enter_gettimeofday
tracepoint:syscalls:sys_enter_getuid
tracepoint:syscalls:sys_enter_getxattr
tracepoint:syscalls:sys_enter_init_module
tracepoint:syscalls:sys_enter_inotify_add_watch
tracepoint:syscalls:sys_enter_inotify_init
tracepoint:syscalls:sys_enter_inotify_init1
tracepoint:syscalls:sys_enter_inotify_rm_watch
tracepoint:syscalls:sys_enter_io_cancel
tracepoint:syscalls:sys_enter_io_destroy
tracepoint:syscalls:sys_enter_io_getevents
tracepoint:syscalls:sys_enter_io_pgetevents
tracepoint:syscalls:sys_enter_io_setup
tracepoint:syscalls:sys_enter_io_submit
tracepoint:syscalls:sys_enter_io_uring_enter
tracepoint:syscalls:sys_enter_io_uring_register
tracepoint:syscalls:sys_enter_io_uring_setup
tracepoint:syscalls:sys_enter_ioctl
tracepoint:syscalls:sys_enter_ioperm
tracepoint:syscalls:sys_enter_iopl
tracepoint:syscalls:sys_enter_ioprio_get
tracepoint:syscalls:sys_enter_ioprio_set
tracepoint:syscalls:sys_enter_kcmp
tracepoint:syscalls:sys_enter_kexec_file_load
tracepoint:syscalls:sys_enter_kexec_load
tracepoint:syscalls:sys_enter_keyctl
tracepoint:syscalls:sys_enter_kill
tracepoint:syscalls:sys_enter_lchown
tracepoint:syscalls:sys_enter_lgetxattr
tracepoint:syscalls:sys_enter_link
tracepoint:syscalls:sys_enter_linkat
tracepoint:syscalls:sys_enter_listen
tracepoint:syscalls:sys_enter_listxattr
tracepoint:syscalls:sys_enter_llistxattr
tracepoint:syscalls:sys_enter_lookup_dcookie
tracepoint:syscalls:sys_enter_lremovexattr
tracepoint:syscalls:sys_enter_lseek
tracepoint:syscalls:sys_enter_lsetxattr
tracepoint:syscalls:sys_enter_madvise
tracepoint:syscalls:sys_enter_mbind
tracepoint:syscalls:sys_enter_membarrier
tracepoint:syscalls:sys_enter_memfd_create
tracepoint:syscalls:sys_enter_migrate_pages
tracepoint:syscalls:sys_enter_mincore
tracepoint:syscalls:sys_enter_mkdir
tracepoint:syscalls:sys_enter_mkdirat
tracepoint:syscalls:sys_enter_mknod
tracepoint:syscalls:sys_enter_mknodat
tracepoint:syscalls:sys_enter_mlock
tracepoint:syscalls:sys_enter_mlock2
tracepoint:syscalls:sys_enter_mlockall
tracepoint:syscalls:sys_enter_mmap
tracepoint:syscalls:sys_enter_mount
tracepoint:syscalls:sys_enter_move_mount
tracepoint:syscalls:sys_enter_move_pages
tracepoint:syscalls:sys_enter_mprotect
tracepoint:syscalls:sys_enter_mq_getsetattr
tracepoint:syscalls:sys_enter_mq_notify
tracepoint:syscalls:sys_enter_mq_open
tracepoint:syscalls:sys_enter_mq_timedreceive
tracepoint:syscalls:sys_enter_mq_timedsend
tracepoint:syscalls:sys_enter_mq_unlink
tracepoint:syscalls:sys_enter_mremap
tracepoint:syscalls:sys_enter_msgctl
tracepoint:syscalls:sys_enter_msgget
tracepoint:syscalls:sys_enter_msgrcv
tracepoint:syscalls:sys_enter_msgsnd
tracepoint:syscalls:sys_enter_msync
tracepoint:syscalls:sys_enter_munlock
tracepoint:syscalls:sys_enter_munlockall
tracepoint:syscalls:sys_enter_munmap
tracepoint:syscalls:sys_enter_name_to_handle_at
tracepoint:syscalls:sys_enter_nanosleep
tracepoint:syscalls:sys_enter_newfstat
tracepoint:syscalls:sys_enter_newfstatat
tracepoint:syscalls:sys_enter_newlstat
tracepoint:syscalls:sys_enter_newstat
tracepoint:syscalls:sys_enter_newuname
tracepoint:syscalls:sys_enter_open
tracepoint:syscalls:sys_enter_open_by_handle_at
tracepoint:syscalls:sys_enter_open_tree
tracepoint:syscalls:sys_enter_openat
tracepoint:syscalls:sys_enter_openat2
tracepoint:syscalls:sys_enter_pause
tracepoint:syscalls:sys_enter_perf_event_open
tracepoint:syscalls:sys_enter_personality
tracepoint:syscalls:sys_enter_pidfd_getfd
tracepoint:syscalls:sys_enter_pidfd_open
tracepoint:syscalls:sys_enter_pidfd_send_signal
tracepoint:syscalls:sys_enter_pipe
tracepoint:syscalls:sys_enter_pipe2
tracepoint:syscalls:sys_enter_pivot_root
tracepoint:syscalls:sys_enter_pkey_alloc
tracepoint:syscalls:sys_enter_pkey_free
tracepoint:syscalls:sys_enter_pkey_mprotect
tracepoint:syscalls:sys_enter_poll
tracepoint:syscalls:sys_enter_ppoll
tracepoint:syscalls:sys_enter_prctl
tracepoint:syscalls:sys_enter_pread64
tracepoint:syscalls:sys_enter_preadv
tracepoint:syscalls:sys_enter_preadv2
tracepoint:syscalls:sys_enter_prlimit64
tracepoint:syscalls:sys_enter_process_madvise
tracepoint:syscalls:sys_enter_process_vm_readv
tracepoint:syscalls:sys_enter_process_vm_writev
tracepoint:syscalls:sys_enter_pselect6
tracepoint:syscalls:sys_enter_ptrace
tracepoint:syscalls:sys_enter_pwrite64
tracepoint:syscalls:sys_enter_pwritev
tracepoint:syscalls:sys_enter_pwritev2
tracepoint:syscalls:sys_enter_quotactl
tracepoint:syscalls:sys_enter_read
tracepoint:syscalls:sys_enter_readahead
tracepoint:syscalls:sys_enter_readlink
tracepoint:syscalls:sys_enter_readlinkat
tracepoint:syscalls:sys_enter_readv
tracepoint:syscalls:sys_enter_reboot
tracepoint:syscalls:sys_enter_recvfrom
tracepoint:syscalls:sys_enter_recvmmsg
tracepoint:syscalls:sys_enter_recvmsg
tracepoint:syscalls:sys_enter_remap_file_pages
tracepoint:syscalls:sys_enter_removexattr
tracepoint:syscalls:sys_enter_rename
tracepoint:syscalls:sys_enter_renameat
tracepoint:syscalls:sys_enter_renameat2
tracepoint:syscalls:sys_enter_request_key
tracepoint:syscalls:sys_enter_restart_syscall
tracepoint:syscalls:sys_enter_rmdir
tracepoint:syscalls:sys_enter_rseq
tracepoint:syscalls:sys_enter_rt_sigaction
tracepoint:syscalls:sys_enter_rt_sigpending
tracepoint:syscalls:sys_enter_rt_sigprocmask
tracepoint:syscalls:sys_enter_rt_sigqueueinfo
tracepoint:syscalls:sys_enter_rt_sigreturn
tracepoint:syscalls:sys_enter_rt_sigsuspend
tracepoint:syscalls:sys_enter_rt_sigtimedwait
tracepoint:syscalls:sys_enter_rt_tgsigqueueinfo
tracepoint:syscalls:sys_enter_sched_get_priority_max
tracepoint:syscalls:sys_enter_sched_get_priority_min
tracepoint:syscalls:sys_enter_sched_getaffinity
tracepoint:syscalls:sys_enter_sched_getattr
tracepoint:syscalls:sys_enter_sched_getparam
tracepoint:syscalls:sys_enter_sched_getscheduler
tracepoint:syscalls:sys_enter_sched_rr_get_interval
tracepoint:syscalls:sys_enter_sched_setaffinity
tracepoint:syscalls:sys_enter_sched_setattr
tracepoint:syscalls:sys_enter_sched_setparam
tracepoint:syscalls:sys_enter_sched_setscheduler
tracepoint:syscalls:sys_enter_sched_yield
tracepoint:syscalls:sys_enter_seccomp
tracepoint:syscalls:sys_enter_select
tracepoint:syscalls:sys_enter_semctl
tracepoint:syscalls:sys_enter_semget
tracepoint:syscalls:sys_enter_semop
tracepoint:syscalls:sys_enter_semtimedop
tracepoint:syscalls:sys_enter_sendfile64
tracepoint:syscalls:sys_enter_sendmmsg
tracepoint:syscalls:sys_enter_sendmsg
tracepoint:syscalls:sys_enter_sendto
tracepoint:syscalls:sys_enter_set_mempolicy
tracepoint:syscalls:sys_enter_set_robust_list
tracepoint:syscalls:sys_enter_set_tid_address
tracepoint:syscalls:sys_enter_setdomainname
tracepoint:syscalls:sys_enter_setfsgid
tracepoint:syscalls:sys_enter_setfsuid
tracepoint:syscalls:sys_enter_setgid
tracepoint:syscalls:sys_enter_setgroups
tracepoint:syscalls:sys_enter_sethostname
tracepoint:syscalls:sys_enter_setitimer
tracepoint:syscalls:sys_enter_setns
tracepoint:syscalls:sys_enter_setpgid
tracepoint:syscalls:sys_enter_setpriority
tracepoint:syscalls:sys_enter_setregid
tracepoint:syscalls:sys_enter_setresgid
tracepoint:syscalls:sys_enter_setresuid
tracepoint:syscalls:sys_enter_setreuid
tracepoint:syscalls:sys_enter_setrlimit
tracepoint:syscalls:sys_enter_setsid
tracepoint:syscalls:sys_enter_setsockopt
tracepoint:syscalls:sys_enter_settimeofday
tracepoint:syscalls:sys_enter_setuid
tracepoint:syscalls:sys_enter_setxattr
tracepoint:syscalls:sys_enter_shmat
tracepoint:syscalls:sys_enter_shmctl
tracepoint:syscalls:sys_enter_shmdt
tracepoint:syscalls:sys_enter_shmget
tracepoint:syscalls:sys_enter_shutdown
tracepoint:syscalls:sys_enter_sigaltstack
tracepoint:syscalls:sys_enter_signalfd
tracepoint:syscalls:sys_enter_signalfd4
tracepoint:syscalls:sys_enter_socket
tracepoint:syscalls:sys_enter_socketpair
tracepoint:syscalls:sys_enter_splice
tracepoint:syscalls:sys_enter_statfs
tracepoint:syscalls:sys_enter_statx
tracepoint:syscalls:sys_enter_swapoff
tracepoint:syscalls:sys_enter_swapon
tracepoint:syscalls:sys_enter_symlink
tracepoint:syscalls:sys_enter_symlinkat
tracepoint:syscalls:sys_enter_sync
tracepoint:syscalls:sys_enter_sync_file_range
tracepoint:syscalls:sys_enter_syncfs
tracepoint:syscalls:sys_enter_sysinfo
tracepoint:syscalls:sys_enter_syslog
tracepoint:syscalls:sys_enter_tee
tracepoint:syscalls:sys_enter_tgkill
tracepoint:syscalls:sys_enter_time
tracepoint:syscalls:sys_enter_timer_create
tracepoint:syscalls:sys_enter_timer_delete
tracepoint:syscalls:sys_enter_timer_getoverrun
tracepoint:syscalls:sys_enter_timer_gettime
tracepoint:syscalls:sys_enter_timer_settime
tracepoint:syscalls:sys_enter_timerfd_create
tracepoint:syscalls:sys_enter_timerfd_gettime
tracepoint:syscalls:sys_enter_timerfd_settime
tracepoint:syscalls:sys_enter_times
tracepoint:syscalls:sys_enter_tkill
tracepoint:syscalls:sys_enter_truncate
tracepoint:syscalls:sys_enter_umask
tracepoint:syscalls:sys_enter_umount
tracepoint:syscalls:sys_enter_unlink
tracepoint:syscalls:sys_enter_unlinkat
tracepoint:syscalls:sys_enter_unshare
tracepoint:syscalls:sys_enter_userfaultfd
tracepoint:syscalls:sys_enter_ustat
tracepoint:syscalls:sys_enter_utime
tracepoint:syscalls:sys_enter_utimensat
tracepoint:syscalls:sys_enter_utimes
tracepoint:syscalls:sys_enter_vfork
tracepoint:syscalls:sys_enter_vhangup
tracepoint:syscalls:sys_enter_vmsplice
tracepoint:syscalls:sys_enter_wait4
tracepoint:syscalls:sys_enter_waitid
tracepoint:syscalls:sys_enter_write
tracepoint:syscalls:sys_enter_writev
- Chapter 2. bpftrace로 hello world! 찍기
# Chapter 2
# hello world 찍기
[root@ip-192-168-1-134 ~]# bpftrace -e 'BEGIN { printf("hello world\n"); }'
Attaching 1 probe...
hello world
- Chapter 3. bpftrace로 파일 openat() 시스템 콜이 발생할때마다 프로세스 이름과 파일명을 출력
# Chapter 3
# file openat() 시스템 호출이 발생할때마다 프로세스 이름과 파일명을 출력하는 bpftrace script
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
kubelet /sys/fs/cgroup/hugetlb/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/hugetlb/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/hugetlb/kubepods.slice
kubelet /sys/fs/cgroup/memory/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/memory/kubepods.slice
kubelet /sys/fs/cgroup/freezer/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/freezer/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/freezer/kubepods.slice
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-besteffort.s
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-burstable.sl
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice
kubelet /sys/fs/cgroup/pids/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/pids/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/pids/kubepods.slice
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-besteff
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-burstab
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice
kubelet /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/cpuset/kubepods.slice
kubelet /sys/fs/cgroup/devices/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/devices/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/devices/kubepods.slice
kubelet /sys/fs/cgroup/systemd/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/systemd/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/systemd/kubepods.slice
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-besteffort.s
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-burstable.sl
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-besteff
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice/kubepods-burstab
kubelet /sys/fs/cgroup/net_cls,net_prio/kubepods.slice
kubelet /sys/fs/cgroup/blkio/kubepods.slice/kubepods-besteffort.slice
kubelet /sys/fs/cgroup/blkio/kubepods.slice/kubepods-burstable.slice
kubelet /sys/fs/cgroup/blkio/kubepods.slice
kubelet /sys/fs/cgroup/perf_event/kubepods.slice/kubepods-besteffort.sl
kubelet /sys/fs/cgroup/perf_event/kubepods.slice/kubepods-burstable.sli
kubelet /sys/fs/cgroup/perf_event/kubepods.slice
kubelet /var/lib/kubelet/pods
kubelet /proc/3049/net/dev
kubelet /sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-burstable.sl
kubelet /proc/3049/fd
kubelet /proc/3049/limits
kube-proxy /dev/null
ip6tables /etc/ld.so.cache
ip6tables /lib64/libip4tc.so.2
ip6tables /lib64/libip6tc.so.2
ip6tables /lib64/libxtables.so.12
ip6tables /lib64/libc.so.6
ip6tables /lib64/libpcap.so.1
ip6tables /lib64/libibverbs.so.1
ip6tables /lib64/libnl-route-3.so.200
ip6tables /lib64/libnl-3.so.200
ip6tables /etc/libnl/classid
ip6tables /run/xtables.lock
kube-proxy /dev/null
iptables /etc/ld.so.cache
iptables /lib64/libip4tc.so.2
iptables /lib64/libip6tc.so.2
iptables /lib64/libxtables.so.12
iptables /lib64/libc.so.6
iptables /lib64/libpcap.so.1
iptables /lib64/libibverbs.so.1
iptables /lib64/libnl-route-3.so.200
iptables /lib64/libnl-3.so.200
iptables /etc/libnl/classid
iptables /run/xtables.lock
^C *** 중략
- Chapter 4. bpftrace로 특정 PID의 read한 바이트 수 체크
# Chapter 4
# 특정 PID read 바이트 체크
# [0,1] 바이트는 성공적으로 호출을 받은 횟수가 1, 실패한 호출이 0임
# 2895는 kubelet PID입니다.
bpftrace -e 'tracepoint:syscalls:sys_exit_read / pid == 2895/ { @bytes = hist(args->ret); }'
Attaching 1 probe...
^C
@bytes:
(..., 0) 324 |@@@@@@@@@@@@ |
[0] 1311 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1] 101 |@@@@ |
[2, 4) 318 |@@@@@@@@@@@@ |
[4, 8) 227 |@@@@@@@@@ |
[8, 16) 251 |@@@@@@@@@ |
[16, 32) 448 |@@@@@@@@@@@@@@@@@ |
[32, 64) 64 |@@ |
[64, 128) 77 |@@@ |
[128, 256) 57 |@@ |
[256, 512) 59 |@@ |
[512, 1K) 69 |@@ |
[1K, 2K) 29 |@ |
[2K, 4K) 36 |@ |
[4K, 8K) 10 | |
[8K, 16K) 35 |@ |
[16K, 32K) 2 | |
✅ bcc 설치
# enable epel to get iperf, luajit, luajit-devel, cmake3 (cmake3 is required to support c++11)
sudo yum-config-manager --enable epel
sudo yum install -y bison cmake3 ethtool flex git iperf libstdc++-static python-netaddr python-cachetools gcc gcc-c++ make zlib-devel elfutils-libelf-devel
sudo yum install -y luajit luajit-devel
sudo yum install -y http://repo.iovisor.org/yum/extra/mageia/cauldron/x86_64/netperf-2.7.0-1.mga6.x86_64.rpm
sudo pip install pyroute2
sudo yum install -y ncurses-devel
git clone https://github.com/iovisor/bcc.git
pushd .
mkdir bcc/build; cd bcc/build
cmake3 ..
time make
sudo make install
sudo /usr/share/bcc/tools/execsnoop
bcc 이전에는 Linux에 있는 다음과 같은 명령어들로 리눅스 성능을 파악하는 도구로 활용했다.
Before using bcc, you should start with the Linux basics. One reference is the Linux Performance Analysis in 60,000 Milliseconds post, which covers these commands:
- uptime
- dmesg | tail
- vmstat 1
- mpstat -P ALL 1
- pidstat 1
- iostat -xz 1
- free -m
- sar -n DEV 1
- sar -n TCP,ETCP 1
- top
After bcc
앞으로는 이런 형태로 수집할수 있다.
biolatency : 디스크 IO latency를 시각화 해서 보여준다.
- 디스크 IO 레이턴시의 요약 히스토그램
biolatency traces disk I/O latency (time from device issue to completion), and when the tool ends (Ctrl-C, or a given interval), it prints a histogram summary of the latency.
This is great for understanding disk I/O latency beyond the average times given by tools like iostat. I/O latency outliers will be visible at the end of the distribution, as well as multi-mode distributions.
- 다량의 IO 발생 시 ( load average 10 이상 )
[root@ip-192-168-2-98 build]# sudo /usr/share/bcc/tools/biolatency
Tracing block device I/O... Hit Ctrl-C to end.
^C
usecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 0 | |
64 -> 127 : 6 | |
128 -> 255 : 88 | |
256 -> 511 : 4705 |**** |
512 -> 1023 : 12365 |************ |
1024 -> 2047 : 3576 |*** |
2048 -> 4095 : 493 | |
4096 -> 8191 : 618 | |
8192 -> 16383 : 309 | |
16384 -> 32767 : 750 | |
32768 -> 65535 : 35543 |************************************* |
65536 -> 131071 : 38363 |****************************************|
131072 -> 262143 : 9831 |********** |
262144 -> 524287 : 34 | |
- 평온할 시 ( load average 0.1 미만 )
[root@ip-192-168-2-98 ~]# sudo /usr/share/bcc/tools/biolatency
Tracing block device I/O... Hit Ctrl-C to end.
^C
usecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 0 | |
64 -> 127 : 0 | |
128 -> 255 : 0 | |
256 -> 511 : 1 | |
512 -> 1023 : 324 |****************************************|
1024 -> 2047 : 15 |*
'DevOps' 카테고리의 다른 글
[AWS EKS] (2) EKS 스터디 1주차 ( eviction ) (0) | 2025.02.04 |
---|---|
[AWS EKS] (1) EKS 스터디 1주차 ( EKS 설치 및 사용 ) (0) | 2025.02.04 |
[AWS EKS] EKS IaC with Terraform (2) (0) | 2024.04.23 |
[AWS EKS] EKS IaC with Terraform (1) (0) | 2024.04.23 |
[AWS EKS] EKS CICD (0) | 2024.04.15 |