Skip to content

Latest commit

 

History

History
143 lines (117 loc) · 6.55 KB

File metadata and controls

143 lines (117 loc) · 6.55 KB
title weight description
Using trace exec
20
Trace new processes.

Screencast of the trace exec gadget

The trace exec gadget streams new processes creation events.

On Kubernetes

Let's deploy an example application that will spawn few new processes:

$ kubectl apply -f docs/examples/ds-myapp.yaml
daemonset.apps/myapp1-pod created
daemonset.apps/myapp2-pod created

$ kubectl get pod --show-labels -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP               NODE              NOMINATED NODE   READINESS GATES   LABELS
myapp1-pod-sbtvw   1/1     Running   0          9s    10.244.192.133   minikube-docker   <none>           <none>            controller-revision-hash=865c886d8f,myapp=app-one,name=myapp1-pod,pod-template-generation=1,role=demo
myapp2-pod-5pg4w   1/1     Running   0          9s    10.244.192.132   minikube-docker   <none>           <none>            controller-revision-hash=677d884fc,myapp=app-two,name=myapp2-pod,pod-template-generation=1,role=demo

Using the trace exec gadget, we can see which new processes are spawned on node minikube-docker where myapp1-pod-sbtvw and myapp2-pod-5pg4w are running:

$ kubectl gadget trace exec --selector role=demo --node minikube-docker
K8S.NODE        K8S.NAMESPACE K8S.POD          K8S.CONTAINER PID     PPID    COMM  PCOMM RET ARGS
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226276 2221571 true  sh    0   /bin/true
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226277 2221571 date  sh    0   /bin/date
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226278 2221571 cat   sh    0   /bin/cat /proc/version
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226279 2221571 true  sh    0   /bin/true
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226280 2221571 date  sh    0   /bin/date
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226281 2221571 cat   sh    0   /bin/cat /proc/version
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226282 2221571 true  sh    0   /bin/true
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226283 2221571 date  sh    0   /bin/date
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226284 2221571 cat   sh    0   /bin/cat /proc/version
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226286 2221571 true  sh    0   /bin/true
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226287 2221571 date  sh    0   /bin/date
minikube-docker default       myapp1-pod-sbtvw myapp1-pod    2226288 2221571 cat   sh    0   /bin/cat /proc/version
minikube-docker default       myapp2-pod-5pg4w myapp2-pod    2226289 2221280 true  sh    0   /bin/true
minikube-docker default       myapp2-pod-5pg4w myapp2-pod    2226290 2221280 date  sh    0   /bin/date
minikube-docker default       myapp2-pod-5pg4w myapp2-pod    2226291 2221280 echo  sh    0   /bin/echo sleep-10
minikube-docker default       myapp2-pod-5pg4w myapp2-pod    2226292 2221280 sleep sh    0   /bin/sleep 10
^C

Processes of both pods are spawned: myapp1 spawns cat /proc/version and sleep 1, myapp2 spawns echo sleep-10 and sleep 10, both spawn true and date. We can stop to trace again by hitting Ctrl-C.

Finally, we clean up our demo app.

$ kubectl delete -f docs/examples/ds-myapp.yaml

With ig

Let's start the gadget in a terminal:

$ sudo ig trace exec -c test-trace-exec
RUNTIME.CONTAINERNAME PID     PPID    COMM   PCOMM           RET ARGS

Run a container that executes some binaries:

$ docker run --name test-trace-exec -it --rm busybox /bin/sh -c 'while /bin/true ; do whoami ; sleep 3 ; done'

The tool will show the different processes executed by the container:

$ sudo ig trace exec -c test-trace-exec
RUNTIME.CONTAINERNAME PID     PPID    COMM   PCOMM           RET ARGS
test-trace-exec       2233189 2233166 sh     containerd-shim 0   /bin/sh -c while /bin/true ; do whoami ; sleep 3 ; done
test-trace-exec       2233214 2233189 true   sh              0   /bin/true
test-trace-exec       2233215 2233189 whoami sh              0   /bin/whoami
test-trace-exec       2233567 2233189 true   sh              0   /bin/true
test-trace-exec       2233570 2233189 whoami sh              0   /bin/whoami
test-trace-exec       2233642 2233189 true   sh              0   /bin/true
test-trace-exec       2233643 2233189 whoami sh              0   /bin/whoami
test-trace-exec       2233757 2233189 true   sh              0   /bin/true
test-trace-exec       2233758 2233189 whoami sh              0   /bin/whoami
test-trace-exec       2233931 2233189 true   sh              0   /bin/true
test-trace-exec       2233932 2233189 whoami sh              0   /bin/whoami

--paths

Optionally, this gadget can provide the current working directory of the process calling exec() and the full path of the executable. This is disabled by default and can be enabled by passing the --paths flag:

$ sudo ig trace exec
RUNTIME.CONTAINERNAME PID    PPID   COMM  RET ARGS
test                  644871 639225 mkdir 0   /usr/bin/mkdir -p /tmp/bar/foo/
test                  644888 639225 cat   0   /usr/bin/cat /dev/null
$ sudo ig trace exec --paths
RUNTIME.CONTAINERN… PID    PPID   COMM  RET ARGS                     CWD EXEPATH
test                644377 639225 mkdir 0   /usr/bin/mkdir -p /tmp/… /   /usr/bin/mkdir
test                644497 639225 cat   0   /usr/bin/cat /dev/null   /   /usr/bin/cat

Overlay filesystem upper layer

It can be useful to know if the executable in a container was modified or part of the original container image. If it was modified, it will be located in the upper layer of the overlay filesystem. For this reason, this gadget provides the upper layer field which is true if the executable is located in the upper layer of the overlay filesystem.

$ sudo ig trace exec -c test -o columns=comm,ret,upperlayer
COMM             RET UPPERLAYER
sh               0   false
cp               0   false
echo             0   false
echo2            0   true
$ docker run -ti --rm --name=test ubuntu \
    sh -c 'cp /bin/echo /bin/echo2 ; /bin/echo lower ; /bin/echo2 upper'
lower
upper

Limitations:

  • The upper layer field is only available when the executable is executed correctly (ret=0). For example, if the executable does not have the "execute" permission, the execution will fail and the upper layer field will not be defined.
  • In case of a shell script, the upper layer field will refer to the location of the shell program (e.g. /bin/sh) and not the script file.