Spuštění kontejneru s -v /:/host
příznak a spuštění perf report
v kontejneru s --symfs /host
flag to opravuje:
96.59% a.out a.out [.] function
2.93% a.out [kernel.kallsyms] [k] 0xffffffff8105144a
0.13% a.out [nvidia] [k] 0x00000000002eda57
0.11% a.out libc-2.19.so [.] vfprintf
0.11% a.out libc-2.19.so [.] 0x0000000000049980
0.09% a.out a.out [.] main
0.02% a.out libc-2.19.so [.] _IO_file_write
0.02% a.out libc-2.19.so [.] write
Část důvodu, proč to nefunguje tak, jak má? Výstup z perf script
trochu to vrhá na světlo:
...
a.out 24 3374818.880960: cycles: ffffffff81141140 __perf_event__output_id_sample ([kernel.kallsyms])
a.out 24 3374818.881012: cycles: ffffffff817319fd _raw_spin_lock_irqsave ([kernel.kallsyms])
a.out 24 3374818.882217: cycles: ffffffff8109aba3 ttwu_do_activate.constprop.75 ([kernel.kallsyms])
a.out 24 3374818.884071: cycles: 40053d [unknown] (/var/lib/docker/aufs/diff/9bd2d4389cf7ad185405245b1f5c7d24d461bd565757880bfb4f970d3f4f7915/a.out)
a.out 24 3374818.885329: cycles: 400544 [unknown] (/var/lib/docker/aufs/diff/9bd2d4389cf7ad185405245b1f5c7d24d461bd565757880bfb4f970d3f4f7915/a.out)
...
Všimněte si /var/lib/docker/aufs
cesta. Pochází od hostitele, takže v kontejneru nebude existovat a potřebujete pomoc perf report
najít to. K tomu pravděpodobně dochází, protože události mmap jsou sledovány perf mimo jakoukoli cgroup a perf se nepokouší přemapovat cesty.
Další možností je spustit perf na straně hostitele, například sudo perf record -a docker run -ti <container name>
. Zde však kolekce musí být celosystémová (-a
flag), protože kontejnery jsou vytvářeny procesem démona dockeru, který není v hierarchii procesů klientského nástroje dockeru, který zde spouštíme.
Dalším způsobem, který nevyžaduje změnu způsobu spouštění kontejneru (takže můžete profilovat již běžící proces), je připojit kořenový adresář kontejneru na hostitele pomocí bindfs:
bindfs /proc/$(docker inspect --format {{.State.Pid}} $CONTAINER_ID)/root /foo
Poté spusťte sestavu výkonu jako perf report --symfs /foo
Budete muset spustit perf record
v celém systému, ale můžete jej omezit na shromažďování událostí pouze pro konkrétní kontejner:
perf record -g -a -F 100 -e cpu-clock -G docker/$(docker inspect --format {{.Id}} $CONTAINER_ID) sleep 90