Use perf inside a docker container without - privileged
I am trying to use the perf tool inside a Docker container to record a given command.
kernel.perf_event_paranoid is set to 1, but the container behaves the same as if it was where 2, when I did not set the --privileged flag.
I could use --privileged, but the code I'm running perf on is not trustworthy and if I'm fine with little security risk letting the primary tool grant privileged rights to the container seems like another level of risk.
Is there any other way to use perf inside a container?
~$ docker version
Client:
Version: 17.03.1-ce
API version: 1.27
Go version: go1.7.5
Git commit: 7392c3b/17.03.1-ce
Built: Tue May 30 17:59:44 2017
OS/Arch: linux/amd64
Server:
Version: 17.03.1-ce
API version: 1.27 (minimum version 1.12)
Go version: go1.7.5
Git commit: 7392c3b/17.03.1-ce
Built: Tue May 30 17:59:44 2017
OS/Arch: linux/amd64
Experimental: false
~$ cat /proc/sys/kernel/perf_event_paranoid
1
~$ perf record ./my-executable
perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 1 (Operation not permitted)
perf_event_open(..., 0) failed unexpectedly with error 1 (Operation not permitted)
Error:
You may not have permission to collect stats.
Consider tweaking /proc/sys/kernel/perf_event_paranoid:
-1 - Not paranoid at all
0 - Disallow raw tracepoint access for unpriv
1 - Disallow cpu events for unpriv
2 - Disallow kernel profiling for unpriv
source to share
After some research, the problem is not with perf_event_paranoid
, but with the fact that perf_event_open
(syscall) is blacklisted in Docker: https://docs.docker.com/engine/security/seccomp/ "Docker v17.06: Seccomp security profiles for Docker "
Significant system calls are blocked by the default profile
perf_event_open
Trace / profiling system call that can leak a lot of information on the host.
My first workaround for this is to have a script that downloads the official seccomp file https://github.com/moby/moby/blob/master/profiles/seccomp/default.json and perf_event_open
whitelists System calls
Then I start docker with --security-opt seccomp=my-seccomp.json
source to share