KVM_仮想ホストからどの仮想ゲストのCPUが高いかを確認

# 概要

KVMの仮想ホストを運用していて、CPUの使用率がかなり上がっていくという事象があった。原因を調査するための方法を記載する。

# 実行内容

該当の仮想ホストから、psコマンドを実行する。まずは普通にgrep qemuでソートしてみる。
```
ps -ef | grep qemu
```

実行結果
```
[user@linux ~]$ ps -ef | grep qemu
qemu        3773       1  0  1月09 ?      17:27:57 /usr/libexec/qemu-kvm -name guest=sampe-test-vmtest-0682,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-1-sampe-test-vmtest-0/master-key.aes"} -blockdev {"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"} -blockdev {"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/sampe-test-vmtest-0682_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"} -machine pc-q35-rhel8.2.0,usb=off,vmport=off,smm=on,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=pc.ram -accel kvm -cpu Haswell-noTSX-IBRS,vme=on,ss=on,vmx=on,pdcm=on,f16c=on,rdrand=on,hypervisor=on,arat=on,tsc-adjust=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaveopt=on,pdpe1gb=on,abm=on,ibpb=on,ibrs=on,amd-stibp=on,amd-ssbd=on,skip-l1dfl-vmentry=on,pschange-mc-no=on -global driver=cfi.pflash01,property=secure,value=on -m 4096 -object {"qom-type":"memory-backend-ram","id":"pc.ram","size":4294967296} -overcommit mem-lock=off -smp 2,sockets=2,cores=1,threads=1 -uuid 3feed8a6-5f10-4220-9b99-43527f4227ae -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=33,server=on,wait=off -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on -device pcie-root-port,port=16,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2 -device pcie-root-port,port=17,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 -device pcie-root-port,port=18,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 -device pcie-root-port,port=19,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 -device pcie-root-port,port=20,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 -device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 -blockdev {"driver":"file","filename":"/var/lib/libvirt/images/sampe-test-vmtest-0682-2.img","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"} -device virtio-blk-pci,bus=pci.3,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=2 -netdev tap,fd=34,id=hostnet0,vhost=on,vhostfd=36 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:00:60:82,bus=pci.1,multifunction=on,addr=0x0 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0,bus=usb.0,port=1 -audiodev {"id":"audio1","driver":"none"} -vnc 127.0.0.1:0,audiodev=audio1 -k ja -device VGA,id=video0,vgamem_mb=16,bus=pcie.0,addr=0x1 -device virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 -object {"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"} -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.5,addr=0x0 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -device pvpanic -msg timestamp=on
qemu        4158       1  5  1月09 ?      5-06:04:36 /usr/libexec/qemu-kvm -name guest=vmname-test-0619,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-3-vmname-test-0/master-key.aes"} -blockdev {"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"} -blockdev {"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/vmname-test-0619_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"} -machine pc-q35-rhel8.2.0,usb=off,vmport=off,smm=on,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-p
```

qemuの右側に表示されているのはプロセスIDであり、これをtopコマンドと照らし合わせる事も可能
```
[user@linux ~]$ top
top - 23:32:12 up 90 days, 12:28,  1 user,  load average: 0.97, 1.04, 1.06
Tasks: 521 total,   1 running, 520 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.6 us,  0.7 sy,  0.0 ni, 97.4 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
MiB Mem : 225028.5 total,    941.6 free,  30011.8 used, 194075.1 buff/cache
MiB Swap:   8192.0 total,   7440.5 free,    751.5 used. 193390.1 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   4158 qemu      20   0 9415392   3.9g  17728 S   3.3   1.8   7564:57 qemu-kvm
   3979 gdm       20   0 7911292 226716  96788 S   0.7   0.1  93:52.55 gnome-shell
   4324 qemu      20   0 3545292 821112  17792 S   0.7   0.4 590:38.88 qemu-kvm
   4362 qemu      20   0 3438860 799468  17936 S   0.7   0.3 558:12.20 qemu-kvm
   4398 qemu      20   0 3542132 844528  17780 S   0.3   0.4 572:12.37 qemu-kvm
1178302 root      20   0       0      0      0 S   0.3   0.0   0:22.05 vhost-1178294
      1 root      20   0  241172  13888   8392 S   0.0   0.0   1:43.71 systemd
```
これにより、VMの名前が`vmname-test-0619`の場合、PIDが4158、CPUを3.3%、メモリを1.8%らしい。


