Skip to main content
Version: latest

Using profile cpu

The profile cpu gadget takes samples of the stack traces.

On Kubernetes

Here we deploy a small demo pod "random":

$ kubectl run --restart=Never --image=busybox random -- sh -c 'cat /dev/urandom > /dev/null'
pod/random created

Using the profile cpu gadget, we can see the list of stack traces. The following command filters only for pods named "random", execute the command and interrupt it after ~30 seconds. The -K option is passed to show only the kernel stack traces.

$ kubectl gadget profile cpu --podname random -K
Capturing stack traces... Hit Ctrl-C to end.^C

After a while press with Ctrl-C to stop trace collection

K8S.NODE         K8S.NAMESPACE    K8S.PODNAME                    K8S.CONTAINERNAME PID     COMM             COUNT
minikube default random random 340800 cat 1
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
ksys_read
vfs_read
urandom_read
urandom_read_nowarn.isra.0
extract_crng
_extract_crng
...
minikube default random random 340800 cat 9
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
vfs_read
ksys_read
urandom_read
urandom_read_nowarn.isra.0
copy_user_generic_string

From the traces above, you can see that the pod is spending CPU time in the Linux function urandom_read.

Instead of waiting, you can use the --timeout argument:

$ kubectl gadget profile cpu --timeout 5 --podname random -K
Capturing stack traces...
K8S.NODE K8S.NAMESPACE K8S.PODNAME K8S.CONTAINERNAME PID COMM COUNT
minikube default random random 340800 cat 1
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
ksys_read
vfs_read
urandom_read
urandom_read_nowarn.isra.0
extract_crng
_extract_crng
...
minikube default random random 340800 cat 9
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
vfs_read
ksys_read
urandom_read
urandom_read_nowarn.isra.0
copy_user_generic_string

This gadget also supports custom column outputting, for example:

$ kubectl gadget profile cpu --timeout 1 --podname random -o columns=k8s.node,k8s.podname
Capturing stack traces...
K8S.NODE K8S.POD
minikube random
...
minikube random

The following command is the same as default printing:

$ kubectl gadget profile cpu --timeout 1 --podname random -o columns=k8s.node,k8s.namespace,k8s.podname,k8s.containername,pid,comm,count
Capturing stack traces...
K8S.NODE K8S.NAMESPACE K8S.PODNAME K8S.CONTAINERNAME PID COMM COUNT
minikube default random random 340800 cat 1
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
ksys_read
urandom_read
vfs_read
urandom_read_nowarn.isra.0
extract_crng
_extract_crng
__lock_text_start
[unknown]
[unknown]
...
minikube default random random 340800 cat 1
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_read
ksys_read
urandom_read
vfs_read
urandom_read_nowarn.isra.0
extract_crng
_extract_crng
__lock_text_start
[unknown]
[unknown]

Finally, we need to clean up our pod:

$ kubectl delete pod random

With ig

  • Generate some kernel load:
$ docker run -d --rm --name random busybox cat /dev/urandom > /dev/null
  • Start ig:
$ sudo ./ig profile cpu -K --containername random --runtimes docker
  • Observe the results:
sudo ./ig profile cpu -K --containername random --runtimes docker
Capturing stack traces... Hit Ctrl-C to end.^C
RUNTIME.CONTAINERNAME COMM PID COUNT
random cat 641045 1
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_sendfile64
do_sendfile
splice_file_to_pipe
generic_file_splice_read
get_random_bytes_user
chacha_block_generic
chacha_permute
...
random cat 641045 5
entry_SYSCALL_64_after_hwframe
do_syscall_64
__x64_sys_sendfile64
do_sendfile
splice_file_to_pipe
generic_file_splice_read
get_random_bytes_user
chacha_block_generic
chacha_permute
  • Remove the docker container:
$ docker stop random