ただ、上記の結果だとかなり長いので、プロセスを以下のように見やすくすることを考える。
```
ps -eo pid,ppid,user,%cpu,%mem,vsz,rss,stat,lstart,etime,time,args --sort=-%mem | head -n 10 | awk '{printf "%-10s %-10s %-10s %-6s %-6s %-10s %-10s %-6s %-25s %-10s %-10s %-s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9" "$10" "$11" "$12, $13, $14, $15}'
```
```:実行結果
[user@linux ~]$  ps -eo pid,ppid,user,%cpu,%mem,vsz,rss,stat,lstart,etime,time,args --sort=-%mem | head -n 10 | awk '{printf "%-10s %-10s %-10s %-6s %-6s %-10s %-10s %-6s %-25s %-10s %-10s %-s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9" "$10" "$11" "$12, $13, $14, $15}'
PID        PPID       USER       %CPU   %MEM   VSZ        RSS        STAT   STARTED ELAPSED TIME COMMAND
1678362    1          qemu       48.2   2.3    13822596   5453324    Sl     Tue Feb 4 23:25:59        2025       64-00:09:55 30-21:42:13
4158       1          qemu       5.8    1.7    9415392    4097564    Sl     Thu Jan 9 11:05:08        2025       90-12:30:46 5-06:05:10
5134       1          qemu       1.8    1.7    9179168    3940908    Sl     Thu Jan 9 11:14:45        2025       90-12:21:09 1-16:17:13
3773       1          qemu       0.8    1.3    9212604    3153364    Sl     Thu Jan 9 11:05:06        2025       90-12:30:48 17:28:00
1178294    1          qemu       19.2   1.2    9266860    2931416    Sl     Wed Apr 9 15:49:17        2025       07:46:37   01:30:00
1176255    1          qemu       19.3   1.2    9305016    2917428    Sl     Wed Apr 9 15:03:51        2025       08:32:03   01:39:17
5306       1          qemu       0.8    0.8    8662356    2062752    Sl     Thu Jan 9 11:15:35        2025       90-12:20:19 19:02:06
5388       1          qemu       26.2   0.8    3042212    2058884    Sl     Thu Jan 9 11:15:58        2025       90-12:19:56 23-17:14:58
4398       1          qemu       0.4    0.3    3542132    844528     Sl     Thu Jan 9 11:05:11        2025       90-12:30:43 09:32:13
```

コマンドの解説。
- ps: プロセス一覧を表示するコマンド。
- -e: 全プロセスを表示。
- -o: 出力する項目を指定。
    - pid: プロセスID
    - ppid: 親プロセスID
    - user: 実行ユーザー
    - %cpu: CPU使用率
    - %mem: メモリ使用率
    - vsz: 仮想メモリサイズ (KB)
    - rss: 実メモリ使用量 (KB)
    - stat: プロセス状態
    - lstart: プロセスの起動時刻（長い形式）
    - etime: 経過時間
    - time: CPU使用時間
    - args: 実行コマンド
- --sort=-%mem: メモリ使用率が高い順にソート

- head -n 10
    - 上位10行だけを表示

awk '{...}'
出力を整形する。

- %-10s：幅10で左寄せ
- %-6s：幅6で左寄せ
- ＄1 ~ ＄15: 各フィールド（列）を順番に指定して整形
- ＄9 ＄10 ＄11 ＄12：lstart（起動時間）は4つのフィールドに分かれているので連結して1つの文字列にしている
- 最後の $15 は args の始まり

上記の場合、PIDが`1678362`のqemuプロセスがかなり食っているようだ。
PIDを指定してゲスト名を見たい場合は以下のコマンドでも見れる。
```
ps -p <PID> -o args=
```

```
[user@linux ~]$ ps -p 1678362 -o args=
/usr/libexec/qemu-kvm -name guest=kensyo-cpu,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","f
[jst-dito@office-sboxvh-0188 ~]$
```
また、ゲストがわかったら`virsh dominfo <ゲスト名>`で、ゲストが現在使っているリソースを見れる。

```
[user@linux ~]$  sudo virsh dominfo 
Id:             30
名前:         kensyo-cpu
UUID:           900730b7-18db-4469-b6fb-8c6788ce8c7d
OS タイプ:   hvm
状態:         実行中
CPU:            4
CPU 時間:     2670773.5s
最大メモリー: 8388608 KiB
使用メモリー: 8388608 KiB
永続:         はい (yes)
自動起動:   無効にする
管理済み保存: いいえ (no)
セキュリティモデル: none
セキュリティ DOI: 0

[jst-dito@office-sboxvh-0188 ~]$
```